diff options
author | Alexander Kabaev <kan@FreeBSD.org> | 2004-07-28 03:12:05 +0000 |
---|---|---|
committer | Alexander Kabaev <kan@FreeBSD.org> | 2004-07-28 03:12:05 +0000 |
commit | ffeaf689a248da869b6bc8d4fd2233dfe513c060 (patch) | |
tree | 75ef0e6da73746d6849e25a0996ae34e1aeff51d /contrib/libstdc++/include | |
parent | 9a63ad9273061dc19cbd117762e365ea9634e241 (diff) | |
download | src-ffeaf689a248da869b6bc8d4fd2233dfe513c060.tar.gz src-ffeaf689a248da869b6bc8d4fd2233dfe513c060.zip |
Gcc 3.4.2 20040728 C++ support bits.
Notes
Notes:
svn path=/vendor/gcc/dist/; revision=132720
Diffstat (limited to 'contrib/libstdc++/include')
234 files changed, 45429 insertions, 20174 deletions
diff --git a/contrib/libstdc++/include/Makefile.am b/contrib/libstdc++/include/Makefile.am index cf1510200ab9..34e20338ae6f 100644 --- a/contrib/libstdc++/include/Makefile.am +++ b/contrib/libstdc++/include/Makefile.am @@ -1,6 +1,6 @@ ## Makefile for the include subdirectory of the GNU C++ Standard library. ## -## Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +## Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. ## ## This file is part of the libstdc++ version 3 distribution. ## Process this file with automake to produce Makefile.in. @@ -21,22 +21,10 @@ ## Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, ## USA. -AUTOMAKE_OPTIONS = 1.3 cygnus -MAINT_CHARSET = latin1 - -mkinstalldirs = $(SHELL) $(toplevel_srcdir)/mkinstalldirs - -# Cross compiler and multilib support. -CXX = @glibcpp_CXX@ -glibcpp_srcdir=@glibcpp_srcdir@ -glibcpp_builddir=@glibcpp_builddir@ - -GLIBCPP_INCLUDES = @GLIBCPP_INCLUDES@ -LIBSUPCXX_INCLUDES = @LIBSUPCXX_INCLUDES@ -INCLUDES = -nostdinc++ $(GLIBCPP_INCLUDES) $(LIBSUPCXX_INCLUDES) +include $(top_srcdir)/fragment.am # Standard C++ includes. -std_srcdir = ${glibcpp_srcdir}/include/std +std_srcdir = ${glibcxx_srcdir}/include/std std_builddir = . std_headers = \ ${std_srcdir}/std_algorithm.h \ @@ -68,7 +56,7 @@ std_headers = \ ${std_srcdir}/std_utility.h \ ${std_srcdir}/std_valarray.h \ ${std_srcdir}/std_vector.h -# Renamed at build time. +# Renamed at build time. std_headers_rename = \ algorithm \ bitset \ @@ -100,9 +88,11 @@ std_headers_rename = \ valarray \ vector -bits_srcdir = ${glibcpp_srcdir}/include/bits +bits_srcdir = ${glibcxx_srcdir}/include/bits bits_builddir = ./bits bits_headers = \ + ${bits_srcdir}/allocator.h \ + ${bits_srcdir}/atomicity.h \ ${bits_srcdir}/basic_ios.h \ ${bits_srcdir}/basic_ios.tcc \ ${bits_srcdir}/basic_string.h \ @@ -111,9 +101,9 @@ bits_headers = \ ${bits_srcdir}/char_traits.h \ ${bits_srcdir}/codecvt.h \ ${bits_srcdir}/concept_check.h \ + ${bits_srcdir}/concurrence.h \ ${bits_srcdir}/cpp_type_traits.h \ ${bits_srcdir}/deque.tcc \ - ${bits_srcdir}/fpos.h \ ${bits_srcdir}/fstream.tcc \ ${bits_srcdir}/functexcept.h \ ${bits_srcdir}/gslice.h \ @@ -128,14 +118,13 @@ bits_headers = \ ${bits_srcdir}/localefwd.h \ ${bits_srcdir}/mask_array.h \ ${bits_srcdir}/ostream.tcc \ - ${bits_srcdir}/pthread_allocimpl.h \ + ${bits_srcdir}/postypes.h \ ${bits_srcdir}/stream_iterator.h \ ${bits_srcdir}/streambuf_iterator.h \ ${bits_srcdir}/slice_array.h \ ${bits_srcdir}/sstream.tcc \ ${bits_srcdir}/stl_algo.h \ ${bits_srcdir}/stl_algobase.h \ - ${bits_srcdir}/stl_alloc.h \ ${bits_srcdir}/stl_bvector.h \ ${bits_srcdir}/stl_construct.h \ ${bits_srcdir}/stl_deque.h \ @@ -150,7 +139,6 @@ bits_headers = \ ${bits_srcdir}/stl_multiset.h \ ${bits_srcdir}/stl_numeric.h \ ${bits_srcdir}/stl_pair.h \ - ${bits_srcdir}/stl_pthread_alloc.h \ ${bits_srcdir}/stl_queue.h \ ${bits_srcdir}/stl_raw_storage_iter.h \ ${bits_srcdir}/stl_relops.h \ @@ -166,10 +154,11 @@ bits_headers = \ ${bits_srcdir}/type_traits.h \ ${bits_srcdir}/valarray_array.h \ ${bits_srcdir}/valarray_array.tcc \ - ${bits_srcdir}/valarray_meta.h \ + ${bits_srcdir}/valarray_before.h \ + ${bits_srcdir}/valarray_after.h \ ${bits_srcdir}/vector.tcc -backward_srcdir = ${glibcpp_srcdir}/include/backward +backward_srcdir = ${glibcxx_srcdir}/include/backward backward_builddir = ./backward backward_headers = \ ${backward_srcdir}/complex.h \ @@ -209,28 +198,36 @@ backward_headers = \ ${backward_srcdir}/strstream \ ${backward_srcdir}/backward_warning.h -ext_srcdir = ${glibcpp_srcdir}/include/ext +ext_srcdir = ${glibcxx_srcdir}/include/ext ext_builddir = ./ext ext_headers = \ ${ext_srcdir}/algorithm \ + ${ext_srcdir}/bitmap_allocator.h \ + ${ext_srcdir}/debug_allocator.h \ + ${ext_srcdir}/demangle.h \ ${ext_srcdir}/enc_filebuf.h \ ${ext_srcdir}/stdio_filebuf.h \ + ${ext_srcdir}/stdio_sync_filebuf.h \ ${ext_srcdir}/functional \ ${ext_srcdir}/hash_map \ ${ext_srcdir}/hash_set \ ${ext_srcdir}/iterator \ + ${ext_srcdir}/malloc_allocator.h \ ${ext_srcdir}/memory \ + ${ext_srcdir}/mt_allocator.h \ + ${ext_srcdir}/new_allocator.h \ ${ext_srcdir}/numeric \ + ${ext_srcdir}/pod_char_traits.h \ + ${ext_srcdir}/pool_allocator.h \ ${ext_srcdir}/rb_tree \ ${ext_srcdir}/rope \ ${ext_srcdir}/ropeimpl.h \ ${ext_srcdir}/slist \ - ${ext_srcdir}/stl_hash_fun.h \ - ${ext_srcdir}/stl_hashtable.h \ - ${ext_srcdir}/stl_rope.h + ${ext_srcdir}/hash_fun.h \ + ${ext_srcdir}/hashtable.h # This is the common subset of files that all three "C" header models use. -c_base_srcdir = @C_INCLUDE_DIR@ +c_base_srcdir = $(C_INCLUDE_DIR) c_base_builddir = . c_base_headers = \ ${c_base_srcdir}/std_cassert.h \ @@ -250,7 +247,7 @@ c_base_headers = \ ${c_base_srcdir}/std_cstring.h \ ${c_base_srcdir}/std_ctime.h \ ${c_base_srcdir}/std_cwchar.h \ - ${c_base_srcdir}/std_cwctype.h + ${c_base_srcdir}/std_cwctype.h c_base_headers_rename = \ cassert \ cctype \ @@ -269,10 +266,10 @@ c_base_headers_rename = \ cstring \ ctime \ cwchar \ - cwctype + cwctype # "C" compatibility headers. -c_compatibility_srcdir = ${glibcpp_srcdir}/include/c_compatibility +c_compatibility_srcdir = ${glibcxx_srcdir}/include/c_compatibility c_compatibility_builddir = . c_compatibility_headers = \ ${c_compatibility_srcdir}/assert.h \ @@ -292,60 +289,108 @@ c_compatibility_headers = \ ${c_compatibility_srcdir}/string.h \ ${c_compatibility_srcdir}/time.h \ ${c_compatibility_srcdir}/wchar.h \ - ${c_compatibility_srcdir}/wctype.h + ${c_compatibility_srcdir}/wctype.h + +# Debug mode headers +debug_srcdir = ${glibcxx_srcdir}/include/debug +debug_builddir = ./debug +debug_headers = \ + ${debug_srcdir}/bitset \ + ${debug_srcdir}/debug.h \ + ${debug_srcdir}/deque \ + ${debug_srcdir}/formatter.h \ + ${debug_srcdir}/hash_map \ + ${debug_srcdir}/hash_map.h \ + ${debug_srcdir}/hash_multimap.h \ + ${debug_srcdir}/hash_multiset.h \ + ${debug_srcdir}/hash_set \ + ${debug_srcdir}/hash_set.h \ + ${debug_srcdir}/list \ + ${debug_srcdir}/map \ + ${debug_srcdir}/map.h \ + ${debug_srcdir}/multimap.h \ + ${debug_srcdir}/multiset.h \ + ${debug_srcdir}/safe_base.h \ + ${debug_srcdir}/safe_iterator.h \ + ${debug_srcdir}/safe_iterator.tcc \ + ${debug_srcdir}/safe_sequence.h \ + ${debug_srcdir}/set \ + ${debug_srcdir}/set.h \ + ${debug_srcdir}/string \ + ${debug_srcdir}/vector # Some of the different "C" header models need extra files. # Some "C" header schemes require the "C" compatibility headers. # For --enable-cheaders=c_std -if GLIBCPP_C_HEADERS_C_STD -c_base_headers_extra = ${c_base_srcdir}/cmath.tcc +if GLIBCXX_C_HEADERS_C_STD +c_base_headers_extra = ${c_base_srcdir}/cmath.tcc else -c_base_headers_extra = +c_base_headers_extra = endif -if GLIBCPP_C_HEADERS_COMPATIBILITY +if GLIBCXX_C_HEADERS_COMPATIBILITY c_compatibility_headers_extra = ${c_compatibility_headers} else -c_compatibility_headers_extra = +c_compatibility_headers_extra = endif -target_srcdir = ${glibcpp_srcdir}/@OS_INC_SRCDIR@ -target_builddir = ./${target_alias}/bits -target_headers = \ - ${target_srcdir}/ctype_base.h \ - ${target_srcdir}/ctype_inline.h \ - ${target_srcdir}/ctype_noninline.h \ - ${target_srcdir}/os_defines.h \ - ${glibcpp_srcdir}/@ATOMICITY_INC_SRCDIR@/atomicity.h - -# Non-installed target_header files. -target_headers_noinst = \ - ${glibcpp_srcdir}/@CLOCALE_INTERNAL_H@ - -# These target_headers_extra files are all built with ad hoc naming rules. -target_headers_extra = \ - ${target_builddir}/basic_file.h \ - ${target_builddir}/c++config.h \ - ${target_builddir}/c++io.h \ - ${target_builddir}/c++locale.h \ - ${target_builddir}/messages_members.h \ - ${target_builddir}/time_members.h \ - ${target_builddir}/codecvt_specializations.h - -thread_target_headers = \ - ${target_builddir}/gthr.h \ - ${target_builddir}/gthr-single.h \ - ${target_builddir}/gthr-posix.h \ - ${target_builddir}/gthr-default.h +host_srcdir = ${glibcxx_srcdir}/$(OS_INC_SRCDIR) +host_builddir = ./${host_alias}/bits +host_headers = \ + ${host_srcdir}/ctype_base.h \ + ${host_srcdir}/ctype_inline.h \ + ${host_srcdir}/ctype_noninline.h \ + ${host_srcdir}/os_defines.h \ + ${glibcxx_srcdir}/$(ATOMIC_WORD_SRCDIR)/atomic_word.h + +# Non-installed host_header files. +host_headers_noinst = \ + ${glibcxx_srcdir}/$(CLOCALE_INTERNAL_H) + +# These host_headers_extra files are all built with ad hoc naming rules. +host_headers_extra = \ + ${host_builddir}/basic_file.h \ + ${host_builddir}/c++config.h \ + ${host_builddir}/c++allocator.h \ + ${host_builddir}/c++io.h \ + ${host_builddir}/c++locale.h \ + ${host_builddir}/messages_members.h \ + ${host_builddir}/time_members.h \ + ${host_builddir}/codecvt_specializations.h + +thread_host_headers = \ + ${host_builddir}/gthr.h \ + ${host_builddir}/gthr-single.h \ + ${host_builddir}/gthr-posix.h \ + ${host_builddir}/gthr-default.h + +pch_input = ${host_builddir}/stdc++.h +pch_output_builddir = ${host_builddir}/stdc++.h.gch +pch_source = ${glibcxx_srcdir}/include/stdc++.h +PCHFLAGS=-Winvalid-pch -Wno-deprecated -x c++-header $(CXXFLAGS) +if GLIBCXX_BUILD_PCH +pch_build = ${pch_input} +pch_install = install-pch +else +pch_build = +pch_install = +endif # List of all timestamp files. By keeping only one copy of this list, both # CLEANFILES and all-local are kept up-to-date. -allstamps = \ +allstamped = \ stamp-std stamp-bits stamp-c_base stamp-c_compatibility \ - stamp-backward stamp-ext stamp-target + stamp-backward stamp-ext stamp-debug stamp-host + +# List of all files that are created by explicit building, editing, or +# catenation. +allcreated = \ + ${host_builddir}/c++config.h \ + ${thread_host_headers} \ + ${pch_build} # Here are the rules for building the headers -all-local: ${target_builddir}/c++config.h ${thread_target_headers} ${allstamps} +all-local: ${allstamped} ${allcreated} # This rule is slightly different, in that we must change the name of the # local file from std_foo.h to foo. @@ -353,124 +398,151 @@ stamp-std: ${std_headers} @if [ ! -d "${std_builddir}" ]; then \ mkdir -p ${std_builddir} ;\ fi ;\ - (cd ${std_builddir} && for h in $?; do \ - official_name=`echo $$h | sed -e 's,.*/std_,,' -e 's,\.h$$,,'` ;\ - @LN_S@ $$h ./$${official_name} || true ;\ - done) ;\ - echo `date` > stamp-std - -stamp-std-precompile: stamp-std - for h in ${std_headers_rename}; do \ - $(CXX) -Winvalid-pch -x c++-header $(INCLUDES) $${h}; \ - done; \ - echo `date` > stamp-std-precompile + if [ ! -f stamp-std ]; then \ + (cd ${std_builddir} && for h in $?; do \ + official_name=`echo $$h | sed -e 's,.*/std_,,' -e 's,\.h$$,,'` ;\ + $(LN_S) $$h ./$${official_name} || true ;\ + done) ;\ + fi ;\ + $(STAMP) stamp-std stamp-bits: ${bits_headers} @if [ ! -d "${bits_builddir}" ]; then \ mkdir -p ${bits_builddir} ;\ fi ;\ - (cd ${bits_builddir} && @LN_S@ $? . || true) ;\ - echo `date` > stamp-bits + if [ ! -f stamp-bits ]; then \ + (cd ${bits_builddir} && $(LN_S) $? . || true) ;\ + fi ;\ + $(STAMP) stamp-bits -stamp-c_base: stamp-bits ${c_base_headers} ${c_base_headers_extra} +stamp-c_base: stamp-bits ${c_base_headers} ${c_base_headers_extra} @if [ ! -d "${c_base_builddir}" ]; then \ mkdir -p ${c_base_builddir} ;\ fi ;\ - (cd ${c_base_builddir} && for h in ${c_base_headers}; do \ - official_name=`echo $$h | sed -e 's,.*/std_,,' -e 's,\.h$$,,'` ;\ - @LN_S@ $$h ./$${official_name} || true ;\ - done) ;\ - if [ ! -z "${c_base_headers_extra}" ]; then \ - (cd ${bits_builddir} && @LN_S@ ${c_base_headers_extra} . || true) ;\ + if [ ! -f stamp-c_base ]; then \ + (cd ${c_base_builddir} && for h in ${c_base_headers}; do \ + official_name=`echo $$h | sed -e 's,.*/std_,,' -e 's,\.h$$,,'` ;\ + $(LN_S) $$h ./$${official_name} || true ;\ + done) ;\ + if [ ! -z "${c_base_headers_extra}" ]; then \ + (cd ${bits_builddir} && $(LN_S) ${c_base_headers_extra} . || true) ;\ + fi ;\ fi ;\ - echo `date` > stamp-c_base + $(STAMP) stamp-c_base stamp-c_compatibility: ${c_compatibility_headers_extra} @if [ ! -d "${c_compatibility_builddir}" ]; then \ mkdir -p ${c_compatibility_builddir} ;\ fi ;\ - if [ ! -z "${c_compatibility_headers_extra}" ]; then \ - (cd ${c_compatibility_builddir} && @LN_S@ $? . || true) ;\ + if [ ! -f stamp-c_compatibility ]; then \ + if [ ! -z "${c_compatibility_headers_extra}" ]; then \ + (cd ${c_compatibility_builddir} && $(LN_S) $? . || true) ;\ + fi ;\ fi ;\ - echo `date` > stamp-c_compatibility + $(STAMP) stamp-c_compatibility stamp-backward: ${backward_headers} @if [ ! -d "${backward_builddir}" ]; then \ mkdir -p ${backward_builddir} ;\ fi ;\ - (cd ${backward_builddir} && @LN_S@ $? . || true) ;\ - echo `date` > stamp-backward + if [ ! -f stamp-backward ]; then \ + (cd ${backward_builddir} && $(LN_S) $? . || true) ;\ + fi ;\ + $(STAMP) stamp-backward stamp-ext: ${ext_headers} @if [ ! -d "${ext_builddir}" ]; then \ - mkdir -p ${ext_builddir} ;\ + mkdir -p ${ext_builddir} ;\ + fi ;\ + if [ ! -f stamp-ext ]; then \ + (cd ${ext_builddir} && $(LN_S) $? . || true) ;\ + fi ;\ + $(STAMP) stamp-ext + +stamp-debug: ${debug_headers} + @if [ ! -d "${debug_builddir}" ]; then \ + mkdir -p ${debug_builddir} ;\ + fi ;\ + if [ ! -f stamp-debug ]; then \ + (cd ${debug_builddir} && @LN_S@ $? . || true) ;\ fi ;\ - (cd ${ext_builddir} && @LN_S@ $? . || true) ;\ - echo `date` > stamp-ext - -stamp-${target_alias}: - @if [ ! -d ${target_builddir} ]; then \ - mkdir -p ${target_builddir} ;\ - echo `date` > stamp-${target_alias} ;\ - fi - -# Target includes static. -# XXX Missing dependency info for {target_headers_extra} -stamp-target: ${target_headers} ${target_headers_noinst} stamp-${target_alias} - @if [ ! -f stamp-target ]; then \ - (cd ${target_builddir} ;\ - @LN_S@ ${target_headers} . || true ;\ - @LN_S@ ${glibcpp_srcdir}/@BASIC_FILE_H@ basic_file.h || true ;\ - @LN_S@ ${glibcpp_srcdir}/@CSTDIO_H@ c++io.h || true ;\ - @LN_S@ ${glibcpp_srcdir}/@CLOCALE_H@ c++locale.h || true ;\ - @LN_S@ ${glibcpp_srcdir}/@CLOCALE_INTERNAL_H@ . || true ;\ - @LN_S@ ${glibcpp_srcdir}/@CMESSAGES_H@ messages_members.h || true ;\ - @LN_S@ ${glibcpp_srcdir}/@CTIME_H@ time_members.h || true ;\ - @LN_S@ ${glibcpp_srcdir}/@CCODECVT_H@ codecvt_specializations.h || true);\ - echo `date` > stamp-target ; \ - fi - -# Target includes dynamic. -${target_builddir}/c++config.h: ${CONFIG_HEADER} \ - ${glibcpp_srcdir}/include/bits/c++config \ - stamp-${target_alias} - @cat ${glibcpp_srcdir}/include/bits/c++config > $@ ;\ - sed -e 's/HAVE_/_GLIBCPP_HAVE_/g' \ - -e 's/PACKAGE/_GLIBCPP_PACKAGE/g' \ - -e 's/VERSION/_GLIBCPP_VERSION/g' \ - -e 's/WORDS_/_GLIBCPP_WORDS_/g' \ + $(STAMP) stamp-debug + +stamp-${host_alias}: + @if [ ! -d ${host_builddir} ]; then \ + mkdir -p ${host_builddir} ;\ + fi ;\ + $(STAMP) stamp-${host_alias} + +# Host includes static. +# XXX Missing dependency info for {host_headers_extra} +stamp-host: ${host_headers} ${host_headers_noinst} stamp-${host_alias} + @if [ ! -f stamp-host ]; then \ + (cd ${host_builddir} ;\ + $(LN_S) ${host_headers} . || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_H) basic_file.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(ALLOCATOR_H) c++allocator.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CSTDIO_H) c++io.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CLOCALE_H) c++locale.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CLOCALE_INTERNAL_H) . || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CMESSAGES_H) messages_members.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CTIME_H) time_members.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CCODECVT_H) codecvt_specializations.h || true);\ + fi ;\ + $(STAMP) stamp-host + +# Host includes dynamic. +${host_builddir}/c++config.h: ${top_builddir}/config.h \ + ${glibcxx_srcdir}/include/bits/c++config \ + stamp-${host_alias} + @cat ${glibcxx_srcdir}/include/bits/c++config > $@ ;\ + sed -e 's/HAVE_/_GLIBCXX_HAVE_/g' \ + -e 's/PACKAGE/_GLIBCXX_PACKAGE/g' \ + -e 's/VERSION/_GLIBCXX_VERSION/g' \ + -e 's/WORDS_/_GLIBCXX_WORDS_/g' \ < ${CONFIG_HEADER} >> $@ ;\ - echo "#endif // _CPP_CPPCONFIG_" >>$@ + echo "#endif // _CXXCONFIG_" >>$@ -# Target includes for threads -glibcpp_thread_h = @glibcpp_thread_h@ +# Host includes for threads uppercase = [ABCDEFGHIJKLMNOPQRSTUVWXYZ_] -${target_builddir}/gthr.h: ${toplevel_srcdir}/gcc/gthr.h stamp-${target_alias} - sed -e '/^#/s/\(${uppercase}${uppercase}*\)/_GLIBCPP_\1/g' \ +${host_builddir}/gthr.h: ${toplevel_srcdir}/gcc/gthr.h stamp-${host_alias} + sed -e '/^#/s/\(${uppercase}${uppercase}*\)/_GLIBCXX_\1/g' \ + -e 's/_GLIBCXX_SUPPORTS_WEAK/__GXX_WEAK__/g' \ -e 's,^#include "\(.*\)",#include <bits/\1>,g' \ < ${toplevel_srcdir}/gcc/gthr.h > $@ -${target_builddir}/gthr-single.h: ${toplevel_srcdir}/gcc/gthr-single.h \ - stamp-${target_alias} - sed -e 's/\(UNUSED\)/_GLIBCPP_\1/g' \ - -e 's/\(GCC${uppercase}*_H\)/_GLIBCPP_\1/g' \ +${host_builddir}/gthr-single.h: ${toplevel_srcdir}/gcc/gthr-single.h \ + stamp-${host_alias} + sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \ + -e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \ < ${toplevel_srcdir}/gcc/gthr-single.h > $@ -${target_builddir}/gthr-posix.h: ${toplevel_srcdir}/gcc/gthr-posix.h \ - stamp-${target_alias} - sed -e 's/\(UNUSED\)/_GLIBCPP_\1/g' \ - -e 's/\(GCC${uppercase}*_H\)/_GLIBCPP_\1/g' \ - -e 's/\(${uppercase}*WEAK\)/_GLIBCPP_\1/g' \ +${host_builddir}/gthr-posix.h: ${toplevel_srcdir}/gcc/gthr-posix.h \ + stamp-${host_alias} + sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \ + -e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \ + -e 's/SUPPORTS_WEAK/__GXX_WEAK__/g' \ + -e 's/\(${uppercase}*USE_WEAK\)/_GLIBCXX_\1/g' \ < ${toplevel_srcdir}/gcc/gthr-posix.h > $@ -${target_builddir}/gthr-default.h: ${toplevel_srcdir}/gcc/${glibcpp_thread_h} \ - stamp-${target_alias} - sed -e 's/\(UNUSED\)/_GLIBCPP_\1/g' \ - -e 's/\(GCC${uppercase}*_H\)/_GLIBCPP_\1/g' \ - -e 's/\(${uppercase}*WEAK\)/_GLIBCPP_\1/g' \ +${host_builddir}/gthr-default.h: ${toplevel_srcdir}/gcc/${glibcxx_thread_h} \ + stamp-${host_alias} + sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \ + -e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \ + -e 's/SUPPORTS_WEAK/__GXX_WEAK__/g' \ + -e 's/\(${uppercase}*USE_WEAK\)/_GLIBCXX_\1/g' \ -e 's,^#include "\(.*\)",#include <bits/\1>,g' \ - < ${toplevel_srcdir}/gcc/${glibcpp_thread_h} > $@ + < ${toplevel_srcdir}/gcc/${glibcxx_thread_h} > $@ + +# Build a precompiled C++ include, stdc++.h.gch. +${pch_input}: ${allstamped} ${host_builddir}/c++config.h ${pch_source} + touch ${pch_input}; \ + if [ ! -d "${pch_output_builddir}" ]; then \ + mkdir -p ${pch_output_builddir}; \ + fi; \ + $(CXX) $(PCHFLAGS) $(AM_CPPFLAGS) ${pch_source} -O0 -g -o ${pch_output_builddir}/O0g; \ + $(CXX) $(PCHFLAGS) $(AM_CPPFLAGS) ${pch_source} -O2 -g -o ${pch_output_builddir}/O2g; # For robustness sake (in light of junk files or in-source # configuration), copy from the build or source tree to the install @@ -478,10 +550,33 @@ ${target_builddir}/gthr-default.h: ${toplevel_srcdir}/gcc/${glibcpp_thread_h} \ # components. Yes, with minor differences, this is sheer duplication # of the staging rules above using $(INSTALL_DATA) instead of LN_S and # `$(mkinstalldirs)' instead of `mkdir -p'. In particular, -# target_headers_extra are taken out of the build tree staging area; +# host_headers_extra are taken out of the build tree staging area; # the rest are taken from the original source tree. -gxx_include_dir = @gxx_include_dir@ -install-data-local: + +if GLIBCXX_HOSTED +install-data-local: install-headers ${pch_install} +else +install-data-local: install-freestanding-headers +endif + +# This is a subset of the full install-headers rule. We only need <cstddef>, +# <limits>, <cstdlib>, <cstdarg>, <new>, <typeinfo>, <exception>, and any +# files which they include (and which we provide). The last three headers +# are installed by libsupc++, so only the first four and the sub-includes +# are copied here. +install-freestanding-headers: + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir} + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${host_builddir} + for file in ${host_srcdir}/os_defines.h ${host_builddir}/c++config.h; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${host_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${std_builddir} + $(INSTALL_DATA) ${std_builddir}/limits $(DESTDIR)${gxx_include_dir}/${std_builddir} + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${c_base_builddir} + for file in cstddef cstdlib cstdarg; do \ + $(INSTALL_DATA) ${c_base_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${c_base_builddir}; done + +# The real deal. +install-headers: $(mkinstalldirs) $(DESTDIR)${gxx_include_dir} $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${bits_builddir} for file in ${bits_headers}; do \ @@ -504,13 +599,21 @@ install-data-local: $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${std_builddir} for file in ${std_headers_rename}; do \ $(INSTALL_DATA) ${std_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${std_builddir}; done - $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${target_builddir} - for file in ${target_headers} ${target_headers_extra} \ - ${thread_target_headers}; do \ - $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${target_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${debug_builddir} + for file in ${debug_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${debug_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${host_builddir} + for file in ${host_headers} ${host_headers_extra} \ + ${thread_host_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${host_builddir}; done + +install-pch: + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${pch_output_builddir} + for file in ${pch_output_builddir}/*; do \ + $(INSTALL_DATA) $$file $(DESTDIR)${gxx_include_dir}/${pch_output_builddir}; done # By adding these files here, automake will remove them for 'make clean' -CLEANFILES = *.pch stamp-std-precompile +CLEANFILES = ${pch_input} ${pch_output_builddir}/* # Stop implicit '.o' make rules from ever stomping on extensionless # headers, in the improbable case where some foolish, crack-addled diff --git a/contrib/libstdc++/include/Makefile.in b/contrib/libstdc++/include/Makefile.in index b6cc4515109c..aad3d17f9569 100644 --- a/contrib/libstdc++/include/Makefile.in +++ b/contrib/libstdc++/include/Makefile.in @@ -1,6 +1,8 @@ -# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am +# Makefile.in generated by automake 1.7.8 from Makefile.am. +# @configure_input@ -# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +# Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -10,71 +12,52 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. - -SHELL = @SHELL@ +@SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include - -DESTDIR = - pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ - top_builddir = .. -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -transform = @program_transform_name@ - +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : -build_alias = @build_alias@ build_triplet = @build@ -host_alias = @host_alias@ host_triplet = @host@ -target_alias = @target_alias@ target_triplet = @target@ +ACLOCAL = @ACLOCAL@ +ALLOCATOR_H = @ALLOCATOR_H@ +ALLOCATOR_NAME = @ALLOCATOR_NAME@ +AMTAR = @AMTAR@ AR = @AR@ AS = @AS@ -ATOMICITY_INC_SRCDIR = @ATOMICITY_INC_SRCDIR@ +ATOMICITY_SRCDIR = @ATOMICITY_SRCDIR@ +ATOMIC_WORD_SRCDIR = @ATOMIC_WORD_SRCDIR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASIC_FILE_CC = @BASIC_FILE_CC@ BASIC_FILE_H = @BASIC_FILE_H@ CC = @CC@ -CCODECVT_C = @CCODECVT_C@ CCODECVT_CC = @CCODECVT_CC@ CCODECVT_H = @CCODECVT_H@ CCOLLATE_CC = @CCOLLATE_CC@ CCTYPE_CC = @CCTYPE_CC@ +CFLAGS = @CFLAGS@ CLOCALE_CC = @CLOCALE_CC@ CLOCALE_H = @CLOCALE_H@ CLOCALE_INTERNAL_H = @CLOCALE_INTERNAL_H@ @@ -83,36 +66,73 @@ CMESSAGES_H = @CMESSAGES_H@ CMONEY_CC = @CMONEY_CC@ CNUMERIC_CC = @CNUMERIC_CC@ CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ CSTDIO_H = @CSTDIO_H@ CTIME_CC = @CTIME_CC@ CTIME_H = @CTIME_H@ +CXX = @CXX@ CXXCPP = @CXXCPP@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ C_INCLUDE_DIR = @C_INCLUDE_DIR@ DEBUG_FLAGS = @DEBUG_FLAGS@ -DLLTOOL = @DLLTOOL@ +DEFS = @DEFS@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_CXX_FLAGS = @EXTRA_CXX_FLAGS@ -GCJ = @GCJ@ -GCJFLAGS = @GCJFLAGS@ -GLIBCPP_IS_CROSS_COMPILING = @GLIBCPP_IS_CROSS_COMPILING@ -LIBIO_INCLUDES = @LIBIO_INCLUDES@ +GLIBCXX_BUILD_DEBUG_FALSE = @GLIBCXX_BUILD_DEBUG_FALSE@ +GLIBCXX_BUILD_DEBUG_TRUE = @GLIBCXX_BUILD_DEBUG_TRUE@ +GLIBCXX_BUILD_PCH_FALSE = @GLIBCXX_BUILD_PCH_FALSE@ +GLIBCXX_BUILD_PCH_TRUE = @GLIBCXX_BUILD_PCH_TRUE@ +GLIBCXX_BUILD_VERSIONED_SHLIB_FALSE = @GLIBCXX_BUILD_VERSIONED_SHLIB_FALSE@ +GLIBCXX_BUILD_VERSIONED_SHLIB_TRUE = @GLIBCXX_BUILD_VERSIONED_SHLIB_TRUE@ +GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE = @GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE@ +GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE = @GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE@ +GLIBCXX_C_HEADERS_C_FALSE = @GLIBCXX_C_HEADERS_C_FALSE@ +GLIBCXX_C_HEADERS_C_STD_FALSE = @GLIBCXX_C_HEADERS_C_STD_FALSE@ +GLIBCXX_C_HEADERS_C_STD_TRUE = @GLIBCXX_C_HEADERS_C_STD_TRUE@ +GLIBCXX_C_HEADERS_C_TRUE = @GLIBCXX_C_HEADERS_C_TRUE@ +GLIBCXX_HOSTED_FALSE = @GLIBCXX_HOSTED_FALSE@ +GLIBCXX_HOSTED_TRUE = @GLIBCXX_HOSTED_TRUE@ +GLIBCXX_INCLUDES = @GLIBCXX_INCLUDES@ +GLIBCXX_TEST_ABI_FALSE = @GLIBCXX_TEST_ABI_FALSE@ +GLIBCXX_TEST_ABI_TRUE = @GLIBCXX_TEST_ABI_TRUE@ +GLIBCXX_TEST_WCHAR_T_FALSE = @GLIBCXX_TEST_WCHAR_T_FALSE@ +GLIBCXX_TEST_WCHAR_T_TRUE = @GLIBCXX_TEST_WCHAR_T_TRUE@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LIBMATHOBJS = @LIBMATHOBJS@ -LIBMATH_INCLUDES = @LIBMATH_INCLUDES@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@ LIBTOOL = @LIBTOOL@ -LIBUNWIND_FLAG = @LIBUNWIND_FLAG@ LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ MAKEINFO = @MAKEINFO@ -OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPTIMIZE_CXXFLAGS = @OPTIMIZE_CXXFLAGS@ OPT_LDFLAGS = @OPT_LDFLAGS@ OS_INC_SRCDIR = @OS_INC_SRCDIR@ PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SECTION_FLAGS = @SECTION_FLAGS@ SECTION_LDFLAGS = @SECTION_LDFLAGS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ STRIP = @STRIP@ SYMVER_MAP = @SYMVER_MAP@ TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@ @@ -120,39 +140,87 @@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ WARN_FLAGS = @WARN_FLAGS@ WERROR = @WERROR@ -baseline_file = @baseline_file@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_AS = @ac_ct_AS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__leading_dot = @am__leading_dot@ +baseline_dir = @baseline_dir@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ check_msgfmt = @check_msgfmt@ +datadir = @datadir@ enable_shared = @enable_shared@ enable_static = @enable_static@ -glibcpp_CXX = @glibcpp_CXX@ -glibcpp_MOFILES = @glibcpp_MOFILES@ -glibcpp_POFILES = @glibcpp_POFILES@ -glibcpp_basedir = @glibcpp_basedir@ -glibcpp_localedir = @glibcpp_localedir@ -glibcpp_prefixdir = @glibcpp_prefixdir@ -glibcpp_toolexecdir = @glibcpp_toolexecdir@ -glibcpp_toolexeclibdir = @glibcpp_toolexeclibdir@ -ifGNUmake = @ifGNUmake@ -libio_la = @libio_la@ +exec_prefix = @exec_prefix@ +glibcxx_MOFILES = @glibcxx_MOFILES@ +glibcxx_PCHFLAGS = @glibcxx_PCHFLAGS@ +glibcxx_POFILES = @glibcxx_POFILES@ +glibcxx_builddir = @glibcxx_builddir@ +glibcxx_localedir = @glibcxx_localedir@ +glibcxx_prefixdir = @glibcxx_prefixdir@ +glibcxx_srcdir = @glibcxx_srcdir@ +glibcxx_thread_h = @glibcxx_thread_h@ +glibcxx_toolexecdir = @glibcxx_toolexecdir@ +glibcxx_toolexeclibdir = @glibcxx_toolexeclibdir@ +gxx_include_dir = @gxx_include_dir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ libtool_VERSION = @libtool_VERSION@ +localstatedir = @localstatedir@ +mandir = @mandir@ +multi_basedir = @multi_basedir@ +oldincludedir = @oldincludedir@ +port_specific_symbol_files = @port_specific_symbol_files@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ toplevel_srcdir = @toplevel_srcdir@ -AUTOMAKE_OPTIONS = 1.3 cygnus MAINT_CHARSET = latin1 mkinstalldirs = $(SHELL) $(toplevel_srcdir)/mkinstalldirs +PWD_COMMAND = $${PWDCMD-pwd} +STAMP = echo timestamp > + +toolexecdir = $(glibcxx_toolexecdir) +toolexeclibdir = $(glibcxx_toolexeclibdir) + +# These bits are all figured out from configure. Look in acinclude.m4 +# or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS. +CONFIG_CXXFLAGS = \ + $(SECTION_FLAGS) $(EXTRA_CXX_FLAGS) + +WARN_CXXFLAGS = \ + $(WARN_FLAGS) $(WERROR) -fdiagnostics-show-location=once -# Cross compiler and multilib support. -CXX = @glibcpp_CXX@ -glibcpp_srcdir = @glibcpp_srcdir@ -glibcpp_builddir = @glibcpp_builddir@ -GLIBCPP_INCLUDES = @GLIBCPP_INCLUDES@ -LIBSUPCXX_INCLUDES = @LIBSUPCXX_INCLUDES@ -INCLUDES = -nostdinc++ $(GLIBCPP_INCLUDES) $(LIBSUPCXX_INCLUDES) +# -I/-D flags to pass when compiling. +AM_CPPFLAGS = $(GLIBCXX_INCLUDES) # Standard C++ includes. -std_srcdir = ${glibcpp_srcdir}/include/std +std_srcdir = ${glibcxx_srcdir}/include/std std_builddir = . std_headers = \ ${std_srcdir}/std_algorithm.h \ @@ -185,7 +253,7 @@ std_headers = \ ${std_srcdir}/std_valarray.h \ ${std_srcdir}/std_vector.h -# Renamed at build time. +# Renamed at build time. std_headers_rename = \ algorithm \ bitset \ @@ -218,9 +286,11 @@ std_headers_rename = \ vector -bits_srcdir = ${glibcpp_srcdir}/include/bits +bits_srcdir = ${glibcxx_srcdir}/include/bits bits_builddir = ./bits bits_headers = \ + ${bits_srcdir}/allocator.h \ + ${bits_srcdir}/atomicity.h \ ${bits_srcdir}/basic_ios.h \ ${bits_srcdir}/basic_ios.tcc \ ${bits_srcdir}/basic_string.h \ @@ -229,9 +299,9 @@ bits_headers = \ ${bits_srcdir}/char_traits.h \ ${bits_srcdir}/codecvt.h \ ${bits_srcdir}/concept_check.h \ + ${bits_srcdir}/concurrence.h \ ${bits_srcdir}/cpp_type_traits.h \ ${bits_srcdir}/deque.tcc \ - ${bits_srcdir}/fpos.h \ ${bits_srcdir}/fstream.tcc \ ${bits_srcdir}/functexcept.h \ ${bits_srcdir}/gslice.h \ @@ -246,14 +316,13 @@ bits_headers = \ ${bits_srcdir}/localefwd.h \ ${bits_srcdir}/mask_array.h \ ${bits_srcdir}/ostream.tcc \ - ${bits_srcdir}/pthread_allocimpl.h \ + ${bits_srcdir}/postypes.h \ ${bits_srcdir}/stream_iterator.h \ ${bits_srcdir}/streambuf_iterator.h \ ${bits_srcdir}/slice_array.h \ ${bits_srcdir}/sstream.tcc \ ${bits_srcdir}/stl_algo.h \ ${bits_srcdir}/stl_algobase.h \ - ${bits_srcdir}/stl_alloc.h \ ${bits_srcdir}/stl_bvector.h \ ${bits_srcdir}/stl_construct.h \ ${bits_srcdir}/stl_deque.h \ @@ -268,7 +337,6 @@ bits_headers = \ ${bits_srcdir}/stl_multiset.h \ ${bits_srcdir}/stl_numeric.h \ ${bits_srcdir}/stl_pair.h \ - ${bits_srcdir}/stl_pthread_alloc.h \ ${bits_srcdir}/stl_queue.h \ ${bits_srcdir}/stl_raw_storage_iter.h \ ${bits_srcdir}/stl_relops.h \ @@ -284,11 +352,12 @@ bits_headers = \ ${bits_srcdir}/type_traits.h \ ${bits_srcdir}/valarray_array.h \ ${bits_srcdir}/valarray_array.tcc \ - ${bits_srcdir}/valarray_meta.h \ + ${bits_srcdir}/valarray_before.h \ + ${bits_srcdir}/valarray_after.h \ ${bits_srcdir}/vector.tcc -backward_srcdir = ${glibcpp_srcdir}/include/backward +backward_srcdir = ${glibcxx_srcdir}/include/backward backward_builddir = ./backward backward_headers = \ ${backward_srcdir}/complex.h \ @@ -329,29 +398,37 @@ backward_headers = \ ${backward_srcdir}/backward_warning.h -ext_srcdir = ${glibcpp_srcdir}/include/ext +ext_srcdir = ${glibcxx_srcdir}/include/ext ext_builddir = ./ext ext_headers = \ ${ext_srcdir}/algorithm \ + ${ext_srcdir}/bitmap_allocator.h \ + ${ext_srcdir}/debug_allocator.h \ + ${ext_srcdir}/demangle.h \ ${ext_srcdir}/enc_filebuf.h \ ${ext_srcdir}/stdio_filebuf.h \ + ${ext_srcdir}/stdio_sync_filebuf.h \ ${ext_srcdir}/functional \ ${ext_srcdir}/hash_map \ ${ext_srcdir}/hash_set \ ${ext_srcdir}/iterator \ + ${ext_srcdir}/malloc_allocator.h \ ${ext_srcdir}/memory \ + ${ext_srcdir}/mt_allocator.h \ + ${ext_srcdir}/new_allocator.h \ ${ext_srcdir}/numeric \ + ${ext_srcdir}/pod_char_traits.h \ + ${ext_srcdir}/pool_allocator.h \ ${ext_srcdir}/rb_tree \ ${ext_srcdir}/rope \ ${ext_srcdir}/ropeimpl.h \ ${ext_srcdir}/slist \ - ${ext_srcdir}/stl_hash_fun.h \ - ${ext_srcdir}/stl_hashtable.h \ - ${ext_srcdir}/stl_rope.h + ${ext_srcdir}/hash_fun.h \ + ${ext_srcdir}/hashtable.h # This is the common subset of files that all three "C" header models use. -c_base_srcdir = @C_INCLUDE_DIR@ +c_base_srcdir = $(C_INCLUDE_DIR) c_base_builddir = . c_base_headers = \ ${c_base_srcdir}/std_cassert.h \ @@ -371,7 +448,7 @@ c_base_headers = \ ${c_base_srcdir}/std_cstring.h \ ${c_base_srcdir}/std_ctime.h \ ${c_base_srcdir}/std_cwchar.h \ - ${c_base_srcdir}/std_cwctype.h + ${c_base_srcdir}/std_cwctype.h c_base_headers_rename = \ cassert \ @@ -391,11 +468,11 @@ c_base_headers_rename = \ cstring \ ctime \ cwchar \ - cwctype + cwctype # "C" compatibility headers. -c_compatibility_srcdir = ${glibcpp_srcdir}/include/c_compatibility +c_compatibility_srcdir = ${glibcxx_srcdir}/include/c_compatibility c_compatibility_builddir = . c_compatibility_headers = \ ${c_compatibility_srcdir}/assert.h \ @@ -415,174 +492,263 @@ c_compatibility_headers = \ ${c_compatibility_srcdir}/string.h \ ${c_compatibility_srcdir}/time.h \ ${c_compatibility_srcdir}/wchar.h \ - ${c_compatibility_srcdir}/wctype.h - -@GLIBCPP_C_HEADERS_C_STD_TRUE@c_base_headers_extra = @GLIBCPP_C_HEADERS_C_STD_TRUE@${c_base_srcdir}/cmath.tcc -@GLIBCPP_C_HEADERS_C_STD_FALSE@c_base_headers_extra = -@GLIBCPP_C_HEADERS_COMPATIBILITY_TRUE@c_compatibility_headers_extra = @GLIBCPP_C_HEADERS_COMPATIBILITY_TRUE@${c_compatibility_headers} -@GLIBCPP_C_HEADERS_COMPATIBILITY_FALSE@c_compatibility_headers_extra = - -target_srcdir = ${glibcpp_srcdir}/@OS_INC_SRCDIR@ -target_builddir = ./${target_alias}/bits -target_headers = \ - ${target_srcdir}/ctype_base.h \ - ${target_srcdir}/ctype_inline.h \ - ${target_srcdir}/ctype_noninline.h \ - ${target_srcdir}/os_defines.h \ - ${glibcpp_srcdir}/@ATOMICITY_INC_SRCDIR@/atomicity.h - - -# Non-installed target_header files. -target_headers_noinst = \ - ${glibcpp_srcdir}/@CLOCALE_INTERNAL_H@ - - -# These target_headers_extra files are all built with ad hoc naming rules. -target_headers_extra = \ - ${target_builddir}/basic_file.h \ - ${target_builddir}/c++config.h \ - ${target_builddir}/c++io.h \ - ${target_builddir}/c++locale.h \ - ${target_builddir}/messages_members.h \ - ${target_builddir}/time_members.h \ - ${target_builddir}/codecvt_specializations.h - - -thread_target_headers = \ - ${target_builddir}/gthr.h \ - ${target_builddir}/gthr-single.h \ - ${target_builddir}/gthr-posix.h \ - ${target_builddir}/gthr-default.h - + ${c_compatibility_srcdir}/wctype.h + + +# Debug mode headers +debug_srcdir = ${glibcxx_srcdir}/include/debug +debug_builddir = ./debug +debug_headers = \ + ${debug_srcdir}/bitset \ + ${debug_srcdir}/debug.h \ + ${debug_srcdir}/deque \ + ${debug_srcdir}/formatter.h \ + ${debug_srcdir}/hash_map \ + ${debug_srcdir}/hash_map.h \ + ${debug_srcdir}/hash_multimap.h \ + ${debug_srcdir}/hash_multiset.h \ + ${debug_srcdir}/hash_set \ + ${debug_srcdir}/hash_set.h \ + ${debug_srcdir}/list \ + ${debug_srcdir}/map \ + ${debug_srcdir}/map.h \ + ${debug_srcdir}/multimap.h \ + ${debug_srcdir}/multiset.h \ + ${debug_srcdir}/safe_base.h \ + ${debug_srcdir}/safe_iterator.h \ + ${debug_srcdir}/safe_iterator.tcc \ + ${debug_srcdir}/safe_sequence.h \ + ${debug_srcdir}/set \ + ${debug_srcdir}/set.h \ + ${debug_srcdir}/string \ + ${debug_srcdir}/vector + +@GLIBCXX_C_HEADERS_C_STD_FALSE@c_base_headers_extra = + +# Some of the different "C" header models need extra files. +# Some "C" header schemes require the "C" compatibility headers. +# For --enable-cheaders=c_std +@GLIBCXX_C_HEADERS_C_STD_TRUE@c_base_headers_extra = ${c_base_srcdir}/cmath.tcc +@GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE@c_compatibility_headers_extra = + +@GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE@c_compatibility_headers_extra = ${c_compatibility_headers} + +host_srcdir = ${glibcxx_srcdir}/$(OS_INC_SRCDIR) +host_builddir = ./${host_alias}/bits +host_headers = \ + ${host_srcdir}/ctype_base.h \ + ${host_srcdir}/ctype_inline.h \ + ${host_srcdir}/ctype_noninline.h \ + ${host_srcdir}/os_defines.h \ + ${glibcxx_srcdir}/$(ATOMIC_WORD_SRCDIR)/atomic_word.h + + +# Non-installed host_header files. +host_headers_noinst = \ + ${glibcxx_srcdir}/$(CLOCALE_INTERNAL_H) + + +# These host_headers_extra files are all built with ad hoc naming rules. +host_headers_extra = \ + ${host_builddir}/basic_file.h \ + ${host_builddir}/c++config.h \ + ${host_builddir}/c++allocator.h \ + ${host_builddir}/c++io.h \ + ${host_builddir}/c++locale.h \ + ${host_builddir}/messages_members.h \ + ${host_builddir}/time_members.h \ + ${host_builddir}/codecvt_specializations.h + + +thread_host_headers = \ + ${host_builddir}/gthr.h \ + ${host_builddir}/gthr-single.h \ + ${host_builddir}/gthr-posix.h \ + ${host_builddir}/gthr-default.h + + +pch_input = ${host_builddir}/stdc++.h +pch_output_builddir = ${host_builddir}/stdc++.h.gch +pch_source = ${glibcxx_srcdir}/include/stdc++.h +PCHFLAGS = -Winvalid-pch -Wno-deprecated -x c++-header $(CXXFLAGS) +@GLIBCXX_BUILD_PCH_TRUE@pch_build = ${pch_input} +@GLIBCXX_BUILD_PCH_FALSE@pch_build = +@GLIBCXX_BUILD_PCH_TRUE@pch_install = install-pch +@GLIBCXX_BUILD_PCH_FALSE@pch_install = # List of all timestamp files. By keeping only one copy of this list, both # CLEANFILES and all-local are kept up-to-date. -allstamps = \ +allstamped = \ stamp-std stamp-bits stamp-c_base stamp-c_compatibility \ - stamp-backward stamp-ext stamp-target - + stamp-backward stamp-ext stamp-debug stamp-host -# Target includes for threads -glibcpp_thread_h = @glibcpp_thread_h@ -uppercase = [ABCDEFGHIJKLMNOPQRSTUVWXYZ_] -# For robustness sake (in light of junk files or in-source -# configuration), copy from the build or source tree to the install -# tree using only the human-maintained file lists and directory -# components. Yes, with minor differences, this is sheer duplication -# of the staging rules above using $(INSTALL_DATA) instead of LN_S and -# `$(mkinstalldirs)' instead of `mkdir -p'. In particular, -# target_headers_extra are taken out of the build tree staging area; -# the rest are taken from the original source tree. -gxx_include_dir = @gxx_include_dir@ +# List of all files that are created by explicit building, editing, or +# catenation. +allcreated = \ + ${host_builddir}/c++config.h \ + ${thread_host_headers} \ + ${pch_build} -# By adding these files here, automake will remove them for 'make clean' -CLEANFILES = *.pch stamp-std-precompile -CONFIG_HEADER = ../config.h -CONFIG_CLEAN_FILES = -DIST_COMMON = Makefile.am Makefile.in +# Host includes for threads +uppercase = [ABCDEFGHIJKLMNOPQRSTUVWXYZ_] -DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) +# By adding these files here, automake will remove them for 'make clean' +CLEANFILES = ${pch_input} ${pch_output_builddir}/* +subdir = include +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +depcomp = +am__depfiles_maybe = +DIST_SOURCES = +DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/fragment.am \ + Makefile.am +all: all-am -TAR = gtar -GZIP_ENV = --best -all: all-redirect .SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && $(AUTOMAKE) --cygnus include/Makefile +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/fragment.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign include/Makefile +Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) \ - && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status +mostlyclean-libtool: + -rm -f *.lo +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: tags: TAGS TAGS: +ctags: CTAGS +CTAGS: -distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -subdir = include +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) distdir: $(DISTFILES) - @for file in $(DISTFILES); do \ - if test -f $$file; then d=.; else d=$(srcdir); fi; \ + $(mkinstalldirs) $(distdir)/.. + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file || :; \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ fi; \ done -info-am: -info: info-am -dvi-am: -dvi: dvi-am -check-am: +check-am: all-am check: check-am -installcheck-am: -installcheck: installcheck-am -install-info-am: -install-info: install-info-am -install-exec-am: -install-exec: install-exec-am +all-am: Makefile all-local -install-data-am: install-data-local +installdirs: +install: install-am +install-exec: install-exec-am install-data: install-data-am +uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -install: install-am -uninstall-am: -uninstall: uninstall-am -all-am: Makefile all-local -all-redirect: all-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install -installdirs: - +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: -mostlyclean-am: mostlyclean-generic + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am -mostlyclean: mostlyclean-am +clean-am: clean-generic clean-libtool mostlyclean-am -clean-am: clean-generic mostlyclean-am +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool -clean: clean-am +dvi: dvi-am -distclean-am: distclean-generic clean-am - -rm -f libtool +dvi-am: -distclean: distclean-am +info: info-am -maintainer-clean-am: maintainer-clean-generic distclean-am - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." +info-am: + +install-data-am: install-data-local + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: -.PHONY: tags distdir info-am info dvi-am dvi check check-am \ -installcheck-am installcheck install-info-am install-info \ -install-exec-am install-exec install-data-local install-data-am \ -install-data install-am install uninstall-am uninstall all-local \ -all-redirect all-am all installdirs mostlyclean-generic \ -distclean-generic clean-generic maintainer-clean-generic clean \ -mostlyclean distclean maintainer-clean +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: all all-am all-local check check-am clean clean-generic \ + clean-libtool distclean distclean-generic distclean-libtool \ + distdir dvi dvi-am info info-am install install-am install-data \ + install-data-am install-data-local install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-info-am # Here are the rules for building the headers -all-local: ${target_builddir}/c++config.h ${thread_target_headers} ${allstamps} +all-local: ${allstamped} ${allcreated} # This rule is slightly different, in that we must change the name of the # local file from std_foo.h to foo. @@ -590,121 +756,179 @@ stamp-std: ${std_headers} @if [ ! -d "${std_builddir}" ]; then \ mkdir -p ${std_builddir} ;\ fi ;\ - (cd ${std_builddir} && for h in $?; do \ - official_name=`echo $$h | sed -e 's,.*/std_,,' -e 's,\.h$$,,'` ;\ - @LN_S@ $$h ./$${official_name} || true ;\ - done) ;\ - echo `date` > stamp-std - -stamp-std-precompile: stamp-std - for h in ${std_headers_rename}; do \ - $(CXX) -Winvalid-pch -x c++-header $(INCLUDES) $${h}; \ - done; \ - echo `date` > stamp-std-precompile + if [ ! -f stamp-std ]; then \ + (cd ${std_builddir} && for h in $?; do \ + official_name=`echo $$h | sed -e 's,.*/std_,,' -e 's,\.h$$,,'` ;\ + $(LN_S) $$h ./$${official_name} || true ;\ + done) ;\ + fi ;\ + $(STAMP) stamp-std stamp-bits: ${bits_headers} @if [ ! -d "${bits_builddir}" ]; then \ mkdir -p ${bits_builddir} ;\ fi ;\ - (cd ${bits_builddir} && @LN_S@ $? . || true) ;\ - echo `date` > stamp-bits + if [ ! -f stamp-bits ]; then \ + (cd ${bits_builddir} && $(LN_S) $? . || true) ;\ + fi ;\ + $(STAMP) stamp-bits -stamp-c_base: stamp-bits ${c_base_headers} ${c_base_headers_extra} +stamp-c_base: stamp-bits ${c_base_headers} ${c_base_headers_extra} @if [ ! -d "${c_base_builddir}" ]; then \ mkdir -p ${c_base_builddir} ;\ fi ;\ - (cd ${c_base_builddir} && for h in ${c_base_headers}; do \ - official_name=`echo $$h | sed -e 's,.*/std_,,' -e 's,\.h$$,,'` ;\ - @LN_S@ $$h ./$${official_name} || true ;\ - done) ;\ - if [ ! -z "${c_base_headers_extra}" ]; then \ - (cd ${bits_builddir} && @LN_S@ ${c_base_headers_extra} . || true) ;\ + if [ ! -f stamp-c_base ]; then \ + (cd ${c_base_builddir} && for h in ${c_base_headers}; do \ + official_name=`echo $$h | sed -e 's,.*/std_,,' -e 's,\.h$$,,'` ;\ + $(LN_S) $$h ./$${official_name} || true ;\ + done) ;\ + if [ ! -z "${c_base_headers_extra}" ]; then \ + (cd ${bits_builddir} && $(LN_S) ${c_base_headers_extra} . || true) ;\ + fi ;\ fi ;\ - echo `date` > stamp-c_base + $(STAMP) stamp-c_base stamp-c_compatibility: ${c_compatibility_headers_extra} @if [ ! -d "${c_compatibility_builddir}" ]; then \ mkdir -p ${c_compatibility_builddir} ;\ fi ;\ - if [ ! -z "${c_compatibility_headers_extra}" ]; then \ - (cd ${c_compatibility_builddir} && @LN_S@ $? . || true) ;\ + if [ ! -f stamp-c_compatibility ]; then \ + if [ ! -z "${c_compatibility_headers_extra}" ]; then \ + (cd ${c_compatibility_builddir} && $(LN_S) $? . || true) ;\ + fi ;\ fi ;\ - echo `date` > stamp-c_compatibility + $(STAMP) stamp-c_compatibility stamp-backward: ${backward_headers} @if [ ! -d "${backward_builddir}" ]; then \ mkdir -p ${backward_builddir} ;\ fi ;\ - (cd ${backward_builddir} && @LN_S@ $? . || true) ;\ - echo `date` > stamp-backward + if [ ! -f stamp-backward ]; then \ + (cd ${backward_builddir} && $(LN_S) $? . || true) ;\ + fi ;\ + $(STAMP) stamp-backward stamp-ext: ${ext_headers} @if [ ! -d "${ext_builddir}" ]; then \ - mkdir -p ${ext_builddir} ;\ + mkdir -p ${ext_builddir} ;\ + fi ;\ + if [ ! -f stamp-ext ]; then \ + (cd ${ext_builddir} && $(LN_S) $? . || true) ;\ + fi ;\ + $(STAMP) stamp-ext + +stamp-debug: ${debug_headers} + @if [ ! -d "${debug_builddir}" ]; then \ + mkdir -p ${debug_builddir} ;\ + fi ;\ + if [ ! -f stamp-debug ]; then \ + (cd ${debug_builddir} && @LN_S@ $? . || true) ;\ fi ;\ - (cd ${ext_builddir} && @LN_S@ $? . || true) ;\ - echo `date` > stamp-ext - -stamp-${target_alias}: - @if [ ! -d ${target_builddir} ]; then \ - mkdir -p ${target_builddir} ;\ - echo `date` > stamp-${target_alias} ;\ - fi - -# Target includes static. -# XXX Missing dependency info for {target_headers_extra} -stamp-target: ${target_headers} ${target_headers_noinst} stamp-${target_alias} - @if [ ! -f stamp-target ]; then \ - (cd ${target_builddir} ;\ - @LN_S@ ${target_headers} . || true ;\ - @LN_S@ ${glibcpp_srcdir}/@BASIC_FILE_H@ basic_file.h || true ;\ - @LN_S@ ${glibcpp_srcdir}/@CSTDIO_H@ c++io.h || true ;\ - @LN_S@ ${glibcpp_srcdir}/@CLOCALE_H@ c++locale.h || true ;\ - @LN_S@ ${glibcpp_srcdir}/@CLOCALE_INTERNAL_H@ . || true ;\ - @LN_S@ ${glibcpp_srcdir}/@CMESSAGES_H@ messages_members.h || true ;\ - @LN_S@ ${glibcpp_srcdir}/@CTIME_H@ time_members.h || true ;\ - @LN_S@ ${glibcpp_srcdir}/@CCODECVT_H@ codecvt_specializations.h || true);\ - echo `date` > stamp-target ; \ - fi - -# Target includes dynamic. -${target_builddir}/c++config.h: ${CONFIG_HEADER} \ - ${glibcpp_srcdir}/include/bits/c++config \ - stamp-${target_alias} - @cat ${glibcpp_srcdir}/include/bits/c++config > $@ ;\ - sed -e 's/HAVE_/_GLIBCPP_HAVE_/g' \ - -e 's/PACKAGE/_GLIBCPP_PACKAGE/g' \ - -e 's/VERSION/_GLIBCPP_VERSION/g' \ - -e 's/WORDS_/_GLIBCPP_WORDS_/g' \ + $(STAMP) stamp-debug + +stamp-${host_alias}: + @if [ ! -d ${host_builddir} ]; then \ + mkdir -p ${host_builddir} ;\ + fi ;\ + $(STAMP) stamp-${host_alias} + +# Host includes static. +# XXX Missing dependency info for {host_headers_extra} +stamp-host: ${host_headers} ${host_headers_noinst} stamp-${host_alias} + @if [ ! -f stamp-host ]; then \ + (cd ${host_builddir} ;\ + $(LN_S) ${host_headers} . || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_H) basic_file.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(ALLOCATOR_H) c++allocator.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CSTDIO_H) c++io.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CLOCALE_H) c++locale.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CLOCALE_INTERNAL_H) . || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CMESSAGES_H) messages_members.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CTIME_H) time_members.h || true ;\ + $(LN_S) ${glibcxx_srcdir}/$(CCODECVT_H) codecvt_specializations.h || true);\ + fi ;\ + $(STAMP) stamp-host + +# Host includes dynamic. +${host_builddir}/c++config.h: ${top_builddir}/config.h \ + ${glibcxx_srcdir}/include/bits/c++config \ + stamp-${host_alias} + @cat ${glibcxx_srcdir}/include/bits/c++config > $@ ;\ + sed -e 's/HAVE_/_GLIBCXX_HAVE_/g' \ + -e 's/PACKAGE/_GLIBCXX_PACKAGE/g' \ + -e 's/VERSION/_GLIBCXX_VERSION/g' \ + -e 's/WORDS_/_GLIBCXX_WORDS_/g' \ < ${CONFIG_HEADER} >> $@ ;\ - echo "#endif // _CPP_CPPCONFIG_" >>$@ + echo "#endif // _CXXCONFIG_" >>$@ -${target_builddir}/gthr.h: ${toplevel_srcdir}/gcc/gthr.h stamp-${target_alias} - sed -e '/^#/s/\(${uppercase}${uppercase}*\)/_GLIBCPP_\1/g' \ +${host_builddir}/gthr.h: ${toplevel_srcdir}/gcc/gthr.h stamp-${host_alias} + sed -e '/^#/s/\(${uppercase}${uppercase}*\)/_GLIBCXX_\1/g' \ + -e 's/_GLIBCXX_SUPPORTS_WEAK/__GXX_WEAK__/g' \ -e 's,^#include "\(.*\)",#include <bits/\1>,g' \ < ${toplevel_srcdir}/gcc/gthr.h > $@ -${target_builddir}/gthr-single.h: ${toplevel_srcdir}/gcc/gthr-single.h \ - stamp-${target_alias} - sed -e 's/\(UNUSED\)/_GLIBCPP_\1/g' \ - -e 's/\(GCC${uppercase}*_H\)/_GLIBCPP_\1/g' \ +${host_builddir}/gthr-single.h: ${toplevel_srcdir}/gcc/gthr-single.h \ + stamp-${host_alias} + sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \ + -e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \ < ${toplevel_srcdir}/gcc/gthr-single.h > $@ -${target_builddir}/gthr-posix.h: ${toplevel_srcdir}/gcc/gthr-posix.h \ - stamp-${target_alias} - sed -e 's/\(UNUSED\)/_GLIBCPP_\1/g' \ - -e 's/\(GCC${uppercase}*_H\)/_GLIBCPP_\1/g' \ - -e 's/\(${uppercase}*WEAK\)/_GLIBCPP_\1/g' \ +${host_builddir}/gthr-posix.h: ${toplevel_srcdir}/gcc/gthr-posix.h \ + stamp-${host_alias} + sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \ + -e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \ + -e 's/SUPPORTS_WEAK/__GXX_WEAK__/g' \ + -e 's/\(${uppercase}*USE_WEAK\)/_GLIBCXX_\1/g' \ < ${toplevel_srcdir}/gcc/gthr-posix.h > $@ -${target_builddir}/gthr-default.h: ${toplevel_srcdir}/gcc/${glibcpp_thread_h} \ - stamp-${target_alias} - sed -e 's/\(UNUSED\)/_GLIBCPP_\1/g' \ - -e 's/\(GCC${uppercase}*_H\)/_GLIBCPP_\1/g' \ - -e 's/\(${uppercase}*WEAK\)/_GLIBCPP_\1/g' \ +${host_builddir}/gthr-default.h: ${toplevel_srcdir}/gcc/${glibcxx_thread_h} \ + stamp-${host_alias} + sed -e 's/\(UNUSED\)/_GLIBCXX_\1/g' \ + -e 's/\(GCC${uppercase}*_H\)/_GLIBCXX_\1/g' \ + -e 's/SUPPORTS_WEAK/__GXX_WEAK__/g' \ + -e 's/\(${uppercase}*USE_WEAK\)/_GLIBCXX_\1/g' \ -e 's,^#include "\(.*\)",#include <bits/\1>,g' \ - < ${toplevel_srcdir}/gcc/${glibcpp_thread_h} > $@ -install-data-local: + < ${toplevel_srcdir}/gcc/${glibcxx_thread_h} > $@ + +# Build a precompiled C++ include, stdc++.h.gch. +${pch_input}: ${allstamped} ${host_builddir}/c++config.h ${pch_source} + touch ${pch_input}; \ + if [ ! -d "${pch_output_builddir}" ]; then \ + mkdir -p ${pch_output_builddir}; \ + fi; \ + $(CXX) $(PCHFLAGS) $(AM_CPPFLAGS) ${pch_source} -O0 -g -o ${pch_output_builddir}/O0g; \ + $(CXX) $(PCHFLAGS) $(AM_CPPFLAGS) ${pch_source} -O2 -g -o ${pch_output_builddir}/O2g; + +# For robustness sake (in light of junk files or in-source +# configuration), copy from the build or source tree to the install +# tree using only the human-maintained file lists and directory +# components. Yes, with minor differences, this is sheer duplication +# of the staging rules above using $(INSTALL_DATA) instead of LN_S and +# `$(mkinstalldirs)' instead of `mkdir -p'. In particular, +# host_headers_extra are taken out of the build tree staging area; +# the rest are taken from the original source tree. + +@GLIBCXX_HOSTED_TRUE@install-data-local: install-headers ${pch_install} +@GLIBCXX_HOSTED_FALSE@install-data-local: install-freestanding-headers + +# This is a subset of the full install-headers rule. We only need <cstddef>, +# <limits>, <cstdlib>, <cstdarg>, <new>, <typeinfo>, <exception>, and any +# files which they include (and which we provide). The last three headers +# are installed by libsupc++, so only the first four and the sub-includes +# are copied here. +install-freestanding-headers: + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir} + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${host_builddir} + for file in ${host_srcdir}/os_defines.h ${host_builddir}/c++config.h; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${host_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${std_builddir} + $(INSTALL_DATA) ${std_builddir}/limits $(DESTDIR)${gxx_include_dir}/${std_builddir} + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${c_base_builddir} + for file in cstddef cstdlib cstdarg; do \ + $(INSTALL_DATA) ${c_base_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${c_base_builddir}; done + +# The real deal. +install-headers: $(mkinstalldirs) $(DESTDIR)${gxx_include_dir} $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${bits_builddir} for file in ${bits_headers}; do \ @@ -727,10 +951,18 @@ install-data-local: $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${std_builddir} for file in ${std_headers_rename}; do \ $(INSTALL_DATA) ${std_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${std_builddir}; done - $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${target_builddir} - for file in ${target_headers} ${target_headers_extra} \ - ${thread_target_headers}; do \ - $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${target_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${debug_builddir} + for file in ${debug_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${debug_builddir}; done + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${host_builddir} + for file in ${host_headers} ${host_headers_extra} \ + ${thread_host_headers}; do \ + $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${host_builddir}; done + +install-pch: + $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${pch_output_builddir} + for file in ${pch_output_builddir}/*; do \ + $(INSTALL_DATA) $$file $(DESTDIR)${gxx_include_dir}/${pch_output_builddir}; done # Stop implicit '.o' make rules from ever stomping on extensionless # headers, in the improbable case where some foolish, crack-addled @@ -740,7 +972,6 @@ install-data-local: .PRECIOUS: $(std_headers_rename) $(c_base_headers_rename) $(std_headers_rename): ; @: $(c_base_headers_rename): ; @: - # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/contrib/libstdc++/include/backward/algo.h b/contrib/libstdc++/include/backward/algo.h index a3554a8f8d06..6f248356cf8e 100644 --- a/contrib/libstdc++/include/backward/algo.h +++ b/contrib/libstdc++/include/backward/algo.h @@ -53,8 +53,8 @@ * purpose. It is provided "as is" without express or implied warranty. */ -#ifndef _CPP_BACKWARD_ALGO_H -#define _CPP_BACKWARD_ALGO_H 1 +#ifndef _BACKWARD_ALGO_H +#define _BACKWARD_ALGO_H 1 #include "backward_warning.h" #include "algobase.h" @@ -66,57 +66,57 @@ #include <ext/numeric> // Names from <stl_algo.h> -using std::for_each; -using std::find; -using std::find_if; -using std::adjacent_find; -using std::count; -using std::count_if; -using std::search; -using std::search_n; -using std::swap_ranges; -using std::transform; -using std::replace; -using std::replace_if; -using std::replace_copy; -using std::replace_copy_if; -using std::generate; -using std::generate_n; -using std::remove; -using std::remove_if; -using std::remove_copy; -using std::remove_copy_if; -using std::unique; -using std::unique_copy; -using std::reverse; -using std::reverse_copy; -using std::rotate; -using std::rotate_copy; -using std::random_shuffle; -using std::partition; -using std::stable_partition; -using std::sort; -using std::stable_sort; -using std::partial_sort; -using std::partial_sort_copy; -using std::nth_element; -using std::lower_bound; -using std::upper_bound; -using std::equal_range; -using std::binary_search; -using std::merge; -using std::inplace_merge; -using std::includes; -using std::set_union; -using std::set_intersection; -using std::set_difference; -using std::set_symmetric_difference; -using std::min_element; -using std::max_element; -using std::next_permutation; -using std::prev_permutation; -using std::find_first_of; -using std::find_end; +using std::for_each; +using std::find; +using std::find_if; +using std::adjacent_find; +using std::count; +using std::count_if; +using std::search; +using std::search_n; +using std::swap_ranges; +using std::transform; +using std::replace; +using std::replace_if; +using std::replace_copy; +using std::replace_copy_if; +using std::generate; +using std::generate_n; +using std::remove; +using std::remove_if; +using std::remove_copy; +using std::remove_copy_if; +using std::unique; +using std::unique_copy; +using std::reverse; +using std::reverse_copy; +using std::rotate; +using std::rotate_copy; +using std::random_shuffle; +using std::partition; +using std::stable_partition; +using std::sort; +using std::stable_sort; +using std::partial_sort; +using std::partial_sort_copy; +using std::nth_element; +using std::lower_bound; +using std::upper_bound; +using std::equal_range; +using std::binary_search; +using std::merge; +using std::inplace_merge; +using std::includes; +using std::set_union; +using std::set_intersection; +using std::set_difference; +using std::set_symmetric_difference; +using std::min_element; +using std::max_element; +using std::next_permutation; +using std::prev_permutation; +using std::find_first_of; +using std::find_end; // Names from stl_heap.h using std::push_heap; @@ -125,24 +125,24 @@ using std::make_heap; using std::sort_heap; // Names from stl_numeric.h -using std::accumulate; -using std::inner_product; -using std::partial_sum; -using std::adjacent_difference; +using std::accumulate; +using std::inner_product; +using std::partial_sum; +using std::adjacent_difference; // Names from ext/algorithm -using __gnu_cxx::random_sample; +using __gnu_cxx::random_sample; using __gnu_cxx::random_sample_n; -using __gnu_cxx::is_sorted; +using __gnu_cxx::is_sorted; using __gnu_cxx::is_heap; using __gnu_cxx::count; // Extension returning void using __gnu_cxx::count_if; // Extension returning void // Names from ext/numeric -using __gnu_cxx::power; -using __gnu_cxx::iota; +using __gnu_cxx::power; +using __gnu_cxx::iota; -#endif /* _CPP_BACKWARD_ALGO_H */ +#endif /* _BACKWARD_ALGO_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/algobase.h b/contrib/libstdc++/include/backward/algobase.h index 1606559828f7..86028a0d05c0 100644 --- a/contrib/libstdc++/include/backward/algobase.h +++ b/contrib/libstdc++/include/backward/algobase.h @@ -52,8 +52,8 @@ * purpose. It is provided "as is" without express or implied warranty. */ -#ifndef _CPP_BACKWARD_ALGOBASE_H -#define _CPP_BACKWARD_ALGOBASE_H 1 +#ifndef _BACKWARD_ALGOBASE_H +#define _BACKWARD_ALGOBASE_H 1 #include "backward_warning.h" #include "pair.h" @@ -64,17 +64,17 @@ #include <ext/memory> // Names from stl_algobase.h -using std::iter_swap; -using std::swap; -using std::min; -using std::max; -using std::copy; -using std::copy_backward; -using std::fill; -using std::fill_n; -using std::mismatch; -using std::equal; -using std::lexicographical_compare; +using std::iter_swap; +using std::swap; +using std::min; +using std::max; +using std::copy; +using std::copy_backward; +using std::fill; +using std::fill_n; +using std::mismatch; +using std::equal; +using std::lexicographical_compare; // Names from stl_uninitialized.h using std::uninitialized_copy; @@ -82,13 +82,13 @@ using std::uninitialized_fill; using std::uninitialized_fill_n; // Names from ext/algorithm -using __gnu_cxx::copy_n; -using __gnu_cxx::lexicographical_compare_3way; +using __gnu_cxx::copy_n; +using __gnu_cxx::lexicographical_compare_3way; // Names from ext/memory using __gnu_cxx::uninitialized_copy_n; -#endif /* _CPP_BACKWARD_ALGOBASE_H */ +#endif /* _BACKWARD_ALGOBASE_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/alloc.h b/contrib/libstdc++/include/backward/alloc.h index 9482e4cfebad..d3c3c738b95e 100644 --- a/contrib/libstdc++/include/backward/alloc.h +++ b/contrib/libstdc++/include/backward/alloc.h @@ -1,6 +1,6 @@ // Backward-compat support -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -40,19 +40,13 @@ * purpose. It is provided "as is" without express or implied warranty. */ -#ifndef _CPP_BACKWARD_ALLOC_H -#define _CPP_BACKWARD_ALLOC_H 1 +#ifndef _BACKWARD_ALLOC_H +#define _BACKWARD_ALLOC_H 1 #include "backward_warning.h" #include <bits/c++config.h> -#include <bits/stl_alloc.h> +#include <bits/allocator.h> -using std::__malloc_alloc_template; -using std::__simple_alloc; -using std::__debug_alloc; -using std::__alloc; -using std::__single_client_alloc; using std::allocator; -using std::__default_alloc_template; -#endif +#endif diff --git a/contrib/libstdc++/include/backward/backward_warning.h b/contrib/libstdc++/include/backward/backward_warning.h index 0f007bf364a1..9e1377793ea7 100644 --- a/contrib/libstdc++/include/backward/backward_warning.h +++ b/contrib/libstdc++/include/backward/backward_warning.h @@ -25,15 +25,15 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_BACKWARD_BACKWARD_WARNING_H -#define _CPP_BACKWARD_BACKWARD_WARNING_H 1 +#ifndef _BACKWARD_BACKWARD_WARNING_H +#define _BACKWARD_BACKWARD_WARNING_H 1 #ifdef __DEPRECATED #warning This file includes at least one deprecated or antiquated header. \ Please consider using one of the 32 headers found in section 17.4.1.2 of the \ C++ standard. Examples include substituting the <X> header for the <X.h> \ -header for C++ includes, or <sstream> instead of the deprecated header \ -<strstream.h>. To disable this warning use -Wno-deprecated. +header for C++ includes, or <iostream> instead of the deprecated header \ +<iostream.h>. To disable this warning use -Wno-deprecated. #endif #endif diff --git a/contrib/libstdc++/include/backward/bvector.h b/contrib/libstdc++/include/backward/bvector.h index b114052933af..924579267883 100644 --- a/contrib/libstdc++/include/backward/bvector.h +++ b/contrib/libstdc++/include/backward/bvector.h @@ -1,6 +1,6 @@ // Backward-compat support -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -53,16 +53,15 @@ * purpose. It is provided "as is" without express or implied warranty. */ -#ifndef __SGI_STL_BVECTOR_H -#define __SGI_STL_BVECTOR_H - +#ifndef _BACKWARD_BVECTOR_H +#define _BACKWARD_BVECTOR_H 1 #include "backward_warning.h" #include <vector> -using std::bit_vector; +typedef std::vector<bool, std::allocator<bool> > bit_vector; -#endif /* __SGI_STL_BVECTOR_H */ +#endif /* _BACKWARD_BVECTOR_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/complex.h b/contrib/libstdc++/include/backward/complex.h index 0e721744a6b7..dfc67140655d 100644 --- a/contrib/libstdc++/include/backward/complex.h +++ b/contrib/libstdc++/include/backward/complex.h @@ -25,16 +25,16 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_BACKWARD_COMPLEX_H -#define _CPP_BACKWARD_COMPLEX_H 1 +#ifndef _BACKWARD_COMPLEX_H +#define _BACKWARD_COMPLEX_H 1 #include "backward_warning.h" #include <complex> using std::complex; -typedef complex<float> float_complex; -typedef complex<double> double_complex; -typedef complex<long double> long_double_complex; +typedef complex<float> float_complex; +typedef complex<double> double_complex; +typedef complex<long double> long_double_complex; #endif diff --git a/contrib/libstdc++/include/backward/defalloc.h b/contrib/libstdc++/include/backward/defalloc.h index 264e2967c3c8..76ea52abc9e2 100644 --- a/contrib/libstdc++/include/backward/defalloc.h +++ b/contrib/libstdc++/include/backward/defalloc.h @@ -47,20 +47,20 @@ // 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. +// 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 _CPP_BACKWARD_DEFALLOC_H -#define _CPP_BACKWARD_DEFALLOC_H 1 +#ifndef _BACKWARD_DEFALLOC_H +#define _BACKWARD_DEFALLOC_H 1 #include "backward_warning.h" #include "new.h" #include <stddef.h> #include <stdlib.h> -#include <limits.h> -#include "iostream.h" +#include <limits.h> +#include "iostream.h" #include "algobase.h" @@ -69,7 +69,7 @@ inline _Tp* allocate(ptrdiff_t __size, _Tp*) { set_new_handler(0); _Tp* __tmp = (_Tp*)(::operator new((size_t)(__size * sizeof(_Tp)))); if (__tmp == 0) { - cerr << "out of memory" << endl; + cerr << "out of memory" << endl; exit(1); } return __tmp; @@ -91,19 +91,19 @@ public: typedef const _Tp& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; - pointer allocate(size_type __n) { + pointer allocate(size_type __n) { return ::allocate((difference_type)__n, (pointer)0); } void deallocate(pointer __p) { ::deallocate(__p); } pointer address(reference __x) { return (pointer)&__x; } - const_pointer const_address(const_reference __x) { - return (const_pointer)&__x; + const_pointer const_address(const_reference __x) { + return (const_pointer)&__x; } - size_type init_page_size() { - return max(size_type(1), size_type(4096/sizeof(_Tp))); + size_type init_page_size() { + return max(size_type(1), size_type(4096/sizeof(_Tp))); } - size_type max_size() const { - return max(size_type(1), size_type(UINT_MAX/sizeof(_Tp))); + size_type max_size() const { + return max(size_type(1), size_type(UINT_MAX/sizeof(_Tp))); } }; @@ -114,4 +114,4 @@ public: -#endif /* _CPP_BACKWARD_DEFALLOC_H */ +#endif /* _BACKWARD_DEFALLOC_H */ diff --git a/contrib/libstdc++/include/backward/deque.h b/contrib/libstdc++/include/backward/deque.h index 983ae07bac7f..36c7479ef091 100644 --- a/contrib/libstdc++/include/backward/deque.h +++ b/contrib/libstdc++/include/backward/deque.h @@ -53,8 +53,8 @@ * purpose. It is provided "as is" without express or implied warranty. */ -#ifndef _CPP_BACKWARD_DEQUE_H -#define _CPP_BACKWARD_DEQUE_H 1 +#ifndef _BACKWARD_DEQUE_H +#define _BACKWARD_DEQUE_H 1 #include "backward_warning.h" #include "algobase.h" @@ -63,7 +63,7 @@ using std::deque; -#endif /* _CPP_BACKWARD_DEQUE_H */ +#endif /* _BACKWARD_DEQUE_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/fstream.h b/contrib/libstdc++/include/backward/fstream.h index 44461f464dda..6dfd514c2f3b 100644 --- a/contrib/libstdc++/include/backward/fstream.h +++ b/contrib/libstdc++/include/backward/fstream.h @@ -25,8 +25,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_BACKWARD_FSTREAM_H -#define _CPP_BACKWARD_FSTREAM_H 1 +#ifndef _BACKWARD_FSTREAM_H +#define _BACKWARD_FSTREAM_H 1 #include "backward_warning.h" #include <fstream> @@ -37,7 +37,7 @@ using std::ofstream; using std::fstream; using std::streampos; -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T using std::wfilebuf; using std::wifstream; using std::wofstream; diff --git a/contrib/libstdc++/include/backward/function.h b/contrib/libstdc++/include/backward/function.h index bc96f49ffabd..9fc8719c07a1 100644 --- a/contrib/libstdc++/include/backward/function.h +++ b/contrib/libstdc++/include/backward/function.h @@ -53,8 +53,8 @@ * purpose. It is provided "as is" without express or implied warranty. */ -#ifndef _CPP_BACKWARD_FUNCTION_H -#define _CPP_BACKWARD_FUNCTION_H 1 +#ifndef _BACKWARD_FUNCTION_H +#define _BACKWARD_FUNCTION_H 1 #include "backward_warning.h" #include <bits/c++config.h> @@ -63,67 +63,67 @@ #include <ext/functional> // Names from stl_function.h -using std::unary_function; -using std::binary_function; -using std::plus; -using std::minus; -using std::multiplies; -using std::divides; -using std::modulus; -using std::negate; -using std::equal_to; -using std::not_equal_to; -using std::greater; -using std::less; -using std::greater_equal; -using std::less_equal; -using std::logical_and; -using std::logical_or; -using std::logical_not; -using std::unary_negate; -using std::binary_negate; -using std::not1; -using std::not2; -using std::binder1st; -using std::binder2nd; -using std::bind1st; -using std::bind2nd; -using std::pointer_to_unary_function; -using std::pointer_to_binary_function; -using std::ptr_fun; -using std::mem_fun_t; -using std::const_mem_fun_t; -using std::mem_fun_ref_t; -using std::const_mem_fun_ref_t; -using std::mem_fun1_t; -using std::const_mem_fun1_t; -using std::mem_fun1_ref_t; -using std::const_mem_fun1_ref_t; -using std::mem_fun; -using std::mem_fun_ref; +using std::unary_function; +using std::binary_function; +using std::plus; +using std::minus; +using std::multiplies; +using std::divides; +using std::modulus; +using std::negate; +using std::equal_to; +using std::not_equal_to; +using std::greater; +using std::less; +using std::greater_equal; +using std::less_equal; +using std::logical_and; +using std::logical_or; +using std::logical_not; +using std::unary_negate; +using std::binary_negate; +using std::not1; +using std::not2; +using std::binder1st; +using std::binder2nd; +using std::bind1st; +using std::bind2nd; +using std::pointer_to_unary_function; +using std::pointer_to_binary_function; +using std::ptr_fun; +using std::mem_fun_t; +using std::const_mem_fun_t; +using std::mem_fun_ref_t; +using std::const_mem_fun_ref_t; +using std::mem_fun1_t; +using std::const_mem_fun1_t; +using std::mem_fun1_ref_t; +using std::const_mem_fun1_ref_t; +using std::mem_fun; +using std::mem_fun_ref; // Names from ext/functional -using __gnu_cxx::identity_element; -using __gnu_cxx::unary_compose; -using __gnu_cxx::binary_compose; -using __gnu_cxx::compose1; -using __gnu_cxx::compose2; -using __gnu_cxx::identity; -using __gnu_cxx::select1st; -using __gnu_cxx::select2nd; -using __gnu_cxx::project1st; -using __gnu_cxx::project2nd; -using __gnu_cxx::constant_void_fun; -using __gnu_cxx::constant_unary_fun; -using __gnu_cxx::constant_binary_fun; -using __gnu_cxx::constant0; -using __gnu_cxx::constant1; -using __gnu_cxx::constant2; -using __gnu_cxx::subtractive_rng; -using __gnu_cxx::mem_fun1; -using __gnu_cxx::mem_fun1_ref; +using __gnu_cxx::identity_element; +using __gnu_cxx::unary_compose; +using __gnu_cxx::binary_compose; +using __gnu_cxx::compose1; +using __gnu_cxx::compose2; +using __gnu_cxx::identity; +using __gnu_cxx::select1st; +using __gnu_cxx::select2nd; +using __gnu_cxx::project1st; +using __gnu_cxx::project2nd; +using __gnu_cxx::constant_void_fun; +using __gnu_cxx::constant_unary_fun; +using __gnu_cxx::constant_binary_fun; +using __gnu_cxx::constant0; +using __gnu_cxx::constant1; +using __gnu_cxx::constant2; +using __gnu_cxx::subtractive_rng; +using __gnu_cxx::mem_fun1; +using __gnu_cxx::mem_fun1_ref; -#endif /* _CPP_BACKWARD_FUNCTION_H */ +#endif /* _BACKWARD_FUNCTION_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/hash_map.h b/contrib/libstdc++/include/backward/hash_map.h index 25c177abb160..bc9c1482c8a4 100644 --- a/contrib/libstdc++/include/backward/hash_map.h +++ b/contrib/libstdc++/include/backward/hash_map.h @@ -53,8 +53,8 @@ * */ -#ifndef _CPP_BACKWARD_HASH_MAP_H -#define _CPP_BACKWARD_HASH_MAP_H 1 +#ifndef _BACKWARD_HASH_MAP_H +#define _BACKWARD_HASH_MAP_H 1 #include "backward_warning.h" #include "algobase.h" @@ -65,7 +65,7 @@ using __gnu_cxx::hashtable; using __gnu_cxx::hash_map; using __gnu_cxx::hash_multimap; -#endif /* _CPP_BACKWARD_HASH_MAP_H */ +#endif /* _BACKWARD_HASH_MAP_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/hash_set.h b/contrib/libstdc++/include/backward/hash_set.h index ddb7a755e565..89307de04020 100644 --- a/contrib/libstdc++/include/backward/hash_set.h +++ b/contrib/libstdc++/include/backward/hash_set.h @@ -53,8 +53,8 @@ * */ -#ifndef _CPP_BACKWARD_HASH_SET_H -#define _CPP_BACKWARD_HASH_SET_H 1 +#ifndef _BACKWARD_HASH_SET_H +#define _BACKWARD_HASH_SET_H 1 #include "backward_warning.h" #include "algobase.h" @@ -65,5 +65,5 @@ using __gnu_cxx::hashtable; using __gnu_cxx::hash_set; using __gnu_cxx::hash_multiset; -#endif /* _CPP_BACKWARD_HASH_SET_H */ +#endif /* _BACKWARD_HASH_SET_H */ diff --git a/contrib/libstdc++/include/backward/hashtable.h b/contrib/libstdc++/include/backward/hashtable.h index bbad51646793..abedd55b0010 100644 --- a/contrib/libstdc++/include/backward/hashtable.h +++ b/contrib/libstdc++/include/backward/hashtable.h @@ -57,11 +57,11 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BACKWARD_HASHTABLE_H -#define _CPP_BACKWARD_HASHTABLE_H 1 +#ifndef _BACKWARD_HASHTABLE_H +#define _BACKWARD_HASHTABLE_H 1 #include "backward_warning.h" -#include <ext/stl_hashtable.h> +#include <ext/hashtable.h> #include "algo.h" #include "alloc.h" #include "vector.h" @@ -69,7 +69,7 @@ using __gnu_cxx::hash; using __gnu_cxx::hashtable; -#endif /* _CPP_BACKWARD_HASHTABLE_H */ +#endif /* _BACKWARD_HASHTABLE_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/heap.h b/contrib/libstdc++/include/backward/heap.h index 9308f0e72674..2f19545d0d70 100644 --- a/contrib/libstdc++/include/backward/heap.h +++ b/contrib/libstdc++/include/backward/heap.h @@ -52,8 +52,8 @@ * purpose. It is provided "as is" without express or implied warranty. */ -#ifndef _CPP_BACKWARD_HEAP_H -#define _CPP_BACKWARD_HEAP_H 1 +#ifndef _BACKWARD_HEAP_H +#define _BACKWARD_HEAP_H 1 #include "backward_warning.h" #include <bits/c++config.h> @@ -64,7 +64,7 @@ using std::pop_heap; using std::make_heap; using std::sort_heap; -#endif /* _CPP_BACKWARD_HEAP_H */ +#endif /* _BACKWARD_HEAP_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/iomanip.h b/contrib/libstdc++/include/backward/iomanip.h index 53286cda4940..160dbebcdbf4 100644 --- a/contrib/libstdc++/include/backward/iomanip.h +++ b/contrib/libstdc++/include/backward/iomanip.h @@ -25,8 +25,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_BACKWARD_IOMANIP_H -#define _CPP_BACKWARD_IOMANIP_H 1 +#ifndef _BACKWARD_IOMANIP_H +#define _BACKWARD_IOMANIP_H 1 #include "backward_warning.h" #include "iostream.h" diff --git a/contrib/libstdc++/include/backward/iostream.h b/contrib/libstdc++/include/backward/iostream.h index 5346d9d22e87..5a5ccea62b77 100644 --- a/contrib/libstdc++/include/backward/iostream.h +++ b/contrib/libstdc++/include/backward/iostream.h @@ -25,8 +25,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_BACKWARD_IOSTREAM_H -#define _CPP_BACKWARD_IOSTREAM_H 1 +#ifndef _BACKWARD_IOSTREAM_H +#define _BACKWARD_IOSTREAM_H 1 #include "backward_warning.h" #include <iostream> @@ -41,7 +41,7 @@ using std::cout; using std::cin; using std::cerr; using std::clog; -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T using std::wcout; using std::wcin; using std::wcerr; diff --git a/contrib/libstdc++/include/backward/istream.h b/contrib/libstdc++/include/backward/istream.h index 059e7742e2fa..707b575a5bd4 100644 --- a/contrib/libstdc++/include/backward/istream.h +++ b/contrib/libstdc++/include/backward/istream.h @@ -25,8 +25,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_BACKWARD_ISTREAM_H -#define _CPP_BACKWARD_ISTREAM_H 1 +#ifndef _BACKWARD_ISTREAM_H +#define _BACKWARD_ISTREAM_H 1 #include "backward_warning.h" #include "iostream.h" diff --git a/contrib/libstdc++/include/backward/iterator.h b/contrib/libstdc++/include/backward/iterator.h index 179f457d324d..8316a83d698e 100644 --- a/contrib/libstdc++/include/backward/iterator.h +++ b/contrib/libstdc++/include/backward/iterator.h @@ -1,3 +1,32 @@ +// Backward-compat support -*- C++ -*- + +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + /* * * Copyright (c) 1994 @@ -24,8 +53,8 @@ * purpose. It is provided "as is" without express or implied warranty. */ -#ifndef _CPP_BACKWARD_ITERATOR_H -#define _CPP_BACKWARD_ITERATOR_H 1 +#ifndef _BACKWARD_ITERATOR_H +#define _BACKWARD_ITERATOR_H 1 #include "backward_warning.h" #include "function.h" @@ -116,7 +145,7 @@ template<class _Iter> using std::distance; using __gnu_cxx::distance; // 3-parameter extension -using std::advance; +using std::advance; using std::insert_iterator; using std::front_insert_iterator; @@ -145,7 +174,7 @@ template <class _Tp> inline void destroy(_Tp* __pointer) { std::_Destroy(__pointer); } - + template <class _ForwardIterator> inline void destroy(_ForwardIterator __first, _ForwardIterator __last) @@ -155,7 +184,7 @@ template <class _ForwardIterator> // Names from stl_raw_storage_iter.h using std::raw_storage_iterator; -#endif /* _CPP_BACKWARD_ITERATOR_H */ +#endif /* _BACKWARD_ITERATOR_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/list.h b/contrib/libstdc++/include/backward/list.h index 350a92a09912..00c11a6987d2 100644 --- a/contrib/libstdc++/include/backward/list.h +++ b/contrib/libstdc++/include/backward/list.h @@ -53,8 +53,8 @@ * purpose. It is provided "as is" without express or implied warranty. */ -#ifndef _CPP_BACKWARD_LIST_H -#define _CPP_BACKWARD_LIST_H 1 +#ifndef _BACKWARD_LIST_H +#define _BACKWARD_LIST_H 1 #include "backward_warning.h" #include "algobase.h" @@ -63,7 +63,7 @@ using std::list; -#endif /* _CPP_BACKWARD_LIST_H */ +#endif /* _BACKWARD_LIST_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/map.h b/contrib/libstdc++/include/backward/map.h index 00f606d7e324..56d5c69973b3 100644 --- a/contrib/libstdc++/include/backward/map.h +++ b/contrib/libstdc++/include/backward/map.h @@ -53,8 +53,8 @@ * purpose. It is provided "as is" without express or implied warranty. */ -#ifndef _CPP_BACKWARD_MAP_H -#define _CPP_BACKWARD_MAP_H 1 +#ifndef _BACKWARD_MAP_H +#define _BACKWARD_MAP_H 1 #include "backward_warning.h" #include "tree.h" @@ -62,7 +62,7 @@ using std::map; -#endif /* _CPP_BACKWARD_MAP_H */ +#endif /* _BACKWARD_MAP_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/multimap.h b/contrib/libstdc++/include/backward/multimap.h index b9cdc848360c..aba42f7217fd 100644 --- a/contrib/libstdc++/include/backward/multimap.h +++ b/contrib/libstdc++/include/backward/multimap.h @@ -53,8 +53,8 @@ * purpose. It is provided "as is" without express or implied warranty. */ -#ifndef _CPP_BACKWARD_MULTIMAP_H -#define _CPP_BACKWARD_MULTIMAP_H 1 +#ifndef _BACKWARD_MULTIMAP_H +#define _BACKWARD_MULTIMAP_H 1 #include "backward_warning.h" #include "tree.h" @@ -62,7 +62,7 @@ using std::multimap; -#endif /* _CPP_BACKWARD_MULTIMAP_H */ +#endif /* _BACKWARD_MULTIMAP_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/multiset.h b/contrib/libstdc++/include/backward/multiset.h index 8aa7fd34157e..7ec0c9476c90 100644 --- a/contrib/libstdc++/include/backward/multiset.h +++ b/contrib/libstdc++/include/backward/multiset.h @@ -53,8 +53,8 @@ * purpose. It is provided "as is" without express or implied warranty. */ -#ifndef _CPP_BACKWARD_MULTISET_H -#define _CPP_BACKWARD_MULTISET_H 1 +#ifndef _BACKWARD_MULTISET_H +#define _BACKWARD_MULTISET_H 1 #include "backward_warning.h" #include "tree.h" @@ -62,7 +62,7 @@ using std::multiset; -#endif /* _CPP_BACKWARD_MULTISET_H */ +#endif /* _BACKWARD_MULTISET_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/new.h b/contrib/libstdc++/include/backward/new.h index 8e4c5c939975..00a4819a0bb2 100644 --- a/contrib/libstdc++/include/backward/new.h +++ b/contrib/libstdc++/include/backward/new.h @@ -1,20 +1,20 @@ // -*- C++ -*- forwarding header. // Copyright (C) 2000 Free Software Foundation -// This file is part of GNU CC. +// This file is part of GCC. // -// GNU CC is free software; you can redistribute it and/or modify +// GCC is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2, or (at your option) // any later version. -// -// GNU CC is distributed in the hope that it will be useful, +// +// GCC is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License -// along with GNU CC; see the file COPYING. If not, write to +// along with GCC; see the file COPYING. If not, write to // the Free Software Foundation, 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. @@ -27,8 +27,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_BACKWARD_NEW_H -#define _CPP_BACKWARD_NEW_H 1 +#ifndef _BACKWARD_NEW_H +#define _BACKWARD_NEW_H 1 #include "backward_warning.h" #include <new> @@ -39,4 +39,4 @@ using std::nothrow; using std::new_handler; using std::set_new_handler; -#endif +#endif diff --git a/contrib/libstdc++/include/backward/ostream.h b/contrib/libstdc++/include/backward/ostream.h index 4c74756192ea..a72de09d9eb2 100644 --- a/contrib/libstdc++/include/backward/ostream.h +++ b/contrib/libstdc++/include/backward/ostream.h @@ -25,13 +25,13 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_BACKWARD_OSTREAM_H -#define _CPP_BACKWARD_OSTREAM_H 1 +#ifndef _BACKWARD_OSTREAM_H +#define _BACKWARD_OSTREAM_H 1 #include "backward_warning.h" #include "iostream.h" -#endif +#endif // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/pair.h b/contrib/libstdc++/include/backward/pair.h index f0ff7d7d6893..cbb3bc7ed6d5 100644 --- a/contrib/libstdc++/include/backward/pair.h +++ b/contrib/libstdc++/include/backward/pair.h @@ -53,8 +53,8 @@ * purpose. It is provided "as is" without express or implied warranty. */ -#ifndef _CPP_BACKWARD_PAIR_H -#define _CPP_BACKWARD_PAIR_H 1 +#ifndef _BACKWARD_PAIR_H +#define _BACKWARD_PAIR_H 1 #include "backward_warning.h" #include <bits/c++config.h> @@ -63,7 +63,7 @@ using std::pair; using std::make_pair; -#endif /* _CPP_BACKWARD_PAIR_H */ +#endif /* _BACKWARD_PAIR_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/queue.h b/contrib/libstdc++/include/backward/queue.h index 1d3b29c36b5a..a3e2ff3af091 100644 --- a/contrib/libstdc++/include/backward/queue.h +++ b/contrib/libstdc++/include/backward/queue.h @@ -25,8 +25,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_BACKWARD_QUEUE_H -#define _CPP_BACKWARD_QUEUE_H 1 +#ifndef _BACKWARD_QUEUE_H +#define _BACKWARD_QUEUE_H 1 #include "backward_warning.h" #include <queue> @@ -34,7 +34,7 @@ using std::queue; using std::priority_queue; -#endif +#endif // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/rope.h b/contrib/libstdc++/include/backward/rope.h index 5f4c78752954..fc6715aa750c 100644 --- a/contrib/libstdc++/include/backward/rope.h +++ b/contrib/libstdc++/include/backward/rope.h @@ -40,20 +40,20 @@ * purpose. It is provided "as is" without express or implied warranty. */ -#ifndef _CPP_BACKWARD_ROPE_H -#define _CPP_BACKWARD_ROPE_H 1 +#ifndef _BACKWARD_ROPE_H +#define _BACKWARD_ROPE_H 1 #include "backward_warning.h" -#include "hashtable.h" +#include "hashtable.h" #include <ext/rope> -using __gnu_cxx::char_producer; -using __gnu_cxx::sequence_buffer; -using __gnu_cxx::rope; -using __gnu_cxx::crope; -using __gnu_cxx::wrope; +using __gnu_cxx::char_producer; +using __gnu_cxx::sequence_buffer; +using __gnu_cxx::rope; +using __gnu_cxx::crope; +using __gnu_cxx::wrope; -#endif /* _CPP_BACKWARD_ROPE_H */ +#endif /* _BACKWARD_ROPE_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/set.h b/contrib/libstdc++/include/backward/set.h index c18925544952..6a8320ba42ff 100644 --- a/contrib/libstdc++/include/backward/set.h +++ b/contrib/libstdc++/include/backward/set.h @@ -53,8 +53,8 @@ * purpose. It is provided "as is" without express or implied warranty. */ -#ifndef _CPP_BACKWARD_SET_H -#define _CPP_BACKWARD_SET_H 1 +#ifndef _BACKWARD_SET_H +#define _BACKWARD_SET_H 1 #include "backward_warning.h" #include "tree.h" @@ -62,7 +62,7 @@ using std::set; -#endif /* _CPP_BACKWARD_SET_H */ +#endif /* _BACKWARD_SET_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/slist.h b/contrib/libstdc++/include/backward/slist.h index decf04df6616..63db065fe354 100644 --- a/contrib/libstdc++/include/backward/slist.h +++ b/contrib/libstdc++/include/backward/slist.h @@ -41,15 +41,15 @@ * */ -#ifndef _CPP_BACKWARD_SLIST_H -#define _CPP_BACKWARD_SLIST_H 1 +#ifndef _BACKWARD_SLIST_H +#define _BACKWARD_SLIST_H 1 #include "backward_warning.h" #include <ext/slist> using __gnu_cxx::slist; -#endif /* _CPP_BACKWARD_SLIST_H */ +#endif /* _BACKWARD_SLIST_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/stack.h b/contrib/libstdc++/include/backward/stack.h index 6f6029366308..0ff53a435720 100644 --- a/contrib/libstdc++/include/backward/stack.h +++ b/contrib/libstdc++/include/backward/stack.h @@ -53,8 +53,8 @@ * purpose. It is provided "as is" without express or implied warranty. */ -#ifndef _CPP_BACKWARD_STACK_H -#define _CPP_BACKWARD_STACK_H 1 +#ifndef _BACKWARD_STACK_H +#define _BACKWARD_STACK_H 1 #include "backward_warning.h" #include "vector.h" @@ -65,7 +65,7 @@ using std::stack; -#endif /* _CPP_BACKWARD_STACK_H */ +#endif /* _BACKWARD_STACK_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/stream.h b/contrib/libstdc++/include/backward/stream.h index 21a851decd8a..5540c7eebd16 100644 --- a/contrib/libstdc++/include/backward/stream.h +++ b/contrib/libstdc++/include/backward/stream.h @@ -25,13 +25,13 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_BACKWARD_STREAM_H -#define _CPP_BACKWARD_STREAM_H 1 +#ifndef _BACKWARD_STREAM_H +#define _BACKWARD_STREAM_H 1 #include "backward_warning.h" #include "iostream.h" -#endif +#endif // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/streambuf.h b/contrib/libstdc++/include/backward/streambuf.h index aef863ff1336..fc9825ef0a3f 100644 --- a/contrib/libstdc++/include/backward/streambuf.h +++ b/contrib/libstdc++/include/backward/streambuf.h @@ -25,15 +25,15 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_BACKWARD_STREAMBUF_H -#define _CPP_BACKWARD_STREAMBUF_H 1 +#ifndef _BACKWARD_STREAMBUF_H +#define _BACKWARD_STREAMBUF_H 1 #include "backward_warning.h" #include <streambuf> using std::streambuf; -#endif +#endif // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/strstream b/contrib/libstdc++/include/backward/strstream index 165c6e70dd4a..a5b95c5e4e99 100644 --- a/contrib/libstdc++/include/backward/strstream +++ b/contrib/libstdc++/include/backward/strstream @@ -1,6 +1,6 @@ // Backward-compat support -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -61,12 +61,12 @@ namespace std // Note that this class is not a template. class strstreambuf : public basic_streambuf<char, char_traits<char> > { - public: + public: // Types. typedef char_traits<char> _Traits; typedef basic_streambuf<char, _Traits> _Base; - public: + public: // Constructor, destructor explicit strstreambuf(streamsize __initial_capacity = 0); strstreambuf(void* (*__alloc)(size_t), void (*__free)(void*)); @@ -97,7 +97,12 @@ namespace std virtual pos_type seekpos(pos_type __pos, ios_base::openmode __mode = ios_base::in | ios_base::out); - private: + private: + strstreambuf& + operator=(const strstreambuf&); + + strstreambuf(const strstreambuf&); + // Dynamic allocation, possibly using _M_alloc_fun and _M_free_fun. char* _M_alloc(size_t); void _M_free(char*); @@ -105,7 +110,7 @@ namespace std // Helper function used in constructors. void _M_setup(char* __get, char* __put, streamsize __n); - private: + private: // Data members. void* (*_M_alloc_fun)(size_t); void (*_M_free_fun)(void*); @@ -171,4 +176,4 @@ namespace std strstreambuf _M_buf; }; } // namespace std -#endif +#endif diff --git a/contrib/libstdc++/include/backward/tempbuf.h b/contrib/libstdc++/include/backward/tempbuf.h index f47e707808a7..06de2bd39d47 100644 --- a/contrib/libstdc++/include/backward/tempbuf.h +++ b/contrib/libstdc++/include/backward/tempbuf.h @@ -53,16 +53,16 @@ * purpose. It is provided "as is" without express or implied warranty. */ -#ifndef _CPP_BACKWARD_TEMPBUF_H -#define _CPP_BACKWARD_TEMPBUF_H 1 +#ifndef _BACKWARD_TEMPBUF_H +#define _BACKWARD_TEMPBUF_H 1 #include "backward_warning.h" #include "pair.h" #include "iterator.h" #include <limits.h> -#include <stddef.h> -#include <stdlib.h> -#include <bits/type_traits.h> +#include <stddef.h> +#include <stdlib.h> +#include <bits/type_traits.h> #include <bits/stl_construct.h> #include <bits/stl_uninitialized.h> #include <ext/memory> @@ -71,7 +71,7 @@ using std::get_temporary_buffer; using std::return_temporary_buffer; using __gnu_cxx::temporary_buffer; -#endif /* _CPP_BACKWARD_TEMPBUF_H */ +#endif /* _BACKWARD_TEMPBUF_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/backward/tree.h b/contrib/libstdc++/include/backward/tree.h index f3ee6525b88c..fcfcbf48dc47 100644 --- a/contrib/libstdc++/include/backward/tree.h +++ b/contrib/libstdc++/include/backward/tree.h @@ -41,15 +41,15 @@ * */ -#ifndef _CPP_EXT_TREE -#define _CPP_EXT_TREE 1 +#ifndef _BACKWARD_TREE +#define _BACKWARD_TREE 1 #include "backward_warning.h" #include <ext/rb_tree> using __gnu_cxx::rb_tree; -#endif +#endif // Local Variables: // mode:C++ // End: diff --git a/contrib/libstdc++/include/backward/vector.h b/contrib/libstdc++/include/backward/vector.h index 77880686f0d9..ba9b704c1dc1 100644 --- a/contrib/libstdc++/include/backward/vector.h +++ b/contrib/libstdc++/include/backward/vector.h @@ -53,17 +53,17 @@ * purpose. It is provided "as is" without express or implied warranty. */ -#ifndef _CPP_BACKWARD_VECTOR_H -#define _CPP_BACKWARD_VECTOR_H 1 +#ifndef _BACKWARD_VECTOR_H +#define _BACKWARD_VECTOR_H 1 #include "backward_warning.h" #include "algobase.h" -#include "alloc.h" +#include "alloc.h" #include <vector> using std::vector; -#endif /* _CPP_BACKWARD_VECTOR_H */ +#endif /* _BACKWARD_VECTOR_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/bits/allocator.h b/contrib/libstdc++/include/bits/allocator.h new file mode 100644 index 000000000000..c9200ecd9949 --- /dev/null +++ b/contrib/libstdc++/include/bits/allocator.h @@ -0,0 +1,130 @@ +// Allocators -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file allocator.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _ALLOCATOR_H +#define _ALLOCATOR_H 1 + +// Define the base class to std::allocator. +#include <bits/c++allocator.h> + +namespace std +{ + template<typename _Tp> + class allocator; + + template<> + class 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<typename _Tp1> + struct rebind + { typedef allocator<_Tp1> other; }; + }; + + /** + * @brief The "standard" allocator, as per [20.4]. + * + * (See @link Allocators allocators info @endlink for more.) + */ + template<typename _Tp> + class allocator: public ___glibcxx_base_allocator<_Tp> + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template<typename _Tp1> + struct rebind + { typedef allocator<_Tp1> other; }; + + allocator() throw() { } + + allocator(const allocator& a) throw() + : ___glibcxx_base_allocator<_Tp>(a) { } + + template<typename _Tp1> + allocator(const allocator<_Tp1>&) throw() { } + + ~allocator() throw() { } + + // Inherit everything else. + }; + + template<typename _T1, typename _T2> + inline bool + operator==(const allocator<_T1>&, const allocator<_T2>&) + { return true; } + + template<typename _T1, typename _T2> + inline bool + operator!=(const allocator<_T1>&, const allocator<_T2>&) + { return false; } + + // Inhibit implicit instantiations for required instantiations, + // which are defined via explicit instantiations elsewhere. + // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class allocator<char>; + extern template class allocator<wchar_t>; +#endif + + // Undefine. +#undef ___glibcxx_base_allocator +} // namespace std + +#endif diff --git a/contrib/libstdc++/include/bits/allocator_traits.h b/contrib/libstdc++/include/bits/allocator_traits.h new file mode 100644 index 000000000000..93bae7a2d442 --- /dev/null +++ b/contrib/libstdc++/include/bits/allocator_traits.h @@ -0,0 +1,237 @@ +// Allocators -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef _ALLOCATOR_TRAITS_H +#define _ALLOCATOR_TRAITS_H 1 + +#include <cstddef> + +namespace std +{ + /** + * @if maint + * This is used primarily (only?) in _Alloc_traits and other places to + * help provide the _Alloc_type typedef. All it does is forward the + * requests after some minimal checking. + * + * This is neither "standard"-conforming nor "SGI". The _Alloc parameter + * must be "SGI" style. + * @endif + * (See @link Allocators allocators info @endlink for more.) + */ + template<typename _Tp, typename _Alloc> + class __simple_alloc + { + public: + static _Tp* + allocate(size_t __n) + { + _Tp* __ret = 0; + if (__n) + __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp))); + return __ret; + } + + static _Tp* + allocate() + { 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)); } + }; + + + /** + * @if maint + * 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>. + * @endif + * (See @link Allocators allocators info @endlink for more.) + */ + template<typename _Tp, typename _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<typename _Tp1> + struct rebind + { typedef __allocator<_Tp1, _Alloc> other; }; + + __allocator() throw() { } + + __allocator(const __allocator& __a) throw() + : __underlying_alloc(__a.__underlying_alloc) { } + + template<typename _Tp1> + __allocator(const __allocator<_Tp1, _Alloc>& __a) throw() + : __underlying_alloc(__a.__underlying_alloc) { } + + ~__allocator() throw() { } + + pointer + address(reference __x) const { return &__x; } + + const_pointer + address(const_reference __x) const { return &__x; } + + // NB: __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) + { + _Tp* __ret = 0; + if (__n) + __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp))); + return __ret; + } + + // __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 throw() { return size_t(-1) / sizeof(_Tp); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_]allocator::construct + void + construct(pointer __p, const _Tp& __val) { ::new(__p) _Tp(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } + }; + + template<typename _Alloc> + struct __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<typename _Tp1> + struct rebind + { typedef __allocator<_Tp1, _Alloc> other; }; + }; + + template<typename _Tp, typename _Alloc> + inline bool + operator==(const __allocator<_Tp,_Alloc>& __a1, + const __allocator<_Tp,_Alloc>& __a2) + { return __a1.__underlying_alloc == __a2.__underlying_alloc; } + + template<typename _Tp, typename _Alloc> + inline bool + operator!=(const __allocator<_Tp, _Alloc>& __a1, + const __allocator<_Tp, _Alloc>& __a2) + { return __a1.__underlying_alloc != __a2.__underlying_alloc; } + + + /** + * @if maint + * 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" allocators. 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. For examples of use, see stl_vector.h, etc, or + * any of the other classes derived from this one. + * + * 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 size_t parameters are "standard" style (see top of + * allocator.h) in that they take counts, not sizes. + * + * @endif + * (See @link Allocators allocators info @endlink for more.) + */ + // The fully general version. + template<typename _Tp, typename _Allocator> + struct _Alloc_traits + { + static const bool _S_instanceless = false; + typedef typename _Allocator::template rebind<_Tp>::other allocator_type; + }; + + template<typename _Tp, typename _Allocator> + const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless; +} // namespace std + +#endif diff --git a/contrib/libstdc++/include/bits/atomicity.h b/contrib/libstdc++/include/bits/atomicity.h new file mode 100644 index 000000000000..d2620b08e5dc --- /dev/null +++ b/contrib/libstdc++/include/bits/atomicity.h @@ -0,0 +1,46 @@ +// Low-level functions for atomic operations -*- C++ -*- + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_ATOMICITY_H +#define _GLIBCXX_ATOMICITY_H 1 + +#include <bits/atomic_word.h> + +namespace __gnu_cxx +{ + _Atomic_word + __attribute__ ((__unused__)) + __exchange_and_add(volatile _Atomic_word* __mem, int __val); + + void + __attribute__ ((__unused__)) + __atomic_add(volatile _Atomic_word* __mem, int __val); +} // namespace __gnu_cxx + +#endif diff --git a/contrib/libstdc++/include/bits/basic_ios.h b/contrib/libstdc++/include/bits/basic_ios.h index 70d8e8404280..7ffe40ef1660 100644 --- a/contrib/libstdc++/include/bits/basic_ios.h +++ b/contrib/libstdc++/include/bits/basic_ios.h @@ -1,6 +1,6 @@ // Iostreams base classes -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003 +// Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2004 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -33,8 +33,8 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_BASICIOS_H -#define _CPP_BITS_BASICIOS_H 1 +#ifndef _BASIC_IOS_H +#define _BASIC_IOS_H 1 #pragma GCC system_header @@ -43,7 +43,7 @@ #include <bits/locale_classes.h> #include <bits/locale_facets.h> -namespace std +namespace std { // 27.4.5 Template class basic_ios /** @@ -76,14 +76,12 @@ namespace std * @endif */ typedef ctype<_CharT> __ctype_type; - typedef ostreambuf_iterator<_CharT, _Traits> __ostreambuf_iter; - typedef num_put<_CharT, __ostreambuf_iter> __numput_type; - typedef istreambuf_iterator<_CharT, _Traits> __istreambuf_iter; - typedef num_get<_CharT, __istreambuf_iter> __numget_type; + typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> > + __num_put_type; + typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> > + __num_get_type; //@} - friend void ios_base::Init::_S_ios_create(bool); - // Data members: protected: basic_ostream<_CharT, _Traits>* _M_tie; @@ -92,11 +90,11 @@ namespace std basic_streambuf<_CharT, _Traits>* _M_streambuf; // Cached use_facet<ctype>, which is based on the current locale info. - const __ctype_type* _M_fctype; - // From ostream. - const __numput_type* _M_fnumput; - // From istream. - const __numget_type* _M_fnumget; + const __ctype_type* _M_ctype; + // For ostream. + const __num_put_type* _M_num_put; + // For istream. + const __num_get_type* _M_num_get; public: //@{ @@ -106,11 +104,11 @@ namespace std * This allows you to write constructs such as * "if (!a_stream) ..." and "while (a_stream) ..." */ - operator void*() const + operator void*() const { return this->fail() ? 0 : const_cast<basic_ios*>(this); } - bool - operator!() const + bool + operator!() const { return this->fail(); } //@} @@ -121,8 +119,8 @@ namespace std * See std::ios_base::iostate for the possible bit values. Most * users will call one of the interpreting wrappers, e.g., good(). */ - iostate - rdstate() const + iostate + rdstate() const { return _M_streambuf_state; } /** @@ -132,7 +130,7 @@ namespace std * See std::ios_base::iostate for the possible bit values. Most * users will not need to pass an argument. */ - void + void clear(iostate __state = goodbit); /** @@ -141,18 +139,31 @@ namespace std * * See std::ios_base::iostate for the possible bit values. */ - void - setstate(iostate __state) + void + setstate(iostate __state) { this->clear(this->rdstate() | __state); } + // Flip the internal state on for the proper state bits, then re + // throws the propagated exception if bit also set in + // exceptions(). + void + _M_setstate(iostate __state) + { + // 27.6.1.2.1 Common requirements. + // Turn this on without causing an ios::failure to be thrown. + _M_streambuf_state |= __state; + if (this->exceptions() & __state) + __throw_exception_again; + } + /** * @brief Fast error checking. * @return True if no error flags are set. * * A wrapper around rdstate. */ - bool - good() const + bool + good() const { return this->rdstate() == 0; } /** @@ -161,8 +172,8 @@ namespace std * * Note that other iostate flags may also be set. */ - bool - eof() const + bool + eof() const { return (this->rdstate() & eofbit) != 0; } /** @@ -172,8 +183,8 @@ namespace std * Checking the badbit in fail() is historical practice. * Note that other iostate flags may also be set. */ - bool - fail() const + bool + fail() const { return (this->rdstate() & (badbit | failbit)) != 0; } /** @@ -182,8 +193,8 @@ namespace std * * Note that other iostate flags may also be set. */ - bool - bad() const + bool + bad() const { return (this->rdstate() & badbit) != 0; } /** @@ -193,8 +204,8 @@ namespace std * This changes nothing in the stream. See the one-argument version * of exceptions(iostate) for the meaning of the return value. */ - iostate - exceptions() const + iostate + exceptions() const { return _M_exception; } /** @@ -213,26 +224,26 @@ namespace std * #include <iostream> * #include <fstream> * #include <exception> - * + * * int main() * { * std::set_terminate (__gnu_cxx::__verbose_terminate_handler); - * + * * std::ifstream f ("/etc/motd"); - * + * * std::cerr << "Setting badbit\n"; * f.setstate (std::ios_base::badbit); - * + * * std::cerr << "Setting exception mask\n"; * f.exceptions (std::ios_base::badbit); * } * @endcode */ - void - exceptions(iostate __except) - { - _M_exception = __except; - this->clear(_M_streambuf_state); + void + exceptions(iostate __except) + { + _M_exception = __except; + this->clear(_M_streambuf_state); } // Constructor/destructor: @@ -241,9 +252,10 @@ namespace std * * The parameter is passed by derived streams. */ - explicit - basic_ios(basic_streambuf<_CharT, _Traits>* __sb) - : ios_base(), _M_fctype(0), _M_fnumput(0), _M_fnumget(0) + explicit + basic_ios(basic_streambuf<_CharT, _Traits>* __sb) + : ios_base(), _M_tie(0), _M_fill(), _M_fill_init(false), _M_streambuf(0), + _M_ctype(0), _M_num_put(0), _M_num_get(0) { this->init(__sb); } /** @@ -252,9 +264,9 @@ namespace std * The destructor does nothing. More specifically, it does not * destroy the streambuf held by rdbuf(). */ - virtual + virtual ~basic_ios() { } - + // Members: /** * @brief Fetches the current @e tied stream. @@ -266,7 +278,7 @@ namespace std * first flushed. For example, @c std::cin is tied to @c std::cout. */ basic_ostream<_CharT, _Traits>* - tie() const + tie() const { return _M_tie; } /** @@ -292,7 +304,7 @@ namespace std * This does not change the state of the stream. */ basic_streambuf<_CharT, _Traits>* - rdbuf() const + rdbuf() const { return _M_streambuf; } /** @@ -308,13 +320,28 @@ namespace std * in derived classes by overrides of the zero-argument @c rdbuf(), * which is non-virtual for hysterical raisins. As a result, you * must use explicit qualifications to access this function via any - * derived class. + * derived class. For example: + * + * @code + * std::fstream foo; // or some other derived type + * std::streambuf* p = .....; + * + * foo.ios::rdbuf(p); // ios == basic_ios<char> + * @endcode */ - basic_streambuf<_CharT, _Traits>* + basic_streambuf<_CharT, _Traits>* rdbuf(basic_streambuf<_CharT, _Traits>* __sb); /** - * @doctodo + * @brief Copies fields of __rhs into this. + * @param __rhs The source values for the copies. + * @return Reference to this object. + * + * All fields of __rhs are copied into this object except that rdbuf() + * and rdstate() remain unchanged. All values in the pword and iword + * arrays are copied. Before copying, each callback is invoked with + * erase_event. After copying, each (new) callback is invoked with + * copyfmt_event. The final step is to copy exceptions(). */ basic_ios& copyfmt(const basic_ios& __rhs); @@ -325,15 +352,15 @@ namespace std * * It defaults to a space (' ') in the current locale. */ - char_type - fill() const + char_type + fill() const { if (!_M_fill_init) { _M_fill = this->widen(' '); _M_fill_init = true; } - return _M_fill; + return _M_fill; } /** @@ -345,7 +372,7 @@ namespace std * have been requested (e.g., via setw), Q characters are actually * used, and Q<P. It defaults to a space (' ') in the current locale. */ - char_type + char_type fill(char_type __ch) { char_type __old = this->fill(); @@ -365,7 +392,7 @@ namespace std * Additional l10n notes are at * http://gcc.gnu.org/onlinedocs/libstdc++/22_locale/howto.html */ - locale + locale imbue(const locale& __loc); /** @@ -379,13 +406,13 @@ namespace std * * Returns the result of * @code - * std::use_facet< ctype<char_type> >(getloc()).narrow(c,dfault) + * std::use_facet<ctype<char_type> >(getloc()).narrow(c,dfault) * @endcode * * Additional l10n notes are at * http://gcc.gnu.org/onlinedocs/libstdc++/22_locale/howto.html */ - char + char narrow(char_type __c, char __dfault) const; /** @@ -397,15 +424,15 @@ namespace std * * Returns the result of * @code - * std::use_facet< ctype<char_type> >(getloc()).widen(c) + * std::use_facet<ctype<char_type> >(getloc()).widen(c) * @endcode * * Additional l10n notes are at * http://gcc.gnu.org/onlinedocs/libstdc++/22_locale/howto.html */ - char_type + char_type widen(char __c) const; - + protected: // 27.4.5.1 basic_ios constructors /** @@ -414,47 +441,27 @@ namespace std * The default constructor does nothing and is not normally * accessible to users. */ - basic_ios() : ios_base() + basic_ios() + : ios_base(), _M_tie(0), _M_fill(char_type()), _M_fill_init(false), + _M_streambuf(0), _M_ctype(0), _M_num_put(0), _M_num_get(0) { } /** * @brief All setup is performed here. * * This is called from the public constructor. It is not virtual and - * cannot be redefined. The second argument, __cache, is used - * to initialize the standard streams without allocating - * memory. + * cannot be redefined. */ - void + void init(basic_streambuf<_CharT, _Traits>* __sb); - bool - _M_check_facet(const locale::facet* __f) const - { - if (!__f) - __throw_bad_cast(); - return true; - } - void _M_cache_locale(const locale& __loc); - -#if 1 - // XXX GLIBCXX_ABI Deprecated, compatibility only. - void - _M_cache_facets(const locale& __loc); -#endif - - // Internal state setter that won't throw, only set the state bits. - // Used to guarantee we don't throw when setting badbit. - void - _M_setstate(iostate __state) { _M_streambuf_state |= __state; } }; } // namespace std -#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT -# define export +#ifndef _GLIBCXX_EXPORT_TEMPLATE #include <bits/basic_ios.tcc> #endif -#endif /* _CPP_BITS_BASICIOS_H */ +#endif /* _BASIC_IOS_H */ diff --git a/contrib/libstdc++/include/bits/basic_ios.tcc b/contrib/libstdc++/include/bits/basic_ios.tcc index 1c9cd3b7256a..fcb4b02493f6 100644 --- a/contrib/libstdc++/include/bits/basic_ios.tcc +++ b/contrib/libstdc++/include/bits/basic_ios.tcc @@ -1,4 +1,4 @@ -// basic_ios locale and locale-related member functions -*- C++ -*- +// basic_ios member functions -*- C++ -*- // Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. // @@ -27,8 +27,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_BITS_BASICIOS_TCC -#define _CPP_BITS_BASICIOS_TCC 1 +#ifndef _BASIC_IOS_TCC +#define _BASIC_IOS_TCC 1 #pragma GCC system_header @@ -37,17 +37,17 @@ namespace std template<typename _CharT, typename _Traits> void basic_ios<_CharT, _Traits>::clear(iostate __state) - { + { if (this->rdbuf()) _M_streambuf_state = __state; else _M_streambuf_state = __state | badbit; - if ((this->rdstate() & this->exceptions())) - __throw_ios_failure("basic_ios::clear(iostate) caused exception"); + if (this->exceptions() & this->rdstate()) + __throw_ios_failure(__N("basic_ios::clear")); } - + template<typename _CharT, typename _Traits> - basic_streambuf<_CharT, _Traits>* + basic_streambuf<_CharT, _Traits>* basic_ios<_CharT, _Traits>::rdbuf(basic_streambuf<_CharT, _Traits>* __sb) { basic_streambuf<_CharT, _Traits>* __old = _M_streambuf; @@ -60,74 +60,66 @@ namespace std basic_ios<_CharT, _Traits>& basic_ios<_CharT, _Traits>::copyfmt(const basic_ios& __rhs) { - // Per 27.1.1.1, do not call imbue, yet must trash all caches - // associated with imbue() - - // Alloc any new word array first, so if it fails we have "rollback". - _Words* __words = (__rhs._M_word_size <= _S_local_word_size) ? - _M_local_word : new _Words[__rhs._M_word_size]; - - // Bump refs before doing callbacks, for safety. - _Callback_list* __cb = __rhs._M_callbacks; - if (__cb) - __cb->_M_add_reference(); - _M_call_callbacks(erase_event); - if (_M_word != _M_local_word) + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 292. effects of a.copyfmt (a) + if (this != &__rhs) { - delete [] _M_word; - _M_word = 0; + // Per 27.1.1, do not call imbue, yet must trash all caches + // associated with imbue() + + // Alloc any new word array first, so if it fails we have "rollback". + _Words* __words = (__rhs._M_word_size <= _S_local_word_size) ? + _M_local_word : new _Words[__rhs._M_word_size]; + + // Bump refs before doing callbacks, for safety. + _Callback_list* __cb = __rhs._M_callbacks; + if (__cb) + __cb->_M_add_reference(); + _M_call_callbacks(erase_event); + if (_M_word != _M_local_word) + { + delete [] _M_word; + _M_word = 0; + } + _M_dispose_callbacks(); + + // NB: Don't want any added during above. + _M_callbacks = __cb; + for (int __i = 0; __i < __rhs._M_word_size; ++__i) + __words[__i] = __rhs._M_word[__i]; + if (_M_word != _M_local_word) + { + delete [] _M_word; + _M_word = 0; + } + _M_word = __words; + _M_word_size = __rhs._M_word_size; + + this->flags(__rhs.flags()); + this->width(__rhs.width()); + this->precision(__rhs.precision()); + this->tie(__rhs.tie()); + this->fill(__rhs.fill()); + _M_ios_locale = __rhs.getloc(); + _M_cache_locale(_M_ios_locale); + + _M_call_callbacks(copyfmt_event); + + // The next is required to be the last assignment. + this->exceptions(__rhs.exceptions()); } - _M_dispose_callbacks(); - - _M_callbacks = __cb; // NB: Don't want any added during above. - for (int __i = 0; __i < __rhs._M_word_size; ++__i) - __words[__i] = __rhs._M_word[__i]; - if (_M_word != _M_local_word) - { - delete [] _M_word; - _M_word = 0; - } - _M_word = __words; - _M_word_size = __rhs._M_word_size; - - this->flags(__rhs.flags()); - this->width(__rhs.width()); - this->precision(__rhs.precision()); - this->tie(__rhs.tie()); - this->fill(__rhs.fill()); - _M_ios_locale = __rhs.getloc(); - - // This removes the link to __rhs locale cache - _M_call_callbacks(copyfmt_event); - - _M_cache_locale(_M_ios_locale); - - - // The next is required to be the last assignment. - this->exceptions(__rhs.exceptions()); - return *this; } template<typename _CharT, typename _Traits> char basic_ios<_CharT, _Traits>::narrow(char_type __c, char __dfault) const - { - char __ret = __dfault; - if (_M_check_facet(_M_fctype)) - __ret = _M_fctype->narrow(__c, __dfault); - return __ret; - } + { return __check_facet(_M_ctype).narrow(__c, __dfault); } template<typename _CharT, typename _Traits> _CharT basic_ios<_CharT, _Traits>::widen(char __c) const - { - char_type __ret = char_type(); - if (_M_check_facet(_M_fctype)) - __ret = _M_fctype->widen(__c); - return __ret; - } + { return __check_facet(_M_ctype).widen(__c); } // Locales: template<typename _CharT, typename _Traits> @@ -148,8 +140,9 @@ namespace std { // NB: This may be called more than once on the same object. ios_base::_M_init(); + + // Cache locale data and specific facets used by iostreams. _M_cache_locale(_M_ios_locale); - _M_tie = 0; // NB: The 27.4.4.1 Postconditions Table specifies requirements // after basic_ios::init() has been called. As part of this, @@ -166,6 +159,7 @@ namespace std _M_fill = _CharT(); _M_fill_init = false; + _M_tie = 0; _M_exception = goodbit; _M_streambuf = __sb; _M_streambuf_state = __sb ? goodbit : badbit; @@ -176,44 +170,31 @@ namespace std basic_ios<_CharT, _Traits>::_M_cache_locale(const locale& __loc) { if (__builtin_expect(has_facet<__ctype_type>(__loc), true)) - _M_fctype = &use_facet<__ctype_type>(__loc); - else - _M_fctype = 0; - if (__builtin_expect(has_facet<__numput_type>(__loc), true)) - _M_fnumput = &use_facet<__numput_type>(__loc); + _M_ctype = &use_facet<__ctype_type>(__loc); else - _M_fnumput = 0; - if (__builtin_expect(has_facet<__numget_type>(__loc), true)) - _M_fnumget = &use_facet<__numget_type>(__loc); + _M_ctype = 0; + + if (__builtin_expect(has_facet<__num_put_type>(__loc), true)) + _M_num_put = &use_facet<__num_put_type>(__loc); else - _M_fnumget = 0; - } + _M_num_put = 0; -#if 1 - // XXX GLIBCXX_ABI Deprecated, compatibility only. - template<typename _CharT, typename _Traits> - void - basic_ios<_CharT, _Traits>::_M_cache_facets(const locale& __loc) - { - if (__builtin_expect(has_facet<__ctype_type>(__loc), true)) - _M_fctype = &use_facet<__ctype_type>(__loc); - if (__builtin_expect(has_facet<__numput_type>(__loc), true)) - _M_fnumput = &use_facet<__numput_type>(__loc); - if (__builtin_expect(has_facet<__numget_type>(__loc), true)) - _M_fnumget = &use_facet<__numget_type>(__loc); + if (__builtin_expect(has_facet<__num_get_type>(__loc), true)) + _M_num_get = &use_facet<__num_get_type>(__loc); + else + _M_num_get = 0; } -#endif // Inhibit implicit instantiations for required instantiations, - // which are defined via explicit instantiations elsewhere. + // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. -#if _GLIBCPP_EXTERN_TEMPLATE +#if _GLIBCXX_EXTERN_TEMPLATE extern template class basic_ios<char>; -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T extern template class basic_ios<wchar_t>; #endif #endif } // namespace std -#endif +#endif diff --git a/contrib/libstdc++/include/bits/basic_string.h b/contrib/libstdc++/include/bits/basic_string.h index e92009dc9d7b..16fe5ac384b9 100644 --- a/contrib/libstdc++/include/bits/basic_string.h +++ b/contrib/libstdc++/include/bits/basic_string.h @@ -1,6 +1,6 @@ // Components for manipulating sequences of characters -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -37,12 +37,13 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_STRING_H -#define _CPP_BITS_STRING_H 1 +#ifndef _BASIC_STRING_H +#define _BASIC_STRING_H 1 #pragma GCC system_header #include <bits/atomicity.h> +#include <debug/debug.h> namespace std { @@ -72,7 +73,7 @@ namespace std * [_Rep] * _M_length * [basic_string<char_type>] _M_capacity - * _M_dataplus _M_state + * _M_dataplus _M_refcount * _M_p ----------------> unnamed array of char_type * @endcode * @@ -110,37 +111,44 @@ namespace std { // Types: public: - typedef _Traits traits_type; - typedef typename _Traits::char_type value_type; - typedef _Alloc allocator_type; - typedef typename _Alloc::size_type size_type; - typedef typename _Alloc::difference_type difference_type; - typedef typename _Alloc::reference reference; - typedef typename _Alloc::const_reference const_reference; - typedef typename _Alloc::pointer pointer; - typedef typename _Alloc::const_pointer const_pointer; + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef _Alloc allocator_type; + typedef typename _Alloc::size_type size_type; + typedef typename _Alloc::difference_type difference_type; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator; typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string> const_iterator; - typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; private: // _Rep: string representation // Invariants: - // 1. String really contains _M_length + 1 characters; last is set - // to 0 only on call to c_str(). We avoid instantiating - // _CharT() where the interface does not require it. + // 1. String really contains _M_length + 1 characters: due to 21.3.4 + // must be kept null-terminated. // 2. _M_capacity >= _M_length - // Allocated memory is always _M_capacity + (1 * sizeof(_CharT)). - // 3. _M_references has three states: + // Allocated memory is always (_M_capacity + 1) * sizeof(_CharT). + // 3. _M_refcount has three states: // -1: leaked, one reference, no ref-copies allowed, non-const. // 0: one reference, non-const. // n>0: n + 1 references, operations require a lock, const. // 4. All fields==0 is an empty string, given the extra storage // beyond-the-end for a null terminator; thus, the shared // empty string representation needs no constructor. - struct _Rep + + struct _Rep_base + { + size_type _M_length; + size_type _M_capacity; + _Atomic_word _M_refcount; + }; + + struct _Rep : _Rep_base { // Types: typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc; @@ -157,38 +165,38 @@ namespace std // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT) // Solving for m: // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1 - // In addition, this implementation quarters this ammount. - static const size_type _S_max_size; - static const _CharT _S_terminal; + // In addition, this implementation quarters this amount. + static const size_type _S_max_size; + static const _CharT _S_terminal; + + // The following storage is init'd to 0 by the linker, resulting + // (carefully) in an empty string with one reference. + static size_type _S_empty_rep_storage[]; - size_type _M_length; - size_type _M_capacity; - _Atomic_word _M_references; + static _Rep& + _S_empty_rep() + { return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); } bool _M_is_leaked() const - { return _M_references < 0; } + { return this->_M_refcount < 0; } bool _M_is_shared() const - { return _M_references > 0; } + { return this->_M_refcount > 0; } void _M_set_leaked() - { _M_references = -1; } + { this->_M_refcount = -1; } void _M_set_sharable() - { _M_references = 0; } + { this->_M_refcount = 0; } _CharT* _M_refdata() throw() { return reinterpret_cast<_CharT*>(this + 1); } - _CharT& - operator[](size_t __s) throw() - { return _M_refdata() [__s]; } - _CharT* _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2) { @@ -198,13 +206,14 @@ namespace std // Create & Destroy static _Rep* - _S_create(size_t, const _Alloc&); + _S_create(size_type, size_type, const _Alloc&); void _M_dispose(const _Alloc& __a) { - if (__exchange_and_add(&_M_references, -1) <= 0) - _M_destroy(__a); + if (__builtin_expect(this != &_S_empty_rep(), false)) + if (__gnu_cxx::__exchange_and_add(&this->_M_refcount, -1) <= 0) + _M_destroy(__a); } // XXX MT void @@ -213,7 +222,8 @@ namespace std _CharT* _M_refcopy() throw() { - __atomic_add(&_M_references, 1); + if (__builtin_expect(this != &_S_empty_rep(), false)) + __gnu_cxx::__atomic_add(&this->_M_refcount, 1); return _M_refdata(); } // XXX MT @@ -234,15 +244,13 @@ namespace std // Data Members (public): // NB: This is an unsigned type, and thus represents the maximum // size that the allocator can hold. - static const size_type npos = static_cast<size_type>(-1); + /// @var + /// Value returned by various member functions when they fail. + static const size_type npos = static_cast<size_type>(-1); private: // Data Members (private): - mutable _Alloc_hider _M_dataplus; - - // The following storage is init'd to 0 by the linker, resulting - // (carefully) in an empty string with one reference. - static size_type _S_empty_rep_storage[(sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)]; + mutable _Alloc_hider _M_dataplus; _CharT* _M_data() const @@ -271,21 +279,20 @@ namespace std _M_leak_hard(); } - iterator - _M_check(size_type __pos) const + size_type + _M_check(size_type __pos, const char* __s) const { if (__pos > this->size()) - __throw_out_of_range("basic_string::_M_check"); - return _M_ibegin() + __pos; + __throw_out_of_range(__N(__s)); + return __pos; } - // NB: _M_fold doesn't check for a bad __pos1 value. - iterator - _M_fold(size_type __pos, size_type __off) const + // NB: _M_limit doesn't check for a bad __pos value. + size_type + _M_limit(size_type __pos, size_type __off) const { - bool __testoff = __off < this->size() - __pos; - size_type __newoff = __testoff ? __off : this->size() - __pos; - return (_M_ibegin() + __pos + __newoff); + const bool __testoff = __off < this->size() - __pos; + return __testoff ? __off : this->size() - __pos; } // _S_copy_chars is a separate template to permit specialization @@ -322,48 +329,131 @@ namespace std static _Rep& _S_empty_rep() - { return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); } + { return _Rep::_S_empty_rep(); } public: // Construct/copy/destroy: // NB: We overload ctors in some cases instead of using default // arguments, per 17.4.4.4 para. 2 item 2. + /** + * @brief Default constructor creates an empty string. + */ inline basic_string(); + /** + * @brief Construct an empty string using allocator a. + */ explicit basic_string(const _Alloc& __a); // NB: per LWG issue 42, semantics different from IS: + /** + * @brief Construct string with copy of value of @a str. + * @param str Source string. + */ basic_string(const basic_string& __str); + /** + * @brief Construct string as copy of a substring. + * @param str Source string. + * @param pos Index of first character to copy from. + * @param n Number of characters to copy (default remainder). + */ basic_string(const basic_string& __str, size_type __pos, size_type __n = npos); + /** + * @brief Construct string as copy of a substring. + * @param str Source string. + * @param pos Index of first character to copy from. + * @param n Number of characters to copy. + * @param a Allocator to use. + */ basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Alloc& __a); + /** + * @brief Construct string initialized by a character array. + * @param s Source character array. + * @param n Number of characters to copy. + * @param a Allocator to use (default is default allocator). + * + * NB: s must have at least n characters, '\0' has no special + * meaning. + */ basic_string(const _CharT* __s, size_type __n, const _Alloc& __a = _Alloc()); + /** + * @brief Construct string as copy of a C string. + * @param s Source C string. + * @param a Allocator to use (default is default allocator). + */ basic_string(const _CharT* __s, const _Alloc& __a = _Alloc()); + /** + * @brief Construct string as multiple characters. + * @param n Number of characters. + * @param c Character to use. + * @param a Allocator to use (default is default allocator). + */ basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc()); + /** + * @brief Construct string as copy of a range. + * @param beg Start of range. + * @param end End of range. + * @param a Allocator to use (default is default allocator). + */ template<class _InputIterator> basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a = _Alloc()); + /** + * @brief Destroy the string instance. + */ ~basic_string() { _M_rep()->_M_dispose(this->get_allocator()); } + /** + * @brief Assign the value of @a str to this string. + * @param str Source string. + */ basic_string& - operator=(const basic_string& __str) { return this->assign(__str); } + operator=(const basic_string& __str) + { + this->assign(__str); + return *this; + } + /** + * @brief Copy contents of @a s into this string. + * @param s Source null-terminated string. + */ basic_string& - operator=(const _CharT* __s) { return this->assign(__s); } + operator=(const _CharT* __s) + { + this->assign(__s); + return *this; + } + /** + * @brief Set value to string of length 1. + * @param c Source character. + * + * Assigning to a character makes this string length 1 and + * (*this)[0] == @a c. + */ basic_string& - operator=(_CharT __c) { return this->assign(1, __c); } + operator=(_CharT __c) + { + this->assign(1, __c); + return *this; + } // Iterators: + /** + * Returns a read/write iterator that points to the first character in + * the %string. Unshares the string. + */ iterator begin() { @@ -371,333 +461,955 @@ namespace std return iterator(_M_data()); } + /** + * Returns a read-only (constant) iterator that points to the first + * character in the %string. + */ const_iterator begin() const { return const_iterator(_M_data()); } + /** + * Returns a read/write iterator that points one past the last + * character in the %string. Unshares the string. + */ iterator end() { - _M_leak(); - return iterator(_M_data() + this->size()); + _M_leak(); + return iterator(_M_data() + this->size()); } + /** + * Returns a read-only (constant) iterator that points one past the + * last character in the %string. + */ const_iterator end() const { return const_iterator(_M_data() + this->size()); } + /** + * Returns a read/write reverse iterator that points to the last + * character in the %string. Iteration is done in reverse element + * order. Unshares the string. + */ reverse_iterator rbegin() { return reverse_iterator(this->end()); } + /** + * Returns a read-only (constant) reverse iterator that points + * to the last character in the %string. Iteration is done in + * reverse element order. + */ const_reverse_iterator rbegin() const { return const_reverse_iterator(this->end()); } + /** + * Returns a read/write reverse iterator that points to one before the + * first character in the %string. Iteration is done in reverse + * element order. Unshares the string. + */ reverse_iterator rend() { return reverse_iterator(this->begin()); } + /** + * Returns a read-only (constant) reverse iterator that points + * to one before the first character in the %string. Iteration + * is done in reverse element order. + */ const_reverse_iterator rend() const { return const_reverse_iterator(this->begin()); } public: // Capacity: + /// Returns the number of characters in the string, not including any + /// null-termination. size_type size() const { return _M_rep()->_M_length; } + /// Returns the number of characters in the string, not including any + /// null-termination. size_type length() const { return _M_rep()->_M_length; } + /// Returns the size() of the largest possible %string. size_type max_size() const { return _Rep::_S_max_size; } + /** + * @brief Resizes the %string to the specified number of characters. + * @param n Number of characters the %string should contain. + * @param c Character to fill any new elements. + * + * This function will %resize the %string to the specified + * number of characters. If the number is smaller than the + * %string's current size the %string is truncated, otherwise + * the %string is extended and new elements are set to @a c. + */ void resize(size_type __n, _CharT __c); + /** + * @brief Resizes the %string to the specified number of characters. + * @param n Number of characters the %string should contain. + * + * This function will resize the %string to the specified length. If + * the new size is smaller than the %string's current size the %string + * is truncated, otherwise the %string is extended and new characters + * are default-constructed. For basic types such as char, this means + * setting them to 0. + */ void resize(size_type __n) { this->resize(__n, _CharT()); } + /** + * Returns the total number of characters that the %string can hold + * before needing to allocate more memory. + */ size_type capacity() const { return _M_rep()->_M_capacity; } + /** + * @brief Attempt to preallocate enough memory for specified number of + * characters. + * @param n Number of characters required. + * @throw std::length_error If @a n exceeds @c max_size(). + * + * This function attempts to reserve enough memory for the + * %string to hold the specified number of characters. If the + * number requested is more than max_size(), length_error is + * thrown. + * + * The advantage of this function is that if optimal code is a + * necessity and the user can determine the string length that will be + * required, the user can reserve the memory in %advance, and thus + * prevent a possible reallocation of memory and copying of %string + * data. + */ void reserve(size_type __res_arg = 0); + /** + * Erases the string, making it empty. + */ void clear() { _M_mutate(0, this->size(), 0); } + /** + * Returns true if the %string is empty. Equivalent to *this == "". + */ bool empty() const { return this->size() == 0; } // Element access: + /** + * @brief Subscript access to the data contained in the %string. + * @param n The index of the character to access. + * @return Read-only (constant) reference to the character. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) + */ const_reference operator[] (size_type __pos) const - { return _M_data()[__pos]; } + { + _GLIBCXX_DEBUG_ASSERT(__pos <= size()); + return _M_data()[__pos]; + } + /** + * @brief Subscript access to the data contained in the %string. + * @param n The index of the character to access. + * @return Read/write reference to the character. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) Unshares the string. + */ reference operator[](size_type __pos) { + _GLIBCXX_DEBUG_ASSERT(__pos < size()); _M_leak(); return _M_data()[__pos]; } + /** + * @brief Provides access to the data contained in the %string. + * @param n The index of the character to access. + * @return Read-only (const) reference to the character. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is + * first checked that it is in the range of the string. The function + * throws out_of_range if the check fails. + */ const_reference at(size_type __n) const { if (__n >= this->size()) - __throw_out_of_range("basic_string::at"); + __throw_out_of_range(__N("basic_string::at")); return _M_data()[__n]; } + /** + * @brief Provides access to the data contained in the %string. + * @param n The index of the character to access. + * @return Read/write reference to the character. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is + * first checked that it is in the range of the string. The function + * throws out_of_range if the check fails. Success results in + * unsharing the string. + */ reference at(size_type __n) { if (__n >= size()) - __throw_out_of_range("basic_string::at"); + __throw_out_of_range(__N("basic_string::at")); _M_leak(); return _M_data()[__n]; } // Modifiers: + /** + * @brief Append a string to this string. + * @param str The string to append. + * @return Reference to this string. + */ basic_string& operator+=(const basic_string& __str) { return this->append(__str); } + /** + * @brief Append a C string. + * @param s The C string to append. + * @return Reference to this string. + */ basic_string& operator+=(const _CharT* __s) { return this->append(__s); } + /** + * @brief Append a character. + * @param s The character to append. + * @return Reference to this string. + */ basic_string& operator+=(_CharT __c) { return this->append(size_type(1), __c); } + /** + * @brief Append a string to this string. + * @param str The string to append. + * @return Reference to this string. + */ basic_string& append(const basic_string& __str); + /** + * @brief Append a substring. + * @param str The string to append. + * @param pos Index of the first character of str to append. + * @param n The number of characters to append. + * @return Reference to this string. + * @throw std::out_of_range if @a pos is not a valid index. + * + * This function appends @a n characters from @a str starting at @a pos + * to this string. If @a n is is larger than the number of available + * characters in @a str, the remainder of @a str is appended. + */ basic_string& append(const basic_string& __str, size_type __pos, size_type __n); + /** + * @brief Append a C substring. + * @param s The C string to append. + * @param n The number of characters to append. + * @return Reference to this string. + */ basic_string& append(const _CharT* __s, size_type __n); + /** + * @brief Append a C string. + * @param s The C string to append. + * @return Reference to this string. + */ basic_string& append(const _CharT* __s) - { return this->append(__s, traits_type::length(__s)); } + { + __glibcxx_requires_string(__s); + return this->append(__s, traits_type::length(__s)); + } + /** + * @brief Append multiple characters. + * @param n The number of characters to append. + * @param c The character to use. + * @return Reference to this string. + * + * Appends n copies of c to this string. + */ basic_string& - append(size_type __n, _CharT __c); - + append(size_type __n, _CharT __c) + { return _M_replace_aux(this->size(), size_type(0), __n, __c); } + + /** + * @brief Append a range of characters. + * @param first Iterator referencing the first character to append. + * @param last Iterator marking the end of the range. + * @return Reference to this string. + * + * Appends characters in the range [first,last) to this string. + */ template<class _InputIterator> basic_string& append(_InputIterator __first, _InputIterator __last) { return this->replace(_M_iend(), _M_iend(), __first, __last); } + /** + * @brief Append a single character. + * @param c Character to append. + */ void push_back(_CharT __c) - { this->replace(_M_iend(), _M_iend(), 1, __c); } + { _M_replace_aux(this->size(), size_type(0), size_type(1), __c); } + /** + * @brief Set value to contents of another string. + * @param str Source string to use. + * @return Reference to this string. + */ basic_string& assign(const basic_string& __str); + /** + * @brief Set value to a substring of a string. + * @param str The string to use. + * @param pos Index of the first character of str. + * @param n Number of characters to use. + * @return Reference to this string. + * @throw std::out_of_range if @a pos is not a valid index. + * + * This function sets this string to the substring of @a str consisting + * of @a n characters at @a pos. If @a n is is larger than the number + * of available characters in @a str, the remainder of @a str is used. + */ basic_string& - assign(const basic_string& __str, size_type __pos, size_type __n); - + assign(const basic_string& __str, size_type __pos, size_type __n) + { return this->assign(__str._M_data() + + __str._M_check(__pos, "basic_string::assign"), + __str._M_limit(__pos, __n)); } + + /** + * @brief Set value to a C substring. + * @param s The C string to use. + * @param n Number of characters to use. + * @return Reference to this string. + * + * This function sets the value of this string to the first @a n + * characters of @a s. If @a n is is larger than the number of + * available characters in @a s, the remainder of @a s is used. + */ basic_string& assign(const _CharT* __s, size_type __n); + /** + * @brief Set value to contents of a C string. + * @param s The C string to use. + * @return Reference to this string. + * + * This function sets the value of this string to the value of @a s. + * The data is copied, so there is no dependence on @a s once the + * function returns. + */ basic_string& assign(const _CharT* __s) - { return this->assign(__s, traits_type::length(__s)); } + { + __glibcxx_requires_string(__s); + return this->assign(__s, traits_type::length(__s)); + } + /** + * @brief Set value to multiple characters. + * @param n Length of the resulting string. + * @param c The character to use. + * @return Reference to this string. + * + * This function sets the value of this string to @a n copies of + * character @a c. + */ basic_string& assign(size_type __n, _CharT __c) - { return this->replace(_M_ibegin(), _M_iend(), __n, __c); } - + { return _M_replace_aux(size_type(0), this->size(), __n, __c); } + + /** + * @brief Set value to a range of characters. + * @param first Iterator referencing the first character to append. + * @param last Iterator marking the end of the range. + * @return Reference to this string. + * + * Sets value of string to characters in the range [first,last). + */ template<class _InputIterator> basic_string& assign(_InputIterator __first, _InputIterator __last) { return this->replace(_M_ibegin(), _M_iend(), __first, __last); } + /** + * @brief Insert multiple characters. + * @param p Iterator referencing location in string to insert at. + * @param n Number of characters to insert + * @param c The character to insert. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts @a n copies of character @a c starting at the position + * referenced by iterator @a p. If adding characters causes the length + * to exceed max_size(), length_error is thrown. The value of the + * string doesn't change if an error is thrown. + */ void insert(iterator __p, size_type __n, _CharT __c) { this->replace(__p, __p, __n, __c); } + /** + * @brief Insert a range of characters. + * @param p Iterator referencing location in string to insert at. + * @param beg Start of range. + * @param end End of range. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts characters in range [beg,end). If adding characters causes + * the length to exceed max_size(), length_error is thrown. The value + * of the string doesn't change if an error is thrown. + */ template<class _InputIterator> void insert(iterator __p, _InputIterator __beg, _InputIterator __end) { this->replace(__p, __p, __beg, __end); } + /** + * @brief Insert value of a string. + * @param pos1 Iterator referencing location in string to insert at. + * @param str The string to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts value of @a str starting at @a pos1. If adding characters + * causes the length to exceed max_size(), length_error is thrown. The + * value of the string doesn't change if an error is thrown. + */ basic_string& insert(size_type __pos1, const basic_string& __str) - { return this->insert(__pos1, __str, 0, __str.size()); } - + { return this->insert(__pos1, __str, size_type(0), __str.size()); } + + /** + * @brief Insert a substring. + * @param pos1 Iterator referencing location in string to insert at. + * @param str The string to insert. + * @param pos2 Start of characters in str to insert. + * @param n Number of characters to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos1 > size() or + * @a pos2 > @a str.size(). + * + * Starting at @a pos1, insert @a n character of @a str beginning with + * @a pos2. If adding characters causes the length to exceed + * max_size(), length_error is thrown. If @a pos1 is beyond the end of + * this string or @a pos2 is beyond the end of @a str, out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ basic_string& insert(size_type __pos1, const basic_string& __str, - size_type __pos2, size_type __n); - + size_type __pos2, size_type __n) + { return this->insert(__pos1, __str._M_data() + + __str._M_check(__pos2, "basic_string::insert"), + __str._M_limit(__pos2, __n)); } + + /** + * @brief Insert a C substring. + * @param pos Iterator referencing location in string to insert at. + * @param s The C string to insert. + * @param n The number of characters to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts the first @a n characters of @a s starting at @a pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a pos is beyond end(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ basic_string& insert(size_type __pos, const _CharT* __s, size_type __n); + /** + * @brief Insert a C string. + * @param pos Iterator referencing location in string to insert at. + * @param s The C string to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts the first @a n characters of @a s starting at @a pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a pos is beyond end(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ basic_string& insert(size_type __pos, const _CharT* __s) - { return this->insert(__pos, __s, traits_type::length(__s)); } - - basic_string& - insert(size_type __pos, size_type __n, _CharT __c) { - this->insert(_M_check(__pos), __n, __c); - return *this; + __glibcxx_requires_string(__s); + return this->insert(__pos, __s, traits_type::length(__s)); } + /** + * @brief Insert multiple characters. + * @param pos Index in string to insert at. + * @param n Number of characters to insert + * @param c The character to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts @a n copies of character @a c starting at index @a pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a pos > length(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + basic_string& + insert(size_type __pos, size_type __n, _CharT __c) + { return _M_replace_aux(_M_check(__pos, "basic_string::insert"), + size_type(0), __n, __c); } + + /** + * @brief Insert one character. + * @param p Iterator referencing position in string to insert at. + * @param c The character to insert. + * @return Iterator referencing newly inserted char. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts character @a c at position referenced by @a p. If adding + * character causes the length to exceed max_size(), length_error is + * thrown. If @a p is beyond end of string, out_of_range is thrown. + * The value of the string doesn't change if an error is thrown. + */ iterator - insert(iterator __p, _CharT __c = _CharT()) + insert(iterator __p, _CharT __c) { - size_type __pos = __p - _M_ibegin(); - this->insert(_M_check(__pos), size_type(1), __c); + _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend()); + const size_type __pos = __p - _M_ibegin(); + _M_replace_aux(__pos, size_type(0), size_type(1), __c); _M_rep()->_M_set_leaked(); - return this->_M_ibegin() + __pos; + return this->_M_ibegin() + __pos; } + /** + * @brief Remove characters. + * @param pos Index of first character to remove (default 0). + * @param n Number of characters to remove (default remainder). + * @return Reference to this string. + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Removes @a n characters from this string starting at @a pos. The + * length of the string is reduced by @a n. If there are < @a n + * characters to remove, the remainder of the string is truncated. If + * @a p is beyond end of string, out_of_range is thrown. The value of + * the string doesn't change if an error is thrown. + */ basic_string& erase(size_type __pos = 0, size_type __n = npos) - { - return this->replace(_M_check(__pos), _M_fold(__pos, __n), - _M_data(), _M_data()); - } - + { return _M_replace_safe(_M_check(__pos, "basic_string::erase"), + _M_limit(__pos, __n), NULL, size_type(0)); } + + /** + * @brief Remove one character. + * @param position Iterator referencing the character to remove. + * @return iterator referencing same location after removal. + * + * Removes the character at @a position from this string. The value + * of the string doesn't change if an error is thrown. + */ iterator erase(iterator __position) { - size_type __i = __position - _M_ibegin(); - this->replace(__position, __position + 1, _M_data(), _M_data()); + _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin() + && __position < _M_iend()); + const size_type __pos = __position - _M_ibegin(); + _M_replace_safe(__pos, size_type(1), NULL, size_type(0)); _M_rep()->_M_set_leaked(); - return _M_ibegin() + __i; + return _M_ibegin() + __pos; } + /** + * @brief Remove a range of characters. + * @param first Iterator referencing the first character to remove. + * @param last Iterator referencing the end of the range. + * @return Iterator referencing location of first after removal. + * + * Removes the characters in the range [first,last) from this string. + * The value of the string doesn't change if an error is thrown. + */ iterator erase(iterator __first, iterator __last) { - size_type __i = __first - _M_ibegin(); - this->replace(__first, __last, _M_data(), _M_data()); + _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last + && __last <= _M_iend()); + const size_type __pos = __first - _M_ibegin(); + _M_replace_safe(__pos, __last - __first, NULL, size_type(0)); _M_rep()->_M_set_leaked(); - return _M_ibegin() + __i; + return _M_ibegin() + __pos; } + /** + * @brief Replace characters with value from another string. + * @param pos Index of first character to replace. + * @param n Number of characters to be replaced. + * @param str String to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos+n) from this string. + * In place, the value of @a str is inserted. If @a pos is beyond end + * of string, out_of_range is thrown. If the length of the result + * exceeds max_size(), length_error is thrown. The value of the string + * doesn't change if an error is thrown. + */ basic_string& replace(size_type __pos, size_type __n, const basic_string& __str) { return this->replace(__pos, __n, __str._M_data(), __str.size()); } + /** + * @brief Replace characters with value from another string. + * @param pos1 Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param str String to insert. + * @param pos2 Index of first character of str to use. + * @param n2 Number of characters from str to use. + * @return Reference to this string. + * @throw std::out_of_range If @a pos1 > size() or @a pos2 > + * str.size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos1,pos1 + n) from this + * string. In place, the value of @a str is inserted. If @a pos is + * beyond end of string, out_of_range is thrown. If the length of the + * result exceeds max_size(), length_error is thrown. The value of the + * string doesn't change if an error is thrown. + */ basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, - size_type __pos2, size_type __n2); - + size_type __pos2, size_type __n2) + { return this->replace(__pos1, __n1, __str._M_data() + + __str._M_check(__pos2, "basic_string::replace"), + __str._M_limit(__pos2, __n2)); } + + /** + * @brief Replace characters with value of a C substring. + * @param pos Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param str C string to insert. + * @param n2 Number of characters from str to use. + * @return Reference to this string. + * @throw std::out_of_range If @a pos1 > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this string. + * In place, the first @a n2 characters of @a str are inserted, or all + * of @a str if @a n2 is too large. If @a pos is beyond end of string, + * out_of_range is thrown. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't change if + * an error is thrown. + */ basic_string& replace(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2); + /** + * @brief Replace characters with value of a C string. + * @param pos Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param str C string to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this string. + * In place, the first @a n characters of @a str are inserted. If @a + * pos is beyond end of string, out_of_range is thrown. If the length + * of result exceeds max_size(), length_error is thrown. The value of + * the string doesn't change if an error is thrown. + */ basic_string& replace(size_type __pos, size_type __n1, const _CharT* __s) - { return this->replace(__pos, __n1, __s, traits_type::length(__s)); } + { + __glibcxx_requires_string(__s); + return this->replace(__pos, __n1, __s, traits_type::length(__s)); + } + /** + * @brief Replace characters with multiple characters. + * @param pos Index of first character to replace. + * @param n1 Number of characters to be replaced. + * @param n2 Number of characters to insert. + * @param c Character to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this string. + * In place, @a n2 copies of @a c are inserted. If @a pos is beyond + * end of string, out_of_range is thrown. If the length of result + * exceeds max_size(), length_error is thrown. The value of the string + * doesn't change if an error is thrown. + */ basic_string& replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) - { return this->replace(_M_check(__pos), _M_fold(__pos, __n1), __n2, __c); } - + { return _M_replace_aux(_M_check(__pos, "basic_string::replace"), + _M_limit(__pos, __n1), __n2, __c); } + + /** + * @brief Replace range of characters with string. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param str String value to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, the value of + * @a str is inserted. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't change if + * an error is thrown. + */ basic_string& replace(iterator __i1, iterator __i2, const basic_string& __str) { return this->replace(__i1, __i2, __str._M_data(), __str.size()); } + /** + * @brief Replace range of characters with C substring. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param s C string value to insert. + * @param n Number of characters from s to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, the first @a + * n characters of @a s are inserted. If the length of result exceeds + * max_size(), length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ basic_string& - replace(iterator __i1, iterator __i2, - const _CharT* __s, size_type __n) - { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); } + replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); + } + /** + * @brief Replace range of characters with C string. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param s C string value to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, the + * characters of @a s are inserted. If the length of result exceeds + * max_size(), length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ basic_string& replace(iterator __i1, iterator __i2, const _CharT* __s) - { return this->replace(__i1, __i2, __s, traits_type::length(__s)); } + { + __glibcxx_requires_string(__s); + return this->replace(__i1, __i2, __s, traits_type::length(__s)); + } + /** + * @brief Replace range of characters with multiple characters + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param n Number of characters to insert. + * @param c Character to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, @a n copies + * of @a c are inserted. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't change if + * an error is thrown. + */ basic_string& - replace(iterator __i1, iterator __i2, size_type __n, _CharT __c); + replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c); + } + /** + * @brief Replace range of characters with range. + * @param i1 Iterator referencing start of range to replace. + * @param i2 Iterator referencing end of range to replace. + * @param k1 Iterator referencing start of range to insert. + * @param k2 Iterator referencing end of range to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [i1,i2). In place, characters + * in the range [k1,k2) are inserted. If the length of result exceeds + * max_size(), length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ template<class _InputIterator> basic_string& replace(iterator __i1, iterator __i2, _InputIterator __k1, _InputIterator __k2) - { return _M_replace(__i1, __i2, __k1, __k2, - typename iterator_traits<_InputIterator>::iterator_category()); } + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral()); + } // Specializations for the common case of pointer and iterator: // useful to avoid the overhead of temporary buffering in _M_replace. basic_string& - replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2) - { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, - __k1, __k2 - __k1); } + replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1, __k2 - __k1); + } basic_string& - replace(iterator __i1, iterator __i2, const _CharT* __k1, const _CharT* __k2) - { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, - __k1, __k2 - __k1); } + replace(iterator __i1, iterator __i2, + const _CharT* __k1, const _CharT* __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + __k1, __k2 - __k1); + } basic_string& - replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2) - { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __k1.base(), __k2 - __k1); } basic_string& - replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2) - { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, + replace(iterator __i1, iterator __i2, + const_iterator __k1, const_iterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 + && __i2 <= _M_iend()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __k1.base(), __k2 - __k1); } private: + template<class _Integer> + basic_string& + _M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n, + _Integer __val, __true_type) + { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); } + template<class _InputIterator> - basic_string& - _M_replace(iterator __i1, iterator __i2, _InputIterator __k1, - _InputIterator __k2, input_iterator_tag); + basic_string& + _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, + _InputIterator __k2, __false_type); - template<class _ForwardIterator> - basic_string& - _M_replace_safe(iterator __i1, iterator __i2, _ForwardIterator __k1, - _ForwardIterator __k2); + basic_string& + _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, + _CharT __c) + { + if (this->max_size() - (this->size() - __n1) < __n2) + __throw_length_error(__N("basic_string::_M_replace_aux")); + _M_mutate(__pos1, __n1, __n2); + if (__n2 == 1) + _M_data()[__pos1] = __c; + else if (__n2) + traits_type::assign(_M_data() + __pos1, __n2, __c); + return *this; + } + + basic_string& + _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s, + size_type __n2) + { + _M_mutate(__pos1, __n1, __n2); + if (__n2 == 1) + _M_data()[__pos1] = *__s; + else if (__n2) + traits_type::copy(_M_data() + __pos1, __s, __n2); + return *this; + } // _S_construct_aux is used to implement the 21.3.1 para 15 which // requires special behaviour if _InIter is an integral type - template<class _InIter> + template<class _InIterator> static _CharT* - _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a, - __false_type) + _S_construct_aux(_InIterator __beg, _InIterator __end, + const _Alloc& __a, __false_type) { - typedef typename iterator_traits<_InIter>::iterator_category _Tag; + typedef typename iterator_traits<_InIterator>::iterator_category _Tag; return _S_construct(__beg, __end, __a, _Tag()); } - template<class _InIter> + template<class _InIterator> static _CharT* - _S_construct_aux(_InIter __beg, _InIter __end, const _Alloc& __a, - __true_type) - { - return _S_construct(static_cast<size_type>(__beg), - static_cast<value_type>(__end), __a); - } + _S_construct_aux(_InIterator __beg, _InIterator __end, + const _Alloc& __a, __true_type) + { return _S_construct(static_cast<size_type>(__beg), + static_cast<value_type>(__end), __a); } - template<class _InIter> + template<class _InIterator> static _CharT* - _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a) + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a) { - typedef typename _Is_integer<_InIter>::_Integral _Integral; + typedef typename _Is_integer<_InIterator>::_Integral _Integral; return _S_construct_aux(__beg, __end, __a, _Integral()); } // For Input Iterators, used in istreambuf_iterators, etc. - template<class _InIter> + template<class _InIterator> static _CharT* - _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a, + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, input_iterator_tag); // For forward_iterators up to random_access_iterators, used for // string::iterator, _CharT*, etc. - template<class _FwdIter> + template<class _FwdIterator> static _CharT* - _S_construct(_FwdIter __beg, _FwdIter __end, const _Alloc& __a, + _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a, forward_iterator_tag); static _CharT* @@ -705,129 +1417,445 @@ namespace std public: + /** + * @brief Copy substring into C string. + * @param s C string to copy value into. + * @param n Number of characters to copy. + * @param pos Index of first character to copy. + * @return Number of characters actually copied + * @throw std::out_of_range If pos > size(). + * + * Copies up to @a n characters starting at @a pos into the C string @a + * s. If @a pos is greater than size(), out_of_range is thrown. + */ size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const; + /** + * @brief Swap contents with another string. + * @param s String to swap with. + * + * Exchanges the contents of this string with that of @a s in constant + * time. + */ void - swap(basic_string<_CharT, _Traits, _Alloc>& __s); + swap(basic_string& __s); // String operations: + /** + * @brief Return const pointer to null-terminated contents. + * + * This is a handle to internal data. Do not modify or dire things may + * happen. + */ const _CharT* - c_str() const - { - // MT: This assumes concurrent writes are OK. - size_type __n = this->size(); - traits_type::assign(_M_data()[__n], _Rep::_S_terminal); - return _M_data(); - } - + c_str() const { return _M_data(); } + + /** + * @brief Return const pointer to contents. + * + * This is a handle to internal data. Do not modify or dire things may + * happen. + */ const _CharT* data() const { return _M_data(); } + /** + * @brief Return copy of allocator used to construct this string. + */ allocator_type get_allocator() const { return _M_dataplus; } + /** + * @brief Find position of a C substring. + * @param s C string to locate. + * @param pos Index of character to search from. + * @param n Number of characters from @a s to search for. + * @return Index of start of first occurrence. + * + * Starting from @a pos, searches forward for the first @a n characters + * in @a s within this string. If found, returns the index where it + * begins. If not found, returns npos. + */ size_type find(const _CharT* __s, size_type __pos, size_type __n) const; + /** + * @brief Find position of a string. + * @param str String to locate. + * @param pos Index of character to search from (default 0). + * @return Index of start of first occurrence. + * + * Starting from @a pos, searches forward for value of @a str within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ size_type find(const basic_string& __str, size_type __pos = 0) const { return this->find(__str.data(), __pos, __str.size()); } + /** + * @brief Find position of a C string. + * @param s C string to locate. + * @param pos Index of character to search from (default 0). + * @return Index of start of first occurrence. + * + * Starting from @a pos, searches forward for the value of @a s within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ size_type find(const _CharT* __s, size_type __pos = 0) const - { return this->find(__s, __pos, traits_type::length(__s)); } + { + __glibcxx_requires_string(__s); + return this->find(__s, __pos, traits_type::length(__s)); + } + /** + * @brief Find position of a character. + * @param c Character to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for @a c within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ size_type find(_CharT __c, size_type __pos = 0) const; + /** + * @brief Find last position of a string. + * @param str String to locate. + * @param pos Index of character to search back from (default end). + * @return Index of start of last occurrence. + * + * Starting from @a pos, searches backward for value of @a str within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ size_type rfind(const basic_string& __str, size_type __pos = npos) const { return this->rfind(__str.data(), __pos, __str.size()); } + /** + * @brief Find last position of a C substring. + * @param s C string to locate. + * @param pos Index of character to search back from. + * @param n Number of characters from s to search for. + * @return Index of start of last occurrence. + * + * Starting from @a pos, searches backward for the first @a n + * characters in @a s within this string. If found, returns the index + * where it begins. If not found, returns npos. + */ size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const; + /** + * @brief Find last position of a C string. + * @param s C string to locate. + * @param pos Index of character to start search at (default 0). + * @return Index of start of last occurrence. + * + * Starting from @a pos, searches backward for the value of @a s within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ size_type rfind(const _CharT* __s, size_type __pos = npos) const - { return this->rfind(__s, __pos, traits_type::length(__s)); } + { + __glibcxx_requires_string(__s); + return this->rfind(__s, __pos, traits_type::length(__s)); + } + /** + * @brief Find last position of a character. + * @param c Character to locate. + * @param pos Index of character to search back from (default 0). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for @a c within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ size_type rfind(_CharT __c, size_type __pos = npos) const; + /** + * @brief Find position of a character of string. + * @param str String containing characters to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for one of the characters of + * @a str within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ size_type find_first_of(const basic_string& __str, size_type __pos = 0) const { return this->find_first_of(__str.data(), __pos, __str.size()); } + /** + * @brief Find position of a character of C substring. + * @param s String containing characters to locate. + * @param pos Index of character to search from (default 0). + * @param n Number of characters from s to search for. + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for one of the first @a n + * characters of @a s within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const; + /** + * @brief Find position of a character of C string. + * @param s String containing characters to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for one of the characters of + * @a s within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ size_type find_first_of(const _CharT* __s, size_type __pos = 0) const - { return this->find_first_of(__s, __pos, traits_type::length(__s)); } + { + __glibcxx_requires_string(__s); + return this->find_first_of(__s, __pos, traits_type::length(__s)); + } + /** + * @brief Find position of a character. + * @param c Character to locate. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for the character @a c within + * this string. If found, returns the index where it was found. If + * not found, returns npos. + * + * Note: equivalent to find(c, pos). + */ size_type find_first_of(_CharT __c, size_type __pos = 0) const { return this->find(__c, __pos); } + /** + * @brief Find last position of a character of string. + * @param str String containing characters to locate. + * @param pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for one of the characters of + * @a str within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ size_type find_last_of(const basic_string& __str, size_type __pos = npos) const { return this->find_last_of(__str.data(), __pos, __str.size()); } + /** + * @brief Find last position of a character of C substring. + * @param s C string containing characters to locate. + * @param pos Index of character to search back from (default end). + * @param n Number of characters from s to search for. + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for one of the first @a n + * characters of @a s within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const; + /** + * @brief Find last position of a character of C string. + * @param s C string containing characters to locate. + * @param pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for one of the characters of + * @a s within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ size_type find_last_of(const _CharT* __s, size_type __pos = npos) const - { return this->find_last_of(__s, __pos, traits_type::length(__s)); } + { + __glibcxx_requires_string(__s); + return this->find_last_of(__s, __pos, traits_type::length(__s)); + } + /** + * @brief Find last position of a character. + * @param c Character to locate. + * @param pos Index of character to search back from (default 0). + * @return Index of last occurrence. + * + * Starting from @a pos, searches backward for @a c within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + * + * Note: equivalent to rfind(c, pos). + */ size_type find_last_of(_CharT __c, size_type __pos = npos) const { return this->rfind(__c, __pos); } + /** + * @brief Find position of a character not in string. + * @param str String containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character not contained + * in @a str within this string. If found, returns the index where it + * was found. If not found, returns npos. + */ size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const { return this->find_first_not_of(__str.data(), __pos, __str.size()); } + /** + * @brief Find position of a character not in C substring. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @param n Number of characters from s to consider. + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character not contained + * in the first @a n characters of @a s within this string. If found, + * returns the index where it was found. If not found, returns npos. + */ size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const; + /** + * @brief Find position of a character not in C string. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character not contained + * in @a s within this string. If found, returns the index where it + * was found. If not found, returns npos. + */ size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const - { return this->find_first_not_of(__s, __pos, traits_type::length(__s)); } + { + __glibcxx_requires_string(__s); + return this->find_first_not_of(__s, __pos, traits_type::length(__s)); + } + /** + * @brief Find position of a different character. + * @param c Character to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches forward for a character other than @a c + * within this string. If found, returns the index where it was found. + * If not found, returns npos. + */ size_type find_first_not_of(_CharT __c, size_type __pos = 0) const; + /** + * @brief Find last position of a character not in string. + * @param str String containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character not + * contained in @a str within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const { return this->find_last_not_of(__str.data(), __pos, __str.size()); } + /** + * @brief Find last position of a character not in C substring. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @param n Number of characters from s to consider. + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character not + * contained in the first @a n characters of @a s within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const; + /** + * @brief Find position of a character not in C string. + * @param s C string containing characters to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character not + * contained in @a s within this string. If found, returns the index + * where it was found. If not found, returns npos. + */ size_type find_last_not_of(const _CharT* __s, size_type __pos = npos) const - { return this->find_last_not_of(__s, __pos, traits_type::length(__s)); } + { + __glibcxx_requires_string(__s); + return this->find_last_not_of(__s, __pos, traits_type::length(__s)); + } + /** + * @brief Find last position of a different character. + * @param c Character to avoid. + * @param pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a pos, searches backward for a character other than + * @a c within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ size_type find_last_not_of(_CharT __c, size_type __pos = npos) const; + /** + * @brief Get a substring. + * @param pos Index of first character (default 0). + * @param n Number of characters in substring (default remainder). + * @return The new string. + * @throw std::out_of_range If pos > size(). + * + * Construct and return a new string using the @a n characters starting + * at @a pos. If the string is too short, use the remainder of the + * characters. If @a pos is beyond the end of the string, out_of_range + * is thrown. + */ basic_string substr(size_type __pos = 0, size_type __n = npos) const - { - if (__pos > this->size()) - __throw_out_of_range("basic_string::substr"); - return basic_string(*this, __pos, __n); - } - + { return basic_string(*this, + _M_check(__pos, "basic_string::substr"), __n); } + + /** + * @brief Compare to a string. + * @param str String to compare against. + * @return Integer < 0, 0, or > 0. + * + * Returns an integer < 0 if this string is ordered before @a str, 0 if + * their values are equivalent, or > 0 if this string is ordered after + * @a str. If the lengths of @a str and this string are different, the + * shorter one is ordered first. If they are the same, returns the + * result of traits::compare(data(),str.data(),size()); + */ int compare(const basic_string& __str) const { - size_type __size = this->size(); - size_type __osize = __str.size(); - size_type __len = std::min(__size, __osize); + const size_type __size = this->size(); + const size_type __osize = __str.size(); + const size_type __len = std::min(__size, __osize); int __r = traits_type::compare(_M_data(), __str.data(), __len); if (!__r) @@ -835,21 +1863,101 @@ namespace std return __r; } + /** + * @brief Compare substring to a string. + * @param pos Index of first character of substring. + * @param n Number of characters in substring. + * @param str String to compare against. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n characters starting + * at @a pos. Returns an integer < 0 if the substring is ordered + * before @a str, 0 if their values are equivalent, or > 0 if the + * substring is ordered after @a str. If the lengths @a of str and the + * substring are different, the shorter one is ordered first. If they + * are the same, returns the result of + * traits::compare(substring.data(),str.data(),size()); + */ int compare(size_type __pos, size_type __n, const basic_string& __str) const; + /** + * @brief Compare substring to a substring. + * @param pos1 Index of first character of substring. + * @param n1 Number of characters in substring. + * @param str String to compare against. + * @param pos2 Index of first character of substring of str. + * @param n2 Number of characters in substring of str. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n1 characters starting + * at @a pos1. Form the substring of @a str from the @a n2 characters + * starting at @a pos2. Returns an integer < 0 if this substring is + * ordered before the substring of @a str, 0 if their values are + * equivalent, or > 0 if this substring is ordered after the substring + * of @a str. If the lengths of the substring of @a str and this + * substring are different, the shorter one is ordered first. If they + * are the same, returns the result of + * traits::compare(substring.data(),str.substr(pos2,n2).data(),size()); + */ int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) const; + /** + * @brief Compare to a C string. + * @param s C string to compare against. + * @return Integer < 0, 0, or > 0. + * + * Returns an integer < 0 if this string is ordered before @a s, 0 if + * their values are equivalent, or > 0 if this string is ordered after + * @a s. If the lengths of @a s and this string are different, the + * shorter one is ordered first. If they are the same, returns the + * result of traits::compare(data(),s,size()); + */ int compare(const _CharT* __s) const; - // _GLIBCPP_RESOLVE_LIB_DEFECTS + // _GLIBCXX_RESOLVE_LIB_DEFECTS // 5 String::compare specification questionable + /** + * @brief Compare substring to a C string. + * @param pos Index of first character of substring. + * @param n1 Number of characters in substring. + * @param s C string to compare against. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n1 characters starting + * at @a pos. Returns an integer < 0 if the substring is ordered + * before @a s, 0 if their values are equivalent, or > 0 if the + * substring is ordered after @a s. If the lengths of @a s and the + * substring are different, the shorter one is ordered first. If they + * are the same, returns the result of + * traits::compare(substring.data(),s,size()); + */ int compare(size_type __pos, size_type __n1, const _CharT* __s) const; + /** + * @brief Compare substring against a character array. + * @param pos1 Index of first character of substring. + * @param n1 Number of characters in substring. + * @param s character array to compare against. + * @param n2 Number of characters of s. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a n1 characters starting + * at @a pos1. Form a string from the first @a n2 characters of @a s. + * Returns an integer < 0 if this substring is ordered before the string + * from @a s, 0 if their values are equivalent, or > 0 if this substring + * is ordered after the string from @a s. If the lengths of this + * substring and @a n2 are different, the shorter one is ordered first. + * If they are the same, returns the result of + * traits::compare(substring.data(),s,size()); + * + * NB: s must have at least n2 characters, '\0' has no special + * meaning. + */ int compare(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) const; @@ -859,9 +1967,15 @@ namespace std template<typename _CharT, typename _Traits, typename _Alloc> inline basic_string<_CharT, _Traits, _Alloc>:: basic_string() - : _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { } + : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { } // operator+ + /** + * @brief Concatenate two strings. + * @param lhs First string. + * @param rhs Last string. + * @return New string with value of @a lhs followed by @a rhs. + */ template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc> operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, @@ -872,15 +1986,33 @@ namespace std return __str; } + /** + * @brief Concatenate C string and string. + * @param lhs First string. + * @param rhs Last string. + * @return New string with value of @a lhs followed by @a rhs. + */ template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT,_Traits,_Alloc> operator+(const _CharT* __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs); + /** + * @brief Concatenate character and string. + * @param lhs First string. + * @param rhs Last string. + * @return New string with @a lhs followed by @a rhs. + */ template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT,_Traits,_Alloc> operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs); + /** + * @brief Concatenate string and C string. + * @param lhs First string. + * @param rhs Last string. + * @return New string with @a lhs followed by @a rhs. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline basic_string<_CharT, _Traits, _Alloc> operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, @@ -891,11 +2023,17 @@ namespace std return __str; } + /** + * @brief Concatenate string and character. + * @param lhs First string. + * @param rhs Last string. + * @return New string with @a lhs followed by @a rhs. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline basic_string<_CharT, _Traits, _Alloc> operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs) { - typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; typedef typename __string_type::size_type __size_type; __string_type __str(__lhs); __str.append(__size_type(1), __rhs); @@ -903,18 +2041,36 @@ namespace std } // operator == + /** + * @brief Test equivalence of two strings. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs.compare(@a rhs) == 0. False otherwise. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { return __lhs.compare(__rhs) == 0; } + /** + * @brief Test equivalence of C string and string. + * @param lhs C string. + * @param rhs String. + * @return True if @a rhs.compare(@a lhs) == 0. False otherwise. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator==(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { return __rhs.compare(__lhs) == 0; } + /** + * @brief Test equivalence of string and C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs.compare(@a rhs) == 0. False otherwise. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs, @@ -922,18 +2078,36 @@ namespace std { return __lhs.compare(__rhs) == 0; } // operator != + /** + * @brief Test difference of two strings. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs.compare(@a rhs) != 0. False otherwise. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { return __rhs.compare(__lhs) != 0; } + /** + * @brief Test difference of C string and string. + * @param lhs C string. + * @param rhs String. + * @return True if @a rhs.compare(@a lhs) != 0. False otherwise. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator!=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { return __rhs.compare(__lhs) != 0; } + /** + * @brief Test difference of string and C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs.compare(@a rhs) != 0. False otherwise. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, @@ -941,18 +2115,36 @@ namespace std { return __lhs.compare(__rhs) != 0; } // operator < + /** + * @brief Test if string precedes string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs precedes @a rhs. False otherwise. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { return __lhs.compare(__rhs) < 0; } + /** + * @brief Test if string precedes C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs precedes @a rhs. False otherwise. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const _CharT* __rhs) { return __lhs.compare(__rhs) < 0; } + /** + * @brief Test if C string precedes string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs precedes @a rhs. False otherwise. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator<(const _CharT* __lhs, @@ -960,18 +2152,36 @@ namespace std { return __rhs.compare(__lhs) > 0; } // operator > + /** + * @brief Test if string follows string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs follows @a rhs. False otherwise. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { return __lhs.compare(__rhs) > 0; } + /** + * @brief Test if string follows C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs follows @a rhs. False otherwise. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const _CharT* __rhs) { return __lhs.compare(__rhs) > 0; } + /** + * @brief Test if C string follows string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs follows @a rhs. False otherwise. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator>(const _CharT* __lhs, @@ -979,18 +2189,36 @@ namespace std { return __rhs.compare(__lhs) < 0; } // operator <= + /** + * @brief Test if string doesn't follow string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs doesn't follow @a rhs. False otherwise. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { return __lhs.compare(__rhs) <= 0; } + /** + * @brief Test if string doesn't follow C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs doesn't follow @a rhs. False otherwise. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const _CharT* __rhs) { return __lhs.compare(__rhs) <= 0; } + /** + * @brief Test if C string doesn't follow string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs doesn't follow @a rhs. False otherwise. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator<=(const _CharT* __lhs, @@ -998,50 +2226,119 @@ namespace std { return __rhs.compare(__lhs) >= 0; } // operator >= + /** + * @brief Test if string doesn't precede string. + * @param lhs First string. + * @param rhs Second string. + * @return True if @a lhs doesn't precede @a rhs. False otherwise. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { return __lhs.compare(__rhs) >= 0; } + /** + * @brief Test if string doesn't precede C string. + * @param lhs String. + * @param rhs C string. + * @return True if @a lhs doesn't precede @a rhs. False otherwise. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const _CharT* __rhs) { return __lhs.compare(__rhs) >= 0; } + /** + * @brief Test if C string doesn't precede string. + * @param lhs C string. + * @param rhs String. + * @return True if @a lhs doesn't precede @a rhs. False otherwise. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator>=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { return __rhs.compare(__lhs) <= 0; } - + /** + * @brief Swap contents of two strings. + * @param lhs First string. + * @param rhs Second string. + * + * Exchanges the contents of @a lhs and @a rhs in constant time. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline void swap(basic_string<_CharT, _Traits, _Alloc>& __lhs, basic_string<_CharT, _Traits, _Alloc>& __rhs) { __lhs.swap(__rhs); } + /** + * @brief Read stream into a string. + * @param is Input stream. + * @param str Buffer to store into. + * @return Reference to the input stream. + * + * Stores characters from @a is into @a str until whitespace is found, the + * end of the stream is encountered, or str.max_size() is reached. If + * is.width() is non-zero, that is the limit on the number of characters + * stored into @a str. Any previous contents of @a str are erased. + */ template<typename _CharT, typename _Traits, typename _Alloc> basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Alloc>& __str); + /** + * @brief Write string to a stream. + * @param os Output stream. + * @param str String to write out. + * @return Reference to the output stream. + * + * Output characters of @a str into os following the same rules as for + * writing a C string. + */ template<typename _CharT, typename _Traits, typename _Alloc> basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const basic_string<_CharT, _Traits, _Alloc>& __str); + /** + * @brief Read a line from stream into a string. + * @param is Input stream. + * @param str Buffer to store into. + * @param delim Character marking end of line. + * @return Reference to the input stream. + * + * Stores characters from @a is into @a str until @a delim is found, the + * end of the stream is encountered, or str.max_size() is reached. If + * is.width() is non-zero, that is the limit on the number of characters + * stored into @a str. Any previous contents of @a str are erased. If @a + * delim was encountered, it is extracted but not stored into @a str. + */ template<typename _CharT, typename _Traits, typename _Alloc> basic_istream<_CharT,_Traits>& getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim); + /** + * @brief Read a line from stream into a string. + * @param is Input stream. + * @param str Buffer to store into. + * @return Reference to the input stream. + * + * Stores characters from is into @a str until '\n' is found, the end of + * the stream is encountered, or str.max_size() is reached. If is.width() + * is non-zero, that is the limit on the number of characters stored into + * @a str. Any previous contents of @a str are erased. If end of line was + * encountered, it is extracted but not stored into @a str. + */ template<typename _CharT, typename _Traits, typename _Alloc> inline basic_istream<_CharT,_Traits>& getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Alloc>& __str); } // namespace std -#endif /* _CPP_BITS_STRING_H */ +#endif /* _BASIC_STRING_H */ diff --git a/contrib/libstdc++/include/bits/basic_string.tcc b/contrib/libstdc++/include/bits/basic_string.tcc index d3f1e8e36059..7034778e9dff 100644 --- a/contrib/libstdc++/include/bits/basic_string.tcc +++ b/contrib/libstdc++/include/bits/basic_string.tcc @@ -1,6 +1,6 @@ // Components for manipulating sequences of characters -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -38,20 +38,30 @@ // Written by Jason Merrill based upon the specification by Takanori Adachi // in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882. -#ifndef _CPP_BITS_STRING_TCC -#define _CPP_BITS_STRING_TCC 1 +#ifndef _BASIC_STRING_TCC +#define _BASIC_STRING_TCC 1 #pragma GCC system_header namespace std { + template<typename _Type> + inline bool + __is_null_pointer(_Type* __ptr) + { return __ptr == 0; } + + template<typename _Type> + inline bool + __is_null_pointer(_Type) + { return false; } + template<typename _CharT, typename _Traits, typename _Alloc> - const typename basic_string<_CharT, _Traits, _Alloc>::size_type + const typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: - _Rep::_S_max_size = (((npos - sizeof(_Rep))/sizeof(_CharT)) - 1) / 4; + _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4; template<typename _CharT, typename _Traits, typename _Alloc> - const _CharT + const _CharT basic_string<_CharT, _Traits, _Alloc>:: _Rep::_S_terminal = _CharT(); @@ -63,100 +73,86 @@ namespace std // at static init time (before static ctors are run). template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type - basic_string<_CharT, _Traits, _Alloc>::_S_empty_rep_storage[ - (sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)]; + basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[ + (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) / + sizeof(size_type)]; // NB: This is the special case for Input Iterators, used in // istreambuf_iterators, etc. // Input Iterators have a cost structure very different from // pointers, calling for a different coding style. template<typename _CharT, typename _Traits, typename _Alloc> - template<typename _InIter> + template<typename _InIterator> _CharT* basic_string<_CharT, _Traits, _Alloc>:: - _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a, + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, input_iterator_tag) { if (__beg == __end && __a == _Alloc()) - return _S_empty_rep()._M_refcopy(); + return _S_empty_rep()._M_refdata(); // Avoid reallocation for common case. - _CharT __buf[100]; - size_type __i = 0; - while (__beg != __end && __i < sizeof(__buf) / sizeof(_CharT)) - { - __buf[__i++] = *__beg; - ++__beg; + _CharT __buf[128]; + size_type __len = 0; + while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT)) + { + __buf[__len++] = *__beg; + ++__beg; } - _Rep* __r = _Rep::_S_create(__i, __a); - traits_type::copy(__r->_M_refdata(), __buf, __i); - __r->_M_length = __i; - try + _Rep* __r = _Rep::_S_create(__len, size_type(0), __a); + traits_type::copy(__r->_M_refdata(), __buf, __len); + try { - // NB: this loop looks precisely this way because - // it avoids comparing __beg != __end any more - // than strictly necessary; != might be expensive! - for (;;) + while (__beg != __end) { - _CharT* __p = __r->_M_refdata() + __r->_M_length; - _CharT* __last = __r->_M_refdata() + __r->_M_capacity; - for (;;) + if (__len == __r->_M_capacity) { - if (__beg == __end) - { - __r->_M_length = __p - __r->_M_refdata(); - *__p = _Rep::_S_terminal; // grrr. - return __r->_M_refdata(); - } - if (__p == __last) - break; - *__p++ = *__beg; - ++__beg; + // Allocate more space. + _Rep* __another = _Rep::_S_create(__len + 1, __len, __a); + traits_type::copy(__another->_M_refdata(), + __r->_M_refdata(), __len); + __r->_M_destroy(__a); + __r = __another; } - // Allocate more space. - size_type __len = __p - __r->_M_refdata(); - _Rep* __another = _Rep::_S_create(__len + 1, __a); - traits_type::copy(__another->_M_refdata(), - __r->_M_refdata(), __len); - __r->_M_destroy(__a); - __r = __another; - __r->_M_length = __len; + __r->_M_refdata()[__len++] = *__beg; + ++__beg; } } - catch(...) + catch(...) { - __r->_M_destroy(__a); + __r->_M_destroy(__a); __throw_exception_again; } - return 0; + __r->_M_length = __len; + __r->_M_refdata()[__len] = _Rep::_S_terminal; // grrr. + return __r->_M_refdata(); } - + template<typename _CharT, typename _Traits, typename _Alloc> - template <class _InIter> + template <typename _InIterator> _CharT* basic_string<_CharT, _Traits, _Alloc>:: - _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a, + _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, forward_iterator_tag) { if (__beg == __end && __a == _Alloc()) - return _S_empty_rep()._M_refcopy(); + return _S_empty_rep()._M_refdata(); // NB: Not required, but considered best practice. - if (__builtin_expect(__beg == _InIter(), 0)) - __throw_logic_error("attempt to create string with null pointer"); + if (__builtin_expect(__is_null_pointer(__beg), 0)) + __throw_logic_error(__N("basic_string::_S_construct NULL not valid")); - size_type __dnew = static_cast<size_type>(std::distance(__beg, __end)); - + const size_type __dnew = static_cast<size_type>(std::distance(__beg, + __end)); // Check for out_of_range and length_error exceptions. - _Rep* __r = _Rep::_S_create(__dnew, __a); - try + _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a); + try { _S_copy_chars(__r->_M_refdata(), __beg, __end); } - catch(...) - { - __r->_M_destroy(__a); + catch(...) + { + __r->_M_destroy(__a); __throw_exception_again; } __r->_M_length = __dnew; - __r->_M_refdata()[__dnew] = _Rep::_S_terminal; // grrr. return __r->_M_refdata(); } @@ -167,20 +163,13 @@ namespace std _S_construct(size_type __n, _CharT __c, const _Alloc& __a) { if (__n == 0 && __a == _Alloc()) - return _S_empty_rep()._M_refcopy(); + return _S_empty_rep()._M_refdata(); // Check for out_of_range and length_error exceptions. - _Rep* __r = _Rep::_S_create(__n, __a); - try - { - if (__n) - traits_type::assign(__r->_M_refdata(), __n, __c); - } - catch(...) - { - __r->_M_destroy(__a); - __throw_exception_again; - } + _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); + if (__n) + traits_type::assign(__r->_M_refdata(), __n, __c); + __r->_M_length = __n; __r->_M_refdata()[__n] = _Rep::_S_terminal; // grrr return __r->_M_refdata(); @@ -189,8 +178,9 @@ namespace std template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>:: basic_string(const basic_string& __str) - : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(), __str.get_allocator()), - __str.get_allocator()) + : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()), + __str.get_allocator()), + __str.get_allocator()) { } template<typename _CharT, typename _Traits, typename _Alloc> @@ -198,28 +188,36 @@ namespace std basic_string(const _Alloc& __a) : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a) { } - + template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>:: basic_string(const basic_string& __str, size_type __pos, size_type __n) - : _M_dataplus(_S_construct(__str._M_check(__pos), - __str._M_fold(__pos, __n), _Alloc()), _Alloc()) + : _M_dataplus(_S_construct(__str._M_data() + + __str._M_check(__pos, + "basic_string::basic_string"), + __str._M_data() + __str._M_limit(__pos, __n) + + __pos, _Alloc()), _Alloc()) { } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>:: basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Alloc& __a) - : _M_dataplus(_S_construct(__str._M_check(__pos), - __str._M_fold(__pos, __n), __a), __a) + : _M_dataplus(_S_construct(__str._M_data() + + __str._M_check(__pos, + "basic_string::basic_string"), + __str._M_data() + __str._M_limit(__pos, __n) + + __pos, __a), __a) { } + // TBD: DPG annotate template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>:: basic_string(const _CharT* __s, size_type __n, const _Alloc& __a) : _M_dataplus(_S_construct(__s, __s + __n, __a), __a) { } + // TBD: DPG annotate template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>:: basic_string(const _CharT* __s, const _Alloc& __a) @@ -232,22 +230,24 @@ namespace std basic_string(size_type __n, _CharT __c, const _Alloc& __a) : _M_dataplus(_S_construct(__n, __c, __a), __a) { } - + + // TBD: DPG annotate template<typename _CharT, typename _Traits, typename _Alloc> - template<typename _InputIter> + template<typename _InputIterator> basic_string<_CharT, _Traits, _Alloc>:: - basic_string(_InputIter __beg, _InputIter __end, const _Alloc& __a) + basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a) : _M_dataplus(_S_construct(__beg, __end, __a), __a) { } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>& - basic_string<_CharT, _Traits, _Alloc>::assign(const basic_string& __str) + basic_string<_CharT, _Traits, _Alloc>:: + assign(const basic_string& __str) { if (_M_rep() != __str._M_rep()) { // XXX MT - allocator_type __a = this->get_allocator(); + const allocator_type __a = this->get_allocator(); _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator()); _M_rep()->_M_dispose(__a); _M_data(__tmp); @@ -258,26 +258,14 @@ namespace std template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: - assign(const basic_string& __str, size_type __pos, size_type __n) - { - const size_type __strsize = __str.size(); - if (__pos > __strsize) - __throw_out_of_range("basic_string::assign"); - const bool __testn = __n < __strsize - __pos; - const size_type __newsize = __testn ? __n : __strsize - __pos; - return this->assign(__str._M_data() + __pos, __newsize); - } - - template<typename _CharT, typename _Traits, typename _Alloc> - basic_string<_CharT, _Traits, _Alloc>& - basic_string<_CharT, _Traits, _Alloc>:: assign(const _CharT* __s, size_type __n) { + __glibcxx_requires_string_len(__s, __n); if (__n > this->max_size()) - __throw_length_error("basic_string::assign"); + __throw_length_error(__N("basic_string::assign")); if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data()) || less<const _CharT*>()(_M_data() + this->size(), __s)) - return _M_replace_safe(_M_ibegin(), _M_iend(), __s, __s + __n); + return _M_replace_safe(size_type(0), this->size(), __s, __n); else { // Work in-place @@ -286,6 +274,7 @@ namespace std traits_type::copy(_M_data(), __s, __n); else if (__pos) traits_type::move(_M_data(), __s, __n); + _M_rep()->_M_set_sharable(); _M_rep()->_M_length = __n; _M_data()[__n] = _Rep::_S_terminal; // grr. return *this; @@ -295,31 +284,15 @@ namespace std template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: - insert(size_type __pos1, const basic_string& __str, - size_type __pos2, size_type __n) - { - const size_type __strsize = __str.size(); - if (__pos2 > __strsize) - __throw_out_of_range("basic_string::insert"); - const bool __testn = __n < __strsize - __pos2; - const size_type __newsize = __testn ? __n : __strsize - __pos2; - return this->insert(__pos1, __str._M_data() + __pos2, __newsize); - } - - template<typename _CharT, typename _Traits, typename _Alloc> - basic_string<_CharT, _Traits, _Alloc>& - basic_string<_CharT, _Traits, _Alloc>:: insert(size_type __pos, const _CharT* __s, size_type __n) { - const size_type __size = this->size(); - if (__pos > __size) - __throw_out_of_range("basic_string::insert"); - if (__size > this->max_size() - __n) - __throw_length_error("basic_string::insert"); + __glibcxx_requires_string_len(__s, __n); + _M_check(__pos, "basic_string::insert"); + if (this->max_size() - this->size() < __n) + __throw_length_error(__N("basic_string::insert")); if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data()) - || less<const _CharT*>()(_M_data() + __size, __s)) - return _M_replace_safe(_M_ibegin() + __pos, _M_ibegin() + __pos, - __s, __s + __n); + || less<const _CharT*>()(_M_data() + this->size(), __s)) + return _M_replace_safe(__pos, size_type(0), __s, __n); else { // Work in-place. If _M_mutate reallocates the string, __s @@ -335,43 +308,60 @@ namespace std traits_type::copy(__p, __s + __n, __n); else { - traits_type::copy(__p, __s, __p - __s); - traits_type::copy(__p + (__p-__s), __p + __n, __n - (__p-__s)); + const size_type __nleft = __p - __s; + traits_type::copy(__p, __s, __nleft); + traits_type::copy(__p + __nleft, __p + __n, __n - __nleft); } return *this; } } - + template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: replace(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) { - const size_type __size = this->size(); - if (__pos > __size) - __throw_out_of_range("basic_string::replace"); - const bool __testn1 = __n1 < __size - __pos; - const size_type __foldn1 = __testn1 ? __n1 : __size - __pos; - if (__size - __foldn1 > this->max_size() - __n2) - __throw_length_error("basic_string::replace"); + __glibcxx_requires_string_len(__s, __n2); + _M_check(__pos, "basic_string::replace"); + __n1 = _M_limit(__pos, __n1); + if (this->max_size() - (this->size() - __n1) < __n2) + __throw_length_error(__N("basic_string::replace")); + bool __left; if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data()) - || less<const _CharT*>()(_M_data() + __size, __s)) - return _M_replace_safe(_M_ibegin() + __pos, - _M_ibegin() + __pos + __foldn1, __s, __s + __n2); - // Todo: optimized in-place replace. + || less<const _CharT*>()(_M_data() + this->size(), __s)) + return _M_replace_safe(__pos, __n1, __s, __n2); + else if ((__left = __s + __n2 <= _M_data() + __pos) + || _M_data() + __pos + __n1 <= __s) + { + // Work in-place: non-overlapping case. + const size_type __off = __s - _M_data(); + _M_mutate(__pos, __n1, __n2); + if (__left) + traits_type::copy(_M_data() + __pos, + _M_data() + __off, __n2); + else + traits_type::copy(_M_data() + __pos, + _M_data() + __off + __n2 - __n1, __n2); + return *this; + } else - return _M_replace(_M_ibegin() + __pos, _M_ibegin() + __pos + __foldn1, - __s, __s + __n2, - typename iterator_traits<const _CharT*>::iterator_category()); + { + // Todo: overlapping case. + const basic_string __tmp(__s, __n2); + return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2); + } } - + template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>::_Rep:: _M_destroy(const _Alloc& __a) throw () { - size_type __size = sizeof(_Rep) + (_M_capacity + 1) * sizeof(_CharT); + if (this == &_S_empty_rep()) + return; + const size_type __size = sizeof(_Rep_base) + + (this->_M_capacity + 1) * sizeof(_CharT); _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size); } @@ -379,97 +369,74 @@ namespace std void basic_string<_CharT, _Traits, _Alloc>::_M_leak_hard() { - if (_M_rep()->_M_is_shared()) + if (_M_rep() == &_S_empty_rep()) + return; + if (_M_rep()->_M_is_shared()) _M_mutate(0, 0, 0); _M_rep()->_M_set_leaked(); } - // _M_mutate and, below, _M_clone, include, in the same form, an exponential - // growth policy, necessary to meet amortized linear time requirements of - // the library: see http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. - // The policy is active for allocations requiring an amount of memory above - // system pagesize. This is consistent with the requirements of the standard: - // see, f.i., http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>:: _M_mutate(size_type __pos, size_type __len1, size_type __len2) { - size_type __old_size = this->size(); + const size_type __old_size = this->size(); const size_type __new_size = __old_size + __len2 - __len1; - const _CharT* __src = _M_data() + __pos + __len1; const size_type __how_much = __old_size - __pos - __len1; - - if (_M_rep()->_M_is_shared() || __new_size > capacity()) + + if (_M_rep() == &_S_empty_rep() + || _M_rep()->_M_is_shared() || __new_size > capacity()) { // Must reallocate. - allocator_type __a = get_allocator(); - // See below (_S_create) for the meaning and value of these - // constants. - const size_type __pagesize = 4096; - const size_type __malloc_header_size = 4 * sizeof (void*); - // The biggest string which fits in a memory page - const size_type __page_capacity = (__pagesize - __malloc_header_size - - sizeof(_Rep) - sizeof(_CharT)) - / sizeof(_CharT); - _Rep* __r; - if (__new_size > capacity() && __new_size > __page_capacity) - // Growing exponentially. - __r = _Rep::_S_create(__new_size > 2*capacity() ? - __new_size : 2*capacity(), __a); - else - __r = _Rep::_S_create(__new_size, __a); - try - { - if (__pos) - traits_type::copy(__r->_M_refdata(), _M_data(), __pos); - if (__how_much) - traits_type::copy(__r->_M_refdata() + __pos + __len2, - __src, __how_much); - } - catch(...) - { - __r->_M_dispose(get_allocator()); - __throw_exception_again; - } + const allocator_type __a = get_allocator(); + _Rep* __r = _Rep::_S_create(__new_size, capacity(), __a); + + if (__pos) + traits_type::copy(__r->_M_refdata(), _M_data(), __pos); + if (__how_much) + traits_type::copy(__r->_M_refdata() + __pos + __len2, + _M_data() + __pos + __len1, __how_much); + _M_rep()->_M_dispose(__a); _M_data(__r->_M_refdata()); - } + } else if (__how_much && __len1 != __len2) { // Work in-place - traits_type::move(_M_data() + __pos + __len2, __src, __how_much); + traits_type::move(_M_data() + __pos + __len2, + _M_data() + __pos + __len1, __how_much); } _M_rep()->_M_set_sharable(); _M_rep()->_M_length = __new_size; _M_data()[__new_size] = _Rep::_S_terminal; // grrr. (per 21.3.4) - // You cannot leave those LWG people alone for a second. + // You cannot leave those LWG people alone for a second. } - + template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>::reserve(size_type __res) { - if (__res > this->capacity() || _M_rep()->_M_is_shared()) + if (__res != this->capacity() || _M_rep()->_M_is_shared()) { if (__res > this->max_size()) - __throw_length_error("basic_string::reserve"); + __throw_length_error(__N("basic_string::reserve")); // Make sure we don't shrink below the current size if (__res < this->size()) __res = this->size(); - allocator_type __a = get_allocator(); + const allocator_type __a = get_allocator(); _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size()); _M_rep()->_M_dispose(__a); _M_data(__tmp); } } - + template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>::swap(basic_string& __s) { - if (_M_rep()->_M_is_leaked()) + if (_M_rep()->_M_is_leaked()) _M_rep()->_M_set_sharable(); - if (__s._M_rep()->_M_is_leaked()) + if (__s._M_rep()->_M_is_leaked()) __s._M_rep()->_M_set_sharable(); if (this->get_allocator() == __s.get_allocator()) { @@ -478,11 +445,12 @@ namespace std __s._M_data(__tmp); } // The code below can usually be optimized away. - else + else { - basic_string __tmp1(_M_ibegin(), _M_iend(), __s.get_allocator()); - basic_string __tmp2(__s._M_ibegin(), __s._M_iend(), - this->get_allocator()); + const basic_string __tmp1(_M_ibegin(), _M_iend(), + __s.get_allocator()); + const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(), + this->get_allocator()); *this = __tmp2; __s = __tmp1; } @@ -491,26 +459,20 @@ namespace std template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::_Rep* basic_string<_CharT, _Traits, _Alloc>::_Rep:: - _S_create(size_t __capacity, const _Alloc& __alloc) + _S_create(size_type __capacity, size_type __old_capacity, + const _Alloc& __alloc) { typedef basic_string<_CharT, _Traits, _Alloc> __string_type; -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + // _GLIBCXX_RESOLVE_LIB_DEFECTS // 83. String::npos vs. string::max_size() if (__capacity > _S_max_size) -#else - if (__capacity == npos) -#endif - __throw_length_error("basic_string::_S_create"); - - // NB: Need an array of char_type[__capacity], plus a - // terminating null char_type() element, plus enough for the - // _Rep data structure. Whew. Seemingly so needy, yet so elemental. - size_t __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); + __throw_length_error(__N("basic_string::_S_create")); // The standard places no restriction on allocating more memory // than is strictly needed within this layer at the moment or as - // requested by an explicit application call to reserve(). Many - // malloc implementations perform quite poorly when an + // requested by an explicit application call to reserve(). + + // Many malloc implementations perform quite poorly when an // application attempts to allocate memory in a stepwise fashion // growing each allocation size by only 1 char. Additionally, // it makes little sense to allocate less linear memory than the @@ -529,22 +491,44 @@ namespace std // low-balling it (especially when this algorithm is used with // malloc implementations that allocate memory blocks rounded up // to a size which is a power of 2). - const size_t __pagesize = 4096; // must be 2^i * __subpagesize - const size_t __subpagesize = 128; // should be >> __malloc_header_size - const size_t __malloc_header_size = 4 * sizeof (void*); - if ((__size + __malloc_header_size) > __pagesize) + const size_type __pagesize = 4096; // must be 2^i * __subpagesize + const size_type __subpagesize = 128; // should be >> __malloc_header_size + const size_type __malloc_header_size = 4 * sizeof (void*); + + // The below implements an exponential growth policy, necessary to + // meet amortized linear time requirements of the library: see + // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. + // It's active for allocations requiring an amount of memory above + // system pagesize. This is consistent with the requirements of the + // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html + + // The biggest string which fits in a memory page + const size_type __page_capacity = ((__pagesize - __malloc_header_size + - sizeof(_Rep) - sizeof(_CharT)) + / sizeof(_CharT)); + + if (__capacity > __old_capacity && __capacity < 2 * __old_capacity + && __capacity > __page_capacity) + __capacity = 2 * __old_capacity; + + // NB: Need an array of char_type[__capacity], plus a terminating + // null char_type() element, plus enough for the _Rep data structure. + // Whew. Seemingly so needy, yet so elemental. + size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); + + const size_type __adj_size = __size + __malloc_header_size; + if (__adj_size > __pagesize) { - size_t __extra = - (__pagesize - ((__size + __malloc_header_size) % __pagesize)) - % __pagesize; + const size_type __extra = __pagesize - __adj_size % __pagesize; __capacity += __extra / sizeof(_CharT); + // Never allocate a string bigger than _S_max_size. + if (__capacity > _S_max_size) + __capacity = _S_max_size; __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); } else if (__size > __subpagesize) { - size_t __extra = - (__subpagesize - ((__size + __malloc_header_size) % __subpagesize)) - % __subpagesize; + const size_type __extra = __subpagesize - __adj_size % __subpagesize; __capacity += __extra / sizeof(_CharT); __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); } @@ -565,43 +549,25 @@ namespace std _M_clone(const _Alloc& __alloc, size_type __res) { // Requested capacity of the clone. - const size_type __requested_cap = _M_length + __res; - // See above (_S_create) for the meaning and value of these constants. - const size_type __pagesize = 4096; - const size_type __malloc_header_size = 4 * sizeof (void*); - // The biggest string which fits in a memory page. - const size_type __page_capacity = - (__pagesize - __malloc_header_size - sizeof(_Rep) - sizeof(_CharT)) - / sizeof(_CharT); - _Rep* __r; - if (__requested_cap > _M_capacity && __requested_cap > __page_capacity) - // Growing exponentially. - __r = _Rep::_S_create(__requested_cap > 2*_M_capacity ? - __requested_cap : 2*_M_capacity, __alloc); - else - __r = _Rep::_S_create(__requested_cap, __alloc); - - if (_M_length) - { - try - { traits_type::copy(__r->_M_refdata(), _M_refdata(), _M_length); } - catch(...) - { - __r->_M_destroy(__alloc); - __throw_exception_again; - } - } - __r->_M_length = _M_length; + const size_type __requested_cap = this->_M_length + __res; + _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity, + __alloc); + if (this->_M_length) + traits_type::copy(__r->_M_refdata(), _M_refdata(), + this->_M_length); + + __r->_M_length = this->_M_length; + __r->_M_refdata()[this->_M_length] = _Rep::_S_terminal; return __r->_M_refdata(); } - + template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>::resize(size_type __n, _CharT __c) { if (__n > max_size()) - __throw_length_error("basic_string::resize"); - size_type __size = this->size(); + __throw_length_error(__N("basic_string::resize")); + const size_type __size = this->size(); if (__size < __n) this->append(__n - __size, __c); else if (__n < __size) @@ -609,76 +575,35 @@ namespace std // else nothing (in particular, avoid calling _M_mutate() unnecessarily.) } - // This is the general replace helper, which currently gets instantiated both - // for input iterators and reverse iterators. It buffers internally and then - // calls _M_replace_safe. template<typename _CharT, typename _Traits, typename _Alloc> - template<typename _InputIter> + template<typename _InputIterator> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: - _M_replace(iterator __i1, iterator __i2, _InputIter __k1, - _InputIter __k2, input_iterator_tag) + _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, + _InputIterator __k2, __false_type) { - // Save concerned source string data in a temporary. - basic_string __s(__k1, __k2); - return _M_replace_safe(__i1, __i2, __s._M_ibegin(), __s._M_iend()); - } - - // This is a special replace helper, which does not buffer internally - // and can be used in "safe" situations involving forward iterators, - // i.e., when source and destination ranges are known to not overlap. - template<typename _CharT, typename _Traits, typename _Alloc> - template<typename _ForwardIter> - basic_string<_CharT, _Traits, _Alloc>& - basic_string<_CharT, _Traits, _Alloc>:: - _M_replace_safe(iterator __i1, iterator __i2, _ForwardIter __k1, - _ForwardIter __k2) - { - size_type __dnew = static_cast<size_type>(std::distance(__k1, __k2)); - size_type __dold = __i2 - __i1; - size_type __dmax = this->max_size(); - - if (__dmax <= __dnew) - __throw_length_error("basic_string::_M_replace"); - size_type __off = __i1 - _M_ibegin(); - _M_mutate(__off, __dold, __dnew); - - // Invalidated __i1, __i2 - if (__dnew) - _S_copy_chars(_M_data() + __off, __k1, __k2); - - return *this; + const basic_string __s(__k1, __k2); + const size_type __n1 = __i2 - __i1; + if (this->max_size() - (this->size() - __n1) < __s.size()) + __throw_length_error(__N("basic_string::_M_replace_dispatch")); + return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(), + __s.size()); } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: - replace(size_type __pos1, size_type __n1, const basic_string& __str, - size_type __pos2, size_type __n2) - { - const size_type __strsize = __str.size(); - if (__pos2 > __strsize) - __throw_out_of_range("basic_string::replace"); - const bool __testn2 = __n2 < __strsize - __pos2; - const size_type __foldn2 = __testn2 ? __n2 : __strsize - __pos2; - return this->replace(__pos1, __n1, - __str._M_data() + __pos2, __foldn2); - } - - template<typename _CharT, typename _Traits, typename _Alloc> - basic_string<_CharT, _Traits, _Alloc>& - basic_string<_CharT, _Traits, _Alloc>:: append(const basic_string& __str) { // Iff appending itself, string needs to pre-reserve the // correct size so that _M_mutate does not clobber the - // iterators formed here. - size_type __size = __str.size(); - size_type __len = __size + this->size(); + // pointer __str._M_data() formed here. + const size_type __size = __str.size(); + const size_type __len = __size + this->size(); if (__len > this->capacity()) this->reserve(__len); - return _M_replace_safe(_M_iend(), _M_iend(), __str._M_ibegin(), - __str._M_iend()); + return _M_replace_safe(this->size(), size_type(0), __str._M_data(), + __str.size()); } template<typename _CharT, typename _Traits, typename _Alloc> @@ -688,13 +613,14 @@ namespace std { // Iff appending itself, string needs to pre-reserve the // correct size so that _M_mutate does not clobber the - // iterators formed here. - size_type __len = std::min(size_type(__str.size() - __pos), - __n) + this->size(); + // pointer __str._M_data() formed here. + __str._M_check(__pos, "basic_string::append"); + __n = __str._M_limit(__pos, __n); + const size_type __len = __n + this->size(); if (__len > this->capacity()) this->reserve(__len); - return _M_replace_safe(_M_iend(), _M_iend(), __str._M_check(__pos), - __str._M_fold(__pos, __n)); + return _M_replace_safe(this->size(), size_type(0), __str._M_data() + + __pos, __n); } template<typename _CharT, typename _Traits, typename _Alloc> @@ -702,21 +628,11 @@ namespace std basic_string<_CharT, _Traits, _Alloc>:: append(const _CharT* __s, size_type __n) { - size_type __len = __n + this->size(); + __glibcxx_requires_string_len(__s, __n); + const size_type __len = __n + this->size(); if (__len > this->capacity()) this->reserve(__len); - return _M_replace_safe(_M_iend(), _M_iend(), __s, __s + __n); - } - - template<typename _CharT, typename _Traits, typename _Alloc> - basic_string<_CharT, _Traits, _Alloc>& - basic_string<_CharT, _Traits, _Alloc>:: - append(size_type __n, _CharT __c) - { - size_type __len = __n + this->size(); - if (__len > this->capacity()) - this->reserve(__len); - return this->replace(_M_iend(), _M_iend(), __n, __c); + return _M_replace_safe(this->size(), size_type(0), __s, __n); } template<typename _CharT, typename _Traits, typename _Alloc> @@ -724,12 +640,13 @@ namespace std operator+(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { + __glibcxx_requires_string(__lhs); typedef basic_string<_CharT, _Traits, _Alloc> __string_type; typedef typename __string_type::size_type __size_type; - __size_type __len = _Traits::length(__lhs); + const __size_type __len = _Traits::length(__lhs); __string_type __str; __str.reserve(__len + __rhs.size()); - __str.append(__lhs, __lhs + __len); + __str.append(__lhs, __len); __str.append(__rhs); return __str; } @@ -741,7 +658,7 @@ namespace std typedef basic_string<_CharT, _Traits, _Alloc> __string_type; typedef typename __string_type::size_type __size_type; __string_type __str; - __size_type __len = __rhs.size(); + const __size_type __len = __rhs.size(); __str.reserve(__len + 1); __str.append(__size_type(1), __lhs); __str.append(__rhs); @@ -749,33 +666,15 @@ namespace std } template<typename _CharT, typename _Traits, typename _Alloc> - basic_string<_CharT, _Traits, _Alloc>& - basic_string<_CharT, _Traits, _Alloc>:: - replace(iterator __i1, iterator __i2, size_type __n2, _CharT __c) - { - size_type __n1 = __i2 - __i1; - size_type __off1 = __i1 - _M_ibegin(); - if (max_size() - (this->size() - __n1) <= __n2) - __throw_length_error("basic_string::replace"); - _M_mutate (__off1, __n1, __n2); - // Invalidated __i1, __i2 - if (__n2) - traits_type::assign(_M_data() + __off1, __n2, __c); - return *this; - } - - template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: copy(_CharT* __s, size_type __n, size_type __pos) const { - if (__pos > this->size()) - __throw_out_of_range("basic_string::copy"); - - if (__n > this->size() - __pos) - __n = this->size() - __pos; - - traits_type::copy(__s, _M_data() + __pos, __n); + _M_check(__pos, "basic_string::copy"); + __n = _M_limit(__pos, __n); + __glibcxx_requires_string_len(__s, __n); + if (__n) + traits_type::copy(__s, _M_data() + __pos, __n); // 21.3.5.7 par 3: do not append null. (good.) return __n; } @@ -785,12 +684,12 @@ namespace std basic_string<_CharT, _Traits, _Alloc>:: find(const _CharT* __s, size_type __pos, size_type __n) const { - size_type __size = this->size(); - size_t __xpos = __pos; + __glibcxx_requires_string_len(__s, __n); + const size_type __size = this->size(); const _CharT* __data = _M_data(); - for (; __xpos + __n <= __size; ++__xpos) - if (traits_type::compare(__data + __xpos, __s, __n) == 0) - return __xpos; + for (; __pos + __n <= __size; ++__pos) + if (traits_type::compare(__data + __pos, __s, __n) == 0) + return __pos; return npos; } @@ -799,12 +698,12 @@ namespace std basic_string<_CharT, _Traits, _Alloc>:: find(_CharT __c, size_type __pos) const { - size_type __size = this->size(); + const size_type __size = this->size(); size_type __ret = npos; if (__pos < __size) { const _CharT* __data = _M_data(); - size_type __n = __size - __pos; + const size_type __n = __size - __pos; const _CharT* __p = traits_type::find(__data + __pos, __n, __c); if (__p) __ret = __p - __data; @@ -812,27 +711,27 @@ namespace std return __ret; } - template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: rfind(const _CharT* __s, size_type __pos, size_type __n) const { - size_type __size = this->size(); + __glibcxx_requires_string_len(__s, __n); + const size_type __size = this->size(); if (__n <= __size) { __pos = std::min(size_type(__size - __n), __pos); const _CharT* __data = _M_data(); - do + do { if (traits_type::compare(__data + __pos, __s, __n) == 0) return __pos; - } + } while (__pos-- > 0); } return npos; } - + template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: @@ -841,22 +740,21 @@ namespace std size_type __size = this->size(); if (__size) { - size_t __xpos = __size - 1; - if (__xpos > __pos) - __xpos = __pos; - - for (++__xpos; __xpos-- > 0; ) - if (traits_type::eq(_M_data()[__xpos], __c)) - return __xpos; + if (--__size > __pos) + __size = __pos; + for (++__size; __size-- > 0; ) + if (traits_type::eq(_M_data()[__size], __c)) + return __size; } return npos; } - + template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: find_first_of(const _CharT* __s, size_type __pos, size_type __n) const { + __glibcxx_requires_string_len(__s, __n); for (; __n && __pos < this->size(); ++__pos) { const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]); @@ -865,36 +763,37 @@ namespace std } return npos; } - + template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: find_last_of(const _CharT* __s, size_type __pos, size_type __n) const { + __glibcxx_requires_string_len(__s, __n); size_type __size = this->size(); if (__size && __n) - { - if (--__size > __pos) + { + if (--__size > __pos) __size = __pos; do { if (traits_type::find(__s, __n, _M_data()[__size])) return __size; - } + } while (__size-- != 0); } return npos; } - + template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const { - size_t __xpos = __pos; - for (; __xpos < this->size(); ++__xpos) - if (!traits_type::find(__s, __n, _M_data()[__xpos])) - return __xpos; + __glibcxx_requires_string_len(__s, __n); + for (; __pos < this->size(); ++__pos) + if (!traits_type::find(__s, __n, _M_data()[__pos])) + return __pos; return npos; } @@ -903,10 +802,9 @@ namespace std basic_string<_CharT, _Traits, _Alloc>:: find_first_not_of(_CharT __c, size_type __pos) const { - size_t __xpos = __pos; - for (; __xpos < this->size(); ++__xpos) - if (!traits_type::eq(_M_data()[__xpos], __c)) - return __xpos; + for (; __pos < this->size(); ++__pos) + if (!traits_type::eq(_M_data()[__pos], __c)) + return __pos; return npos; } @@ -915,16 +813,17 @@ namespace std basic_string<_CharT, _Traits, _Alloc>:: find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const { + __glibcxx_requires_string_len(__s, __n); size_type __size = this->size(); if (__size) - { - if (--__size > __pos) + { + if (--__size > __pos) __size = __pos; do { if (!traits_type::find(__s, __n, _M_data()[__size])) return __size; - } + } while (__size--); } return npos; @@ -937,34 +836,31 @@ namespace std { size_type __size = this->size(); if (__size) - { - if (--__size > __pos) + { + if (--__size > __pos) __size = __pos; do { if (!traits_type::eq(_M_data()[__size], __c)) return __size; - } + } while (__size--); } return npos; } - + template<typename _CharT, typename _Traits, typename _Alloc> int basic_string<_CharT, _Traits, _Alloc>:: compare(size_type __pos, size_type __n, const basic_string& __str) const { - size_type __size = this->size(); - size_type __osize = __str.size(); - if (__pos > __size) - __throw_out_of_range("basic_string::compare"); - - size_type __rsize= std::min(size_type(__size - __pos), __n); - size_type __len = std::min(__rsize, __osize); + _M_check(__pos, "basic_string::compare"); + __n = _M_limit(__pos, __n); + const size_type __osize = __str.size(); + const size_type __len = std::min(__n, __osize); int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len); if (!__r) - __r = __rsize - __osize; + __r = __n - __osize; return __r; } @@ -974,117 +870,96 @@ namespace std compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) const { - size_type __size = this->size(); - size_type __osize = __str.size(); - if (__pos1 > __size || __pos2 > __osize) - __throw_out_of_range("basic_string::compare"); - - size_type __rsize = std::min(size_type(__size - __pos1), __n1); - size_type __rosize = std::min(size_type(__osize - __pos2), __n2); - size_type __len = std::min(__rsize, __rosize); - int __r = traits_type::compare(_M_data() + __pos1, + _M_check(__pos1, "basic_string::compare"); + __str._M_check(__pos2, "basic_string::compare"); + __n1 = _M_limit(__pos1, __n1); + __n2 = __str._M_limit(__pos2, __n2); + const size_type __len = std::min(__n1, __n2); + int __r = traits_type::compare(_M_data() + __pos1, __str.data() + __pos2, __len); if (!__r) - __r = __rsize - __rosize; + __r = __n1 - __n2; return __r; } - template<typename _CharT, typename _Traits, typename _Alloc> int basic_string<_CharT, _Traits, _Alloc>:: compare(const _CharT* __s) const { - size_type __size = this->size(); - size_type __osize = traits_type::length(__s); - size_type __len = std::min(__size, __osize); + __glibcxx_requires_string(__s); + const size_type __size = this->size(); + const size_type __osize = traits_type::length(__s); + const size_type __len = std::min(__size, __osize); int __r = traits_type::compare(_M_data(), __s, __len); if (!__r) __r = __size - __osize; return __r; } - template<typename _CharT, typename _Traits, typename _Alloc> int basic_string <_CharT, _Traits, _Alloc>:: compare(size_type __pos, size_type __n1, const _CharT* __s) const { - size_type __size = this->size(); - if (__pos > __size) - __throw_out_of_range("basic_string::compare"); - - size_type __osize = traits_type::length(__s); - size_type __rsize = std::min(size_type(__size - __pos), __n1); - size_type __len = std::min(__rsize, __osize); + __glibcxx_requires_string(__s); + _M_check(__pos, "basic_string::compare"); + __n1 = _M_limit(__pos, __n1); + const size_type __osize = traits_type::length(__s); + const size_type __len = std::min(__n1, __osize); int __r = traits_type::compare(_M_data() + __pos, __s, __len); if (!__r) - __r = __rsize - __osize; + __r = __n1 - __osize; return __r; } template<typename _CharT, typename _Traits, typename _Alloc> int basic_string <_CharT, _Traits, _Alloc>:: - compare(size_type __pos, size_type __n1, const _CharT* __s, + compare(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) const { - size_type __size = this->size(); - if (__pos > __size) - __throw_out_of_range("basic_string::compare"); - - size_type __osize = std::min(traits_type::length(__s), __n2); - size_type __rsize = std::min(size_type(__size - __pos), __n1); - size_type __len = std::min(__rsize, __osize); + __glibcxx_requires_string_len(__s, __n2); + _M_check(__pos, "basic_string::compare"); + __n1 = _M_limit(__pos, __n1); + const size_type __len = std::min(__n1, __n2); int __r = traits_type::compare(_M_data() + __pos, __s, __len); if (!__r) - __r = __rsize - __osize; + __r = __n1 - __n2; return __r; } - template <class _CharT, class _Traits, class _Alloc> - void - _S_string_copy(const basic_string<_CharT, _Traits, _Alloc>& __str, - _CharT* __buf, typename _Alloc::size_type __bufsiz) - { - typedef typename _Alloc::size_type size_type; - size_type __strsize = __str.size(); - size_type __bytes = std::min(__strsize, __bufsiz - 1); - _Traits::copy(__buf, __str.data(), __bytes); - __buf[__bytes] = _CharT(); - } - // Inhibit implicit instantiations for required instantiations, - // which are defined via explicit instantiations elsewhere. + // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. -#if _GLIBCPP_EXTERN_TEMPLATE +#if _GLIBCXX_EXTERN_TEMPLATE extern template class basic_string<char>; - extern template - basic_istream<char>& + extern template + basic_istream<char>& operator>>(basic_istream<char>&, string&); - extern template - basic_ostream<char>& + extern template + basic_ostream<char>& operator<<(basic_ostream<char>&, const string&); - extern template - basic_istream<char>& + extern template + basic_istream<char>& getline(basic_istream<char>&, string&, char); - extern template - basic_istream<char>& + extern template + basic_istream<char>& getline(basic_istream<char>&, string&); -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T extern template class basic_string<wchar_t>; - extern template - basic_istream<wchar_t>& + extern template + basic_istream<wchar_t>& operator>>(basic_istream<wchar_t>&, wstring&); - extern template - basic_ostream<wchar_t>& + extern template + basic_ostream<wchar_t>& operator<<(basic_ostream<wchar_t>&, const wstring&); - extern template - basic_istream<wchar_t>& + extern template + basic_istream<wchar_t>& getline(basic_istream<wchar_t>&, wstring&, wchar_t); - extern template - basic_istream<wchar_t>& + extern template + basic_istream<wchar_t>& getline(basic_istream<wchar_t>&, wstring&); #endif #endif diff --git a/contrib/libstdc++/include/bits/boost_concept_check.h b/contrib/libstdc++/include/bits/boost_concept_check.h index d91c2e88e3c9..7c99838dcb79 100644 --- a/contrib/libstdc++/include/bits/boost_concept_check.h +++ b/contrib/libstdc++/include/bits/boost_concept_check.h @@ -1,4 +1,30 @@ +// Copyright (C) 2004 Free Software Foundation, Inc. // +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + // (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, // sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided @@ -13,15 +39,15 @@ * You should not attempt to use it directly. */ -#ifndef _GLIBCPP_BOOST_CONCEPT_CHECK -#define _GLIBCPP_BOOST_CONCEPT_CHECK 1 +#ifndef _BOOST_CONCEPT_CHECK_H +#define _BOOST_CONCEPT_CHECK_H 1 #pragma GCC system_header + #include <cstddef> // for ptrdiff_t, used next #include <bits/stl_iterator_base_types.h> // for traits and tags #include <utility> // for pair<> - namespace __gnu_cxx { @@ -36,9 +62,15 @@ inline void __function_requires() void (_Concept::*__x)() _IsUnused = &_Concept::__constraints; } +// No definition: if this is referenced, there's a problem with +// the instantiating type not being one of the required integer types. +// Unfortunately, this results in a link-time error, not a compile-time error. +void __error_type_must_be_an_integer_type(); +void __error_type_must_be_an_unsigned_integer_type(); +void __error_type_must_be_a_signed_integer_type(); // ??? Should the "concept_checking*" structs begin with more than _ ? -#define _GLIBCPP_CLASS_REQUIRES(_type_var, _ns, _concept) \ +#define _GLIBCXX_CLASS_REQUIRES(_type_var, _ns, _concept) \ typedef void (_ns::_concept <_type_var>::* _func##_type_var##_concept)(); \ template <_func##_type_var##_concept _Tp1> \ struct _concept_checking##_type_var##_concept { }; \ @@ -46,7 +78,7 @@ inline void __function_requires() &_ns::_concept <_type_var>::__constraints> \ _concept_checking_typedef##_type_var##_concept -#define _GLIBCPP_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \ +#define _GLIBCXX_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \ typedef void (_ns::_concept <_type_var1,_type_var2>::* _func##_type_var1##_type_var2##_concept)(); \ template <_func##_type_var1##_type_var2##_concept _Tp1> \ struct _concept_checking##_type_var1##_type_var2##_concept { }; \ @@ -54,7 +86,7 @@ inline void __function_requires() &_ns::_concept <_type_var1,_type_var2>::__constraints> \ _concept_checking_typedef##_type_var1##_type_var2##_concept -#define _GLIBCPP_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \ +#define _GLIBCXX_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \ typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3>::* _func##_type_var1##_type_var2##_type_var3##_concept)(); \ template <_func##_type_var1##_type_var2##_type_var3##_concept _Tp1> \ struct _concept_checking##_type_var1##_type_var2##_type_var3##_concept { }; \ @@ -62,7 +94,7 @@ inline void __function_requires() &_ns::_concept <_type_var1,_type_var2,_type_var3>::__constraints> \ _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_concept -#define _GLIBCPP_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \ +#define _GLIBCXX_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \ typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::* _func##_type_var1##_type_var2##_type_var3##_type_var4##_concept)(); \ template <_func##_type_var1##_type_var2##_type_var3##_type_var4##_concept _Tp1> \ struct _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept { }; \ @@ -87,7 +119,7 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; template <class _Tp> struct _IntegerConcept { - void __constraints() { + void __constraints() { __error_type_must_be_an_integer_type(); } }; @@ -103,7 +135,7 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; template <class _Tp> struct _SignedIntegerConcept { - void __constraints() { + void __constraints() { __error_type_must_be_a_signed_integer_type(); } }; @@ -114,7 +146,7 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; template <class _Tp> struct _UnsignedIntegerConcept { - void __constraints() { + void __constraints() { __error_type_must_be_an_unsigned_integer_type(); } }; @@ -162,7 +194,7 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; __const_constraints(__a); } void __const_constraints(const _Tp& __a) { - _Tp __c(__a) _IsUnused; // require const copy constructor + _Tp __c _IsUnused(__a); // require const copy constructor const _Tp* __ptr _IsUnused = &__a; // require const address of operator } _Tp __b; @@ -173,12 +205,12 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; struct _SGIAssignableConcept { void __constraints() { - _Tp __b(__a) _IsUnused; + _Tp __b _IsUnused(__a); __a = __a; // require assignment operator __const_constraints(__a); } void __const_constraints(const _Tp& __b) { - _Tp __c(__b) _IsUnused; + _Tp __c _IsUnused(__b); __a = __b; // const required for argument to assignment } _Tp __a; @@ -213,7 +245,6 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; { void __constraints() { __aux_require_boolean_expr(__a == __b); - __aux_require_boolean_expr(__a != __b); } _Tp __a, __b; }; @@ -240,7 +271,7 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; _Tp __a, __b; }; -#define _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \ +#define _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \ template <class _First, class _Second> \ struct _NAME { \ void __constraints() { (void)__constraints_(); } \ @@ -251,7 +282,7 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; _Second __b; \ } -#define _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \ +#define _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \ template <class _Ret, class _First, class _Second> \ struct _NAME { \ void __constraints() { (void)__constraints_(); } \ @@ -262,21 +293,21 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; _Second __b; \ } - _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept); - _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept); - _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept); - _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept); - _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept); - _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept); + _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept); - _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept); - _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept); - _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept); - _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept); - _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept); + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept); + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept); + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept); + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept); + _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept); -#undef _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT -#undef _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT +#undef _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT +#undef _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT //=========================================================================== // Function Object Concepts @@ -313,7 +344,7 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; template <class _Func, class _Arg> struct _UnaryFunctionConcept<_Func, void, _Arg> { - void __constraints() { + void __constraints() { __f(__arg); // require operator() } _Func __f; @@ -323,7 +354,7 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; template <class _Func, class _Return, class _First, class _Second> struct _BinaryFunctionConcept { - void __constraints() { + void __constraints() { __r = __f(__first, __second); // require operator() } _Func __f; @@ -367,7 +398,7 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; // use this when functor is used inside a container class like std::set template <class _Func, class _First, class _Second> struct _Const_BinaryPredicateConcept { - void __constraints() { + void __constraints() { __const_constraints(__f); } void __const_constraints(const _Func& __fun) { @@ -387,7 +418,7 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; struct _TrivialIteratorConcept { void __constraints() { - __function_requires< _DefaultConstructibleConcept<_Tp> >(); +// __function_requires< _DefaultConstructibleConcept<_Tp> >(); __function_requires< _AssignableConcept<_Tp> >(); __function_requires< _EqualityComparableConcept<_Tp> >(); // typedef typename std::iterator_traits<_Tp>::value_type _V; @@ -412,9 +443,9 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; void __constraints() { __function_requires< _TrivialIteratorConcept<_Tp> >(); // require iterator_traits typedef's - typedef typename std::iterator_traits<_Tp>::difference_type _D; -// __function_requires< _SignedIntegerConcept<_D> >(); - typedef typename std::iterator_traits<_Tp>::reference _R; + typedef typename std::iterator_traits<_Tp>::difference_type _Diff; +// __function_requires< _SignedIntegerConcept<_Diff> >(); + typedef typename std::iterator_traits<_Tp>::reference _Ref; typedef typename std::iterator_traits<_Tp>::pointer _Pt; typedef typename std::iterator_traits<_Tp>::iterator_category _Cat; __function_requires< _ConvertibleConcept< @@ -444,11 +475,12 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; { void __constraints() { __function_requires< _InputIteratorConcept<_Tp> >(); + __function_requires< _DefaultConstructibleConcept<_Tp> >(); __function_requires< _ConvertibleConcept< typename std::iterator_traits<_Tp>::iterator_category, std::forward_iterator_tag> >(); - typedef typename std::iterator_traits<_Tp>::reference _R; - _R __r _IsUnused = *__i; + typedef typename std::iterator_traits<_Tp>::reference _Ref; + _Ref __r _IsUnused = *__i; } _Tp __i; }; @@ -498,8 +530,8 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; __function_requires< _ConvertibleConcept< typename std::iterator_traits<_Tp>::iterator_category, std::random_access_iterator_tag> >(); - // ??? We don't use _R, are we just checking for "referenceability"? - typedef typename std::iterator_traits<_Tp>::reference _R; + // ??? We don't use _Ref, are we just checking for "referenceability"? + typedef typename std::iterator_traits<_Tp>::reference _Ref; __i += __n; // require assignment addition operator __i = __i + __n; __i = __n + __i; // require addition with difference type @@ -561,7 +593,7 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; typedef typename _Container::reference _Reference; typedef typename _Container::iterator _Iterator; typedef typename _Container::pointer _Pointer; - + void __constraints() { __function_requires< _ContainerConcept<_Container> >(); __function_requires< _AssignableConcept<_Value_type> >(); @@ -583,7 +615,7 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; typedef typename _ForwardContainer::const_iterator _Const_iterator; __function_requires< _ForwardIteratorConcept<_Const_iterator> >(); } - }; + }; template <class _ForwardContainer> struct _Mutable_ForwardContainerConcept @@ -594,7 +626,7 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; typedef typename _ForwardContainer::iterator _Iterator; __function_requires< _Mutable_ForwardIteratorConcept<_Iterator> >(); } - }; + }; template <class _ReversibleContainer> struct _ReversibleContainerConcept @@ -694,10 +726,10 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; __function_requires< _Mutable_ForwardContainerConcept<_Sequence> >(); __function_requires< _DefaultConstructibleConcept<_Sequence> >(); - _Sequence - __c(__n) _IsUnused, - __c2(__n, __t) _IsUnused, - __c3(__first, __last) _IsUnused; + _Sequence + __c _IsUnused(__n), + __c2 _IsUnused(__n, __t), + __c3 _IsUnused(__first, __last); __c.insert(__p, __t); __c.insert(__p, __n, __t); @@ -759,7 +791,7 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; __function_requires< _ForwardContainerConcept<_AssociativeContainer> >(); __function_requires< _DefaultConstructibleConcept<_AssociativeContainer> >(); - + __i = __c.find(__k); __r = __c.equal_range(__k); __c.erase(__k); @@ -790,9 +822,9 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; void __constraints() { __function_requires< _AssociativeContainerConcept<_UniqueAssociativeContainer> >(); - + _UniqueAssociativeContainer __c(__first, __last); - + __pos_flag = __c.insert(__t); __c.insert(__first, __last); } @@ -809,12 +841,12 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; _AssociativeContainerConcept<_MultipleAssociativeContainer> >(); _MultipleAssociativeContainer __c(__first, __last); - + __pos = __c.insert(__t); __c.insert(__first, __last); } - typename _MultipleAssociativeContainer::iterator __pos _IsUnused; + typename _MultipleAssociativeContainer::iterator __pos; typename _MultipleAssociativeContainer::value_type __t; typename _MultipleAssociativeContainer::value_type *__first, *__last; }; @@ -828,7 +860,7 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; typedef typename _SimpleAssociativeContainer::key_type _Key_type; typedef typename _SimpleAssociativeContainer::value_type _Value_type; typedef typename _Aux_require_same<_Key_type, _Value_type>::_Type - _Requqired; + _Required; } }; @@ -856,15 +888,15 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; __function_requires< _ReversibleContainerConcept<_SortedAssociativeContainer> >(); - _SortedAssociativeContainer - __c(__kc) _IsUnused, - __c2(__first, __last) _IsUnused, - __c3(__first, __last, __kc) _IsUnused; + _SortedAssociativeContainer + __c _IsUnused(__kc), + __c2 _IsUnused(__first, __last), + __c3 _IsUnused(__first, __last, __kc); __p = __c.upper_bound(__k); __p = __c.lower_bound(__k); __r = __c.equal_range(__k); - + __c.insert(__p, __t); } void __const_constraints(const _SortedAssociativeContainer& __c) { @@ -896,6 +928,6 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; #undef _IsUnused -#endif // _GLIBCPP_BOOST_CONCEPT_CHECK +#endif // _GLIBCXX_BOOST_CONCEPT_CHECK diff --git a/contrib/libstdc++/include/bits/c++config b/contrib/libstdc++/include/bits/c++config index 9fdb8ccf1f18..80539b1a9715 100644 --- a/contrib/libstdc++/include/bits/c++config +++ b/contrib/libstdc++/include/bits/c++config @@ -1,6 +1,6 @@ // Predefined symbols and macros -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -28,26 +28,18 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_CPPCONFIG -#define _CPP_CPPCONFIG 1 +#ifndef _CXXCONFIG +#define _CXXCONFIG 1 // Pick up any OS-specific definitions. #include <bits/os_defines.h> // The current version of the C++ library in compressed ISO date format. -#define __GLIBCPP__ 20031106 +#define __GLIBCXX__ 20040728 -// This is necessary until GCC supports separate template compilation. -#define _GLIBCPP_NO_TEMPLATE_EXPORT 1 - -// This is a hack around not having either pre-compiled headers or -// export compilation. If defined, the io, string, and valarray -// headers will include all the necessary bits. If not defined, the -// implementation optimizes the headers for the most commonly-used -// types. For the io library, this means that larger, out-of-line -// member functions are only declared, and definitions are not parsed -// by the compiler, but instead instantiated into the library binary. -#define _GLIBCPP_FULLY_COMPLIANT_HEADERS 1 +// Allow use of "export template." This is currently not a feature +// that g++ supports. +// #define _GLIBCXX_EXPORT_TEMPLATE 1 // Allow use of the GNU syntax extension, "extern template." This // extension is fully documented in the g++ manual, but in a nutshell, @@ -55,46 +47,49 @@ // library to avoid multiple weak definitions for required types that // are already explicitly instantiated in the library binary. This // substantially reduces the binary size of resulting executables. -#ifndef _GLIBCPP_EXTERN_TEMPLATE -#define _GLIBCPP_EXTERN_TEMPLATE 1 +#ifndef _GLIBCXX_EXTERN_TEMPLATE +# define _GLIBCXX_EXTERN_TEMPLATE 1 #endif -// To enable older, ARM-style iostreams and other anachronisms use this. -//#define _GLIBCPP_DEPRECATED 1 - -// Use corrected code from the committee library group's issues list. -#define _GLIBCPP_RESOLVE_LIB_DEFECTS 1 - -// Hopefully temporary workaround to autoconf/m4 issue with quoting '@'. -#define _GLIBCPP_AT_AT "@@" - -// In those parts of the standard C++ library that use a mutex instead -// of a spin-lock, we now unconditionally use GCC's gthr.h mutex -// abstraction layer. All support to directly map to various -// threading models has been removed. Note: gthr.h may well map to -// gthr-single.h which is a correct way to express no threads support -// in gcc. Support for the undocumented _NOTHREADS has been removed. - -// Default to the typically high-speed, pool-based allocator (as -// libstdc++-v2) instead of the malloc-based allocator (libstdc++-v3 -// snapshots). See libstdc++-v3/docs/html/17_intro/howto.html for -// details on why you don't want to override this setting. Ensure -// that threads are properly configured on your platform before -// assigning blame to the STL container-memory allocator. After doing -// so, please report any possible issues to libstdc++@gcc.gnu.org . -// Do not define __USE_MALLOC on the command line. Enforce it here: -#ifdef __USE_MALLOC -#error __USE_MALLOC should never be defined. Read the release notes. +// Debug mode support. Debug mode basic_string is not allowed to be +// associated with std, because of locale and exception link +// dependence. +namespace __gnu_debug_def { } + +namespace __gnu_debug +{ + using namespace __gnu_debug_def; +} + +#ifdef _GLIBCXX_DEBUG +# define _GLIBCXX_STD __gnu_norm +namespace __gnu_norm +{ + using namespace std; +} +namespace std +{ + using namespace __gnu_debug_def __attribute__ ((strong)); +} +#else +# define _GLIBCXX_STD std #endif + +// The remainder of the prewritten config is automatic; all the +// user hooks are listed above. + // Create a boolean flag to be used to determine if --fast-math is set. #ifdef __FAST_MATH__ -#define _GLIBCPP_FAST_MATH 1 +# define _GLIBCXX_FAST_MATH 1 #else -#define _GLIBCPP_FAST_MATH 0 +# define _GLIBCXX_FAST_MATH 0 #endif -// The remainder of the prewritten config is mostly automatic; all the -// user hooks are listed above. +// This marks string literals in header files to be extracted for eventual +// translation. It is primarily used for messages in thrown exceptions; see +// src/functexcept.cc. We use __N because the more traditional _N is used +// for something else under certain OSes (see BADNAMES). +#define __N(msgid) (msgid) // End of prewritten config; the discovered settings follow. diff --git a/contrib/libstdc++/include/bits/char_traits.h b/contrib/libstdc++/include/bits/char_traits.h index 2b733cd94a01..323fdfb47c09 100644 --- a/contrib/libstdc++/include/bits/char_traits.h +++ b/contrib/libstdc++/include/bits/char_traits.h @@ -1,6 +1,6 @@ // Character Traits for use by standard string and iostream -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -37,104 +37,219 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_CHAR_TRAITS_H -#define _CPP_BITS_CHAR_TRAITS_H 1 +#ifndef _CHAR_TRAITS_H +#define _CHAR_TRAITS_H 1 #pragma GCC system_header #include <cstring> // For memmove, memset, memchr -#include <bits/fpos.h> // For streampos +#include <bits/stl_algobase.h>// For copy, lexicographical_compare, fill_n +#include <bits/postypes.h> // For streampos -namespace std +namespace __gnu_cxx { - // 21.1 /** - * @brief Basis for explicit traits specializations. + * @brief Mapping from character type to associated types. * - * @note For any given actual character type, this definition is - * probably wrong. + * + * @note This is an implementation class for the generic version + * of char_traits. It defines int_type, off_type, pos_type, and + * state_type. By default these are unsigned long, streamoff, + * streampos, and mbstate_t. Users who need a different set of + * types, but who don't need to change the definitions of any function + * defined in char_traits, can specialize __gnu_cxx::_Char_types + * while leaving __gnu_cxx::char_traits alone. */ + template <class _CharT> + struct _Char_types + { + typedef unsigned long int_type; + typedef std::streampos pos_type; + typedef std::streamoff off_type; + typedef std::mbstate_t state_type; + }; + + + /** + * @brief Base class used to implement std::char_traits. + * + * @note For any given actual character type, this definition is + * probably wrong. (Most of the member functions are likely to be + * right, but the int_type and state_type typedefs, and the eof() + * member function, are likely to be wrong.) The reason this class + * exists is so users can specialize it. Classes in namespace std + * may not be specialized for fundamentl types, but classes in + * namespace __gnu_cxx may be. * * See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5 * for advice on how to make use of this class for "unusual" character - * types. - */ - template<class _CharT> + * types. Also, check out include/ext/pod_char_traits.h. */ + template<typename _CharT> struct char_traits { - typedef _CharT char_type; - // Unsigned as wint_t is unsigned. - typedef unsigned long int_type; - typedef streampos pos_type; - typedef streamoff off_type; - typedef mbstate_t state_type; - - static void - assign(char_type& __c1, const char_type& __c2); + typedef _CharT char_type; + typedef typename _Char_types<_CharT>::int_type int_type; + typedef typename _Char_types<_CharT>::pos_type pos_type; + typedef typename _Char_types<_CharT>::off_type off_type; + typedef typename _Char_types<_CharT>::state_type state_type; - static bool - eq(const char_type& __c1, const char_type& __c2); + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } - static bool - lt(const char_type& __c1, const char_type& __c2); + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } - static int - compare(const char_type* __s1, const char_type* __s2, size_t __n); + static int + compare(const char_type* __s1, const char_type* __s2, std::size_t __n); - static size_t + static std::size_t length(const char_type* __s); - static const char_type* - find(const char_type* __s, size_t __n, const char_type& __a); + static const char_type* + find(const char_type* __s, std::size_t __n, const char_type& __a); - static char_type* - move(char_type* __s1, const char_type* __s2, size_t __n); + static char_type* + move(char_type* __s1, const char_type* __s2, std::size_t __n); - static char_type* - copy(char_type* __s1, const char_type* __s2, size_t __n); + static char_type* + copy(char_type* __s1, const char_type* __s2, std::size_t __n); - static char_type* - assign(char_type* __s, size_t __n, char_type __a); + static char_type* + assign(char_type* __s, std::size_t __n, char_type __a); - static char_type - to_char_type(const int_type& __c); + static char_type + to_char_type(const int_type& __c) + { return static_cast<char_type>(__c); } - static int_type - to_int_type(const char_type& __c); + static int_type + to_int_type(const char_type& __c) + { return static_cast<int_type>(__c); } - static bool - eq_int_type(const int_type& __c1, const int_type& __c2); + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } - static int_type - eof(); + static int_type + eof() + { return static_cast<int_type>(EOF); } - static int_type - not_eof(const int_type& __c); + static int_type + not_eof(const int_type& __c) + { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } }; + template<typename _CharT> + int + char_traits<_CharT>:: + compare(const char_type* __s1, const char_type* __s2, std::size_t __n) + { + for (size_t __i = 0; __i < __n; ++__i) + if (lt(__s1[__i], __s2[__i])) + return -1; + else if (lt(__s2[__i], __s1[__i])) + return 1; + return 0; + } + + template<typename _CharT> + std::size_t + char_traits<_CharT>:: + length(const char_type* __p) + { + std::size_t __i = 0; + while (!eq(__p[__i], char_type())) + ++__i; + return __i; + } + + template<typename _CharT> + const typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + find(const char_type* __s, std::size_t __n, const char_type& __a) + { + for (std::size_t __i = 0; __i < __n; ++__i) + if (eq(__s[__i], __a)) + return __s + __i; + return 0; + } + + template<typename _CharT> + typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + move(char_type* __s1, const char_type* __s2, std::size_t __n) + { + return static_cast<_CharT*>(std::memmove(__s1, __s2, + __n * sizeof(char_type))); + } + + template<typename _CharT> + typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + copy(char_type* __s1, const char_type* __s2, std::size_t __n) + { + std::copy(__s2, __s2 + __n, __s1); + return __s1; + } + + template<typename _CharT> + typename char_traits<_CharT>::char_type* + char_traits<_CharT>:: + assign(char_type* __s, std::size_t __n, char_type __a) + { + std::fill_n(__s, __n, __a); + return __s; + } +} + +namespace std +{ + // 21.1 + /** + * @brief Basis for explicit traits specializations. + * + * @note For any given actual character type, this definition is + * probably wrong. Since this is just a thin wrapper around + * __gnu_cxx::char_traits, it is possible to achieve a more + * appropriate definition by specializing __gnu_cxx::char_traits. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5 + * for advice on how to make use of this class for "unusual" character + * types. Also, check out include/ext/pod_char_traits.h. + */ + template<class _CharT> + struct char_traits + : public __gnu_cxx::char_traits<_CharT> + { }; + /// 21.1.3.1 char_traits specializations template<> struct char_traits<char> { - typedef char char_type; - typedef int int_type; - typedef streampos pos_type; - typedef streamoff off_type; - typedef mbstate_t state_type; + typedef char char_type; + typedef int int_type; + typedef streampos pos_type; + typedef streamoff off_type; + typedef mbstate_t state_type; - static void + static void assign(char_type& __c1, const char_type& __c2) { __c1 = __c2; } - static bool + static bool eq(const char_type& __c1, const char_type& __c2) { return __c1 == __c2; } - static bool + static bool lt(const char_type& __c1, const char_type& __c2) { return __c1 < __c2; } - static int + static int compare(const char_type* __s1, const char_type* __s2, size_t __n) { return memcmp(__s1, __s2, __n); } @@ -142,69 +257,69 @@ namespace std length(const char_type* __s) { return strlen(__s); } - static const char_type* + static const char_type* find(const char_type* __s, size_t __n, const char_type& __a) { return static_cast<const char_type*>(memchr(__s, __a, __n)); } - static char_type* + static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) { return static_cast<char_type*>(memmove(__s1, __s2, __n)); } - static char_type* + static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) - { return static_cast<char_type*>(memcpy(__s1, __s2, __n)); } + { return static_cast<char_type*>(memcpy(__s1, __s2, __n)); } - static char_type* + static char_type* assign(char_type* __s, size_t __n, char_type __a) { return static_cast<char_type*>(memset(__s, __a, __n)); } - static char_type + static char_type to_char_type(const int_type& __c) { return static_cast<char_type>(__c); } // To keep both the byte 0xff and the eof symbol 0xffffffff // from ending up as 0xffffffff. - static int_type + static int_type to_int_type(const char_type& __c) { return static_cast<int_type>(static_cast<unsigned char>(__c)); } - static bool + static bool eq_int_type(const int_type& __c1, const int_type& __c2) { return __c1 == __c2; } - static int_type + static int_type eof() { return static_cast<int_type>(EOF); } - static int_type + static int_type not_eof(const int_type& __c) { return (__c == eof()) ? 0 : __c; } }; -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T /// 21.1.3.2 char_traits specializations template<> struct char_traits<wchar_t> { - typedef wchar_t char_type; - typedef wint_t int_type; - typedef streamoff off_type; - typedef wstreampos pos_type; - typedef mbstate_t state_type; - - static void + typedef wchar_t char_type; + typedef wint_t int_type; + typedef streamoff off_type; + typedef wstreampos pos_type; + typedef mbstate_t state_type; + + static void assign(char_type& __c1, const char_type& __c2) { __c1 = __c2; } - static bool + static bool eq(const char_type& __c1, const char_type& __c2) { return __c1 == __c2; } - static bool + static bool lt(const char_type& __c1, const char_type& __c2) { return __c1 < __c2; } - static int + static int compare(const char_type* __s1, const char_type* __s2, size_t __n) { return wmemcmp(__s1, __s2, __n); } @@ -212,40 +327,40 @@ namespace std length(const char_type* __s) { return wcslen(__s); } - static const char_type* + static const char_type* find(const char_type* __s, size_t __n, const char_type& __a) { return wmemchr(__s, __a, __n); } - static char_type* - move(char_type* __s1, const char_type* __s2, int_type __n) + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n) { return wmemmove(__s1, __s2, __n); } - static char_type* + static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) { return wmemcpy(__s1, __s2, __n); } - static char_type* + static char_type* assign(char_type* __s, size_t __n, char_type __a) { return wmemset(__s, __a, __n); } - static char_type + static char_type to_char_type(const int_type& __c) { return char_type(__c); } - static int_type + static int_type to_int_type(const char_type& __c) { return int_type(__c); } - static bool + static bool eq_int_type(const int_type& __c1, const int_type& __c2) { return __c1 == __c2; } - static int_type + static int_type eof() { return static_cast<int_type>(WEOF); } - static int_type + static int_type not_eof(const int_type& __c) { return eq_int_type(__c, eof()) ? 0 : __c; } }; -#endif //_GLIBCPP_USE_WCHAR_T +#endif //_GLIBCXX_USE_WCHAR_T template<typename _CharT, typename _Traits> struct _Char_traits_match @@ -253,7 +368,7 @@ namespace std _CharT _M_c; _Char_traits_match(_CharT const& __c) : _M_c(__c) { } - bool + bool operator()(_CharT const& __a) { return _Traits::eq(_M_c, __a); } }; } // namespace std diff --git a/contrib/libstdc++/include/bits/codecvt.h b/contrib/libstdc++/include/bits/codecvt.h index 9ab9f94e71d5..d31ebf2d3621 100644 --- a/contrib/libstdc++/include/bits/codecvt.h +++ b/contrib/libstdc++/include/bits/codecvt.h @@ -1,6 +1,6 @@ // Locale support (codecvt) -*- C++ -*- -// Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +// Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -38,12 +38,13 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_CODECVT_H -#define _CPP_BITS_CODECVT_H 1 +#ifndef _CODECVT_H +#define _CODECVT_H 1 #pragma GCC system_header // 22.2.1.5 Template class codecvt + /// Base class for codecvt facet providing conversion result enum. class codecvt_base { public: @@ -60,148 +61,269 @@ // NB: An abstract base class that fills in the public inlines, so // that the specializations don't have to re-copy the public // interface. + /** + * @brief Common base for codecvt facet + * + * This template class provides implementations of the public functions + * that forward to the protected virtual functions. + * + * This template also provides abstract stubs for the protected virtual + * functions. + */ template<typename _InternT, typename _ExternT, typename _StateT> - class __codecvt_abstract_base + class __codecvt_abstract_base : public locale::facet, public codecvt_base { public: // Types: typedef codecvt_base::result result; - typedef _InternT intern_type; - typedef _ExternT extern_type; - typedef _StateT state_type; - + typedef _InternT intern_type; + typedef _ExternT extern_type; + typedef _StateT state_type; + // 22.2.1.5.1 codecvt members + /** + * @brief Convert from internal to external character set. + * + * Converts input string of intern_type to output string of + * extern_type. This is analogous to wcsrtombs. It does this by + * calling codecvt::do_out. + * + * The source and destination character sets are determined by the + * facet's locale, internal and external types. + * + * The characters in [from,from_end) are converted and written to + * [to,to_end). from_next and to_next are set to point to the + * character following the last successfully converted character, + * respectively. If the result needed no conversion, from_next and + * to_next are not affected. + * + * The @a state argument should be intialized if the input is at the + * beginning and carried from a previous call if continuing + * conversion. There are no guarantees about how @a state is used. + * + * The result returned is a member of codecvt_base::result. If all the + * input is converted, returns codecvt_base::ok. If no conversion is + * necessary, returns codecvt_base::noconv. If the input ends early or + * there is insufficient space in the output, returns codecvt_base::partial. + * Otherwise the conversion failed and codecvt_base::error is returned. + * + * @param state Persistent conversion state data. + * @param from Start of input. + * @param from_end End of input. + * @param from_next Returns start of unconverted data. + * @param to Start of output buffer. + * @param to_end End of output buffer. + * @param to_next Returns start of unused output area. + * @return codecvt_base::result. + */ result - out(state_type& __state, const intern_type* __from, + out(state_type& __state, const intern_type* __from, const intern_type* __from_end, const intern_type*& __from_next, - extern_type* __to, extern_type* __to_end, + extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const - { - return this->do_out(__state, __from, __from_end, __from_next, - __to, __to_end, __to_next); + { + return this->do_out(__state, __from, __from_end, __from_next, + __to, __to_end, __to_next); } + /** + * @brief Reset conversion state. + * + * Writes characters to output that would restore @a state to initial + * conditions. The idea is that if a partial conversion occurs, then + * the converting the characters written by this function would leave + * the state in initial conditions, rather than partial conversion + * state. It does this by calling codecvt::do_unshift(). + * + * For example, if 4 external characters always converted to 1 internal + * character, and input to in() had 6 external characters with state + * saved, this function would write two characters to the output and + * set the state to initialized conditions. + * + * The source and destination character sets are determined by the + * facet's locale, internal and external types. + * + * The result returned is a member of codecvt_base::result. If the + * state could be reset and data written, returns codecvt_base::ok. If + * no conversion is necessary, returns codecvt_base::noconv. If the + * output has insufficient space, returns codecvt_base::partial. + * Otherwise the reset failed and codecvt_base::error is returned. + * + * @param state Persistent conversion state data. + * @param to Start of output buffer. + * @param to_end End of output buffer. + * @param to_next Returns start of unused output area. + * @return codecvt_base::result. + */ result unshift(state_type& __state, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const { return this->do_unshift(__state, __to,__to_end,__to_next); } + /** + * @brief Convert from external to internal character set. + * + * Converts input string of extern_type to output string of + * intern_type. This is analogous to mbsrtowcs. It does this by + * calling codecvt::do_in. + * + * The source and destination character sets are determined by the + * facet's locale, internal and external types. + * + * The characters in [from,from_end) are converted and written to + * [to,to_end). from_next and to_next are set to point to the + * character following the last successfully converted character, + * respectively. If the result needed no conversion, from_next and + * to_next are not affected. + * + * The @a state argument should be intialized if the input is at the + * beginning and carried from a previous call if continuing + * conversion. There are no guarantees about how @a state is used. + * + * The result returned is a member of codecvt_base::result. If all the + * input is converted, returns codecvt_base::ok. If no conversion is + * necessary, returns codecvt_base::noconv. If the input ends early or + * there is insufficient space in the output, returns codecvt_base::partial. + * Otherwise the conversion failed and codecvt_base::error is returned. + * + * @param state Persistent conversion state data. + * @param from Start of input. + * @param from_end End of input. + * @param from_next Returns start of unconverted data. + * @param to Start of output buffer. + * @param to_end End of output buffer. + * @param to_next Returns start of unused output area. + * @return codecvt_base::result. + */ result - in(state_type& __state, const extern_type* __from, + in(state_type& __state, const extern_type* __from, const extern_type* __from_end, const extern_type*& __from_next, - intern_type* __to, intern_type* __to_end, + intern_type* __to, intern_type* __to_end, intern_type*& __to_next) const - { + { return this->do_in(__state, __from, __from_end, __from_next, - __to, __to_end, __to_next); + __to, __to_end, __to_next); } - int + int encoding() const throw() { return this->do_encoding(); } - bool + bool always_noconv() const throw() { return this->do_always_noconv(); } int - length(const state_type& __state, const extern_type* __from, + length(state_type& __state, const extern_type* __from, const extern_type* __end, size_t __max) const { return this->do_length(__state, __from, __end, __max); } - int + int max_length() const throw() { return this->do_max_length(); } protected: - explicit + explicit __codecvt_abstract_base(size_t __refs = 0) : locale::facet(__refs) { } - virtual + virtual ~__codecvt_abstract_base() { } + /** + * @brief Convert from internal to external character set. + * + * Converts input string of intern_type to output string of + * extern_type. This function is a hook for derived classes to change + * the value returned. @see out for more information. + */ virtual result - do_out(state_type& __state, const intern_type* __from, + do_out(state_type& __state, const intern_type* __from, const intern_type* __from_end, const intern_type*& __from_next, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const = 0; virtual result - do_unshift(state_type& __state, extern_type* __to, + do_unshift(state_type& __state, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const = 0; - + virtual result - do_in(state_type& __state, const extern_type* __from, - const extern_type* __from_end, const extern_type*& __from_next, - intern_type* __to, intern_type* __to_end, + do_in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, intern_type*& __to_next) const = 0; - - virtual int + + virtual int do_encoding() const throw() = 0; - virtual bool + virtual bool do_always_noconv() const throw() = 0; - virtual int - do_length(const state_type&, const extern_type* __from, + virtual int + do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const = 0; - virtual int + virtual int do_max_length() const throw() = 0; }; // 22.2.1.5 Template class codecvt // NB: Generic, mostly useless implementation. template<typename _InternT, typename _ExternT, typename _StateT> - class codecvt + class codecvt : public __codecvt_abstract_base<_InternT, _ExternT, _StateT> { - public: + public: // Types: typedef codecvt_base::result result; - typedef _InternT intern_type; - typedef _ExternT extern_type; - typedef _StateT state_type; + typedef _InternT intern_type; + typedef _ExternT extern_type; + typedef _StateT state_type; + + protected: + __c_locale _M_c_locale_codecvt; public: - static locale::id id; + static locale::id id; - explicit - codecvt(size_t __refs = 0) + explicit + codecvt(size_t __refs = 0) : __codecvt_abstract_base<_InternT, _ExternT, _StateT> (__refs) { } + explicit + codecvt(__c_locale __cloc, size_t __refs = 0); + protected: - virtual + virtual ~codecvt() { } virtual result - do_out(state_type& __state, const intern_type* __from, + do_out(state_type& __state, const intern_type* __from, const intern_type* __from_end, const intern_type*& __from_next, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const; virtual result - do_unshift(state_type& __state, extern_type* __to, + do_unshift(state_type& __state, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const; - + virtual result - do_in(state_type& __state, const extern_type* __from, - const extern_type* __from_end, const extern_type*& __from_next, - intern_type* __to, intern_type* __to_end, + do_in(state_type& __state, const extern_type* __from, + const extern_type* __from_end, const extern_type*& __from_next, + intern_type* __to, intern_type* __to_end, intern_type*& __to_next) const; - - virtual int + + virtual int do_encoding() const throw(); - virtual bool + virtual bool do_always_noconv() const throw(); - virtual int - do_length(const state_type&, const extern_type* __from, + virtual int + do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const; - virtual int + virtual int do_max_length() const throw(); }; @@ -210,79 +332,91 @@ // codecvt<char, char, mbstate_t> required specialization template<> - class codecvt<char, char, mbstate_t> + class codecvt<char, char, mbstate_t> : public __codecvt_abstract_base<char, char, mbstate_t> { - public: + public: // Types: - typedef char intern_type; - typedef char extern_type; - typedef mbstate_t state_type; + typedef char intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + protected: + __c_locale _M_c_locale_codecvt; public: static locale::id id; - explicit + explicit codecvt(size_t __refs = 0); + explicit + codecvt(__c_locale __cloc, size_t __refs = 0); + protected: - virtual + virtual ~codecvt(); virtual result - do_out(state_type& __state, const intern_type* __from, + do_out(state_type& __state, const intern_type* __from, const intern_type* __from_end, const intern_type*& __from_next, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const; virtual result - do_unshift(state_type& __state, extern_type* __to, + do_unshift(state_type& __state, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const; virtual result - do_in(state_type& __state, const extern_type* __from, + do_in(state_type& __state, const extern_type* __from, const extern_type* __from_end, const extern_type*& __from_next, - intern_type* __to, intern_type* __to_end, + intern_type* __to, intern_type* __to_end, intern_type*& __to_next) const; - virtual int + virtual int do_encoding() const throw(); - virtual bool + virtual bool do_always_noconv() const throw(); - virtual int - do_length(const state_type&, const extern_type* __from, + virtual int + do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const; - virtual int + virtual int do_max_length() const throw(); }; -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T // codecvt<wchar_t, char, mbstate_t> required specialization template<> - class codecvt<wchar_t, char, mbstate_t> + class codecvt<wchar_t, char, mbstate_t> : public __codecvt_abstract_base<wchar_t, char, mbstate_t> { public: // Types: - typedef wchar_t intern_type; - typedef char extern_type; - typedef mbstate_t state_type; + typedef wchar_t intern_type; + typedef char extern_type; + typedef mbstate_t state_type; + + protected: + __c_locale _M_c_locale_codecvt; public: - static locale::id id; + static locale::id id; - explicit + explicit codecvt(size_t __refs = 0); + explicit + codecvt(__c_locale __cloc, size_t __refs = 0); + protected: - virtual + virtual ~codecvt(); virtual result - do_out(state_type& __state, const intern_type* __from, + do_out(state_type& __state, const intern_type* __from, const intern_type* __from_end, const intern_type*& __from_next, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const; @@ -299,39 +433,46 @@ intern_type* __to, intern_type* __to_end, intern_type*& __to_next) const; - virtual + virtual int do_encoding() const throw(); - virtual + virtual bool do_always_noconv() const throw(); - virtual - int do_length(const state_type&, const extern_type* __from, + virtual + int do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const; - virtual int + virtual int do_max_length() const throw(); }; -#endif //_GLIBCPP_USE_WCHAR_T +#endif //_GLIBCXX_USE_WCHAR_T // 22.2.1.6 Template class codecvt_byname template<typename _InternT, typename _ExternT, typename _StateT> class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT> { public: - explicit - codecvt_byname(const char*, size_t __refs = 0) - : codecvt<_InternT, _ExternT, _StateT>(__refs) { } + explicit + codecvt_byname(const char* __s, size_t __refs = 0) + : codecvt<_InternT, _ExternT, _StateT>(__refs) + { + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + this->_S_destroy_c_locale(this->_M_c_locale_codecvt); + this->_S_create_c_locale(this->_M_c_locale_codecvt, __s); + } + } protected: - virtual + virtual ~codecvt_byname() { } }; // Include host and configuration specific partial specializations // with additional functionality, if possible. -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T #include <bits/codecvt_specializations.h> #endif -#endif // _CPP_BITS_CODECVT_H +#endif // _CODECVT_H diff --git a/contrib/libstdc++/include/bits/concept_check.h b/contrib/libstdc++/include/bits/concept_check.h index 88877ebf57e4..80c1439342d7 100644 --- a/contrib/libstdc++/include/bits/concept_check.h +++ b/contrib/libstdc++/include/bits/concept_check.h @@ -32,8 +32,8 @@ * You should not attempt to use it directly. */ -#ifndef _GLIBCPP_CONCEPT_CHECK -#define _GLIBCPP_CONCEPT_CHECK 1 +#ifndef _CONCEPT_CHECK_H +#define _CONCEPT_CHECK_H 1 #pragma GCC system_header @@ -47,13 +47,13 @@ // Concept-checking code is off by default unless users turn it on via // configure options or editing c++config.h. -#ifndef _GLIBCPP_CONCEPT_CHECKS +#ifndef _GLIBCXX_CONCEPT_CHECKS -#define __glibcpp_function_requires(...) -#define __glibcpp_class_requires(_a,_b) -#define __glibcpp_class_requires2(_a,_b,_c) -#define __glibcpp_class_requires3(_a,_b,_c,_d) -#define __glibcpp_class_requires4(_a,_b,_c,_d,_e) +#define __glibcxx_function_requires(...) +#define __glibcxx_class_requires(_a,_b) +#define __glibcxx_class_requires2(_a,_b,_c) +#define __glibcxx_class_requires3(_a,_b,_c,_d) +#define __glibcxx_class_requires4(_a,_b,_c,_d,_e) #else // the checks are on @@ -61,7 +61,7 @@ // Note that the obvious and elegant approach of // -//#define glibcpp_function_requires(C) boost::function_requires< boost::C >() +//#define glibcxx_function_requires(C) boost::function_requires< boost::C >() // // won't work due to concept templates with more than one parameter, e.g., // BinaryPredicateConcept. The preprocessor tries to split things up on @@ -69,17 +69,17 @@ // parenthesis to hide the commas, because "boost::(Temp<Foo,Bar>)" isn't // a valid instantiation pattern. Thus, we steal a feature from C99. -#define __glibcpp_function_requires(...) \ +#define __glibcxx_function_requires(...) \ __gnu_cxx::__function_requires< __gnu_cxx::__VA_ARGS__ >(); -#define __glibcpp_class_requires(_a,_C) \ - _GLIBCPP_CLASS_REQUIRES(_a, __gnu_cxx, _C); -#define __glibcpp_class_requires2(_a,_b,_C) \ - _GLIBCPP_CLASS_REQUIRES2(_a, _b, __gnu_cxx, _C); -#define __glibcpp_class_requires3(_a,_b,_c,_C) \ - _GLIBCPP_CLASS_REQUIRES3(_a, _b, _c, __gnu_cxx, _C); -#define __glibcpp_class_requires4(_a,_b,_c,_d,_C) \ - _GLIBCPP_CLASS_REQUIRES4(_a, _b, _c, _d, __gnu_cxx, _C); +#define __glibcxx_class_requires(_a,_C) \ + _GLIBCXX_CLASS_REQUIRES(_a, __gnu_cxx, _C); +#define __glibcxx_class_requires2(_a,_b,_C) \ + _GLIBCXX_CLASS_REQUIRES2(_a, _b, __gnu_cxx, _C); +#define __glibcxx_class_requires3(_a,_b,_c,_C) \ + _GLIBCXX_CLASS_REQUIRES3(_a, _b, _c, __gnu_cxx, _C); +#define __glibcxx_class_requires4(_a,_b,_c,_d,_C) \ + _GLIBCXX_CLASS_REQUIRES4(_a, _b, _c, _d, __gnu_cxx, _C); #endif // enable/disable -#endif // _GLIBCPP_CONCEPT_CHECK +#endif // _GLIBCXX_CONCEPT_CHECK diff --git a/contrib/libstdc++/include/bits/concurrence.h b/contrib/libstdc++/include/bits/concurrence.h new file mode 100644 index 000000000000..c436a1b08069 --- /dev/null +++ b/contrib/libstdc++/include/bits/concurrence.h @@ -0,0 +1,95 @@ +// Support for concurrent programing -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _CONCURRENCE_H +#define _CONCURRENCE_H 1 + +// GCC's thread abstraction layer +#include "bits/gthr.h" + +#if __GTHREADS + +# ifdef __GTHREAD_MUTEX_INIT +# define __glibcxx_mutex_type __gthread_mutex_t +# define __glibcxx_mutex_define_initialized(NAME) \ +__gthread_mutex_t NAME = __GTHREAD_MUTEX_INIT +# define __glibcxx_mutex_lock(NAME) \ +__gthread_mutex_lock(&NAME) +# else +// Implies __GTHREAD_MUTEX_INIT_FUNCTION +struct __glibcxx_mutex : public __gthread_mutex_t +{ + __glibcxx_mutex() { __GTHREAD_MUTEX_INIT_FUNCTION(this); } +}; + +# define __glibcxx_mutex_type __glibcxx_mutex +# define __glibcxx_mutex_define_initialized(NAME) \ +__glibcxx_mutex NAME +# define __glibcxx_mutex_lock(NAME) \ +__gthread_mutex_lock(&NAME) +# endif + +# define __glibcxx_mutex_unlock(NAME) __gthread_mutex_unlock(&NAME) + +#else + +# define __glibcxx_mutex_type __gthread_mutex_t +# define __glibcxx_mutex_define_initialized(NAME) __gthread_mutex_t NAME +# define __glibcxx_mutex_lock(NAME) +# define __glibcxx_mutex_unlock(NAME) + +#endif + +namespace __gnu_cxx +{ + typedef __glibcxx_mutex_type mutex_type; + + // Scoped lock idiom. + // Acquire the mutex here with a constructor call, then release with + // the destructor call in accordance with RAII style. + class lock + { + // Externally defined and initialized. + mutex_type& device; + + public: + explicit lock(mutex_type& name) : device(name) + { __glibcxx_mutex_lock(device); } + + ~lock() throw() + { __glibcxx_mutex_unlock(device); } + + private: + lock(const lock&); + lock& operator=(const lock&); + }; +} + +#endif diff --git a/contrib/libstdc++/include/bits/cpp_type_traits.h b/contrib/libstdc++/include/bits/cpp_type_traits.h index d66fe7638410..d4e4ea0410a5 100644 --- a/contrib/libstdc++/include/bits/cpp_type_traits.h +++ b/contrib/libstdc++/include/bits/cpp_type_traits.h @@ -1,6 +1,6 @@ // The -*- C++ -*- type traits classes for internal use in libstdc++ -// Copyright (C) 2000, 2001 Free Software Foundation, Inc. +// Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -34,8 +34,8 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_CPP_TYPE_TRAITS_H -#define _CPP_BITS_CPP_TYPE_TRAITS_H 1 +#ifndef _CPP_TYPE_TRAITS_H +#define _CPP_TYPE_TRAITS_H 1 #pragma GCC system_header @@ -64,24 +64,69 @@ // -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06. // +// NB: g++ can not compile these if declared within the class +// __is_pod itself. +namespace __gnu_internal +{ + typedef char __one; + typedef char __two[2]; + + template <typename _Tp> + __one __test_type (int _Tp::*); + template <typename _Tp> + __two& __test_type (...); +} // namespace __gnu_internal + namespace std { + // Compare for equality of types. + template<typename, typename> + struct __are_same + { + enum + { + _M_type = 0 + }; + }; + + template<typename _Tp> + struct __are_same<_Tp, _Tp> + { + enum + { + _M_type = 1 + }; + }; + + // Define a nested type if some predicate holds. + template<typename, bool> + struct __enable_if + { + }; + + template<typename _Tp> + struct __enable_if<_Tp, true> + { + typedef _Tp _M_type; + }; + + // Holds if the template-argument is a void type. template<typename _Tp> struct __is_void { enum - { - _M_type = 0 - }; + { + _M_type = 0 + }; }; template<> struct __is_void<void> { enum - { - _M_type = 1 - }; + { + _M_type = 1 + }; }; // @@ -91,9 +136,9 @@ namespace std struct __is_integer { enum - { - _M_type = 0 - }; + { + _M_type = 0 + }; }; // Thirteen specializations (yes there are eleven standard integer @@ -103,198 +148,198 @@ namespace std struct __is_integer<bool> { enum - { - _M_type = 1 - }; + { + _M_type = 1 + }; }; - + template<> struct __is_integer<char> { enum - { - _M_type = 1 - }; + { + _M_type = 1 + }; }; template<> struct __is_integer<signed char> { enum - { - _M_type = 1 - }; + { + _M_type = 1 + }; }; - + template<> - struct __is_integer<unsigned char> - { - enum + struct __is_integer<unsigned char> { - _M_type = 1 + enum + { + _M_type = 1 + }; }; - }; -# ifdef _GLIBCPP_USE_WCHAR_T +# ifdef _GLIBCXX_USE_WCHAR_T template<> - struct __is_integer<wchar_t> - { - enum + struct __is_integer<wchar_t> { - _M_type = 1 + enum + { + _M_type = 1 + }; }; - }; # endif - + template<> - struct __is_integer<short> - { - enum + struct __is_integer<short> { - _M_type = 1 + enum + { + _M_type = 1 + }; }; - }; template<> - struct __is_integer<unsigned short> - { - enum + struct __is_integer<unsigned short> { - _M_type = 1 + enum + { + _M_type = 1 + }; }; - }; template<> - struct __is_integer<int> - { - enum + struct __is_integer<int> { - _M_type = 1 + enum + { + _M_type = 1 + }; }; - }; template<> - struct __is_integer<unsigned int> - { - enum + struct __is_integer<unsigned int> { - _M_type = 1 + enum + { + _M_type = 1 + }; }; - }; template<> - struct __is_integer<long> - { - enum + struct __is_integer<long> { - _M_type = 1 + enum + { + _M_type = 1 + }; }; - }; template<> - struct __is_integer<unsigned long> - { - enum + struct __is_integer<unsigned long> { - _M_type = 1 + enum + { + _M_type = 1 + }; }; - }; template<> - struct __is_integer<long long> - { - enum + struct __is_integer<long long> { - _M_type = 1 + enum + { + _M_type = 1 + }; }; - }; template<> - struct __is_integer<unsigned long long> - { - enum + struct __is_integer<unsigned long long> { - _M_type = 1 + enum + { + _M_type = 1 + }; }; - }; // // Floating point types // template<typename _Tp> - struct __is_floating - { - enum + struct __is_floating { - _M_type = 0 + enum + { + _M_type = 0 + }; }; - }; // three specializations (float, double and 'long double') template<> - struct __is_floating<float> - { - enum + struct __is_floating<float> { - _M_type = 1 + enum + { + _M_type = 1 + }; }; - }; template<> - struct __is_floating<double> - { - enum + struct __is_floating<double> { - _M_type = 1 + enum + { + _M_type = 1 + }; }; - }; template<> - struct __is_floating<long double> - { - enum + struct __is_floating<long double> { - _M_type = 1 + enum + { + _M_type = 1 + }; }; - }; // // An arithmetic type is an integer type or a floating point type // template<typename _Tp> - struct __is_arithmetic - { - enum + struct __is_arithmetic { - _M_type = __is_integer<_Tp>::_M_type || __is_floating<_Tp>::_M_type + enum + { + _M_type = __is_integer<_Tp>::_M_type || __is_floating<_Tp>::_M_type + }; }; - }; - + // // A fundamental type is `void' or and arithmetic type // template<typename _Tp> - struct __is_fundamental - { - enum + struct __is_fundamental { - _M_type = __is_void<_Tp>::_M_type || __is_arithmetic<_Tp>::_M_type + enum + { + _M_type = __is_void<_Tp>::_M_type || __is_arithmetic<_Tp>::_M_type + }; }; - }; // // For the immediate use, the following is a good approximation // template<typename _Tp> - struct __is_pod - { - enum + struct __is_pod { - _M_type = __is_fundamental<_Tp>::_M_type + enum + { + _M_type = (sizeof(__gnu_internal::__test_type<_Tp>(0)) + != sizeof(__gnu_internal::__one)) + }; }; - }; } // namespace std - -#endif //_CPP_BITS_CPP_TYPE_TRAITS_H +#endif //_CPP_TYPE_TRAITS_H diff --git a/contrib/libstdc++/include/bits/deque.tcc b/contrib/libstdc++/include/bits/deque.tcc index a8d43d024c29..e8e043886abb 100644 --- a/contrib/libstdc++/include/bits/deque.tcc +++ b/contrib/libstdc++/include/bits/deque.tcc @@ -1,6 +1,6 @@ // Deque implementation (out of line) -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,11 +58,11 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_DEQUE_TCC -#define __GLIBCPP_INTERNAL_DEQUE_TCC +#ifndef _DEQUE_TCC +#define _DEQUE_TCC 1 -namespace std -{ +namespace _GLIBCXX_STD +{ template <typename _Tp, typename _Alloc> deque<_Tp,_Alloc>& deque<_Tp,_Alloc>:: @@ -70,125 +70,128 @@ namespace std { 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()); - } - } + { + if (__len >= __x.size()) + erase(std::copy(__x.begin(), __x.end(), this->_M_impl._M_start), + this->_M_impl._M_finish); + else + { + const_iterator __mid = __x.begin() + difference_type(__len); + std::copy(__x.begin(), __mid, this->_M_impl._M_start); + insert(this->_M_impl._M_finish, __mid, __x.end()); + } + } return *this; - } - + } + template <typename _Tp, typename _Alloc> - typename deque<_Tp,_Alloc>::iterator + typename deque<_Tp,_Alloc>::iterator deque<_Tp,_Alloc>:: insert(iterator position, const value_type& __x) { - if (position._M_cur == _M_start._M_cur) - { - push_front(__x); - return _M_start; - } - else if (position._M_cur == _M_finish._M_cur) - { - push_back(__x); - iterator __tmp = _M_finish; - --__tmp; - return __tmp; - } + if (position._M_cur == this->_M_impl._M_start._M_cur) + { + push_front(__x); + return this->_M_impl._M_start; + } + else if (position._M_cur == this->_M_impl._M_finish._M_cur) + { + push_back(__x); + iterator __tmp = this->_M_impl._M_finish; + --__tmp; + return __tmp; + } else return _M_insert_aux(position, __x); } - + template <typename _Tp, typename _Alloc> - typename deque<_Tp,_Alloc>::iterator + typename deque<_Tp,_Alloc>::iterator deque<_Tp,_Alloc>:: erase(iterator __position) { iterator __next = __position; ++__next; - size_type __index = __position - _M_start; + size_type __index = __position - this->_M_impl._M_start; if (__index < (size() >> 1)) - { - copy_backward(_M_start, __position, __next); - pop_front(); - } + { + std::copy_backward(this->_M_impl._M_start, __position, __next); + pop_front(); + } else - { - copy(__next, _M_finish, __position); - pop_back(); - } - return _M_start + __index; + { + std::copy(__next, this->_M_impl._M_finish, __position); + pop_back(); + } + return this->_M_impl._M_start + __index; } - + template <typename _Tp, typename _Alloc> - typename deque<_Tp,_Alloc>::iterator + typename deque<_Tp,_Alloc>::iterator deque<_Tp,_Alloc>:: erase(iterator __first, iterator __last) { - if (__first == _M_start && __last == _M_finish) - { - clear(); - return _M_finish; - } + if (__first == this->_M_impl._M_start && __last == this->_M_impl._M_finish) + { + clear(); + return this->_M_impl._M_finish; + } else - { - difference_type __n = __last - __first; - difference_type __elems_before = __first - _M_start; - if (static_cast<size_type>(__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(_M_start._M_node, __new_start._M_node); - _M_start = __new_start; - } - else - { - copy(__last, _M_finish, __first); - iterator __new_finish = _M_finish - __n; - _Destroy(__new_finish, _M_finish); - _M_destroy_nodes(__new_finish._M_node + 1, _M_finish._M_node + 1); - _M_finish = __new_finish; - } - return _M_start + __elems_before; - } + { + const difference_type __n = __last - __first; + const difference_type __elems_before = __first - this->_M_impl._M_start; + if (static_cast<size_type>(__elems_before) < (size() - __n) / 2) + { + std::copy_backward(this->_M_impl._M_start, __first, __last); + iterator __new_start = this->_M_impl._M_start + __n; + std::_Destroy(this->_M_impl._M_start, __new_start); + _M_destroy_nodes(this->_M_impl._M_start._M_node, __new_start._M_node); + this->_M_impl._M_start = __new_start; + } + else + { + std::copy(__last, this->_M_impl._M_finish, __first); + iterator __new_finish = this->_M_impl._M_finish - __n; + std::_Destroy(__new_finish, this->_M_impl._M_finish); + _M_destroy_nodes(__new_finish._M_node + 1, + this->_M_impl._M_finish._M_node + 1); + this->_M_impl._M_finish = __new_finish; + } + return this->_M_impl._M_start + __elems_before; + } } - - template <typename _Tp, typename _Alloc> + + template <typename _Tp, typename _Alloc> void deque<_Tp,_Alloc>:: clear() { - for (_Map_pointer __node = _M_start._M_node + 1; - __node < _M_finish._M_node; + for (_Map_pointer __node = this->_M_impl._M_start._M_node + 1; + __node < this->_M_impl._M_finish._M_node; ++__node) - { - _Destroy(*__node, *__node + _S_buffer_size()); - _M_deallocate_node(*__node); - } - - if (_M_start._M_node != _M_finish._M_node) - { - _Destroy(_M_start._M_cur, _M_start._M_last); - _Destroy(_M_finish._M_first, _M_finish._M_cur); - _M_deallocate_node(_M_finish._M_first); - } + { + std::_Destroy(*__node, *__node + _S_buffer_size()); + _M_deallocate_node(*__node); + } + + if (this->_M_impl._M_start._M_node != this->_M_impl._M_finish._M_node) + { + std::_Destroy(this->_M_impl._M_start._M_cur, this->_M_impl._M_start._M_last); + std::_Destroy(this->_M_impl._M_finish._M_first, this->_M_impl._M_finish._M_cur); + _M_deallocate_node(this->_M_impl._M_finish._M_first); + } else - _Destroy(_M_start._M_cur, _M_finish._M_cur); - - _M_finish = _M_start; + std::_Destroy(this->_M_impl._M_start._M_cur, this->_M_impl._M_finish._M_cur); + + this->_M_impl._M_finish = this->_M_impl._M_start; } - + template <typename _Tp, class _Alloc> - template <typename _InputIter> + template <typename _InputIterator> void deque<_Tp,_Alloc> - ::_M_assign_aux(_InputIter __first, _InputIter __last, input_iterator_tag) + ::_M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag) { iterator __cur = begin(); for ( ; __first != __last && __cur != end(); ++__cur, ++__first) @@ -198,44 +201,45 @@ namespace std else insert(end(), __first, __last); } - + template <typename _Tp, typename _Alloc> void deque<_Tp,_Alloc>:: _M_fill_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); - try - { - uninitialized_fill(__new_start, _M_start, __x); - _M_start = __new_start; - } - catch(...) - { - _M_destroy_nodes(__new_start._M_node, _M_start._M_node); - __throw_exception_again; - } - } - else if (__pos._M_cur == _M_finish._M_cur) - { - iterator __new_finish = _M_reserve_elements_at_back(__n); - try - { - uninitialized_fill(_M_finish, __new_finish, __x); - _M_finish = __new_finish; - } - catch(...) - { - _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1); - __throw_exception_again; - } - } - else + if (__pos._M_cur == this->_M_impl._M_start._M_cur) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + try + { + std::uninitialized_fill(__new_start, this->_M_impl._M_start, __x); + this->_M_impl._M_start = __new_start; + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); + __throw_exception_again; + } + } + else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + try + { + std::uninitialized_fill(this->_M_impl._M_finish, __new_finish, __x); + this->_M_impl._M_finish = __new_finish; + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } + else _M_insert_aux(__pos, __n, __x); } - + template <typename _Tp, typename _Alloc> void deque<_Tp,_Alloc>:: @@ -244,17 +248,21 @@ namespace std _Map_pointer __cur; try { - for (__cur = _M_start._M_node; __cur < _M_finish._M_node; ++__cur) - uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value); - uninitialized_fill(_M_finish._M_first, _M_finish._M_cur, __value); + for (__cur = this->_M_impl._M_start._M_node; + __cur < this->_M_impl._M_finish._M_node; + ++__cur) + std::uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value); + std::uninitialized_fill(this->_M_impl._M_finish._M_first, + this->_M_impl._M_finish._M_cur, + __value); } catch(...) { - _Destroy(_M_start, iterator(*__cur, __cur)); + std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur)); __throw_exception_again; } } - + template <typename _Tp, typename _Alloc> template <typename _InputIterator> void @@ -262,7 +270,7 @@ namespace std _M_range_initialize(_InputIterator __first, _InputIterator __last, input_iterator_tag) { - _M_initialize_map(0); + this->_M_initialize_map(0); try { for ( ; __first != __last; ++__first) @@ -274,7 +282,7 @@ namespace std __throw_exception_again; } } - + template <typename _Tp, typename _Alloc> template <typename _ForwardIterator> void @@ -282,31 +290,31 @@ namespace std _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag) { - size_type __n = distance(__first, __last); - _M_initialize_map(__n); - + const size_type __n = std::distance(__first, __last); + this->_M_initialize_map(__n); + _Map_pointer __cur_node; try { - for (__cur_node = _M_start._M_node; - __cur_node < _M_finish._M_node; + for (__cur_node = this->_M_impl._M_start._M_node; + __cur_node < this->_M_impl._M_finish._M_node; ++__cur_node) { _ForwardIterator __mid = __first; - advance(__mid, _S_buffer_size()); - uninitialized_copy(__first, __mid, *__cur_node); + std::advance(__mid, _S_buffer_size()); + std::uninitialized_copy(__first, __mid, *__cur_node); __first = __mid; } - uninitialized_copy(__first, __last, _M_finish._M_first); + std::uninitialized_copy(__first, __last, this->_M_impl._M_finish._M_first); } catch(...) { - _Destroy(_M_start, iterator(*__cur_node, __cur_node)); + std::_Destroy(this->_M_impl._M_start, iterator(*__cur_node, __cur_node)); __throw_exception_again; } } - - // Called only if _M_finish._M_cur == _M_finish._M_last - 1. + + // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1. template <typename _Tp, typename _Alloc> void deque<_Tp,_Alloc>:: @@ -314,44 +322,21 @@ namespace std { value_type __t_copy = __t; _M_reserve_map_at_back(); - *(_M_finish._M_node + 1) = _M_allocate_node(); + *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node(); try { - _Construct(_M_finish._M_cur, __t_copy); - _M_finish._M_set_node(_M_finish._M_node + 1); - _M_finish._M_cur = _M_finish._M_first; + std::_Construct(this->_M_impl._M_finish._M_cur, __t_copy); + this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node + 1); + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first; } catch(...) { - _M_deallocate_node(*(_M_finish._M_node + 1)); + _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1)); __throw_exception_again; } } - - #ifdef _GLIBCPP_DEPRECATED - // Called only if _M_finish._M_cur == _M_finish._M_last - 1. - template <typename _Tp, typename _Alloc> - void - deque<_Tp,_Alloc>:: - _M_push_back_aux() - { - _M_reserve_map_at_back(); - *(_M_finish._M_node + 1) = _M_allocate_node(); - try - { - _Construct(_M_finish._M_cur); - _M_finish._M_set_node(_M_finish._M_node + 1); - _M_finish._M_cur = _M_finish._M_first; - } - catch(...) - { - _M_deallocate_node(*(_M_finish._M_node + 1)); - __throw_exception_again; - } - } - #endif - - // Called only if _M_start._M_cur == _M_start._M_first. + + // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first. template <typename _Tp, typename _Alloc> void deque<_Tp,_Alloc>:: @@ -359,70 +344,46 @@ namespace std { value_type __t_copy = __t; _M_reserve_map_at_front(); - *(_M_start._M_node - 1) = _M_allocate_node(); - try - { - _M_start._M_set_node(_M_start._M_node - 1); - _M_start._M_cur = _M_start._M_last - 1; - _Construct(_M_start._M_cur, __t_copy); - } - catch(...) - { - ++_M_start; - _M_deallocate_node(*(_M_start._M_node - 1)); - __throw_exception_again; - } - } - - #ifdef _GLIBCPP_DEPRECATED - // Called only if _M_start._M_cur == _M_start._M_first. - template <typename _Tp, typename _Alloc> - void - deque<_Tp,_Alloc>:: - _M_push_front_aux() - { - _M_reserve_map_at_front(); - *(_M_start._M_node - 1) = _M_allocate_node(); + *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node(); 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); + this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node - 1); + this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1; + std::_Construct(this->_M_impl._M_start._M_cur, __t_copy); } catch(...) { - ++_M_start; - _M_deallocate_node(*(_M_start._M_node - 1)); + ++this->_M_impl._M_start; + _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1)); __throw_exception_again; } - } - #endif - - // Called only if _M_finish._M_cur == _M_finish._M_first. + } + + // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first. template <typename _Tp, typename _Alloc> void deque<_Tp,_Alloc>:: _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); + _M_deallocate_node(this->_M_impl._M_finish._M_first); + this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1); + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1; + std::_Destroy(this->_M_impl._M_finish._M_cur); } - - // Called only if _M_start._M_cur == _M_start._M_last - 1. Note that - // if the deque has at least one element (a precondition for this member - // function), and if _M_start._M_cur == _M_start._M_last, then the deque + + // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1. Note that + // if the deque has at least one element (a precondition for this member + // function), and if _M_impl._M_start._M_cur == _M_impl._M_start._M_last, then the deque // must have at least two nodes. template <typename _Tp, typename _Alloc> void deque<_Tp,_Alloc>:: _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; - } - + std::_Destroy(this->_M_impl._M_start._M_cur); + _M_deallocate_node(this->_M_impl._M_start._M_first); + this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1); + this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first; + } + template <typename _Tp, typename _Alloc> template <typename _InputIterator> void @@ -430,10 +391,8 @@ namespace std _M_range_insert_aux(iterator __pos, _InputIterator __first, _InputIterator __last, input_iterator_tag) - { - copy(__first, __last, inserter(*this, __pos)); - } - + { std::copy(__first, __last, std::inserter(*this, __pos)); } + template <typename _Tp, typename _Alloc> template <typename _ForwardIterator> void @@ -442,180 +401,149 @@ namespace std _ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag) { - size_type __n = distance(__first, __last); - if (__pos._M_cur == _M_start._M_cur) - { - iterator __new_start = _M_reserve_elements_at_front(__n); - try - { - uninitialized_copy(__first, __last, __new_start); - _M_start = __new_start; - } - catch(...) - { - _M_destroy_nodes(__new_start._M_node, _M_start._M_node); - __throw_exception_again; - } - } - else if (__pos._M_cur == _M_finish._M_cur) - { - iterator __new_finish = _M_reserve_elements_at_back(__n); - try - { - uninitialized_copy(__first, __last, _M_finish); - _M_finish = __new_finish; - } - catch(...) - { - _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1); - __throw_exception_again; - } - } + size_type __n = std::distance(__first, __last); + if (__pos._M_cur == this->_M_impl._M_start._M_cur) + { + iterator __new_start = _M_reserve_elements_at_front(__n); + try + { + std::uninitialized_copy(__first, __last, __new_start); + this->_M_impl._M_start = __new_start; + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); + __throw_exception_again; + } + } + else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + try + { + std::uninitialized_copy(__first, __last, this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } else _M_insert_aux(__pos, __first, __last, __n); } - + template <typename _Tp, typename _Alloc> typename deque<_Tp, _Alloc>::iterator deque<_Tp,_Alloc>:: _M_insert_aux(iterator __pos, const value_type& __x) { - difference_type __index = __pos - _M_start; + difference_type __index = __pos - this->_M_impl._M_start; value_type __x_copy = __x; // XXX copy if (static_cast<size_type>(__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); - } + { + push_front(front()); + iterator __front1 = this->_M_impl._M_start; + ++__front1; + iterator __front2 = __front1; + ++__front2; + __pos = this->_M_impl._M_start + __index; + iterator __pos1 = __pos; + ++__pos1; + std::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); - } + { + push_back(back()); + iterator __back1 = this->_M_impl._M_finish; + --__back1; + iterator __back2 = __back1; + --__back2; + __pos = this->_M_impl._M_start + __index; + std::copy_backward(__pos, __back2, __back1); + } *__pos = __x_copy; return __pos; } - - #ifdef _GLIBCPP_DEPRECATED - // Nothing seems to actually use this. According to the pattern followed by - // the rest of the SGI code, it would be called by the deprecated insert(pos) - // function, but that has been replaced. We'll take our time removing this - // anyhow; mark for 3.4. -pme - template <typename _Tp, typename _Alloc> - typename deque<_Tp,_Alloc>::iterator - deque<_Tp,_Alloc>:: - _M_insert_aux(iterator __pos) - { - difference_type __index = __pos - _M_start; - if (static_cast<size_type>(__index) < size() / 2) - { - push_front(front()); - iterator __front1 = _M_start; - ++__front1; - iterator __front2 = __front1; - ++__front2; - __pos = _M_start + __index; - iterator __pos1 = __pos; - ++__pos1; - copy(__front2, __pos1, __front1); - } - else - { - push_back(back()); - iterator __back1 = _M_finish; - --__back1; - iterator __back2 = __back1; - --__back2; - __pos = _M_start + __index; - copy_backward(__pos, __back2, __back1); - } - *__pos = value_type(); - return __pos; - } - #endif - + template <typename _Tp, typename _Alloc> void deque<_Tp,_Alloc>:: _M_insert_aux(iterator __pos, size_type __n, const value_type& __x) { - const difference_type __elems_before = __pos - _M_start; + const difference_type __elems_before = __pos - this->_M_impl._M_start; size_type __length = this->size(); value_type __x_copy = __x; if (__elems_before < difference_type(__length / 2)) - { - iterator __new_start = _M_reserve_elements_at_front(__n); - iterator __old_start = _M_start; - __pos = _M_start + __elems_before; - try - { - if (__elems_before >= difference_type(__n)) - { - iterator __start_n = _M_start + difference_type(__n); - uninitialized_copy(_M_start, __start_n, __new_start); - _M_start = __new_start; - copy(__start_n, __pos, __old_start); - fill(__pos - difference_type(__n), __pos, __x_copy); - } - else - { - __uninitialized_copy_fill(_M_start, __pos, __new_start, - _M_start, __x_copy); - _M_start = __new_start; - fill(__old_start, __pos, __x_copy); - } - } - catch(...) - { - _M_destroy_nodes(__new_start._M_node, _M_start._M_node); - __throw_exception_again; - } - } + { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = this->_M_impl._M_start; + __pos = this->_M_impl._M_start + __elems_before; + try + { + if (__elems_before >= difference_type(__n)) + { + iterator __start_n = this->_M_impl._M_start + difference_type(__n); + std::uninitialized_copy(this->_M_impl._M_start, __start_n, + __new_start); + this->_M_impl._M_start = __new_start; + std::copy(__start_n, __pos, __old_start); + fill(__pos - difference_type(__n), __pos, __x_copy); + } + else + { + std::__uninitialized_copy_fill(this->_M_impl._M_start, __pos, + __new_start, + this->_M_impl._M_start, __x_copy); + this->_M_impl._M_start = __new_start; + std::fill(__old_start, __pos, __x_copy); + } + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); + __throw_exception_again; + } + } else - { - iterator __new_finish = _M_reserve_elements_at_back(__n); - iterator __old_finish = _M_finish; - const difference_type __elems_after = - difference_type(__length) - __elems_before; - __pos = _M_finish - __elems_after; - try - { - if (__elems_after > difference_type(__n)) - { - iterator __finish_n = _M_finish - difference_type(__n); - uninitialized_copy(__finish_n, _M_finish, _M_finish); - _M_finish = __new_finish; - copy_backward(__pos, __finish_n, __old_finish); - fill(__pos, __pos + difference_type(__n), __x_copy); - } - else - { - __uninitialized_fill_copy(_M_finish, __pos + difference_type(__n), - __x_copy, __pos, _M_finish); - _M_finish = __new_finish; - fill(__pos, __old_finish, __x_copy); - } - } - catch(...) - { - _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1); - __throw_exception_again; - } - } + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = this->_M_impl._M_finish; + const difference_type __elems_after = + difference_type(__length) - __elems_before; + __pos = this->_M_impl._M_finish - __elems_after; + try + { + if (__elems_after > difference_type(__n)) + { + iterator __finish_n = this->_M_impl._M_finish - difference_type(__n); + std::uninitialized_copy(__finish_n, this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; + std::copy_backward(__pos, __finish_n, __old_finish); + std::fill(__pos, __pos + difference_type(__n), __x_copy); + } + else + { + std::__uninitialized_fill_copy(this->_M_impl._M_finish, + __pos + difference_type(__n), + __x_copy, __pos, + this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; + std::fill(__pos, __old_finish, __x_copy); + } + } + catch(...) + { + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } } - + template <typename _Tp, typename _Alloc> template <typename _ForwardIterator> void @@ -624,96 +552,101 @@ namespace std _ForwardIterator __first, _ForwardIterator __last, size_type __n) { - const difference_type __elemsbefore = __pos - _M_start; + const difference_type __elemsbefore = __pos - this->_M_impl._M_start; size_type __length = size(); if (static_cast<size_type>(__elemsbefore) < __length / 2) - { - iterator __new_start = _M_reserve_elements_at_front(__n); - iterator __old_start = _M_start; - __pos = _M_start + __elemsbefore; - try - { - if (__elemsbefore >= difference_type(__n)) - { - iterator __start_n = _M_start + difference_type(__n); - uninitialized_copy(_M_start, __start_n, __new_start); - _M_start = __new_start; - copy(__start_n, __pos, __old_start); - copy(__first, __last, __pos - difference_type(__n)); - } - else - { - _ForwardIterator __mid = __first; - advance(__mid, difference_type(__n) - __elemsbefore); - __uninitialized_copy_copy(_M_start, __pos, __first, __mid, - __new_start); - _M_start = __new_start; - copy(__mid, __last, __old_start); - } - } - catch(...) - { - _M_destroy_nodes(__new_start._M_node, _M_start._M_node); - __throw_exception_again; - } - } + { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = this->_M_impl._M_start; + __pos = this->_M_impl._M_start + __elemsbefore; + try + { + if (__elemsbefore >= difference_type(__n)) + { + iterator __start_n = this->_M_impl._M_start + difference_type(__n); + std::uninitialized_copy(this->_M_impl._M_start, __start_n, + __new_start); + this->_M_impl._M_start = __new_start; + std::copy(__start_n, __pos, __old_start); + std::copy(__first, __last, __pos - difference_type(__n)); + } + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, difference_type(__n) - __elemsbefore); + std::__uninitialized_copy_copy(this->_M_impl._M_start, __pos, + __first, __mid, __new_start); + this->_M_impl._M_start = __new_start; + std::copy(__mid, __last, __old_start); + } + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); + __throw_exception_again; + } + } else { iterator __new_finish = _M_reserve_elements_at_back(__n); - iterator __old_finish = _M_finish; - const difference_type __elemsafter = + iterator __old_finish = this->_M_impl._M_finish; + const difference_type __elemsafter = difference_type(__length) - __elemsbefore; - __pos = _M_finish - __elemsafter; + __pos = this->_M_impl._M_finish - __elemsafter; try { if (__elemsafter > difference_type(__n)) - { - iterator __finish_n = _M_finish - difference_type(__n); - uninitialized_copy(__finish_n, _M_finish, _M_finish); - _M_finish = __new_finish; - copy_backward(__pos, __finish_n, __old_finish); - copy(__first, __last, __pos); - } + { + iterator __finish_n = this->_M_impl._M_finish - difference_type(__n); + std::uninitialized_copy(__finish_n, + this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; + std::copy_backward(__pos, __finish_n, __old_finish); + std::copy(__first, __last, __pos); + } else - { - _ForwardIterator __mid = __first; - advance(__mid, __elemsafter); - __uninitialized_copy_copy(__mid, __last, __pos, - _M_finish, _M_finish); - _M_finish = __new_finish; - copy(__first, __mid, __pos); - } + { + _ForwardIterator __mid = __first; + std::advance(__mid, __elemsafter); + std::__uninitialized_copy_copy(__mid, __last, __pos, + this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; + std::copy(__first, __mid, __pos); + } } catch(...) { - _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1); + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); __throw_exception_again; } } } - + template <typename _Tp, typename _Alloc> void deque<_Tp,_Alloc>:: _M_new_elements_at_front(size_type __new_elems) { size_type __new_nodes - = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size(); + = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size(); _M_reserve_map_at_front(__new_nodes); size_type __i; try { for (__i = 1; __i <= __new_nodes; ++__i) - *(_M_start._M_node - __i) = _M_allocate_node(); + *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node(); } catch(...) { for (size_type __j = 1; __j < __i; ++__j) - _M_deallocate_node(*(_M_start._M_node - __j)); + _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j)); __throw_exception_again; } } - + template <typename _Tp, typename _Alloc> void deque<_Tp,_Alloc>:: @@ -726,54 +659,61 @@ namespace std try { for (__i = 1; __i <= __new_nodes; ++__i) - *(_M_finish._M_node + __i) = _M_allocate_node(); + *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node(); } catch(...) { for (size_type __j = 1; __j < __i; ++__j) - _M_deallocate_node(*(_M_finish._M_node + __j)); + _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j)); __throw_exception_again; } } - + template <typename _Tp, typename _Alloc> void deque<_Tp,_Alloc>:: _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 __old_num_nodes + = this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1; size_type __new_num_nodes = __old_num_nodes + __nodes_to_add; - + _Map_pointer __new_nstart; - if (_M_map_size > 2 * __new_num_nodes) - { - __new_nstart = _M_map + (_M_map_size - __new_num_nodes) / 2 - + (__add_at_front ? __nodes_to_add : 0); - if (__new_nstart < _M_start._M_node) - copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart); - else - copy_backward(_M_start._M_node, _M_finish._M_node + 1, - __new_nstart + __old_num_nodes); - } + if (this->_M_impl._M_map_size > 2 * __new_num_nodes) + { + __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size + - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + if (__new_nstart < this->_M_impl._M_start._M_node) + std::copy(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1, + __new_nstart); + else + std::copy_backward(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1, + __new_nstart + __old_num_nodes); + } else - { - size_type __new_map_size = - _M_map_size + max(_M_map_size, __nodes_to_add) + 2; - - _Map_pointer __new_map = _M_allocate_map(__new_map_size); - __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 - + (__add_at_front ? __nodes_to_add : 0); - copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart); - _M_deallocate_map(_M_map, _M_map_size); - - _M_map = __new_map; - _M_map_size = __new_map_size; - } - - _M_start._M_set_node(__new_nstart); - _M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); + { + size_type __new_map_size = this->_M_impl._M_map_size + + std::max(this->_M_impl._M_map_size, + __nodes_to_add) + 2; + + _Map_pointer __new_map = this->_M_allocate_map(__new_map_size); + __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + std::copy(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1, + __new_nstart); + _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); + + this->_M_impl._M_map = __new_map; + this->_M_impl._M_map_size = __new_map_size; + } + + this->_M_impl._M_start._M_set_node(__new_nstart); + this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); } -} // namespace std - -#endif /* __GLIBCPP_INTERNAL_DEQUE_TCC */ +} // namespace std +#endif diff --git a/contrib/libstdc++/include/bits/fstream.tcc b/contrib/libstdc++/include/bits/fstream.tcc index c69ac9c72266..6c2e1822adb0 100644 --- a/contrib/libstdc++/include/bits/fstream.tcc +++ b/contrib/libstdc++/include/bits/fstream.tcc @@ -1,6 +1,6 @@ // File based streams -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -32,8 +32,8 @@ // ISO C++ 14882: 27.8 File-based streams // -#ifndef _CPP_BITS_FSTREAM_TCC -#define _CPP_BITS_FSTREAM_TCC 1 +#ifndef _FSTREAM_TCC +#define _FSTREAM_TCC 1 #pragma GCC system_header @@ -44,17 +44,15 @@ namespace std basic_filebuf<_CharT, _Traits>:: _M_allocate_internal_buffer() { - if (!_M_buf && _M_buf_size_opt) + // Allocate internal buffer only if one doesn't already exist + // (either allocated or provided by the user via setbuf). + if (!_M_buf_allocated && !this->_M_buf) { - _M_buf_size = _M_buf_size_opt; - - // Allocate internal buffer. - _M_buf = new char_type[_M_buf_size]; + this->_M_buf = new char_type[this->_M_buf_size]; _M_buf_allocated = true; } } - // Both close and setbuf need to deallocate internal buffers, if it exists. template<typename _CharT, typename _Traits> void basic_filebuf<_CharT, _Traits>:: @@ -62,23 +60,33 @@ namespace std { if (_M_buf_allocated) { - delete [] _M_buf; - _M_buf = NULL; + delete [] this->_M_buf; + this->_M_buf = NULL; _M_buf_allocated = false; - this->setg(NULL, NULL, NULL); - this->setp(NULL, NULL); } + delete [] _M_ext_buf; + _M_ext_buf = NULL; + _M_ext_buf_size = 0; + _M_ext_next = NULL; + _M_ext_end = NULL; } template<typename _CharT, typename _Traits> basic_filebuf<_CharT, _Traits>:: - basic_filebuf() : __streambuf_type(), _M_file(&_M_lock), - _M_state_cur(__state_type()), _M_state_beg(__state_type()), - _M_buf_allocated(false), _M_last_overflowed(false) - { _M_buf_unified = true; } + basic_filebuf() : __streambuf_type(), _M_lock(), _M_file(&_M_lock), + _M_mode(ios_base::openmode(0)), _M_state_beg(), _M_state_cur(), + _M_state_last(), _M_buf(NULL), _M_buf_size(BUFSIZ), + _M_buf_allocated(false), _M_reading(false), _M_writing(false), _M_pback(), + _M_pback_cur_save(0), _M_pback_end_save(0), _M_pback_init(false), + _M_codecvt(0), _M_ext_buf(0), _M_ext_buf_size(0), _M_ext_next(0), + _M_ext_end(0) + { + if (has_facet<__codecvt_type>(this->_M_buf_locale)) + _M_codecvt = &use_facet<__codecvt_type>(this->_M_buf_locale); + } template<typename _CharT, typename _Traits> - typename basic_filebuf<_CharT, _Traits>::__filebuf_type* + typename basic_filebuf<_CharT, _Traits>::__filebuf_type* basic_filebuf<_CharT, _Traits>:: open(const char* __s, ios_base::openmode __mode) { @@ -89,27 +97,30 @@ namespace std if (this->is_open()) { _M_allocate_internal_buffer(); - _M_mode = __mode; + this->_M_mode = __mode; - // Setup initial position of buffer. - _M_set_indeterminate(); + // Setup initial buffer to 'uncommitted' mode. + _M_reading = false; + _M_writing = false; + _M_set_buffer(-1); - if ((__mode & ios_base::ate) - && this->seekoff(0, ios_base::end, __mode) < 0) - { - // 27.8.1.3,4 - this->close(); - return __ret; - } + // Reset to initial state. + _M_state_last = _M_state_cur = _M_state_beg; - __ret = this; + // 27.8.1.3,4 + if ((__mode & ios_base::ate) + && this->seekoff(0, ios_base::end, __mode) + == pos_type(off_type(-1))) + this->close(); + else + __ret = this; } } return __ret; } template<typename _CharT, typename _Traits> - typename basic_filebuf<_CharT, _Traits>::__filebuf_type* + typename basic_filebuf<_CharT, _Traits>::__filebuf_type* basic_filebuf<_CharT, _Traits>:: close() throw() { @@ -119,31 +130,20 @@ namespace std bool __testfail = false; try { - const int_type __eof = traits_type::eof(); - bool __testput = _M_out_cur && _M_out_beg < _M_out_end; - if (__testput - && traits_type::eq_int_type(_M_really_overflow(__eof), - __eof)) + if (!_M_terminate_output()) __testfail = true; - -#if 0 - // XXX not done - if (_M_last_overflowed) - { - _M_output_unshift(); - _M_really_overflow(__eof); - } -#endif } catch(...) - { - __testfail = true; - } + { __testfail = true; } // NB: Do this here so that re-opened filebufs will be cool... this->_M_mode = ios_base::openmode(0); + this->_M_pback_init = false; _M_destroy_internal_buffer(); - _M_pback_destroy(); + _M_reading = false; + _M_writing = false; + _M_set_buffer(-1); + _M_state_last = _M_state_cur = _M_state_beg; if (!_M_file.close()) __testfail = true; @@ -151,158 +151,311 @@ namespace std if (!__testfail) __ret = this; } - _M_last_overflowed = false; return __ret; } template<typename _CharT, typename _Traits> - streamsize + streamsize basic_filebuf<_CharT, _Traits>:: showmanyc() { streamsize __ret = -1; - bool __testin = _M_mode & ios_base::in; - const locale __loc = this->getloc(); - const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc); - + const bool __testin = this->_M_mode & ios_base::in; if (__testin && this->is_open()) { - __ret = _M_in_end - _M_in_cur; - if (__cvt.always_noconv()) - __ret += _M_file.showmanyc_helper(); + // For a stateful encoding (-1) the pending sequence might be just + // shift and unshift prefixes with no actual character. + __ret = this->egptr() - this->gptr(); + if (__check_facet(_M_codecvt).encoding() >= 0) + __ret += _M_file.showmanyc() / _M_codecvt->max_length(); } - - _M_last_overflowed = false; return __ret; } - + template<typename _CharT, typename _Traits> - typename basic_filebuf<_CharT, _Traits>::int_type + typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>:: - pbackfail(int_type __i) + underflow() { int_type __ret = traits_type::eof(); - bool __testin = _M_mode & ios_base::in; - - if (__testin) + const bool __testin = this->_M_mode & ios_base::in; + if (__testin && !_M_writing) { - bool __testpb = _M_in_beg < _M_in_cur; - char_type __c = traits_type::to_char_type(__i); - bool __testeof = traits_type::eq_int_type(__i, __ret); - - if (__testpb) + // Check for pback madness, and if so swich back to the + // normal buffers and jet outta here before expensive + // fileops happen... + _M_destroy_pback(); + + if (this->gptr() < this->egptr()) + return traits_type::to_int_type(*this->gptr()); + + // Get and convert input sequence. + const size_t __buflen = this->_M_buf_size > 1 + ? this->_M_buf_size - 1 : 1; + + // Will be set to true if ::read() returns 0 indicating EOF. + bool __got_eof = false; + // Number of internal characters produced. + streamsize __ilen = 0; + codecvt_base::result __r = codecvt_base::ok; + if (__check_facet(_M_codecvt).always_noconv()) { - bool __testout = _M_mode & ios_base::out; - bool __testeq = traits_type::eq(__c, this->gptr()[-1]); - - // Try to put back __c into input sequence in one of three ways. - // Order these tests done in is unspecified by the standard. - if (!__testeof && __testeq) + __ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()), + __buflen); + if (__ilen == 0) + __got_eof = true; + } + else + { + // Worst-case number of external bytes. + // XXX Not done encoding() == -1. + const int __enc = _M_codecvt->encoding(); + streamsize __blen; // Minimum buffer size. + streamsize __rlen; // Number of chars to read. + if (__enc > 0) + __blen = __rlen = __buflen * __enc; + else { - --_M_in_cur; - if (__testout) - --_M_out_cur; - __ret = __i; + __blen = __buflen + _M_codecvt->max_length() - 1; + __rlen = __buflen; } - else if (__testeof) + const streamsize __remainder = _M_ext_end - _M_ext_next; + __rlen = __rlen > __remainder ? __rlen - __remainder : 0; + + // An imbue in 'read' mode implies first converting the external + // chars already present. + if (_M_reading && this->egptr() == this->eback() && __remainder) + __rlen = 0; + + // Allocate buffer if necessary and move unconverted + // bytes to front. + if (_M_ext_buf_size < __blen) { - --_M_in_cur; - if (__testout) - --_M_out_cur; - __ret = traits_type::not_eof(__i); + char* __buf = new char[__blen]; + if (__remainder) + std::memcpy(__buf, _M_ext_next, __remainder); + + delete [] _M_ext_buf; + _M_ext_buf = __buf; + _M_ext_buf_size = __blen; } - else if (!__testeof) + else if (__remainder) + std::memmove(_M_ext_buf, _M_ext_next, __remainder); + + _M_ext_next = _M_ext_buf; + _M_ext_end = _M_ext_buf + __remainder; + _M_state_last = _M_state_cur; + + do { - --_M_in_cur; - if (__testout) - --_M_out_cur; - _M_pback_create(); - *_M_in_cur = __c; - __ret = __i; + if (__rlen > 0) + { + // Sanity check! + // This may fail if the return value of + // codecvt::max_length() is bogus. + if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size) + { + __throw_ios_failure(__N("basic_filebuf::underflow " + "codecvt::max_length() " + "is not valid")); + } + streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen); + if (__elen == 0) + __got_eof = true; + else if (__elen == -1) + break; + _M_ext_end += __elen; + } + + char_type* __iend; + __r = _M_codecvt->in(_M_state_cur, _M_ext_next, + _M_ext_end, _M_ext_next, this->eback(), + this->eback() + __buflen, __iend); + if (__r == codecvt_base::noconv) + { + size_t __avail = _M_ext_end - _M_ext_buf; + __ilen = std::min(__avail, __buflen); + traits_type::copy(this->eback(), + reinterpret_cast<char_type*>(_M_ext_buf), __ilen); + _M_ext_next = _M_ext_buf + __ilen; + } + else + __ilen = __iend - this->eback(); + + // _M_codecvt->in may return error while __ilen > 0: this is + // ok, and actually occurs in case of mixed encodings (e.g., + // XML files). + if (__r == codecvt_base::error) + break; + + __rlen = 1; } + while (__ilen == 0 && !__got_eof); + } + + if (__ilen > 0) + { + _M_set_buffer(__ilen); + _M_reading = true; + __ret = traits_type::to_int_type(*this->gptr()); + } + else if (__got_eof) + { + // If the actual end of file is reached, set 'uncommitted' + // mode, thus allowing an immediate write without an + // intervening seek. + _M_set_buffer(-1); + _M_reading = false; + // However, reaching it while looping on partial means that + // the file has got an incomplete character. + if (__r == codecvt_base::partial) + __throw_ios_failure(__N("basic_filebuf::underflow " + "incomplete character in file")); + } + else if (__r == codecvt_base::error) + __throw_ios_failure(__N("basic_filebuf::underflow " + "invalid byte sequence in file")); + else + __throw_ios_failure(__N("basic_filebuf::underflow " + "error reading the file")); + } + return __ret; + } + + template<typename _CharT, typename _Traits> + typename basic_filebuf<_CharT, _Traits>::int_type + basic_filebuf<_CharT, _Traits>:: + pbackfail(int_type __i) + { + int_type __ret = traits_type::eof(); + const bool __testin = this->_M_mode & ios_base::in; + if (__testin && !_M_writing) + { + // Remember whether the pback buffer is active, otherwise below + // we may try to store in it a second char (libstdc++/9761). + const bool __testpb = this->_M_pback_init; + const bool __testeof = traits_type::eq_int_type(__i, __ret); + int_type __tmp; + if (this->eback() < this->gptr()) + { + this->gbump(-1); + __tmp = traits_type::to_int_type(*this->gptr()); + } + else if (this->seekoff(-1, ios_base::cur) != pos_type(off_type(-1))) + { + __tmp = this->underflow(); + if (traits_type::eq_int_type(__tmp, __ret)) + return __ret; } else - { - // At the beginning of the buffer, need to make a - // putback position available. - // But the seek may fail (f.i., at the beginning of - // a file, see libstdc++/9439) and in that case - // we return traits_type::eof() - if (this->seekoff(-1, ios_base::cur) >= 0) - { - this->underflow(); - if (!__testeof) - { - if (!traits_type::eq(__c, *_M_in_cur)) - { - _M_pback_create(); - *_M_in_cur = __c; - } - __ret = __i; - } - else - __ret = traits_type::not_eof(__i); - } - } + { + // At the beginning of the buffer, need to make a + // putback position available. But the seek may fail + // (f.i., at the beginning of a file, see + // libstdc++/9439) and in that case we return + // traits_type::eof(). + return __ret; + } + + // Try to put back __i into input sequence in one of three ways. + // Order these tests done in is unspecified by the standard. + if (!__testeof && traits_type::eq_int_type(__i, __tmp)) + __ret = __i; + else if (__testeof) + __ret = traits_type::not_eof(__i); + else if (!__testpb) + { + _M_create_pback(); + _M_reading = true; + *this->gptr() = traits_type::to_char_type(__i); + __ret = __i; + } } - _M_last_overflowed = false; return __ret; } template<typename _CharT, typename _Traits> - typename basic_filebuf<_CharT, _Traits>::int_type + typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>:: overflow(int_type __c) { int_type __ret = traits_type::eof(); - bool __testput = _M_out_cur && _M_out_cur < _M_buf + _M_buf_size; - bool __testout = _M_mode & ios_base::out; - - if (__testout) + const bool __testeof = traits_type::eq_int_type(__c, __ret); + const bool __testout = this->_M_mode & ios_base::out; + if (__testout && !_M_reading) { - if (traits_type::eq_int_type(__c, traits_type::eof())) - __ret = traits_type::not_eof(__c); - else if (__testput) + if (this->pbase() < this->pptr()) { - *_M_out_cur = traits_type::to_char_type(__c); - _M_out_cur_move(1); + // If appropriate, append the overflow char. + if (!__testeof) + { + *this->pptr() = traits_type::to_char_type(__c); + this->pbump(1); + } + + // Convert pending sequence to external representation, + // and output. + if (_M_convert_to_external(this->pbase(), + this->pptr() - this->pbase()) + && (!__testeof || !_M_file.sync())) + { + _M_set_buffer(0); + __ret = traits_type::not_eof(__c); + } + } + else if (this->_M_buf_size > 1) + { + // Overflow in 'uncommitted' mode: set _M_writing, set + // the buffer to the initial 'write' mode, and put __c + // into the buffer. + _M_set_buffer(0); + _M_writing = true; + if (!__testeof) + { + *this->pptr() = traits_type::to_char_type(__c); + this->pbump(1); + } __ret = traits_type::not_eof(__c); } - else - __ret = this->_M_really_overflow(__c); + else + { + // Unbuffered. + char_type __conv = traits_type::to_char_type(__c); + if (__testeof || _M_convert_to_external(&__conv, 1)) + { + _M_writing = true; + __ret = traits_type::not_eof(__c); + } + } } - - _M_last_overflowed = false; // Set in _M_really_overflow, below. return __ret; } - + template<typename _CharT, typename _Traits> - void + bool basic_filebuf<_CharT, _Traits>:: - _M_convert_to_external(_CharT* __ibuf, streamsize __ilen, - streamsize& __elen, streamsize& __plen) + _M_convert_to_external(_CharT* __ibuf, streamsize __ilen) { - const locale __loc = this->getloc(); - const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc); - - if (__cvt.always_noconv() && __ilen) + // Sizes of external and pending output. + streamsize __elen; + streamsize __plen; + if (__check_facet(_M_codecvt).always_noconv()) { - __elen += _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen); - __plen += __ilen; + __elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen); + __plen = __ilen; } else { // Worst-case number of external bytes needed. - int __ext_multiplier = __cvt.encoding(); - if (__ext_multiplier == -1 || __ext_multiplier == 0) - __ext_multiplier = sizeof(char_type); - streamsize __blen = __ilen * __ext_multiplier; + // XXX Not done encoding() == -1. + streamsize __blen = __ilen * _M_codecvt->max_length(); char* __buf = static_cast<char*>(__builtin_alloca(__blen)); + char* __bend; const char_type* __iend; codecvt_base::result __r; - __r = __cvt.out(_M_state_cur, __ibuf, __ibuf + __ilen, - __iend, __buf, __buf + __blen, __bend); + __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen, + __iend, __buf, __buf + __blen, __bend); if (__r == codecvt_base::ok || __r == codecvt_base::partial) __blen = __bend - __buf; @@ -313,225 +466,340 @@ namespace std __blen = __ilen; } else - { - // Result == error - __blen = 0; - } - - if (__blen) - { - __elen += _M_file.xsputn(__buf, __blen); - __plen += __blen; - } + __throw_ios_failure(__N("basic_filebuf::_M_convert_to_external " + "conversion error")); + + __elen = _M_file.xsputn(__buf, __blen); + __plen = __blen; // Try once more for partial conversions. - if (__r == codecvt_base::partial) + if (__r == codecvt_base::partial && __elen == __plen) { const char_type* __iresume = __iend; - streamsize __rlen = _M_out_end - __iend; - __r = __cvt.out(_M_state_cur, __iresume, __iresume + __rlen, - __iend, __buf, __buf + __blen, __bend); + streamsize __rlen = this->pptr() - __iend; + __r = _M_codecvt->out(_M_state_cur, __iresume, + __iresume + __rlen, __iend, __buf, + __buf + __blen, __bend); if (__r != codecvt_base::error) { __rlen = __bend - __buf; - __elen += _M_file.xsputn(__buf, __rlen); - __plen += __rlen; + __elen = _M_file.xsputn(__buf, __rlen); + __plen = __rlen; } + else + __throw_ios_failure(__N("basic_filebuf::_M_convert_to_external " + "conversion error")); } } + return __elen == __plen; } - template<typename _CharT, typename _Traits> - typename basic_filebuf<_CharT, _Traits>::int_type - basic_filebuf<_CharT, _Traits>:: - _M_really_overflow(int_type __c) - { - int_type __ret = traits_type::eof(); - bool __testput = _M_out_cur && _M_out_beg < _M_out_end; - bool __testunbuffered = _M_file.is_open() && !_M_buf_size; - - if (__testput || __testunbuffered) + template<typename _CharT, typename _Traits> + streamsize + basic_filebuf<_CharT, _Traits>:: + xsputn(const _CharT* __s, streamsize __n) + { + // Optimization in the always_noconv() case, to be generalized in the + // future: when __n is sufficiently large we write directly instead of + // using the buffer. + streamsize __ret = 0; + const bool __testout = this->_M_mode & ios_base::out; + if (__testout && !_M_reading + && __check_facet(_M_codecvt).always_noconv()) { - // Sizes of external and pending output. - streamsize __elen = 0; - streamsize __plen = 0; - - // Need to restore current position. The position of the external - // byte sequence (_M_file) corresponds to _M_filepos, and we need - // to move it to _M_out_beg for the write. - if (_M_filepos && _M_filepos != _M_out_beg) - { - off_type __off = _M_out_beg - _M_filepos; - _M_file.seekoff(__off, ios_base::cur); - } + // Measurement would reveal the best choice. + const streamsize __chunk = 1ul << 10; + streamsize __bufavail = this->epptr() - this->pptr(); - // Convert internal buffer to external representation, output. - // NB: In the unbuffered case, no internal buffer exists. - if (!__testunbuffered) - _M_convert_to_external(_M_out_beg, _M_out_end - _M_out_beg, - __elen, __plen); - - // Checks for codecvt.out failures and _M_file.xsputn failures, - // respectively, inside _M_convert_to_external. - if (__testunbuffered || (__elen && __elen == __plen)) - { - // Convert pending sequence to external representation, output. - // If eof, then just attempt sync. - if (!traits_type::eq_int_type(__c, traits_type::eof())) + // Don't mistake 'uncommitted' mode buffered with unbuffered. + if (!_M_writing && this->_M_buf_size > 1) + __bufavail = this->_M_buf_size - 1; + + const streamsize __limit = std::min(__chunk, __bufavail); + if (__n >= __limit) + { + const streamsize __buffill = this->pptr() - this->pbase(); + const char* __buf = reinterpret_cast<const char*>(this->pbase()); + __ret = _M_file.xsputn_2(__buf, __buffill, + reinterpret_cast<const char*>(__s), + __n); + if (__ret == __buffill + __n) { - char_type __pending = traits_type::to_char_type(__c); - _M_convert_to_external(&__pending, 1, __elen, __plen); - - // User code must flush when switching modes (thus - // don't sync). - if (__elen == __plen && __elen) - { - _M_set_indeterminate(); - __ret = traits_type::not_eof(__c); - } + _M_set_buffer(0); + _M_writing = true; } - else if (!_M_file.sync()) - { - _M_set_indeterminate(); - __ret = traits_type::not_eof(__c); - } - } + if (__ret > __buffill) + __ret -= __buffill; + else + __ret = 0; + } + else + __ret = __streambuf_type::xsputn(__s, __n); } - _M_last_overflowed = true; - return __ret; + else + __ret = __streambuf_type::xsputn(__s, __n); + return __ret; } template<typename _CharT, typename _Traits> - typename basic_filebuf<_CharT, _Traits>::__streambuf_type* + typename basic_filebuf<_CharT, _Traits>::__streambuf_type* basic_filebuf<_CharT, _Traits>:: setbuf(char_type* __s, streamsize __n) { - if (!this->is_open() && __s == 0 && __n == 0) - _M_buf_size_opt = 0; - else if (__s && __n) - { - // This is implementation-defined behavior, and assumes - // that an external char_type array of length (__s + __n) - // exists and has been pre-allocated. If this is not the - // case, things will quickly blow up. - // Step 1: Destroy the current internal array. - _M_destroy_internal_buffer(); - - // Step 2: Use the external array. - _M_buf = __s; - _M_buf_size_opt = _M_buf_size = __n; - _M_set_indeterminate(); - } - _M_last_overflowed = false; - return this; + if (!this->is_open()) + if (__s == 0 && __n == 0) + this->_M_buf_size = 1; + else if (__s && __n > 0) + { + // This is implementation-defined behavior, and assumes that + // an external char_type array of length __n exists and has + // been pre-allocated. If this is not the case, things will + // quickly blow up. When __n > 1, __n - 1 positions will be + // used for the get area, __n - 1 for the put area and 1 + // position to host the overflow char of a full put area. + // When __n == 1, 1 position will be used for the get area + // and 0 for the put area, as in the unbuffered case above. + this->_M_buf = __s; + this->_M_buf_size = __n; + } + return this; } - + + + // According to 27.8.1.4 p11 - 13, seekoff should ignore the last + // argument (of type openmode). template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>:: - seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode) + seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode) { - pos_type __ret = pos_type(off_type(-1)); - bool __testin = (ios_base::in & _M_mode & __mode) != 0; - bool __testout = (ios_base::out & _M_mode & __mode) != 0; - int __width = 0; - if (has_facet<__codecvt_type>(this->_M_buf_locale)) - __width = use_facet<__codecvt_type>(this->_M_buf_locale).encoding(); + if (_M_codecvt) + __width = _M_codecvt->encoding(); if (__width < 0) __width = 0; - bool __testfail = __off != 0 && __width <= 0; - if (this->is_open() && !__testfail && (__testin || __testout)) + pos_type __ret = pos_type(off_type(-1)); + const bool __testfail = __off != 0 && __width <= 0; + if (this->is_open() && !__testfail) { // Ditch any pback buffers to avoid confusion. - _M_pback_destroy(); - - if (__way != ios_base::cur || __off != 0) - { - off_type __computed_off = __width * __off; - - bool __testget = _M_in_cur && _M_in_beg < _M_in_end; - bool __testput = _M_out_cur && _M_out_beg < _M_out_end; - // Sync the internal and external streams. - // out - if (__testput || _M_last_overflowed) - { - // Part one: update the output sequence. - this->sync(); - // Part two: output unshift sequence. - _M_output_unshift(); - } - //in - else if (__testget && __way == ios_base::cur) - __computed_off += _M_in_cur - _M_filepos; - - // Return pos_type(off_type(-1)) in case of failure. - __ret = _M_file.seekoff(__computed_off, __way, __mode); - _M_set_indeterminate(); - } - // NB: Need to do this in case _M_file in indeterminate - // state, ie _M_file._offset == -1 - else + _M_destroy_pback(); + + // Correct state at destination. Note that this is the correct + // state for the current position during output, because + // codecvt::unshift() returns the state to the initial state. + // This is also the correct state at the end of the file because + // an unshift sequence should have been written at the end. + __state_type __state = _M_state_beg; + off_type __computed_off = __off * __width; + if (_M_reading && __way == ios_base::cur) { - pos_type __tmp = - _M_file.seekoff(__off, ios_base::cur, __mode); - if (__tmp >= 0) + if (_M_codecvt->always_noconv()) + __computed_off += this->gptr() - this->egptr(); + else { - // Seek successful. - __ret = __tmp; - __ret += max(_M_out_cur, _M_in_cur) - _M_filepos; + // Calculate offset from _M_ext_buf that corresponds + // to gptr(). Note: uses _M_state_last, which + // corresponds to eback(). + const int __gptr_off = + _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next, + this->gptr() - this->eback()); + __computed_off += _M_ext_buf + __gptr_off - _M_ext_end; + + // _M_state_last is modified by codecvt::length() so + // it now corresponds to gptr(). + __state = _M_state_last; } } + __ret = _M_seek(__computed_off, __way, __state); } - _M_last_overflowed = false; return __ret; } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 171. Strange seekpos() semantics due to joint position + // According to the resolution of DR 171, seekpos should ignore the last + // argument (of type openmode). template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>:: - seekpos(pos_type __pos, ios_base::openmode __mode) + seekpos(pos_type __pos, ios_base::openmode) { -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -// 171. Strange seekpos() semantics due to joint position - return this->seekoff(off_type(__pos), ios_base::beg, __mode); -#endif + pos_type __ret = pos_type(off_type(-1)); + if (this->is_open()) + { + // Ditch any pback buffers to avoid confusion. + _M_destroy_pback(); + __ret = _M_seek(off_type(__pos), ios_base::beg, __pos.state()); + } + return __ret; } template<typename _CharT, typename _Traits> - void + typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>:: - _M_output_unshift() - { } + _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state) + { + pos_type __ret = pos_type(off_type(-1)); + if (_M_terminate_output()) + { + // Returns pos_type(off_type(-1)) in case of failure. + __ret = pos_type(_M_file.seekoff(__off, __way)); + _M_reading = false; + _M_writing = false; + _M_ext_next = _M_ext_end = _M_ext_buf; + _M_set_buffer(-1); + _M_state_cur = __state; + __ret.state(_M_state_cur); + } + return __ret; + } + + template<typename _CharT, typename _Traits> + bool + basic_filebuf<_CharT, _Traits>:: + _M_terminate_output() + { + // Part one: update the output sequence. + bool __testvalid = true; + if (this->pbase() < this->pptr()) + { + const int_type __tmp = this->overflow(); + if (traits_type::eq_int_type(__tmp, traits_type::eof())) + __testvalid = false; + } + + // Part two: output unshift sequence. + if (_M_writing && !__check_facet(_M_codecvt).always_noconv() + && __testvalid) + { + // Note: this value is arbitrary, since there is no way to + // get the length of the unshift sequence from codecvt, + // without calling unshift. + const size_t __blen = 128; + char __buf[__blen]; + codecvt_base::result __r; + streamsize __ilen = 0; + + do + { + char* __next; + __r = _M_codecvt->unshift(_M_state_cur, __buf, + __buf + __blen, __next); + if (__r == codecvt_base::error) + __testvalid = false; + else if (__r == codecvt_base::ok || + __r == codecvt_base::partial) + { + __ilen = __next - __buf; + if (__ilen > 0) + { + const streamsize __elen = _M_file.xsputn(__buf, __ilen); + if (__elen != __ilen) + __testvalid = false; + } + } + } + while (__r == codecvt_base::partial && __ilen > 0 && __testvalid); + + if (__testvalid) + { + // This second call to overflow() is required by the standard, + // but it's not clear why it's needed, since the output buffer + // should be empty by this point (it should have been emptied + // in the first call to overflow()). + const int_type __tmp = this->overflow(); + if (traits_type::eq_int_type(__tmp, traits_type::eof())) + __testvalid = false; + } + } + return __testvalid; + } + + template<typename _CharT, typename _Traits> + int + basic_filebuf<_CharT, _Traits>:: + sync() + { + // Make sure that the internal buffer resyncs its idea of + // the file position with the external file. + // NB: _M_file.sync() will be called within. + int __ret = 0; + if (this->pbase() < this->pptr()) + { + const int_type __tmp = this->overflow(); + if (traits_type::eq_int_type(__tmp, traits_type::eof())) + __ret = -1; + } + return __ret; + } template<typename _CharT, typename _Traits> void basic_filebuf<_CharT, _Traits>:: imbue(const locale& __loc) { - bool __testbeg = gptr() == eback() && pptr() == pbase(); + bool __testvalid = true; - if (__testbeg && _M_buf_locale != __loc) - _M_buf_locale = __loc; + const __codecvt_type* _M_codecvt_tmp = 0; + if (__builtin_expect(has_facet<__codecvt_type>(__loc), true)) + _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc); - // NB this may require the reconversion of previously - // converted chars. This in turn may cause the reconstruction - // of the original file. YIKES!! - // XXX The part in the above comment is not done. - _M_last_overflowed = false; + if (this->is_open()) + { + // encoding() == -1 is ok only at the beginning. + if ((_M_reading || _M_writing) + && __check_facet(_M_codecvt).encoding() == -1) + __testvalid = false; + else + { + if (_M_reading) + { + if (__check_facet(_M_codecvt).always_noconv()) + { + if (_M_codecvt_tmp + && !__check_facet(_M_codecvt_tmp).always_noconv()) + __testvalid = this->seekoff(0, ios_base::cur, this->_M_mode) + != pos_type(off_type(-1)); + } + else + { + // External position corresponding to gptr(). + _M_ext_next = _M_ext_buf + + _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next, + this->gptr() - this->eback()); + const streamsize __remainder = _M_ext_end - _M_ext_next; + if (__remainder) + std::memmove(_M_ext_buf, _M_ext_next, __remainder); + + _M_ext_next = _M_ext_buf; + _M_ext_end = _M_ext_buf + __remainder; + _M_set_buffer(-1); + _M_state_last = _M_state_cur = _M_state_beg; + } + } + else if (_M_writing && (__testvalid = _M_terminate_output())) + _M_set_buffer(-1); + } + } + + if (__testvalid) + _M_codecvt = _M_codecvt_tmp; + else + _M_codecvt = 0; } // Inhibit implicit instantiations for required instantiations, - // which are defined via explicit instantiations elsewhere. + // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. -#if _GLIBCPP_EXTERN_TEMPLATE +#if _GLIBCXX_EXTERN_TEMPLATE extern template class basic_filebuf<char>; extern template class basic_ifstream<char>; extern template class basic_ofstream<char>; extern template class basic_fstream<char>; -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T extern template class basic_filebuf<wchar_t>; extern template class basic_ifstream<wchar_t>; extern template class basic_ofstream<wchar_t>; @@ -540,4 +808,4 @@ namespace std #endif } // namespace std -#endif +#endif diff --git a/contrib/libstdc++/include/bits/functexcept.h b/contrib/libstdc++/include/bits/functexcept.h index eac2c95b4327..8b1d16c8e59a 100644 --- a/contrib/libstdc++/include/bits/functexcept.h +++ b/contrib/libstdc++/include/bits/functexcept.h @@ -35,22 +35,22 @@ namespace std { - // Helper for exception objects in <except> + // Helper for exception objects in <except> void __throw_bad_exception(void); - // Helper for exception objects in <new> + // Helper for exception objects in <new> void __throw_bad_alloc(void); - // Helper for exception objects in <typeinfo> + // Helper for exception objects in <typeinfo> void __throw_bad_cast(void); void __throw_bad_typeid(void); - // Helpers for exception objects in <stdexcept> + // Helpers for exception objects in <stdexcept> void __throw_logic_error(const char* __s); diff --git a/contrib/libstdc++/include/bits/gslice.h b/contrib/libstdc++/include/bits/gslice.h index 95781f9bbcc2..78f8a67146be 100644 --- a/contrib/libstdc++/include/bits/gslice.h +++ b/contrib/libstdc++/include/bits/gslice.h @@ -1,6 +1,7 @@ // The template and inlines for the -*- C++ -*- gslice class. -// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2004 +// Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -34,61 +35,101 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_GSLICE_H -#define _CPP_BITS_GSLICE_H 1 +#ifndef _GSLICE_H +#define _GSLICE_H 1 #pragma GCC system_header namespace std { - + + /** + * @brief Class defining multi-dimensional subset of an array. + * + * The slice class represents a multi-dimensional subset of an array, + * specified by three parameter sets: start offset, size array, and stride + * array. The start offset is the index of the first element of the array + * that is part of the subset. The size and stride array describe each + * dimension of the slice. Size is the number of elements in that + * dimension, and stride is the distance in the array between successive + * elements in that dimension. Each dimension's size and stride is taken + * to begin at an array element described by the previous dimension. The + * size array and stride array must be the same size. + * + * For example, if you have offset==3, stride[0]==11, size[1]==3, + * stride[1]==3, then slice[0,0]==array[3], slice[0,1]==array[6], + * slice[0,2]==array[9], slice[1,0]==array[14], slice[1,1]==array[17], + * slice[1,2]==array[20]. + */ class gslice { public: - gslice (); - gslice (size_t, const valarray<size_t>&, const valarray<size_t>&); - // XXX: the IS says the copy-ctor and copy-assignment operators are - // synthetized by the compiler but they are just unsuitable - // for a ref-counted semantic - gslice(const gslice&); - ~gslice(); - - // XXX: See the note above. - gslice& operator= (const gslice&); - - size_t start () const; - valarray<size_t> size () const; - valarray<size_t> stride () const; - + /// Construct an empty slice. + gslice (); + + /** + * @brief Construct a slice. + * + * Constructs a slice with as many dimensions as the length of the @a l + * and @a s arrays. + * + * @param o Offset in array of first element. + * @param l Array of dimension lengths. + * @param s Array of dimension strides between array elements. + */ + gslice(size_t, const valarray<size_t>&, const valarray<size_t>&); + + // XXX: the IS says the copy-ctor and copy-assignment operators are + // synthetized by the compiler but they are just unsuitable + // for a ref-counted semantic + /// Copy constructor. + gslice(const gslice&); + + /// Destructor. + ~gslice(); + + // XXX: See the note above. + /// Assignment operator. + gslice& operator=(const gslice&); + + /// Return array offset of first slice element. + size_t start() const; + + /// Return array of sizes of slice dimensions. + valarray<size_t> size() const; + + /// Return array of array strides for each dimension. + valarray<size_t> stride() const; + private: - 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; } - }; - - _Indexer* _M_index; - - template<typename _Tp> friend class valarray; + 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; // Linear array of referenced indices + _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; } + }; + + _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 @@ -99,7 +140,7 @@ namespace std { 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; } @@ -112,12 +153,12 @@ namespace std { _M_index = __g._M_index; return *this; } - - + + } // std:: -#endif /* _CPP_BITS_GSLICE_H */ +#endif /* _GSLICE_H */ // Local Variables: // mode:c++ diff --git a/contrib/libstdc++/include/bits/gslice_array.h b/contrib/libstdc++/include/bits/gslice_array.h index 1116e9c7e97d..7e2e6848e883 100644 --- a/contrib/libstdc++/include/bits/gslice_array.h +++ b/contrib/libstdc++/include/bits/gslice_array.h @@ -1,6 +1,7 @@ // The template and inlines for the -*- C++ -*- gslice_array class. -// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2004 +// Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -34,30 +35,65 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_GSLICE_ARRAY -#define _CPP_BITS_GSLICE_ARRAY 1 +#ifndef _GSLICE_ARRAY_H +#define _GSLICE_ARRAY_H 1 #pragma GCC system_header namespace std { + /** + * @brief Reference to multi-dimensional subset of an array. + * + * A gslice_array is a reference to the actual elements of an array + * specified by a gslice. The way to get a gslice_array is to call + * operator[](gslice) on a valarray. The returned gslice_array then + * permits carrying operations out on the referenced subset of elements in + * the original valarray. For example, operator+=(valarray) will add + * values to the subset of elements in the underlying valarray this + * gslice_array refers to. + * + * @param Tp Element type. + */ template<typename _Tp> class gslice_array { public: typedef _Tp value_type; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 253. valarray helper functions are almost entirely useless + + /// Copy constructor. Both slices refer to the same underlying array. + gslice_array(const gslice_array&); + + /// Assignment operator. Assigns slice elements to corresponding + /// elements of @a a. + gslice_array& operator=(const gslice_array&); + + /// Assign slice elements to corresponding elements of @a v. void operator=(const valarray<_Tp>&) const; + /// Multiply slice elements by corresponding elements of @a v. void operator*=(const valarray<_Tp>&) const; + /// Divide slice elements by corresponding elements of @a v. void operator/=(const valarray<_Tp>&) const; + /// Modulo slice elements by corresponding elements of @a v. void operator%=(const valarray<_Tp>&) const; + /// Add corresponding elements of @a v to slice elements. void operator+=(const valarray<_Tp>&) const; + /// Subtract corresponding elements of @a v from slice elements. void operator-=(const valarray<_Tp>&) const; + /// Logical xor slice elements with corresponding elements of @a v. void operator^=(const valarray<_Tp>&) const; + /// Logical and slice elements with corresponding elements of @a v. void operator&=(const valarray<_Tp>&) const; + /// Logical or slice elements with corresponding elements of @a v. void operator|=(const valarray<_Tp>&) const; + /// Left shift slice elements by corresponding elements of @a v. void operator<<=(const valarray<_Tp>&) const; + /// Right shift slice elements by corresponding elements of @a v. void operator>>=(const valarray<_Tp>&) const; + /// Assign all slice elements to @a t. void operator=(const _Tp&) const; template<class _Dom> @@ -82,50 +118,56 @@ namespace std { 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&); + gslice_array(_Array<_Tp>, const valarray<size_t>&); // 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) {} + : _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) {} + : _M_array(__a._M_array), _M_index(__a._M_index) {} + + + template<typename _Tp> + inline gslice_array<_Tp>& + gslice_array<_Tp>::operator=(const gslice_array<_Tp>& __a) + { + std::__valarray_copy(_Array<_Tp>(__a._M_array), + _Array<size_t>(__a._M_index), _M_index.size(), + _M_array, _Array<size_t>(_M_index)); + return *this; + } - template<typename _Tp> inline void gslice_array<_Tp>::operator=(const _Tp& __t) const - { - __valarray_fill(_M_array, _Array<size_t>(_M_index), - _M_index.size(), __t); + { + std::__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)); + std::__valarray_copy(_Array<_Tp>(__v), __v.size(), + _M_array, _Array<size_t>(_M_index)); } template<typename _Tp> @@ -133,8 +175,8 @@ namespace std { inline void gslice_array<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) const { - __valarray_copy (__e, _M_index.size(), _M_array, - _Array<size_t>(_M_index)); + std::__valarray_copy (__e, _M_index.size(), _M_array, + _Array<size_t>(_M_index)); } #undef _DEFINE_VALARRAY_OPERATOR @@ -148,8 +190,8 @@ namespace std { } \ \ template<typename _Tp> \ - template<class _Dom> \ - inline void \ + template<class _Dom> \ + inline void \ gslice_array<_Tp>::operator _Op##= (const _Expr<_Dom, _Tp>& __e) const\ { \ _Array_augmented_##_Name(_M_array, _Array<size_t>(_M_index), __e,\ @@ -157,9 +199,9 @@ namespace std { } _DEFINE_VALARRAY_OPERATOR(*, __multiplies) -_DEFINE_VALARRAY_OPERATOR(/, __divides) +_DEFINE_VALARRAY_OPERATOR(/, __divides) _DEFINE_VALARRAY_OPERATOR(%, __modulus) -_DEFINE_VALARRAY_OPERATOR(+, __plus) +_DEFINE_VALARRAY_OPERATOR(+, __plus) _DEFINE_VALARRAY_OPERATOR(-, __minus) _DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor) _DEFINE_VALARRAY_OPERATOR(&, __bitwise_and) @@ -171,7 +213,7 @@ _DEFINE_VALARRAY_OPERATOR(>>, __shift_right) } // std:: -#endif /* _CPP_BITS_GSLICE_ARRAY */ +#endif /* _GSLICE_ARRAY_H */ // Local Variables: // mode:c++ diff --git a/contrib/libstdc++/include/bits/indirect_array.h b/contrib/libstdc++/include/bits/indirect_array.h index 9fc973e2bbca..912f522450db 100644 --- a/contrib/libstdc++/include/bits/indirect_array.h +++ b/contrib/libstdc++/include/bits/indirect_array.h @@ -1,6 +1,6 @@ // The template and inlines for the -*- C++ -*- indirect_array class. -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -35,90 +35,124 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_INDIRECT_ARRAY_H -#define _CPP_BITS_INDIRECT_ARRAY_H 1 +#ifndef _INDIRECT_ARRAY_H +#define _INDIRECT_ARRAY_H 1 #pragma GCC system_header namespace std { + /** + * @brief Reference to arbitrary subset of an array. + * + * An indirect_array is a reference to the actual elements of an array + * specified by an ordered array of indices. The way to get an indirect_array is to + * call operator[](valarray<size_t>) on a valarray. The returned + * indirect_array then permits carrying operations out on the referenced + * subset of elements in the original valarray. + * + * For example, if an indirect_array is obtained using the array (4,2,0) as + * an argument, and then assigned to an array containing (1,2,3), then the + * underlying array will have array[0]==3, array[2]==2, and array[4]==1. + * + * @param Tp Element type. + */ template <class _Tp> - class indirect_array - { - public: - typedef _Tp value_type; - - // XXX: This is a proposed resolution for DR-253. - indirect_array& operator=(const indirect_array&); - - 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&) const; - // ~indirect_array(); - - 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(); - }; + class indirect_array + { + public: + typedef _Tp value_type; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 253. valarray helper functions are almost entirely useless + + /// Copy constructor. Both slices refer to the same underlying array. + indirect_array(const indirect_array&); + + /// Assignment operator. Assigns elements to corresponding elements + /// of @a a. + indirect_array& operator=(const indirect_array&); + + /// Assign slice elements to corresponding elements of @a v. + void operator=(const valarray<_Tp>&) const; + /// Multiply slice elements by corresponding elements of @a v. + void operator*=(const valarray<_Tp>&) const; + /// Divide slice elements by corresponding elements of @a v. + void operator/=(const valarray<_Tp>&) const; + /// Modulo slice elements by corresponding elements of @a v. + void operator%=(const valarray<_Tp>&) const; + /// Add corresponding elements of @a v to slice elements. + void operator+=(const valarray<_Tp>&) const; + /// Subtract corresponding elements of @a v from slice elements. + void operator-=(const valarray<_Tp>&) const; + /// Logical xor slice elements with corresponding elements of @a v. + void operator^=(const valarray<_Tp>&) const; + /// Logical and slice elements with corresponding elements of @a v. + void operator&=(const valarray<_Tp>&) const; + /// Logical or slice elements with corresponding elements of @a v. + void operator|=(const valarray<_Tp>&) const; + /// Left shift slice elements by corresponding elements of @a v. + void operator<<=(const valarray<_Tp>&) const; + /// Right shift slice elements by corresponding elements of @a v. + void operator>>=(const valarray<_Tp>&) const; + /// Assign all slice elements to @a t. + void operator= (const _Tp&) const; + // ~indirect_array(); + + 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: + /// Copy constructor. Both slices refer to the same underlying 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(); + }; template<typename _Tp> - inline + 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) {} + : _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, + indirect_array<_Tp>::indirect_array(_Array<_Tp> __a, size_t __s, _Array<size_t> __i) - : _M_sz(__s), _M_index(__i), _M_array(__a) {} + : _M_sz(__s), _M_index(__i), _M_array(__a) {} template<typename _Tp> inline indirect_array<_Tp>& indirect_array<_Tp>::operator=(const indirect_array<_Tp>& __a) { - __valarray_copy(__a._M_array, _M_sz, __a._M_index, _M_array, _M_index); + std::__valarray_copy(__a._M_array, _M_sz, __a._M_index, _M_array, _M_index); return *this; } @@ -126,18 +160,18 @@ namespace std template<typename _Tp> inline void indirect_array<_Tp>::operator=(const _Tp& __t) const - { __valarray_fill(_M_array, _M_index, _M_sz, __t); } + { std::__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); } + { std::__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); } + { std::__valarray_copy(__e, _M_sz, _M_array, _M_index); } #undef _DEFINE_VALARRAY_OPERATOR #define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \ @@ -171,7 +205,7 @@ _DEFINE_VALARRAY_OPERATOR(>>, __shift_right) } // std:: -#endif /* _CPP_BITS_INDIRECT_ARRAY_H */ +#endif /* _INDIRECT_ARRAY_H */ // Local Variables: // mode:c++ diff --git a/contrib/libstdc++/include/bits/ios_base.h b/contrib/libstdc++/include/bits/ios_base.h index 3437f847c4a8..694785df1f55 100644 --- a/contrib/libstdc++/include/bits/ios_base.h +++ b/contrib/libstdc++/include/bits/ios_base.h @@ -1,6 +1,6 @@ // Iostreams base classes -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -29,7 +29,7 @@ // the GNU General Public License. // -// ISO C++ 14882: 27.8 File-based streams +// ISO C++ 14882: 27.4 Iostreams base classes // /** @file ios_base.h @@ -37,8 +37,8 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_IOSBASE_H -#define _CPP_BITS_IOSBASE_H 1 +#ifndef _IOS_BASE_H +#define _IOS_BASE_H 1 #pragma GCC system_header @@ -52,99 +52,99 @@ namespace std // as permitted (but not required) in the standard, in order to provide // better type safety in iostream calls. A side effect is that // expressions involving them are no longer compile-time constants. - enum _Ios_Fmtflags { _M_ios_fmtflags_end = 1L << 16 }; + enum _Ios_Fmtflags { _S_ios_fmtflags_end = 1L << 16 }; - inline _Ios_Fmtflags + inline _Ios_Fmtflags operator&(_Ios_Fmtflags __a, _Ios_Fmtflags __b) { return _Ios_Fmtflags(static_cast<int>(__a) & static_cast<int>(__b)); } - inline _Ios_Fmtflags + inline _Ios_Fmtflags operator|(_Ios_Fmtflags __a, _Ios_Fmtflags __b) { return _Ios_Fmtflags(static_cast<int>(__a) | static_cast<int>(__b)); } - inline _Ios_Fmtflags + inline _Ios_Fmtflags operator^(_Ios_Fmtflags __a, _Ios_Fmtflags __b) { return _Ios_Fmtflags(static_cast<int>(__a) ^ static_cast<int>(__b)); } - inline _Ios_Fmtflags + inline _Ios_Fmtflags operator|=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) { return __a = __a | __b; } - inline _Ios_Fmtflags + inline _Ios_Fmtflags operator&=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) { return __a = __a & __b; } - inline _Ios_Fmtflags + inline _Ios_Fmtflags operator^=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) { return __a = __a ^ __b; } - inline _Ios_Fmtflags + inline _Ios_Fmtflags operator~(_Ios_Fmtflags __a) { return _Ios_Fmtflags(~static_cast<int>(__a)); } - enum _Ios_Openmode { _M_ios_openmode_end = 1L << 16 }; + enum _Ios_Openmode { _S_ios_openmode_end = 1L << 16 }; - inline _Ios_Openmode + inline _Ios_Openmode operator&(_Ios_Openmode __a, _Ios_Openmode __b) { return _Ios_Openmode(static_cast<int>(__a) & static_cast<int>(__b)); } - inline _Ios_Openmode + inline _Ios_Openmode operator|(_Ios_Openmode __a, _Ios_Openmode __b) { return _Ios_Openmode(static_cast<int>(__a) | static_cast<int>(__b)); } - inline _Ios_Openmode + inline _Ios_Openmode operator^(_Ios_Openmode __a, _Ios_Openmode __b) { return _Ios_Openmode(static_cast<int>(__a) ^ static_cast<int>(__b)); } - inline _Ios_Openmode + inline _Ios_Openmode operator|=(_Ios_Openmode& __a, _Ios_Openmode __b) { return __a = __a | __b; } - inline _Ios_Openmode + inline _Ios_Openmode operator&=(_Ios_Openmode& __a, _Ios_Openmode __b) { return __a = __a & __b; } - inline _Ios_Openmode + inline _Ios_Openmode operator^=(_Ios_Openmode& __a, _Ios_Openmode __b) { return __a = __a ^ __b; } - inline _Ios_Openmode + inline _Ios_Openmode operator~(_Ios_Openmode __a) { return _Ios_Openmode(~static_cast<int>(__a)); } - enum _Ios_Iostate { _M_ios_iostate_end = 1L << 16 }; + enum _Ios_Iostate { _S_ios_iostate_end = 1L << 16 }; - inline _Ios_Iostate + inline _Ios_Iostate operator&(_Ios_Iostate __a, _Ios_Iostate __b) { return _Ios_Iostate(static_cast<int>(__a) & static_cast<int>(__b)); } - inline _Ios_Iostate + inline _Ios_Iostate operator|(_Ios_Iostate __a, _Ios_Iostate __b) { return _Ios_Iostate(static_cast<int>(__a) | static_cast<int>(__b)); } - inline _Ios_Iostate + inline _Ios_Iostate operator^(_Ios_Iostate __a, _Ios_Iostate __b) { return _Ios_Iostate(static_cast<int>(__a) ^ static_cast<int>(__b)); } - inline _Ios_Iostate + inline _Ios_Iostate operator|=(_Ios_Iostate& __a, _Ios_Iostate __b) { return __a = __a | __b; } - inline _Ios_Iostate + inline _Ios_Iostate operator&=(_Ios_Iostate& __a, _Ios_Iostate __b) { return __a = __a & __b; } - inline _Ios_Iostate + inline _Ios_Iostate operator^=(_Ios_Iostate& __a, _Ios_Iostate __b) { return __a = __a ^ __b; } - inline _Ios_Iostate + inline _Ios_Iostate operator~(_Ios_Iostate __a) { return _Ios_Iostate(~static_cast<int>(__a)); } - enum _Ios_Seekdir { _M_ios_seekdir_end = 1L << 16 }; + enum _Ios_Seekdir { _S_ios_seekdir_end = 1L << 16 }; // 27.4.2 Class ios_base /** @@ -158,29 +158,27 @@ namespace std class ios_base { public: - + // 27.4.2.1.1 Class ios_base::failure /// These are thrown to indicate problems. Doc me. class failure : public exception { public: -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS - //48. Use of non-existent exception constructor - explicit + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 48. Use of non-existent exception constructor + explicit failure(const string& __str) throw(); // This declaration is not useless: // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 - virtual + virtual ~failure() throw(); virtual const char* what() const throw(); - + private: - enum { _M_bufsize = 256 }; - char _M_name[_M_bufsize]; -#endif + string _M_msg; }; // 27.4.2.1.2 Type ios_base::fmtflags @@ -210,47 +208,65 @@ namespace std * - floatfield */ typedef _Ios_Fmtflags fmtflags; + /// Insert/extract @c bool in alphabetic rather than numeric format. static const fmtflags boolalpha = fmtflags(__ios_flags::_S_boolalpha); + /// Converts integer input or generates integer output in decimal base. static const fmtflags dec = fmtflags(__ios_flags::_S_dec); + /// Generate floating-point output in fixed-point notation. static const fmtflags fixed = fmtflags(__ios_flags::_S_fixed); + /// Converts integer input or generates integer output in hexadecimal base. static const fmtflags hex = fmtflags(__ios_flags::_S_hex); + /// Adds fill characters at a designated internal point in certain /// generated output, or identical to @c right if no such point is /// designated. static const fmtflags internal = fmtflags(__ios_flags::_S_internal); + /// Adds fill characters on the right (final positions) of certain /// generated output. (I.e., the thing you print is flush left.) static const fmtflags left = fmtflags(__ios_flags::_S_left); + /// Converts integer input or generates integer output in octal base. static const fmtflags oct = fmtflags(__ios_flags::_S_oct); + /// Adds fill characters on the left (initial positions) of certain /// generated output. (I.e., the thing you print is flush right.) static const fmtflags right = fmtflags(__ios_flags::_S_right); + /// Generates floating-point output in scientific notation. static const fmtflags scientific = fmtflags(__ios_flags::_S_scientific); + /// Generates a prefix indicating the numeric base of generated integer /// output. static const fmtflags showbase = fmtflags(__ios_flags::_S_showbase); + /// Generates a decimal-point character unconditionally in generated /// floating-point output. static const fmtflags showpoint = fmtflags(__ios_flags::_S_showpoint); + /// Generates a + sign in non-negative generated numeric output. static const fmtflags showpos = fmtflags(__ios_flags::_S_showpos); + /// Skips leading white space before certain input operations. static const fmtflags skipws = fmtflags(__ios_flags::_S_skipws); + /// Flushes output after each output operation. static const fmtflags unitbuf = fmtflags(__ios_flags::_S_unitbuf); + /// Replaces certain lowercase letters with their uppercase equivalents /// in generated output. static const fmtflags uppercase = fmtflags(__ios_flags::_S_uppercase); + /// A mask of left|right|internal. Useful for the 2-arg form of @c setf. static const fmtflags adjustfield = fmtflags(__ios_flags::_S_adjustfield); + /// A mask of dec|oct|hex. Useful for the 2-arg form of @c setf. static const fmtflags basefield = fmtflags(__ios_flags::_S_basefield); + /// A mask of scientific|fixed. Useful for the 2-arg form of @c setf. static const fmtflags floatfield = fmtflags(__ios_flags::_S_floatfield); @@ -267,17 +283,21 @@ namespace std * - goodbit */ typedef _Ios_Iostate iostate; + /// Indicates a loss of integrity in an input or output sequence (such /// as an irrecoverable read error from a file). - static const iostate badbit = iostate(__ios_flags::_S_badbit); + static const iostate badbit = iostate(__ios_flags::_S_badbit); + /// Indicates that an input operation reached the end of an input sequence. - static const iostate eofbit = iostate(__ios_flags::_S_eofbit); + static const iostate eofbit = iostate(__ios_flags::_S_eofbit); + /// Indicates that an input operation failed to read the expected /// characters, or that an output operation failed to generate the /// desired characters. - static const iostate failbit = iostate(__ios_flags::_S_failbit); + static const iostate failbit = iostate(__ios_flags::_S_failbit); + /// Indicates all is well. - static const iostate goodbit = iostate(0); + static const iostate goodbit = iostate(0); // 27.4.2.1.4 Type ios_base::openmode /** @@ -294,21 +314,27 @@ namespace std * - trunc */ typedef _Ios_Openmode openmode; + /// Seek to end before each write. - static const openmode app = openmode(__ios_flags::_S_app); + static const openmode app = openmode(__ios_flags::_S_app); + /// Open and seek to end immediately after opening. - static const openmode ate = openmode(__ios_flags::_S_ate); + static const openmode ate = openmode(__ios_flags::_S_ate); + /// Perform input and output in binary mode (as opposed to text mode). /// This is probably not what you think it is; see /// http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#3 and /// http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#7 for more. - static const openmode binary = openmode(__ios_flags::_S_bin); + static const openmode binary = openmode(__ios_flags::_S_bin); + /// Open for input. Default for @c ifstream and fstream. - static const openmode in = openmode(__ios_flags::_S_in); + static const openmode in = openmode(__ios_flags::_S_in); + /// Open for output. Default for @c ofstream and fstream. - static const openmode out = openmode(__ios_flags::_S_out); + static const openmode out = openmode(__ios_flags::_S_out); + /// Open for input. Default for @c ofstream. - static const openmode trunc = openmode(__ios_flags::_S_trunc); + static const openmode trunc = openmode(__ios_flags::_S_trunc); // 27.4.2.1.5 Type ios_base::seekdir /** @@ -321,26 +347,32 @@ namespace std * - end, equivalent to @c SEEK_END in the C standard library. */ typedef _Ios_Seekdir seekdir; + /// Request a seek relative to the beginning of the stream. - static const seekdir beg = seekdir(0); + static const seekdir beg = seekdir(0); + /// Request a seek relative to the current position within the sequence. - static const seekdir cur = seekdir(SEEK_CUR); + static const seekdir cur = seekdir(SEEK_CUR); + /// Request a seek relative to the current end of the sequence. - static const seekdir end = seekdir(SEEK_END); + static const seekdir end = seekdir(SEEK_END); -#ifdef _GLIBCPP_DEPRECATED +#ifdef _GLIBCXX_DEPRECATED // Annex D.6 typedef int io_state; typedef int open_mode; typedef int seek_dir; - + typedef std::streampos streampos; typedef std::streamoff streamoff; #endif // Callbacks; /** - * @doctodo + * @brief The set of events that may be passed to an event callback. + * + * erase_event is used during ~ios() and copyfmt(). imbue_event is used + * during imbue(). copyfmt_event is used during copyfmt(). */ enum event { @@ -350,14 +382,28 @@ namespace std }; /** - * @doctodo + * @brief The type of an event callback function. + * @param event One of the members of the event enum. + * @param ios_base Reference to the ios_base object. + * @param int The integer provided when the callback was registered. + * + * Event callbacks are user defined functions that get called during + * several ios_base and basic_ios functions, specifically imbue(), + * copyfmt(), and ~ios(). */ typedef void (*event_callback) (event, ios_base&, int); /** - * @doctodo + * @brief Add the callback __fn with parameter __index. + * @param __fn The function to add. + * @param __index The integer to pass to the function when invoked. + * + * Registers a function as an event callback with an integer parameter to + * be passed to the function when invoked. Multiple copies of the + * function are allowed. If there are multiple callbacks, they are + * invoked in the order they were registered. */ - void + void register_callback(event_callback __fn, int __index); protected: @@ -367,11 +413,11 @@ namespace std * ios_base data members (doc me) * @endif */ - streamsize _M_precision; - streamsize _M_width; - fmtflags _M_flags; - iostate _M_exception; - iostate _M_streambuf_state; + streamsize _M_precision; + streamsize _M_width; + fmtflags _M_flags; + iostate _M_exception; + iostate _M_streambuf_state; //@} // 27.4.2.6 Members for callbacks @@ -379,58 +425,59 @@ namespace std struct _Callback_list { // Data Members - _Callback_list* _M_next; - ios_base::event_callback _M_fn; - int _M_index; + _Callback_list* _M_next; + ios_base::event_callback _M_fn; + int _M_index; _Atomic_word _M_refcount; // 0 means one reference. - - _Callback_list(ios_base::event_callback __fn, int __index, + + _Callback_list(ios_base::event_callback __fn, int __index, _Callback_list* __cb) : _M_next(__cb), _M_fn(__fn), _M_index(__index), _M_refcount(0) { } - - void - _M_add_reference() { __atomic_add(&_M_refcount, 1); } + + void + _M_add_reference() { __gnu_cxx::__atomic_add(&_M_refcount, 1); } // 0 => OK to delete. - int - _M_remove_reference() { return __exchange_and_add(&_M_refcount, -1); } + int + _M_remove_reference() + { return __gnu_cxx::__exchange_and_add(&_M_refcount, -1); } }; - _Callback_list* _M_callbacks; + _Callback_list* _M_callbacks; - void + void _M_call_callbacks(event __ev) throw(); - void + void _M_dispose_callbacks(void); // 27.4.2.5 Members for iword/pword storage - struct _Words - { - void* _M_pword; - long _M_iword; + struct _Words + { + void* _M_pword; + long _M_iword; _Words() : _M_pword(0), _M_iword(0) { } }; // Only for failed iword/pword calls. - _Words _M_word_zero; + _Words _M_word_zero; // Guaranteed storage. // The first 5 iword and pword slots are reserved for internal use. - static const int _S_local_word_size = 8; - _Words _M_local_word[_S_local_word_size]; + static const int _S_local_word_size = 8; + _Words _M_local_word[_S_local_word_size]; // Allocated storage. - int _M_word_size; - _Words* _M_word; - - _Words& - _M_grow_words(int __index); + int _M_word_size; + _Words* _M_word; + + _Words& + _M_grow_words(int __index, bool __iword); // Members for locale and locale caching. - locale _M_ios_locale; + locale _M_ios_locale; - void + void _M_init(); public: @@ -438,29 +485,17 @@ namespace std // 27.4.2.1.6 Class ios_base::Init // Used to initialize standard streams. In theory, g++ could use // -finit-priority to order this stuff correctly without going - // through these machinations. - class Init + // through these machinations. + class Init { friend class ios_base; public: Init(); ~Init(); - - static void - _S_ios_create(bool __sync); - - static void - _S_ios_destroy(); - - // NB: Allows debugger applications use of the standard streams - // from operator new. _S_ios_base_init must be incremented in - // _S_ios_create _after_ initialization is completed. - static bool - _S_initialized() { return _S_ios_base_init; } private: - static int _S_ios_base_init; - static bool _S_synced_with_stdio; + static _Atomic_word _S_refcount; + static bool _S_synced_with_stdio; }; // [27.4.2.2] fmtflags state functions @@ -468,7 +503,7 @@ namespace std * @brief Access to format flags. * @return The format control flags for both input and output. */ - inline fmtflags + inline fmtflags flags() const { return _M_flags; } /** @@ -478,12 +513,12 @@ namespace std * * This function overwrites all the format flags with @a fmtfl. */ - inline fmtflags + inline fmtflags flags(fmtflags __fmtfl) - { - fmtflags __old = _M_flags; - _M_flags = __fmtfl; - return __old; + { + fmtflags __old = _M_flags; + _M_flags = __fmtfl; + return __old; } /** @@ -494,12 +529,12 @@ namespace std * This function sets additional flags in format control. Flags that * were previously set remain set. */ - inline fmtflags + inline fmtflags setf(fmtflags __fmtfl) - { - fmtflags __old = _M_flags; - _M_flags |= __fmtfl; - return __old; + { + fmtflags __old = _M_flags; + _M_flags |= __fmtfl; + return __old; } /** @@ -511,7 +546,7 @@ namespace std * This function clears @a mask in the format flags, then sets * @a fmtfl @c & @a mask. An example mask is @c ios_base::adjustfield. */ - inline fmtflags + inline fmtflags setf(fmtflags __fmtfl, fmtflags __mask) { fmtflags __old = _M_flags; @@ -526,7 +561,7 @@ namespace std * * This function clears @a mask in the format flags. */ - inline void + inline void unsetf(fmtflags __mask) { _M_flags &= ~__mask; } /** @@ -538,7 +573,7 @@ namespace std * DR 189. * @endif */ - inline streamsize + inline streamsize precision() const { return _M_precision; } /** @@ -546,12 +581,12 @@ namespace std * @param prec The new precision value. * @return The previous value of precision(). */ - inline streamsize + inline streamsize precision(streamsize __prec) - { - streamsize __old = _M_precision; - _M_precision = __prec; - return __old; + { + streamsize __old = _M_precision; + _M_precision = __prec; + return __old; } /** @@ -560,7 +595,7 @@ namespace std * * "Minimum field width" refers to the number of characters. */ - inline streamsize + inline streamsize width() const { return _M_width; } /** @@ -568,12 +603,12 @@ namespace std * @param wide The new width value. * @return The previous value of width(). */ - inline streamsize + inline streamsize width(streamsize __wide) - { - streamsize __old = _M_width; - _M_width = __wide; - return __old; + { + streamsize __old = _M_width; + _M_width = __wide; + return __old; } // [27.4.2.4] ios_base static members @@ -587,7 +622,7 @@ namespace std * cout). User-declared streams are unaffected. See * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#8 for more. */ - static bool + static bool sync_with_stdio(bool __sync = true); // [27.4.2.3] ios_base locale functions @@ -596,10 +631,10 @@ namespace std * @param loc The new locale. * @return The previous locale. * - * Sets the new locale for this stream, and - * [XXX does something with callbacks]. + * Sets the new locale for this stream, and then invokes each callback + * with imbue_event. */ - locale + locale imbue(const locale& __loc); /** @@ -610,7 +645,7 @@ namespace std * returns @c loc. Otherwise, it returns a copy of @c std::locale(), * the global C++ locale. */ - inline locale + inline locale getloc() const { return _M_ios_locale; } /** @@ -620,61 +655,95 @@ namespace std * Like getloc above, but returns a reference instead of * generating a copy. */ - inline const locale& + inline const locale& _M_getloc() const { return _M_ios_locale; } // [27.4.2.5] ios_base storage functions /** - * @doctodo + * @brief Access to unique indices. + * @return An integer different from all previous calls. + * + * This function returns a unique integer every time it is called. It + * can be used for any purpose, but is primarily intended to be a unique + * index for the iword and pword functions. The expectation is that an + * application calls xalloc in order to obtain an index in the iword and + * pword arrays that can be used without fear of conflict. + * + * The implementation maintains a static variable that is incremented and + * returned on each invocation. xalloc is guaranteed to return an index + * that is safe to use in the iword and pword arrays. */ - static int + static int xalloc() throw(); /** - * @doctodo + * @brief Access to integer array. + * @param __ix Index into the array. + * @return A reference to an integer associated with the index. + * + * The iword function provides access to an array of integers that can be + * used for any purpose. The array grows as required to hold the + * supplied index. All integers in the array are initialized to 0. + * + * The implementation reserves several indices. You should use xalloc to + * obtain an index that is safe to use. Also note that since the array + * can grow dynamically, it is not safe to hold onto the reference. */ - inline long& + inline long& iword(int __ix) { - _Words& __word = (__ix < _M_word_size) - ? _M_word[__ix] : _M_grow_words(__ix); + _Words& __word = (__ix < _M_word_size) + ? _M_word[__ix] : _M_grow_words(__ix, true); return __word._M_iword; } /** - * @doctodo + * @brief Access to void pointer array. + * @param __ix Index into the array. + * @return A reference to a void* associated with the index. + * + * The pword function provides access to an array of pointers that can be + * used for any purpose. The array grows as required to hold the + * supplied index. All pointers in the array are initialized to 0. + * + * The implementation reserves several indices. You should use xalloc to + * obtain an index that is safe to use. Also note that since the array + * can grow dynamically, it is not safe to hold onto the reference. */ - inline void*& + inline void*& pword(int __ix) { - _Words& __word = (__ix < _M_word_size) - ? _M_word[__ix] : _M_grow_words(__ix); + _Words& __word = (__ix < _M_word_size) + ? _M_word[__ix] : _M_grow_words(__ix, false); return __word._M_pword; } // Destructor /** - * Destroys local storage and - * [XXX does something with callbacks]. + * Invokes each callback with erase_event. Destroys local storage. + * + * Note that the ios_base object for the standard streams never gets + * destroyed. As a result, any callbacks registered with the standard + * streams will not get invoked with erase_event (unless copyfmt is + * used). */ - ~ios_base(); + virtual ~ios_base(); protected: ios_base(); -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS - //50. Copy constructor and assignment operator of ios_base + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 50. Copy constructor and assignment operator of ios_base private: ios_base(const ios_base&); - ios_base& + ios_base& operator=(const ios_base&); -#endif }; - + // [27.4.5.1] fmtflags manipulators /// Calls base.setf(ios_base::boolalpha). - inline ios_base& + inline ios_base& boolalpha(ios_base& __base) { __base.setf(ios_base::boolalpha); @@ -682,7 +751,7 @@ namespace std } /// Calls base.unsetf(ios_base::boolalpha). - inline ios_base& + inline ios_base& noboolalpha(ios_base& __base) { __base.unsetf(ios_base::boolalpha); @@ -690,7 +759,7 @@ namespace std } /// Calls base.setf(ios_base::showbase). - inline ios_base& + inline ios_base& showbase(ios_base& __base) { __base.setf(ios_base::showbase); @@ -698,7 +767,7 @@ namespace std } /// Calls base.unsetf(ios_base::showbase). - inline ios_base& + inline ios_base& noshowbase(ios_base& __base) { __base.unsetf(ios_base::showbase); @@ -706,7 +775,7 @@ namespace std } /// Calls base.setf(ios_base::showpoint). - inline ios_base& + inline ios_base& showpoint(ios_base& __base) { __base.setf(ios_base::showpoint); @@ -714,7 +783,7 @@ namespace std } /// Calls base.unsetf(ios_base::showpoint). - inline ios_base& + inline ios_base& noshowpoint(ios_base& __base) { __base.unsetf(ios_base::showpoint); @@ -722,7 +791,7 @@ namespace std } /// Calls base.setf(ios_base::showpos). - inline ios_base& + inline ios_base& showpos(ios_base& __base) { __base.setf(ios_base::showpos); @@ -730,7 +799,7 @@ namespace std } /// Calls base.unsetf(ios_base::showpos). - inline ios_base& + inline ios_base& noshowpos(ios_base& __base) { __base.unsetf(ios_base::showpos); @@ -738,15 +807,15 @@ namespace std } /// Calls base.setf(ios_base::skipws). - inline ios_base& + inline ios_base& skipws(ios_base& __base) { __base.setf(ios_base::skipws); return __base; } - + /// Calls base.unsetf(ios_base::skipws). - inline ios_base& + inline ios_base& noskipws(ios_base& __base) { __base.unsetf(ios_base::skipws); @@ -754,7 +823,7 @@ namespace std } /// Calls base.setf(ios_base::uppercase). - inline ios_base& + inline ios_base& uppercase(ios_base& __base) { __base.setf(ios_base::uppercase); @@ -762,7 +831,7 @@ namespace std } /// Calls base.unsetf(ios_base::uppercase). - inline ios_base& + inline ios_base& nouppercase(ios_base& __base) { __base.unsetf(ios_base::uppercase); @@ -770,57 +839,57 @@ namespace std } /// Calls base.setf(ios_base::unitbuf). - inline ios_base& + inline ios_base& unitbuf(ios_base& __base) { - __base.setf(ios_base::unitbuf); + __base.setf(ios_base::unitbuf); return __base; } /// Calls base.unsetf(ios_base::unitbuf). - inline ios_base& + inline ios_base& nounitbuf(ios_base& __base) { __base.unsetf(ios_base::unitbuf); - return __base; + return __base; } // [27.4.5.2] adjustfield anipulators /// Calls base.setf(ios_base::internal, ios_base::adjustfield). - inline ios_base& + inline ios_base& internal(ios_base& __base) { __base.setf(ios_base::internal, ios_base::adjustfield); - return __base; + return __base; } /// Calls base.setf(ios_base::left, ios_base::adjustfield). - inline ios_base& + inline ios_base& left(ios_base& __base) { __base.setf(ios_base::left, ios_base::adjustfield); return __base; } - + /// Calls base.setf(ios_base::right, ios_base::adjustfield). - inline ios_base& + inline ios_base& right(ios_base& __base) { __base.setf(ios_base::right, ios_base::adjustfield); return __base; } - + // [27.4.5.3] basefield anipulators /// Calls base.setf(ios_base::dec, ios_base::basefield). - inline ios_base& + inline ios_base& dec(ios_base& __base) { __base.setf(ios_base::dec, ios_base::basefield); return __base; } - + /// Calls base.setf(ios_base::hex, ios_base::basefield). - inline ios_base& + inline ios_base& hex(ios_base& __base) { __base.setf(ios_base::hex, ios_base::basefield); @@ -828,16 +897,16 @@ namespace std } /// Calls base.setf(ios_base::oct, ios_base::basefield). - inline ios_base& + inline ios_base& oct(ios_base& __base) { __base.setf(ios_base::oct, ios_base::basefield); return __base; } - + // [27.4.5.4] floatfield anipulators /// Calls base.setf(ios_base::fixed, ios_base::floatfield). - inline ios_base& + inline ios_base& fixed(ios_base& __base) { __base.setf(ios_base::fixed, ios_base::floatfield); @@ -845,14 +914,13 @@ namespace std } /// Calls base.setf(ios_base::scientific, ios_base::floatfield). - inline ios_base& + inline ios_base& scientific(ios_base& __base) { __base.setf(ios_base::scientific, ios_base::floatfield); return __base; } - } // namespace std -#endif /* _CPP_BITS_IOSBASE_H */ +#endif /* _IOS_BASE_H */ diff --git a/contrib/libstdc++/include/bits/istream.tcc b/contrib/libstdc++/include/bits/istream.tcc index ae0c5077e516..6417e951f03a 100644 --- a/contrib/libstdc++/include/bits/istream.tcc +++ b/contrib/libstdc++/include/bits/istream.tcc @@ -1,6 +1,6 @@ // istream classes -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -29,482 +29,409 @@ // the GNU General Public License. // -// ISO C++ 14882: 27.6.2 Output streams +// ISO C++ 14882: 27.6.1 Input streams // +#ifndef _ISTREAM_TCC +#define _ISTREAM_TCC 1 + #pragma GCC system_header #include <locale> #include <ostream> // For flush() -namespace std +namespace std { template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>::sentry:: - sentry(basic_istream<_CharT, _Traits>& __in, bool __noskipws) + sentry(basic_istream<_CharT, _Traits>& __in, bool __noskip) : _M_ok(false) { - if (__in.good()) + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + if (__in.good()) { if (__in.tie()) __in.tie()->flush(); - if (!__noskipws && (__in.flags() & ios_base::skipws)) - { + if (!__noskip && (__in.flags() & ios_base::skipws)) + { const __int_type __eof = traits_type::eof(); __streambuf_type* __sb = __in.rdbuf(); __int_type __c = __sb->sgetc(); - if (__in._M_check_facet(__in._M_fctype)) - while (!traits_type::eq_int_type(__c, __eof) - && __in._M_fctype->is(ctype_base::space, - traits_type::to_char_type(__c))) - __c = __sb->snextc(); + const __ctype_type& __ct = __check_facet(__in._M_ctype); + while (!traits_type::eq_int_type(__c, __eof) + && __ct.is(ctype_base::space, + traits_type::to_char_type(__c))) + __c = __sb->snextc(); -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -//195. Should basic_istream::sentry's constructor ever set eofbit? + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 195. Should basic_istream::sentry's constructor ever + // set eofbit? if (traits_type::eq_int_type(__c, __eof)) - __in.setstate(ios_base::eofbit); -#endif + __err |= ios_base::eofbit; } } - if (__in.good()) + if (__in.good() && __err == ios_base::goodbit) _M_ok = true; else { - _M_ok = false; - __in.setstate(ios_base::failbit); + __err |= ios_base::failbit; + __in.setstate(__err); } } template<typename _CharT, typename _Traits> - basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(__istream_type& (*__pf)(__istream_type&)) - { - __pf(*this); - return *this; - } + { return __pf(*this); } template<typename _CharT, typename _Traits> - basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(__ios_type& (*__pf)(__ios_type&)) { __pf(*this); return *this; } - + template<typename _CharT, typename _Traits> - basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(ios_base& (*__pf)(ios_base&)) { __pf(*this); return *this; } - + template<typename _CharT, typename _Traits> - basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(bool& __n) { sentry __cerb(*this, false); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); - if (_M_check_facet(_M_fnumget)) - _M_fnumget->get(*this, 0, *this, __err, __n); - this->setstate(__err); + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> - basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(short& __n) { sentry __cerb(*this, false); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); long __l; - if (_M_check_facet(_M_fnumget)) - _M_fnumget->get(*this, 0, *this, __err, __l); -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __l); + // _GLIBCXX_RESOLVE_LIB_DEFECTS // 118. basic_istream uses nonexistent num_get member functions. if (!(__err & ios_base::failbit) - && (numeric_limits<short>::min() <= __l + && (numeric_limits<short>::min() <= __l && __l <= numeric_limits<short>::max())) __n = __l; else __err |= ios_base::failbit; -#endif - this->setstate(__err); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> - basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(unsigned short& __n) { sentry __cerb(*this, false); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); - if (_M_check_facet(_M_fnumget)) - _M_fnumget->get(*this, 0, *this, __err, __n); - this->setstate(__err); + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> - basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(int& __n) { sentry __cerb(*this, false); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); long __l; - if (_M_check_facet(_M_fnumget)) - _M_fnumget->get(*this, 0, *this, __err, __l); -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __l); + // _GLIBCXX_RESOLVE_LIB_DEFECTS // 118. basic_istream uses nonexistent num_get member functions. if (!(__err & ios_base::failbit) - && (numeric_limits<int>::min() <= __l + && (numeric_limits<int>::min() <= __l && __l <= numeric_limits<int>::max())) __n = __l; else __err |= ios_base::failbit; -#endif - this->setstate(__err); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> - basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(unsigned int& __n) { sentry __cerb(*this, false); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); - if (_M_check_facet(_M_fnumget)) - _M_fnumget->get(*this, 0, *this, __err, __n); - this->setstate(__err); + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> - basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(long& __n) { sentry __cerb(*this, false); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); - if (_M_check_facet(_M_fnumget)) - _M_fnumget->get(*this, 0, *this, __err, __n); - this->setstate(__err); + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> - basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(unsigned long& __n) { sentry __cerb(*this, false); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); - if (_M_check_facet(_M_fnumget)) - _M_fnumget->get(*this, 0, *this, __err, __n); - this->setstate(__err); + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } -#ifdef _GLIBCPP_USE_LONG_LONG +#ifdef _GLIBCXX_USE_LONG_LONG template<typename _CharT, typename _Traits> - basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(long long& __n) { sentry __cerb(*this, false); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); - if (_M_check_facet(_M_fnumget)) - _M_fnumget->get(*this, 0, *this, __err, __n); - this->setstate(__err); + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> - basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(unsigned long long& __n) { sentry __cerb(*this, false); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); - if (_M_check_facet(_M_fnumget)) - _M_fnumget->get(*this, 0, *this, __err, __n); - this->setstate(__err); + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } #endif template<typename _CharT, typename _Traits> - basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(float& __n) { sentry __cerb(*this, false); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); - if (_M_check_facet(_M_fnumget)) - _M_fnumget->get(*this, 0, *this, __err, __n); - this->setstate(__err); + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> - basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(double& __n) { sentry __cerb(*this, false); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); - if (_M_check_facet(_M_fnumget)) - _M_fnumget->get(*this, 0, *this, __err, __n); - this->setstate(__err); + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> - basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(long double& __n) { sentry __cerb(*this, false); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); - if (_M_check_facet(_M_fnumget)) - _M_fnumget->get(*this, 0, *this, __err, __n); - this->setstate(__err); + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> - basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(void*& __n) { sentry __cerb(*this, false); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); - if (_M_check_facet(_M_fnumget)) - _M_fnumget->get(*this, 0, *this, __err, __n); - this->setstate(__err); + const __num_get_type& __ng = __check_facet(this->_M_num_get); + __ng.get(*this, 0, *this, __err, __n); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> - basic_istream<_CharT, _Traits>& + basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(__streambuf_type* __sbout) { - sentry __cerb(*this, false); - if (__cerb) - { - try - { - streamsize __xtrct = 0; - if (__sbout) - { - __streambuf_type* __sbin = this->rdbuf(); - __xtrct = __copy_streambufs(*this, __sbin, __sbout); - } - if (!__sbout || !__xtrct) - this->setstate(ios_base::failbit); - } - catch(...) - { - // 27.6.2.5.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } - } - return *this; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + sentry __cerb(*this, false); + if (__cerb && __sbout) + { + try + { + if (!__copy_streambufs(this->rdbuf(), __sbout)) + __err |= ios_base::failbit; + } + catch(...) + { this->_M_setstate(ios_base::failbit); } + } + else if (!__sbout) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); + return *this; } template<typename _CharT, typename _Traits> @@ -515,27 +442,26 @@ namespace std const int_type __eof = traits_type::eof(); int_type __c = __eof; _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); sentry __cerb(*this, true); - if (__cerb) + if (__cerb) { - try + try { __c = this->rdbuf()->sbumpc(); // 27.6.1.1 paragraph 3 if (!traits_type::eq_int_type(__c, __eof)) _M_gcount = 1; else - this->setstate(ios_base::eofbit | ios_base::failbit); + __err |= ios_base::eofbit; } catch(...) - { - // 27.6.1.3 paragraph 1 - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } } + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); return __c; } @@ -545,31 +471,29 @@ namespace std get(char_type& __c) { _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); sentry __cerb(*this, true); - if (__cerb) + if (__cerb) { - try + try { - const int_type __eof = traits_type::eof(); - int_type __bufval = this->rdbuf()->sbumpc(); + const int_type __cb = this->rdbuf()->sbumpc(); // 27.6.1.1 paragraph 3 - if (!traits_type::eq_int_type(__bufval, __eof)) + if (!traits_type::eq_int_type(__cb, traits_type::eof())) { _M_gcount = 1; - __c = traits_type::to_char_type(__bufval); + __c = traits_type::to_char_type(__cb); } else - this->setstate(ios_base::eofbit | ios_base::failbit); + __err |= ios_base::eofbit; } catch(...) - { - // 27.6.1.3 paragraph 1 - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } } + if (!_M_gcount) + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); return *this; } @@ -579,39 +503,36 @@ namespace std get(char_type* __s, streamsize __n, char_type __delim) { _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); sentry __cerb(*this, true); - if (__cerb) + if (__cerb) { - try + try { const int_type __idelim = traits_type::to_int_type(__delim); const int_type __eof = traits_type::eof(); __streambuf_type* __sb = this->rdbuf(); - int_type __c = __sb->sgetc(); - - while (_M_gcount + 1 < __n + int_type __c = __sb->sgetc(); + + while (_M_gcount + 1 < __n && !traits_type::eq_int_type(__c, __eof) && !traits_type::eq_int_type(__c, __idelim)) { *__s++ = traits_type::to_char_type(__c); - __c = __sb->snextc(); ++_M_gcount; + __c = __sb->snextc(); } if (traits_type::eq_int_type(__c, __eof)) - this->setstate(ios_base::eofbit); + __err |= ios_base::eofbit; } catch(...) - { - // 27.6.1.3 paragraph 1 - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } } *__s = char_type(); if (!_M_gcount) - this->setstate(ios_base::failbit); + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); return *this; } @@ -621,19 +542,20 @@ namespace std get(__streambuf_type& __sb, char_type __delim) { _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); sentry __cerb(*this, true); - if (__cerb) + if (__cerb) { - try + try { const int_type __idelim = traits_type::to_int_type(__delim); - const int_type __eof = traits_type::eof(); + const int_type __eof = traits_type::eof(); __streambuf_type* __this_sb = this->rdbuf(); int_type __c = __this_sb->sgetc(); char_type __c2 = traits_type::to_char_type(__c); - - while (!traits_type::eq_int_type(__c, __eof) - && !traits_type::eq_int_type(__c, __idelim) + + while (!traits_type::eq_int_type(__c, __eof) + && !traits_type::eq_int_type(__c, __idelim) && !traits_type::eq_int_type(__sb.sputc(__c2), __eof)) { ++_M_gcount; @@ -641,19 +563,15 @@ namespace std __c2 = traits_type::to_char_type(__c); } if (traits_type::eq_int_type(__c, __eof)) - this->setstate(ios_base::eofbit); + __err |= ios_base::eofbit; } catch(...) - { - // 27.6.1.3 paragraph 1 - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } } if (!_M_gcount) - this->setstate(ios_base::failbit); + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); return *this; } @@ -663,52 +581,66 @@ namespace std getline(char_type* __s, streamsize __n, char_type __delim) { _M_gcount = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); sentry __cerb(*this, true); - if (__cerb) + if (__cerb) { - try + try { const int_type __idelim = traits_type::to_int_type(__delim); const int_type __eof = traits_type::eof(); __streambuf_type* __sb = this->rdbuf(); int_type __c = __sb->sgetc(); - - while (_M_gcount + 1 < __n + + while (_M_gcount + 1 < __n && !traits_type::eq_int_type(__c, __eof) && !traits_type::eq_int_type(__c, __idelim)) { - *__s++ = traits_type::to_char_type(__c); - __c = __sb->snextc(); - ++_M_gcount; - } - if (traits_type::eq_int_type(__c, __eof)) - this->setstate(ios_base::eofbit); - else - { - if (traits_type::eq_int_type(__c, __idelim)) + streamsize __size = std::min(streamsize(__sb->egptr() + - __sb->gptr()), + __n - _M_gcount - 1); + if (__size > 1) { - __sb->sbumpc(); - ++_M_gcount; + const char_type* __p = traits_type::find(__sb->gptr(), + __size, + __delim); + if (__p) + __size = __p - __sb->gptr(); + traits_type::copy(__s, __sb->gptr(), __size); + __s += __size; + __sb->gbump(__size); + _M_gcount += __size; + __c = __sb->sgetc(); } else - this->setstate(ios_base::failbit); + { + *__s++ = traits_type::to_char_type(__c); + ++_M_gcount; + __c = __sb->snextc(); + } } + + if (traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (traits_type::eq_int_type(__c, __idelim)) + { + ++_M_gcount; + __sb->sbumpc(); + } + else + __err |= ios_base::failbit; } catch(...) - { - // 27.6.1.3 paragraph 1 - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } } *__s = char_type(); if (!_M_gcount) - this->setstate(ios_base::failbit); + __err |= ios_base::failbit; + if (__err) + this->setstate(__err); return *this; } - + template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: @@ -716,16 +648,18 @@ namespace std { _M_gcount = 0; sentry __cerb(*this, true); - if (__cerb && __n > 0) + if (__cerb && __n > 0) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { const int_type __eof = traits_type::eof(); __streambuf_type* __sb = this->rdbuf(); int_type __c; - - __n = min(__n, numeric_limits<streamsize>::max()); - while (_M_gcount < __n + + if (__n != numeric_limits<streamsize>::max()) + --__n; + while (_M_gcount <= __n && !traits_type::eq_int_type(__c = __sb->sbumpc(), __eof)) { ++_M_gcount; @@ -733,20 +667,16 @@ namespace std break; } if (traits_type::eq_int_type(__c, __eof)) - this->setstate(ios_base::eofbit); + __err |= ios_base::eofbit; } catch(...) - { - // 27.6.1.3 paragraph 1 - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } - + template<typename _CharT, typename _Traits> typename basic_istream<_CharT, _Traits>::int_type basic_istream<_CharT, _Traits>:: @@ -757,21 +687,18 @@ namespace std sentry __cerb(*this, true); if (__cerb) { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); try { __c = this->rdbuf()->sgetc(); if (traits_type::eq_int_type(__c, traits_type::eof())) - this->setstate(ios_base::eofbit); + __err |= ios_base::eofbit; } catch(...) - { - // 27.6.1.3 paragraph 1 - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); + } return __c; } @@ -782,195 +709,180 @@ namespace std { _M_gcount = 0; sentry __cerb(*this, true); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { _M_gcount = this->rdbuf()->sgetn(__s, __n); if (_M_gcount != __n) - this->setstate(ios_base::eofbit | ios_base::failbit); - } - catch(...) - { - // 27.6.1.3 paragraph 1 - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; + __err |= (ios_base::eofbit | ios_base::failbit); } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } - else - this->setstate(ios_base::failbit); return *this; } - + template<typename _CharT, typename _Traits> - streamsize + streamsize basic_istream<_CharT, _Traits>:: readsome(char_type* __s, streamsize __n) { _M_gcount = 0; sentry __cerb(*this, true); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { // Cannot compare int_type with streamsize generically. - streamsize __num = this->rdbuf()->in_avail(); - if (__num >= 0) - { - __num = min(__num, __n); - if (__num) - _M_gcount = this->rdbuf()->sgetn(__s, __num); - } - else - this->setstate(ios_base::eofbit); + const streamsize __num = this->rdbuf()->in_avail(); + if (__num > 0) + _M_gcount = this->rdbuf()->sgetn(__s, std::min(__num, __n)); + else if (__num == -1) + __err |= ios_base::eofbit; } catch(...) - { - // 27.6.1.3 paragraph 1 - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } - else - this->setstate(ios_base::failbit); return _M_gcount; } - + template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: putback(char_type __c) { -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -// 60. What is a formatted input function? + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 60. What is a formatted input function? _M_gcount = 0; -#endif sentry __cerb(*this, true); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { const int_type __eof = traits_type::eof(); __streambuf_type* __sb = this->rdbuf(); - if (!__sb + if (!__sb || traits_type::eq_int_type(__sb->sputbackc(__c), __eof)) - this->setstate(ios_base::badbit); + __err |= ios_base::badbit; } catch(...) - { - // 27.6.1.3 paragraph 1 - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } - else - this->setstate(ios_base::failbit); return *this; } - + template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: unget(void) { -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -// 60. What is a formatted input function? + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 60. What is a formatted input function? _M_gcount = 0; -#endif sentry __cerb(*this, true); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { const int_type __eof = traits_type::eof(); __streambuf_type* __sb = this->rdbuf(); - if (!__sb + if (!__sb || traits_type::eq_int_type(__sb->sungetc(), __eof)) - this->setstate(ios_base::badbit); + __err |= ios_base::badbit; } catch(...) - { - // 27.6.1.3 paragraph 1 - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } - else - this->setstate(ios_base::failbit); return *this; } - + template<typename _CharT, typename _Traits> int basic_istream<_CharT, _Traits>:: sync(void) { + // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR60. Do not change _M_gcount. int __ret = -1; sentry __cerb(*this, true); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { __streambuf_type* __sb = this->rdbuf(); if (__sb) { if (__sb->pubsync() == -1) - this->setstate(ios_base::badbit); - else + __err |= ios_base::badbit; + else __ret = 0; } } catch(...) - { - // 27.6.1.3 paragraph 1 - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return __ret; } - + template<typename _CharT, typename _Traits> typename basic_istream<_CharT, _Traits>::pos_type basic_istream<_CharT, _Traits>:: tellg(void) { + // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR60. Do not change _M_gcount. pos_type __ret = pos_type(-1); - if (!this->fail()) - __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in); + try + { + if (!this->fail()) + __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } return __ret; } - template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: seekg(pos_type __pos) { + // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR60. Do not change _M_gcount. - if (!this->fail()) + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -// 136. seekp, seekg setting wrong streams? - pos_type __err = this->rdbuf()->pubseekpos(__pos, ios_base::in); + if (!this->fail()) + { + // 136. seekp, seekg setting wrong streams? + const pos_type __p = this->rdbuf()->pubseekpos(__pos, + ios_base::in); -// 129. Need error indication from seekp() and seekg() - if (__err == pos_type(off_type(-1))) - this->setstate(ios_base::failbit); -#endif + // 129. Need error indication from seekp() and seekg() + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); return *this; } @@ -979,19 +891,26 @@ namespace std basic_istream<_CharT, _Traits>:: seekg(off_type __off, ios_base::seekdir __dir) { + // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR60. Do not change _M_gcount. - if (!this->fail()) + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -// 136. seekp, seekg setting wrong streams? - pos_type __err = this->rdbuf()->pubseekoff(__off, __dir, - ios_base::in); - -// 129. Need error indication from seekp() and seekg() - if (__err == pos_type(off_type(-1))) - this->setstate(ios_base::failbit); -#endif + if (!this->fail()) + { + // 136. seekp, seekg setting wrong streams? + const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, + ios_base::in); + + // 129. Need error indication from seekp() and seekg() + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); return *this; } @@ -1000,23 +919,26 @@ namespace std basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c) { - typedef basic_istream<_CharT, _Traits> __istream_type; + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; + typename __istream_type::sentry __cerb(__in, false); if (__cerb) { - try - { __in.get(__c); } - catch(...) + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - __in._M_setstate(ios_base::badbit); - if ((__in.exceptions() & ios_base::badbit) != 0) - __throw_exception_again; + const __int_type __cb = __in.rdbuf()->sbumpc(); + if (!_Traits::eq_int_type(__cb, _Traits::eof())) + __c = _Traits::to_char_type(__cb); + else + __err |= (ios_base::eofbit | ios_base::failbit); } + catch(...) + { __in._M_setstate(ios_base::badbit); } + if (__err) + __in.setstate(__err); } - else - __in.setstate(ios_base::failbit); return __in; } @@ -1024,81 +946,78 @@ namespace std basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s) { - typedef basic_istream<_CharT, _Traits> __istream_type; + typedef basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::__streambuf_type __streambuf_type; - typedef typename _Traits::int_type int_type; - typedef _CharT char_type; - typedef ctype<_CharT> __ctype_type; - streamsize __extracted = 0; + typedef typename _Traits::int_type int_type; + typedef _CharT char_type; + typedef ctype<_CharT> __ctype_type; + streamsize __extracted = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); typename __istream_type::sentry __cerb(__in, false); if (__cerb) { - try + try { // Figure out how many characters to extract. streamsize __num = __in.width(); if (__num <= 0) __num = numeric_limits<streamsize>::max(); - - const __ctype_type& __ctype = use_facet<__ctype_type>(__in.getloc()); + + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + const int_type __eof = _Traits::eof(); __streambuf_type* __sb = __in.rdbuf(); int_type __c = __sb->sgetc(); - - while (__extracted < __num - 1 + + while (__extracted < __num - 1 && !_Traits::eq_int_type(__c, __eof) - && !__ctype.is(ctype_base::space, _Traits::to_char_type(__c))) + && !__ct.is(ctype_base::space, + _Traits::to_char_type(__c))) { *__s++ = _Traits::to_char_type(__c); ++__extracted; __c = __sb->snextc(); } if (_Traits::eq_int_type(__c, __eof)) - __in.setstate(ios_base::eofbit); + __err |= ios_base::eofbit; -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -//68. Extractors for char* should store null at end + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 68. Extractors for char* should store null at end *__s = char_type(); -#endif __in.width(0); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - __in._M_setstate(ios_base::badbit); - if ((__in.exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { __in._M_setstate(ios_base::badbit); } } if (!__extracted) - __in.setstate(ios_base::failbit); + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); return __in; } // 27.6.1.4 Standard basic_istream manipulators template<typename _CharT, typename _Traits> - basic_istream<_CharT,_Traits>& + basic_istream<_CharT,_Traits>& ws(basic_istream<_CharT,_Traits>& __in) { - typedef basic_istream<_CharT, _Traits> __istream_type; + typedef basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::__streambuf_type __streambuf_type; - typedef typename __istream_type::__ctype_type __ctype_type; - typedef typename __istream_type::int_type __int_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef typename __istream_type::int_type __int_type; - const __ctype_type& __ctype = use_facet<__ctype_type>(__in.getloc()); - const __int_type __eof = _Traits::eof(); + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + const __int_type __eof = _Traits::eof(); __streambuf_type* __sb = __in.rdbuf(); __int_type __c = __sb->sgetc(); - while (!_Traits::eq_int_type(__c, __eof) - && __ctype.is(ctype_base::space, _Traits::to_char_type(__c))) + while (!_Traits::eq_int_type(__c, __eof) + && __ct.is(ctype_base::space, _Traits::to_char_type(__c))) __c = __sb->snextc(); if (_Traits::eq_int_type(__c, __eof)) - __in.setstate(ios_base::eofbit); - + __in.setstate(ios_base::eofbit); return __in; } @@ -1108,44 +1027,64 @@ namespace std operator>>(basic_istream<_CharT, _Traits>& __in, basic_string<_CharT, _Traits, _Alloc>& __str) { - typedef basic_istream<_CharT, _Traits> __istream_type; - typedef typename __istream_type::int_type __int_type; + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; typedef typename __istream_type::__streambuf_type __streambuf_type; - typedef typename __istream_type::__ctype_type __ctype_type; - typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; typedef typename __string_type::size_type __size_type; - __size_type __extracted = 0; + __size_type __extracted = 0; + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); typename __istream_type::sentry __cerb(__in, false); - if (__cerb) + if (__cerb) { - __str.erase(); - streamsize __w = __in.width(); - __size_type __n; - __n = __w > 0 ? static_cast<__size_type>(__w) : __str.max_size(); - - const __ctype_type& __ctype = use_facet<__ctype_type>(__in.getloc()); - const __int_type __eof = _Traits::eof(); - __streambuf_type* __sb = __in.rdbuf(); - __int_type __c = __sb->sgetc(); - - while (__extracted < __n - && !_Traits::eq_int_type(__c, __eof) - && !__ctype.is(ctype_base::space, _Traits::to_char_type(__c))) + try { - __str += _Traits::to_char_type(__c); - ++__extracted; - __c = __sb->snextc(); + // Avoid reallocation for common case. + __str.erase(); + _CharT __buf[128]; + __size_type __len = 0; + const streamsize __w = __in.width(); + const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) + : __str.max_size(); + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + const __int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !_Traits::eq_int_type(__c, __eof) + && !__ct.is(ctype_base::space, _Traits::to_char_type(__c))) + { + if (__len == sizeof(__buf) / sizeof(_CharT)) + { + __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); + __len = 0; + } + __buf[__len++] = _Traits::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + __str.append(__buf, __len); + + if (_Traits::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + __in.width(0); + } + catch(...) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 91. Description of operator>> and getline() for string<> + // might cause endless loop + __in._M_setstate(ios_base::badbit); } - if (_Traits::eq_int_type(__c, __eof)) - __in.setstate(ios_base::eofbit); - __in.width(0); } -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -//211. operator>>(istream&, string&) doesn't set failbit + // 211. operator>>(istream&, string&) doesn't set failbit if (!__extracted) - __in.setstate (ios_base::failbit); -#endif + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); return __in; } @@ -1154,54 +1093,80 @@ namespace std getline(basic_istream<_CharT, _Traits>& __in, basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim) { - typedef basic_istream<_CharT, _Traits> __istream_type; - typedef typename __istream_type::int_type __int_type; + typedef basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::int_type __int_type; typedef typename __istream_type::__streambuf_type __streambuf_type; - typedef typename __istream_type::__ctype_type __ctype_type; - typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __istream_type::__ctype_type __ctype_type; + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; typedef typename __string_type::size_type __size_type; __size_type __extracted = 0; - bool __testdelim = false; + const __size_type __n = __str.max_size(); + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); typename __istream_type::sentry __cerb(__in, true); - if (__cerb) + if (__cerb) { - __str.erase(); - __size_type __n = __str.max_size(); - - __int_type __idelim = _Traits::to_int_type(__delim); - __streambuf_type* __sb = __in.rdbuf(); - __int_type __c = __sb->sbumpc(); - const __int_type __eof = _Traits::eof(); - __testdelim = _Traits::eq_int_type(__c, __idelim); - - while (__extracted <= __n - && !_Traits::eq_int_type(__c, __eof) - && !__testdelim) + try + { + // Avoid reallocation for common case. + __str.erase(); + _CharT __buf[128]; + __size_type __len = 0; + const __int_type __idelim = _Traits::to_int_type(__delim); + const __int_type __eof = _Traits::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !_Traits::eq_int_type(__c, __eof) + && !_Traits::eq_int_type(__c, __idelim)) + { + if (__len == sizeof(__buf) / sizeof(_CharT)) + { + __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); + __len = 0; + } + __buf[__len++] = _Traits::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + __str.append(__buf, __len); + + if (_Traits::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (_Traits::eq_int_type(__c, __idelim)) + { + ++__extracted; + __sb->sbumpc(); + } + else + __err |= ios_base::failbit; + } + catch(...) { - __str += _Traits::to_char_type(__c); - ++__extracted; - __c = __sb->sbumpc(); - __testdelim = _Traits::eq_int_type(__c, __idelim); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 91. Description of operator>> and getline() for string<> + // might cause endless loop + __in._M_setstate(ios_base::badbit); } - if (_Traits::eq_int_type(__c, __eof)) - __in.setstate(ios_base::eofbit); } - if (!__extracted && !__testdelim) - __in.setstate(ios_base::failbit); + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); return __in; } template<class _CharT, class _Traits, class _Alloc> inline basic_istream<_CharT,_Traits>& - getline(basic_istream<_CharT, _Traits>& __in, + getline(basic_istream<_CharT, _Traits>& __in, basic_string<_CharT,_Traits,_Alloc>& __str) { return getline(__in, __str, __in.widen('\n')); } // Inhibit implicit instantiations for required instantiations, - // which are defined via explicit instantiations elsewhere. + // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. -#if _GLIBCPP_EXTERN_TEMPLATE +#if _GLIBCXX_EXTERN_TEMPLATE extern template class basic_istream<char>; extern template istream& ws(istream&); extern template istream& operator>>(istream&, char&); @@ -1211,7 +1176,7 @@ namespace std extern template istream& operator>>(istream&, unsigned char*); extern template istream& operator>>(istream&, signed char*); -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T extern template class basic_istream<wchar_t>; extern template wistream& ws(wistream&); extern template wistream& operator>>(wistream&, wchar_t&); @@ -1219,3 +1184,5 @@ namespace std #endif #endif } // namespace std + +#endif diff --git a/contrib/libstdc++/include/bits/list.tcc b/contrib/libstdc++/include/bits/list.tcc index 898a5020c23b..aaaa8c364bdf 100644 --- a/contrib/libstdc++/include/bits/list.tcc +++ b/contrib/libstdc++/include/bits/list.tcc @@ -1,6 +1,6 @@ // List implementation (out of line) -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,57 +58,47 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_LIST_TCC -#define __GLIBCPP_INTERNAL_LIST_TCC +#ifndef _LIST_TCC +#define _LIST_TCC 1 -namespace std +namespace _GLIBCXX_STD { template<typename _Tp, typename _Alloc> void _List_base<_Tp,_Alloc>:: - __clear() + _M_clear() { typedef _List_node<_Tp> _Node; - _Node* __cur = static_cast<_Node*>(_M_node->_M_next); - while (__cur != _M_node) + _Node* __cur = static_cast<_Node*>(this->_M_impl._M_node._M_next); + while (__cur != &this->_M_impl._M_node) { _Node* __tmp = __cur; __cur = static_cast<_Node*>(__cur->_M_next); - _Destroy(&__tmp->_M_data); + std::_Destroy(&__tmp->_M_data); _M_put_node(__tmp); } - _M_node->_M_next = _M_node; - _M_node->_M_prev = _M_node; } - + template<typename _Tp, typename _Alloc> typename list<_Tp,_Alloc>::iterator list<_Tp,_Alloc>:: insert(iterator __position, const value_type& __x) { _Node* __tmp = _M_create_node(__x); - __tmp->_M_next = __position._M_node; - __tmp->_M_prev = __position._M_node->_M_prev; - __position._M_node->_M_prev->_M_next = __tmp; - __position._M_node->_M_prev = __tmp; + __tmp->hook(__position._M_node); return __tmp; } - + template<typename _Tp, typename _Alloc> typename list<_Tp,_Alloc>::iterator list<_Tp,_Alloc>:: erase(iterator __position) { - _List_node_base* __next_node = __position._M_node->_M_next; - _List_node_base* __prev_node = __position._M_node->_M_prev; - _Node* __n = static_cast<_Node*>(__position._M_node); - __prev_node->_M_next = __next_node; - __next_node->_M_prev = __prev_node; - _Destroy(&__n->_M_data); - _M_put_node(__n); - return iterator(static_cast<_Node*>(__next_node)); + iterator __ret = __position._M_node->_M_next; + _M_erase(__position); + return __ret; } - + template<typename _Tp, typename _Alloc> void list<_Tp,_Alloc>:: @@ -123,28 +113,28 @@ namespace std else // __i == end() insert(end(), __new_size - __len, __x); } - + template<typename _Tp, typename _Alloc> list<_Tp,_Alloc>& list<_Tp,_Alloc>:: operator=(const list& __x) { if (this != &__x) - { - iterator __first1 = begin(); - iterator __last1 = end(); - const_iterator __first2 = __x.begin(); - const_iterator __last2 = __x.end(); - while (__first1 != __last1 && __first2 != __last2) - *__first1++ = *__first2++; - if (__first2 == __last2) - erase(__first1, __last1); - else - insert(__last1, __first2, __last2); - } + { + iterator __first1 = begin(); + iterator __last1 = end(); + const_iterator __first2 = __x.begin(); + const_iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + *__first1++ = *__first2++; + if (__first2 == __last2) + erase(__first1, __last1); + else + insert(__last1, __first2, __last2); + } return *this; } - + template<typename _Tp, typename _Alloc> void list<_Tp,_Alloc>:: @@ -158,23 +148,25 @@ namespace std else erase(__i, end()); } - + template<typename _Tp, typename _Alloc> - template <typename _InputIter> + template <typename _InputIterator> void list<_Tp,_Alloc>:: - _M_assign_dispatch(_InputIter __first2, _InputIter __last2, __false_type) + _M_assign_dispatch(_InputIterator __first2, _InputIterator __last2, + __false_type) { iterator __first1 = begin(); iterator __last1 = end(); - for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) + for (; __first1 != __last1 && __first2 != __last2; + ++__first1, ++__first2) *__first1 = *__first2; if (__first2 == __last2) erase(__first1, __last1); else insert(__last1, __first2, __last2); } - + template<typename _Tp, typename _Alloc> void list<_Tp,_Alloc>:: @@ -187,11 +179,11 @@ namespace std iterator __next = __first; ++__next; if (*__first == __value) - erase(__first); + _M_erase(__first); __first = __next; } } - + template<typename _Tp, typename _Alloc> void list<_Tp,_Alloc>:: @@ -199,81 +191,83 @@ namespace std { iterator __first = begin(); iterator __last = end(); - if (__first == __last) return; + if (__first == __last) + return; iterator __next = __first; while (++__next != __last) { if (*__first == *__next) - erase(__next); + _M_erase(__next); else __first = __next; __next = __first; } } - + template<typename _Tp, typename _Alloc> void list<_Tp,_Alloc>:: merge(list& __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; - _M_transfer(__first1, __first2, ++__next); - __first2 = __next; - } - else - ++__first1; - if (__first2 != __last2) - _M_transfer(__last1, __first2, __last2); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 300. list::merge() specification incomplete + if (this != &__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; + _M_transfer(__first1, __first2, ++__next); + __first2 = __next; + } + else + ++__first1; + if (__first2 != __last2) + _M_transfer(__last1, __first2, __last2); + } } - - // FIXME put this somewhere else - inline void - __List_base_reverse(_List_node_base* __p) - { - _List_node_base* __tmp = __p; - do { - std::swap(__tmp->_M_next, __tmp->_M_prev); - __tmp = __tmp->_M_prev; // Old next node is now prev. - } while (__tmp != __p); - } - + template<typename _Tp, typename _Alloc> void list<_Tp,_Alloc>:: sort() { // Do nothing if the list has length 0 or 1. - if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) + if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node + && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node) { list __carry; - list __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]); + list __tmp[64]; + list * __fill = &__tmp[0]; + list * __counter; + + do + { + __carry.splice(__carry.begin(), *this, begin()); + + for(__counter = &__tmp[0]; + (__counter != __fill) && !__counter->empty(); + ++__counter) + { + __counter->merge(__carry); + __carry.swap(*__counter); + } + __carry.swap(*__counter); + if (__counter == __fill) + ++__fill; + } + while ( !empty() ); + + for (__counter = &__tmp[1]; __counter != __fill; ++__counter) + __counter->merge( *(__counter-1) ); + swap( *(__fill-1) ); } } - + template<typename _Tp, typename _Alloc> template <typename _Predicate> void @@ -286,11 +280,12 @@ namespace std { iterator __next = __first; ++__next; - if (__pred(*__first)) erase(__first); + if (__pred(*__first)) + _M_erase(__first); __first = __next; } } - + template<typename _Tp, typename _Alloc> template <typename _BinaryPredicate> void @@ -304,65 +299,79 @@ namespace std while (++__next != __last) { if (__binary_pred(*__first, *__next)) - erase(__next); + _M_erase(__next); else __first = __next; __next = __first; } } - + template<typename _Tp, typename _Alloc> template <typename _StrictWeakOrdering> void list<_Tp,_Alloc>:: merge(list& __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; - _M_transfer(__first1, __first2, ++__next); - __first2 = __next; - } - else - ++__first1; - if (__first2 != __last2) _M_transfer(__last1, __first2, __last2); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 300. list::merge() specification incomplete + if (this != &__x) + { + 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; + _M_transfer(__first1, __first2, ++__next); + __first2 = __next; + } + else + ++__first1; + if (__first2 != __last2) + _M_transfer(__last1, __first2, __last2); + } } - + template<typename _Tp, typename _Alloc> template <typename _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 && _M_node->_M_next->_M_next != _M_node) + void + list<_Tp,_Alloc>:: + sort(_StrictWeakOrdering __comp) { - list __carry; - list __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]); + // Do nothing if the list has length 0 or 1. + if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node + && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node) + { + list __carry; + list __tmp[64]; + list * __fill = &__tmp[0]; + list * __counter; + + do + { + __carry.splice(__carry.begin(), *this, begin()); + + for(__counter = &__tmp[0]; + (__counter != __fill) && !__counter->empty(); + ++__counter) + { + __counter->merge(__carry, __comp); + __carry.swap(*__counter); + } + __carry.swap(*__counter); + if (__counter == __fill) + ++__fill; + } + while ( !empty() ); + + for (__counter = &__tmp[1]; __counter != __fill; ++__counter) + __counter->merge( *(__counter-1), __comp ); + swap( *(__fill-1) ); + } } - } } // namespace std -#endif /* __GLIBCPP_INTERNAL_LIST_TCC */ +#endif /* _LIST_TCC */ + diff --git a/contrib/libstdc++/include/bits/locale_classes.h b/contrib/libstdc++/include/bits/locale_classes.h index ddd23fb9726a..95d9c0366a0b 100644 --- a/contrib/libstdc++/include/bits/locale_classes.h +++ b/contrib/libstdc++/include/bits/locale_classes.h @@ -1,6 +1,6 @@ // Locale support -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -37,8 +37,8 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_LOCALE_CLASSES_H -#define _CPP_BITS_LOCALE_CLASSES_H 1 +#ifndef _LOCALE_CLASSES_H +#define _LOCALE_CLASSES_H 1 #pragma GCC system_header @@ -46,18 +46,30 @@ #include <cstring> // For strcmp. #include <string> #include <bits/atomicity.h> +#include <bits/gthr.h> namespace std { - class __locale_cache_base; - template<typename _Facet> class __locale_cache; - // 22.1.1 Class locale + /** + * @brief Container class for localization functionality. + * + * The locale class is first a class wrapper for C library locales. It is + * also an extensible container for user-defined localization. A locale is + * a collection of facets that implement various localization features such + * as money, time, and number printing. + * + * Constructing C++ locales does not change the C library locale. + * + * This library supports efficient construction and copying of locales + * through a reference counting implementation of the locale class. + */ class locale { public: // Types: - typedef unsigned int category; + /// Definition of locale::category. + typedef int category; // Forward decls and friends: class facet; @@ -68,118 +80,249 @@ namespace std friend class _Impl; template<typename _Facet> - friend const _Facet& - use_facet(const locale&); - - template<typename _Facet> - friend bool + friend bool has_facet(const locale&) throw(); - + template<typename _Facet> - friend const __locale_cache<_Facet>& - __use_cache(const locale&); + friend const _Facet& + use_facet(const locale&); - // Category values: - // NB: Order must match _S_facet_categories definition in locale.cc + template<typename _Cache> + friend struct __use_cache; + + //@{ + /** + * @brief Category values. + * + * The standard category values are none, ctype, numeric, collate, time, + * monetary, and messages. They form a bitmask that supports union and + * intersection. The category all is the union of these values. + * + * @if maint + * NB: Order must match _S_facet_categories definition in locale.cc + * @endif + */ static const category none = 0; - static const category ctype = 1L << 0; - static const category numeric = 1L << 1; - static const category collate = 1L << 2; - static const category time = 1L << 3; - static const category monetary = 1L << 4; - static const category messages = 1L << 5; - static const category all = (ctype | numeric | collate | - time | monetary | messages); + static const category ctype = 1L << 0; + static const category numeric = 1L << 1; + static const category collate = 1L << 2; + static const category time = 1L << 3; + static const category monetary = 1L << 4; + static const category messages = 1L << 5; + static const category all = (ctype | numeric | collate | + time | monetary | messages); + //@} // Construct/copy/destroy: + + /** + * @brief Default constructor. + * + * Constructs a copy of the global locale. If no locale has been + * explicitly set, this is the "C" locale. + */ locale() throw(); + /** + * @brief Copy constructor. + * + * Constructs a copy of @a other. + * + * @param other The locale to copy. + */ locale(const locale& __other) throw(); - explicit + /** + * @brief Named locale constructor. + * + * Constructs a copy of the named C library locale. + * + * @param s Name of the locale to construct. + * @throw std::runtime_error if s is null or an undefined locale. + */ + explicit locale(const char* __s); + /** + * @brief Construct locale with facets from another locale. + * + * Constructs a copy of the locale @a base. The facets specified by @a + * cat are replaced with those from the locale named by @a s. If base is + * named, this locale instance will also be named. + * + * @param base The locale to copy. + * @param s Name of the locale to use facets from. + * @param cat Set of categories defining the facets to use from s. + * @throw std::runtime_error if s is null or an undefined locale. + */ locale(const locale& __base, const char* __s, category __cat); + /** + * @brief Construct locale with facets from another locale. + * + * Constructs a copy of the locale @a base. The facets specified by @a + * cat are replaced with those from the locale @a add. If @a base and @a + * add are named, this locale instance will also be named. + * + * @param base The locale to copy. + * @param add The locale to use facets from. + * @param cat Set of categories defining the facets to use from add. + */ locale(const locale& __base, const locale& __add, category __cat); + /** + * @brief Construct locale with another facet. + * + * Constructs a copy of the locale @a other. The facet @f is added to + * @other, replacing an existing facet of type Facet if there is one. If + * @f is null, this locale is a copy of @a other. + * + * @param other The locale to copy. + * @param f The facet to add in. + */ template<typename _Facet> locale(const locale& __other, _Facet* __f); + /// Locale destructor. ~locale() throw(); - const locale& + /** + * @brief Assignment operator. + * + * Set this locale to be a copy of @a other. + * + * @param other The locale to copy. + * @return A reference to this locale. + */ + const locale& operator=(const locale& __other) throw(); + /** + * @brief Construct locale with another facet. + * + * Constructs and returns a new copy of this locale. Adds or replaces an + * existing facet of type Facet from the locale @a other into the new + * locale. + * + * @param Facet The facet type to copy from other + * @param other The locale to copy from. + * @return Newly constructed locale. + * @throw std::runtime_error if other has no facet of type Facet. + */ template<typename _Facet> - locale + locale combine(const locale& __other) const; // Locale operations: - string + /** + * @brief Return locale name. + * @return Locale name or "*" if unnamed. + */ + string name() const; - bool + /** + * @brief Locale equality. + * + * @param other The locale to compare against. + * @return True if other and this refer to the same locale instance, are + * copies, or have the same name. False otherwise. + */ + bool operator==(const locale& __other) const throw (); - inline bool + /** + * @brief Locale inequality. + * + * @param other The locale to compare against. + * @return ! (*this == other) + */ + inline bool operator!=(const locale& __other) const throw () { return !(this->operator==(__other)); } + /** + * @brief Compare two strings according to collate. + * + * Template operator to compare two strings using the compare function of + * the collate facet in this locale. One use is to provide the locale to + * the sort function. For example, a vector v of strings could be sorted + * according to locale loc by doing: + * @code + * std::sort(v.begin(), v.end(), loc); + * @endcode + * + * @param s1 First string to compare. + * @param s2 Second string to compare. + * @return True if collate<Char> facet compares s1 < s2, else false. + */ template<typename _Char, typename _Traits, typename _Alloc> - bool + bool operator()(const basic_string<_Char, _Traits, _Alloc>& __s1, const basic_string<_Char, _Traits, _Alloc>& __s2) const; // Global locale objects: - static locale + /** + * @brief Set global locale + * + * This function sets the global locale to the argument and returns a + * copy of the previous global locale. If the argument has a name, it + * will also call std::setlocale(LC_ALL, loc.name()). + * + * @param locale The new locale to make global. + * @return Copy of the old global locale. + */ + static locale global(const locale&); - static const locale& + /** + * @brief Return reference to the "C" locale. + */ + static const locale& classic(); private: // The (shared) implementation - _Impl* _M_impl; + _Impl* _M_impl; // The "C" reference locale - static _Impl* _S_classic; + static _Impl* _S_classic; // Current global locale - static _Impl* _S_global; + static _Impl* _S_global; + + // Names of underlying locale categories. + // NB: locale::global() has to know how to modify all the + // underlying categories, not just the ones required by the C++ + // standard. + static const char* const* const _S_categories; // Number of standard categories. For C++, these categories are // collate, ctype, monetary, numeric, time, and messages. These // directly correspond to ISO C99 macros LC_COLLATE, LC_CTYPE, // LC_MONETARY, LC_NUMERIC, and LC_TIME. In addition, POSIX (IEEE // 1003.1-2001) specifies LC_MESSAGES. - static const size_t _S_categories_size = 6; - // In addition to the standard categories, the underlying // operating system is allowed to define extra LC_* // macros. For GNU systems, the following are also valid: // LC_PAPER, LC_NAME, LC_ADDRESS, LC_TELEPHONE, LC_MEASUREMENT, // and LC_IDENTIFICATION. - static const size_t _S_extra_categories_size = _GLIBCPP_NUM_CATEGORIES; + static const size_t _S_categories_size = 6 + _GLIBCXX_NUM_CATEGORIES; - // Names of underlying locale categories. - // NB: locale::global() has to know how to modify all the - // underlying categories, not just the ones required by the C++ - // standard. - static const char* _S_categories[_S_categories_size - + _S_extra_categories_size]; +#ifdef __GTHREADS + static __gthread_once_t _S_once; +#endif - explicit + explicit locale(_Impl*) throw(); - static inline void - _S_initialize() - { - if (!_S_classic) - classic(); - } + static void + _S_initialize(); + + static void + _S_initialize_once(); - static category + static category _S_normalize_category(category); void @@ -187,7 +330,146 @@ namespace std }; - // Implementation object for locale + // 22.1.1.1.2 Class locale::facet + /** + * @brief Localization functionality base class. + * + * The facet class is the base class for a localization feature, such as + * money, time, and number printing. It provides common support for facets + * and reference management. + * + * Facets may not be copied or assigned. + */ + class locale::facet + { + private: + friend class locale; + friend class locale::_Impl; + + mutable _Atomic_word _M_refcount; + + // Contains data from the underlying "C" library for the classic locale. + static __c_locale _S_c_locale; + + // String literal for the name of the classic locale. + static const char _S_c_name[2]; + +#ifdef __GTHREADS + static __gthread_once_t _S_once; +#endif + + static void + _S_initialize_once(); + + protected: + /** + * @brief Facet constructor. + * + * This is the constructor provided by the standard. If refs is 0, the + * facet is destroyed when the last referencing locale is destroyed. + * Otherwise the facet will never be destroyed. + * + * @param refs The initial value for reference count. + */ + explicit + facet(size_t __refs = 0) throw() : _M_refcount(__refs ? 1 : 0) + { } + + /// Facet destructor. + virtual + ~facet(); + + static void + _S_create_c_locale(__c_locale& __cloc, const char* __s, + __c_locale __old = 0); + + static __c_locale + _S_clone_c_locale(__c_locale& __cloc); + + static void + _S_destroy_c_locale(__c_locale& __cloc); + + // Returns data from the underlying "C" library data for the + // classic locale. + static __c_locale + _S_get_c_locale(); + + static const char* + _S_get_c_name(); + + private: + inline void + _M_add_reference() const throw() + { __gnu_cxx::__atomic_add(&_M_refcount, 1); } + + inline void + _M_remove_reference() const throw() + { + if (__gnu_cxx::__exchange_and_add(&_M_refcount, -1) == 1) + { + try + { delete this; } + catch (...) + { } + } + } + + facet(const facet&); // Not defined. + + facet& + operator=(const facet&); // Not defined. + }; + + + // 22.1.1.1.3 Class locale::id + /** + * @brief Facet ID class. + * + * The ID class provides facets with an index used to identify them. + * Every facet class must define a public static member locale::id, or be + * derived from a facet that provides this member, otherwise the facet + * cannot be used in a locale. The locale::id ensures that each class + * type gets a unique identifier. + */ + class locale::id + { + private: + friend class locale; + friend class locale::_Impl; + + template<typename _Facet> + friend const _Facet& + use_facet(const locale&); + + template<typename _Facet> + friend bool + has_facet(const locale&) throw (); + + // NB: There is no accessor for _M_index because it may be used + // before the constructor is run; the effect of calling a member + // function (even an inline) would be undefined. + mutable size_t _M_index; + + // Last id number assigned. + static _Atomic_word _S_refcount; + + void + operator=(const id&); // Not defined. + + id(const id&); // Not defined. + + public: + // NB: This class is always a static data member, and thus can be + // counted on to be zero-initialized. + /// Constructor. + id() { } + + size_t + _M_id() const; + }; + + + // Implementation object for locale. class locale::_Impl { public: @@ -196,209 +478,122 @@ namespace std friend class locale::facet; template<typename _Facet> - friend const _Facet& - use_facet(const locale&); - - template<typename _Facet> - friend bool + friend bool has_facet(const locale&) throw(); template<typename _Facet> - friend const __locale_cache<_Facet>& - __use_cache(const locale&); + friend const _Facet& + use_facet(const locale&); + + template<typename _Cache> + friend struct __use_cache; private: // Data Members. - _Atomic_word _M_references; - facet** _M_facets; - size_t _M_facets_size; - - char* _M_names[_S_categories_size - + _S_extra_categories_size]; - static const locale::id* const _S_id_ctype[]; - static const locale::id* const _S_id_numeric[]; - static const locale::id* const _S_id_collate[]; - static const locale::id* const _S_id_time[]; - static const locale::id* const _S_id_monetary[]; - static const locale::id* const _S_id_messages[]; + _Atomic_word _M_refcount; + const facet** _M_facets; + size_t _M_facets_size; + const facet** _M_caches; + char** _M_names; + static const locale::id* const _S_id_ctype[]; + static const locale::id* const _S_id_numeric[]; + static const locale::id* const _S_id_collate[]; + static const locale::id* const _S_id_time[]; + static const locale::id* const _S_id_monetary[]; + static const locale::id* const _S_id_messages[]; static const locale::id* const* const _S_facet_categories[]; - inline void + inline void _M_add_reference() throw() - { __atomic_add(&_M_references, 1); } + { __gnu_cxx::__atomic_add(&_M_refcount, 1); } - inline void + inline void _M_remove_reference() throw() { - if (__exchange_and_add(&_M_references, -1) == 1) + if (__gnu_cxx::__exchange_and_add(&_M_refcount, -1) == 1) { - try - { delete this; } - catch(...) + try + { delete this; } + catch(...) { } } } _Impl(const _Impl&, size_t); _Impl(const char*, size_t); - _Impl(facet**, size_t, bool); + _Impl(size_t) throw(); ~_Impl() throw(); _Impl(const _Impl&); // Not defined. - void + void operator=(const _Impl&); // Not defined. inline bool _M_check_same_name() { bool __ret = true; - for (size_t __i = 0; - __ret && __i < _S_categories_size + _S_extra_categories_size - 1; - ++__i) - __ret &= (strcmp(_M_names[__i], _M_names[__i + 1]) == 0); + for (size_t __i = 0; __ret && __i < _S_categories_size - 1; ++__i) + __ret = std::strcmp(_M_names[__i], _M_names[__i + 1]) == 0; return __ret; } - void + void _M_replace_categories(const _Impl*, category); - void + void _M_replace_category(const _Impl*, const locale::id* const*); - void + void _M_replace_facet(const _Impl*, const locale::id*); - void - _M_install_facet(const locale::id*, facet*); + void + _M_install_facet(const locale::id*, const facet*); template<typename _Facet> - inline void + inline void _M_init_facet(_Facet* __facet) - { _M_install_facet(&_Facet::id, __facet); } - - // Retrieve the cache at __index. 0 is returned if the cache is - // missing. Cache is actually located at __index + - // _M_facets_size. __index must be < _M_facets_size. - inline __locale_cache_base* - _M_get_cache(size_t __index) - { - return (__locale_cache_base*)_M_facets[__index + _M_facets_size]; - } - - // Save the supplied cache at __id. Assumes _M_get_cache has been - // called. + { _M_install_facet(&_Facet::id, __facet); } + void - _M_install_cache(__locale_cache_base* __cache, int __id) + _M_install_cache(const facet* __cache, size_t __index) throw() { - _M_facets[__id + _M_facets_size] = - reinterpret_cast<locale::facet*>(__cache); + __cache->_M_add_reference(); + _M_caches[__index] = __cache; } - }; template<typename _Facet> locale::locale(const locale& __other, _Facet* __f) { _M_impl = new _Impl(*__other._M_impl, 1); - _M_impl->_M_install_facet(&_Facet::id, __f); - for (size_t __i = 0; - __i < _S_categories_size + _S_extra_categories_size; ++__i) + + char* _M_tmp_names[_S_categories_size]; + size_t __i = 0; + try { - delete [] _M_impl->_M_names[__i]; - char* __new = new char[2]; - strcpy(__new, "*"); - _M_impl->_M_names[__i] = __new; + for (; __i < _S_categories_size; ++__i) + { + _M_tmp_names[__i] = new char[2]; + std::strcpy(_M_tmp_names[__i], "*"); + } + _M_impl->_M_install_facet(&_Facet::id, __f); + } + catch(...) + { + _M_impl->_M_remove_reference(); + for (size_t __j = 0; __j < __i; ++__j) + delete [] _M_tmp_names[__j]; + __throw_exception_again; } - } - - - // 22.1.1.1.2 Class locale::facet - class locale::facet - { - private: - friend class locale; - friend class locale::_Impl; - - _Atomic_word _M_references; - - protected: - // Contains data from the underlying "C" library for the classic locale. - static __c_locale _S_c_locale; - - // String literal for the name of the classic locale. - static char _S_c_name[2]; - - explicit - facet(size_t __refs = 0) throw(); - - virtual - ~facet(); - - static void - _S_create_c_locale(__c_locale& __cloc, const char* __s, - __c_locale __old = 0); - - static __c_locale - _S_clone_c_locale(__c_locale& __cloc); - - static void - _S_destroy_c_locale(__c_locale& __cloc); - - private: - void - _M_add_reference() throw(); - - void - _M_remove_reference() throw(); - - facet(const facet&); // Not defined. - - void - operator=(const facet&); // Not defined. - }; - - - // 22.1.1.1.3 Class locale::id - class locale::id - { - private: - friend class locale; - friend class locale::_Impl; - template<typename _Facet> - friend const _Facet& - use_facet(const locale&); - template<typename _Facet> - friend bool - has_facet(const locale&) throw (); - - // NB: There is no accessor for _M_index because it may be used - // before the constructor is run; the effect of calling a member - // function (even an inline) would be undefined. - mutable size_t _M_index; - - // Last id number assigned. - static _Atomic_word _S_highwater; - - void - operator=(const id&); // Not defined. - - id(const id&); // Not defined. - - public: - // NB: This class is always a static data member, and thus can be - // counted on to be zero-initialized. - id(); - inline size_t - _M_id() const - { - if (!_M_index) - _M_index = 1 + __exchange_and_add(&_S_highwater, 1); - return _M_index - 1; + for (size_t __k = 0; __k < _S_categories_size; ++__k) + { + delete [] _M_impl->_M_names[__k]; + _M_impl->_M_names[__k] = _M_tmp_names[__k]; + } } - }; } // namespace std #endif diff --git a/contrib/libstdc++/include/bits/locale_facets.h b/contrib/libstdc++/include/bits/locale_facets.h index 37f6875bc252..60db8a45f261 100644 --- a/contrib/libstdc++/include/bits/locale_facets.h +++ b/contrib/libstdc++/include/bits/locale_facets.h @@ -1,6 +1,6 @@ // Locale support -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -37,8 +37,8 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_LOCFACETS_H -#define _CPP_BITS_LOCFACETS_H 1 +#ifndef _LOCALE_FACETS_H +#define _LOCALE_FACETS_H 1 #pragma GCC system_header @@ -51,57 +51,35 @@ namespace std { // NB: Don't instantiate required wchar_t facets if no wchar_t support. -#ifdef _GLIBCPP_USE_WCHAR_T -# define _GLIBCPP_NUM_FACETS 28 +#ifdef _GLIBCXX_USE_WCHAR_T +# define _GLIBCXX_NUM_FACETS 28 #else -# define _GLIBCPP_NUM_FACETS 14 +# define _GLIBCXX_NUM_FACETS 14 #endif - // Convert string to numeric value of type _Tv and store results. + // Convert string to numeric value of type _Tv and store results. // NB: This is specialized for all required types, there is no // generic definition. template<typename _Tv> void - __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err, - const __c_locale& __cloc, int __base = 10); + __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err, + const __c_locale& __cloc); // Explicit specializations for required types. template<> void - __convert_to_v(const char*, long&, ios_base::iostate&, - const __c_locale&, int); + __convert_to_v(const char*, float&, ios_base::iostate&, + const __c_locale&); template<> void - __convert_to_v(const char*, unsigned long&, ios_base::iostate&, - const __c_locale&, int); + __convert_to_v(const char*, double&, ios_base::iostate&, + const __c_locale&); -#ifdef _GLIBCPP_USE_LONG_LONG template<> void - __convert_to_v(const char*, long long&, ios_base::iostate&, - const __c_locale&, int); - - template<> - void - __convert_to_v(const char*, unsigned long long&, ios_base::iostate&, - const __c_locale&, int); -#endif - - template<> - void - __convert_to_v(const char*, float&, ios_base::iostate&, - const __c_locale&, int); - - template<> - void - __convert_to_v(const char*, double&, ios_base::iostate&, - const __c_locale&, int); - - template<> - void - __convert_to_v(const char*, long double&, ios_base::iostate&, - const __c_locale&, int); + __convert_to_v(const char*, long double&, ios_base::iostate&, + const __c_locale&); // NB: __pad is a struct, rather than a function, so it can be // partially-specialized. @@ -109,33 +87,20 @@ namespace std struct __pad { static void - _S_pad(ios_base& __io, _CharT __fill, _CharT* __news, - const _CharT* __olds, const streamsize __newlen, + _S_pad(ios_base& __io, _CharT __fill, _CharT* __news, + const _CharT* __olds, const streamsize __newlen, const streamsize __oldlen, const bool __num); }; // Used by both numeric and monetary facets. - // Check to make sure that the __grouping_tmp string constructed in - // money_get or num_get matches the canonical grouping for a given - // locale. - // __grouping_tmp is parsed L to R - // 1,222,444 == __grouping_tmp of "\1\3\3" - // __grouping is parsed R to L - // 1,222,444 == __grouping of "\3" == "\3\3\3" - template<typename _CharT> - bool - __verify_grouping(const basic_string<_CharT>& __grouping, - basic_string<_CharT>& __grouping_tmp); - - // Used by both numeric and monetary facets. // Inserts "group separator" characters into an array of characters. // It's recursive, one iteration per group. It moves the characters // in the buffer this way: "xxxx12345" -> "12,345xxx". Call this - // only with __gbeg != __gend. + // only with __glen != 0. template<typename _CharT> _CharT* - __add_grouping(_CharT* __s, _CharT __sep, - const char* __gbeg, const char* __gend, + __add_grouping(_CharT* __s, _CharT __sep, + const char* __gbeg, size_t __gsize, const _CharT* __first, const _CharT* __last); // This template permits specializing facet output code for @@ -161,135 +126,501 @@ namespace std return __s; } + // 22.2.1.1 Template class ctype // Include host and configuration specific ctype enums for ctype_base. #include <bits/ctype_base.h> - // Common base for ctype<_CharT>. + // Common base for ctype<_CharT>. + /** + * @brief Common base for ctype facet + * + * This template class provides implementations of the public functions + * that forward to the protected virtual functions. + * + * This template also provides abtract stubs for the protected virtual + * functions. + */ template<typename _CharT> class __ctype_abstract_base : public locale::facet, public ctype_base { public: // Types: + /// Typedef for the template parameter typedef _CharT char_type; - bool + /** + * @brief Test char_type classification. + * + * This function finds a mask M for @a c and compares it to mask @a m. + * It does so by returning the value of ctype<char_type>::do_is(). + * + * @param c The char_type to compare the mask of. + * @param m The mask to compare against. + * @return (M & m) != 0. + */ + bool is(mask __m, char_type __c) const { return this->do_is(__m, __c); } + /** + * @brief Return a mask array. + * + * This function finds the mask for each char_type in the range [lo,hi) + * and successively writes it to vec. vec must have as many elements + * as the char array. It does so by returning the value of + * ctype<char_type>::do_is(). + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param vec Pointer to an array of mask storage. + * @return @a hi. + */ const char_type* - is(const char_type *__lo, const char_type *__hi, mask *__vec) const + is(const char_type *__lo, const char_type *__hi, mask *__vec) const { return this->do_is(__lo, __hi, __vec); } + /** + * @brief Find char_type matching a mask + * + * This function searches for and returns the first char_type c in + * [lo,hi) for which is(m,c) is true. It does so by returning + * ctype<char_type>::do_scan_is(). + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to matching char_type if found, else @a hi. + */ const char_type* scan_is(mask __m, const char_type* __lo, const char_type* __hi) const { return this->do_scan_is(__m, __lo, __hi); } + /** + * @brief Find char_type not matching a mask + * + * This function searches for and returns the first char_type c in + * [lo,hi) for which is(m,c) is false. It does so by returning + * ctype<char_type>::do_scan_not(). + * + * @param m The mask to compare against. + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @return Pointer to non-matching char if found, else @a hi. + */ const char_type* scan_not(mask __m, const char_type* __lo, const char_type* __hi) const { return this->do_scan_not(__m, __lo, __hi); } - char_type + /** + * @brief Convert to uppercase. + * + * This function converts the argument to uppercase if possible. + * If not possible (for example, '2'), returns the argument. It does + * so by returning ctype<char_type>::do_toupper(). + * + * @param c The char_type to convert. + * @return The uppercase char_type if convertible, else @a c. + */ + char_type toupper(char_type __c) const { return this->do_toupper(__c); } + /** + * @brief Convert array to uppercase. + * + * This function converts each char_type in the range [lo,hi) to + * uppercase if possible. Other elements remain untouched. It does so + * by returning ctype<char_type>:: do_toupper(lo, hi). + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ const char_type* toupper(char_type *__lo, const char_type* __hi) const { return this->do_toupper(__lo, __hi); } - char_type + /** + * @brief Convert to lowercase. + * + * This function converts the argument to lowercase if possible. If + * not possible (for example, '2'), returns the argument. It does so + * by returning ctype<char_type>::do_tolower(c). + * + * @param c The char_type to convert. + * @return The lowercase char_type if convertible, else @a c. + */ + char_type tolower(char_type __c) const { return this->do_tolower(__c); } + /** + * @brief Convert array to lowercase. + * + * This function converts each char_type in the range [lo,hi) to + * lowercase if possible. Other elements remain untouched. It does so + * by returning ctype<char_type>:: do_tolower(lo, hi). + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ const char_type* tolower(char_type* __lo, const char_type* __hi) const { return this->do_tolower(__lo, __hi); } - char_type + /** + * @brief Widen char to char_type + * + * This function converts the char argument to char_type using the + * simplest reasonable transformation. It does so by returning + * ctype<char_type>::do_widen(c). + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted char_type. + */ + char_type widen(char __c) const { return this->do_widen(__c); } + /** + * @brief Widen array to char_type + * + * This function converts each char in the input to char_type using the + * simplest reasonable transformation. It does so by returning + * ctype<char_type>::do_widen(c). + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ const char* widen(const char* __lo, const char* __hi, char_type* __to) const { return this->do_widen(__lo, __hi, __to); } - char + /** + * @brief Narrow char_type to char + * + * This function converts the char_type to char using the simplest + * reasonable transformation. If the conversion fails, dfault is + * returned instead. It does so by returning + * ctype<char_type>::do_narrow(c). + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char_type to convert. + * @param dfault Char to return if conversion fails. + * @return The converted char. + */ + char narrow(char_type __c, char __dfault) const { return this->do_narrow(__c, __dfault); } + /** + * @brief Narrow array to char array + * + * This function converts each char_type in the input to char using the + * simplest reasonable transformation and writes the results to the + * destination array. For any char_type in the input that cannot be + * converted, @a dfault is used instead. It does so by returning + * ctype<char_type>::do_narrow(lo, hi, dfault, to). + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ const char_type* narrow(const char_type* __lo, const char_type* __hi, char __dfault, char *__to) const { return this->do_narrow(__lo, __hi, __dfault, __to); } protected: - explicit - __ctype_abstract_base(size_t __refs = 0): locale::facet(__refs) { } + explicit + __ctype_abstract_base(size_t __refs = 0): facet(__refs) { } - virtual + virtual ~__ctype_abstract_base() { } - - virtual bool + + /** + * @brief Test char_type classification. + * + * This function finds a mask M for @a c and compares it to mask @a m. + * + * do_is() is a hook for a derived facet to change the behavior of + * classifying. do_is() must always return the same result for the + * same input. + * + * @param c The char_type to find the mask of. + * @param m The mask to compare against. + * @return (M & m) != 0. + */ + virtual bool do_is(mask __m, char_type __c) const = 0; + /** + * @brief Return a mask array. + * + * This function finds the mask for each char_type in the range [lo,hi) + * and successively writes it to vec. vec must have as many elements + * as the input. + * + * do_is() is a hook for a derived facet to change the behavior of + * classifying. do_is() must always return the same result for the + * same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param vec Pointer to an array of mask storage. + * @return @a hi. + */ virtual const char_type* - do_is(const char_type* __lo, const char_type* __hi, + do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const = 0; + /** + * @brief Find char_type matching mask + * + * This function searches for and returns the first char_type c in + * [lo,hi) for which is(m,c) is true. + * + * do_scan_is() is a hook for a derived facet to change the behavior of + * match searching. do_is() must always return the same result for the + * same input. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a matching char_type if found, else @a hi. + */ virtual const char_type* do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const = 0; + /** + * @brief Find char_type not matching mask + * + * This function searches for and returns a pointer to the first + * char_type c of [lo,hi) for which is(m,c) is false. + * + * do_scan_is() is a hook for a derived facet to change the behavior of + * match searching. do_is() must always return the same result for the + * same input. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a non-matching char_type if found, else @a hi. + */ virtual const char_type* - do_scan_not(mask __m, const char_type* __lo, + do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const = 0; - virtual char_type + /** + * @brief Convert to uppercase. + * + * This virtual function converts the char_type argument to uppercase + * if possible. If not possible (for example, '2'), returns the + * argument. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param c The char_type to convert. + * @return The uppercase char_type if convertible, else @a c. + */ + virtual char_type do_toupper(char_type) const = 0; + /** + * @brief Convert array to uppercase. + * + * This virtual function converts each char_type in the range [lo,hi) + * to uppercase if possible. Other elements remain untouched. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ virtual const char_type* do_toupper(char_type* __lo, const char_type* __hi) const = 0; - virtual char_type + /** + * @brief Convert to lowercase. + * + * This virtual function converts the argument to lowercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param c The char_type to convert. + * @return The lowercase char_type if convertible, else @a c. + */ + virtual char_type do_tolower(char_type) const = 0; + /** + * @brief Convert array to lowercase. + * + * This virtual function converts each char_type in the range [lo,hi) + * to lowercase if possible. Other elements remain untouched. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ virtual const char_type* do_tolower(char_type* __lo, const char_type* __hi) const = 0; - - virtual char_type + + /** + * @brief Widen char + * + * This virtual function converts the char to char_type using the + * simplest reasonable transformation. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted char_type + */ + virtual char_type do_widen(char) const = 0; + /** + * @brief Widen char array + * + * This function converts each char in the input to char_type using the + * simplest reasonable transformation. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ virtual const char* - do_widen(const char* __lo, const char* __hi, + do_widen(const char* __lo, const char* __hi, char_type* __dest) const = 0; - virtual char + /** + * @brief Narrow char_type to char + * + * This virtual function converts the argument to char using the + * simplest reasonable transformation. If the conversion fails, dfault + * is returned instead. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char_type to convert. + * @param dfault Char to return if conversion fails. + * @return The converted char. + */ + virtual char do_narrow(char_type, char __dfault) const = 0; + /** + * @brief Narrow char_type array to char + * + * This virtual function converts each char_type in the range [lo,hi) to + * char using the simplest reasonable transformation and writes the + * results to the destination array. For any element in the input that + * cannot be converted, @a dfault is used instead. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ virtual const char_type* do_narrow(const char_type* __lo, const char_type* __hi, - char __dfault, char* __dest) const = 0; + char __dfault, char* __dest) const = 0; }; // NB: Generic, mostly useless implementation. + /** + * @brief Template ctype facet + * + * This template class defines classification and conversion functions for + * character sets. It wraps <cctype> functionality. Ctype gets used by + * streams for many I/O operations. + * + * This template provides the protected virtual functions the developer + * will have to replace in a derived class or specialization to make a + * working facet. The public functions that access them are defined in + * __ctype_abstract_base, to allow for implementation flexibility. See + * ctype<wchar_t> for an example. The functions are documented in + * __ctype_abstract_base. + * + * Note: implementations are provided for all the protected virtual + * functions, but will likely not be useful. + */ template<typename _CharT> class ctype : public __ctype_abstract_base<_CharT> { public: // Types: - typedef _CharT char_type; - typedef typename ctype::mask mask; + typedef _CharT char_type; + typedef typename __ctype_abstract_base<_CharT>::mask mask; - static locale::id id; + /// The facet id for ctype<char_type> + static locale::id id; - explicit + explicit ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { } protected: - virtual + virtual ~ctype(); - virtual bool + virtual bool do_is(mask __m, char_type __c) const; virtual const char_type* @@ -302,25 +633,25 @@ namespace std do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const; - virtual char_type + virtual char_type do_toupper(char_type __c) const; virtual const char_type* do_toupper(char_type* __lo, const char_type* __hi) const; - virtual char_type + virtual char_type do_tolower(char_type __c) const; virtual const char_type* do_tolower(char_type* __lo, const char_type* __hi) const; - virtual char_type + virtual char_type do_widen(char __c) const; virtual const char* do_widen(const char* __lo, const char* __hi, char_type* __dest) const; - virtual char + virtual char do_narrow(char_type, char __dfault) const; virtual const char_type* @@ -332,172 +663,850 @@ namespace std locale::id ctype<_CharT>::id; // 22.2.1.3 ctype<char> specialization. + /** + * @brief The ctype<char> specialization. + * + * This class defines classification and conversion functions for + * the char type. It gets used by char streams for many I/O + * operations. The char specialization provides a number of + * optimizations as well. + */ template<> - class ctype<char> : public __ctype_abstract_base<char> + class ctype<char> : public locale::facet, public ctype_base { public: // Types: - typedef char char_type; + /// Typedef for the template parameter char. + typedef char char_type; protected: // Data Members: __c_locale _M_c_locale_ctype; - bool _M_del; - __to_type _M_toupper; - __to_type _M_tolower; - const mask* _M_table; - + bool _M_del; + __to_type _M_toupper; + __to_type _M_tolower; + const mask* _M_table; + mutable char _M_widen_ok; + mutable char _M_widen[1 + static_cast<unsigned char>(-1)]; + mutable char _M_narrow[1 + static_cast<unsigned char>(-1)]; + mutable char _M_narrow_ok; // 0 uninitialized, 1 init, + // 2 non-consecutive + public: + /// The facet id for ctype<char> static locale::id id; + /// The size of the mask table. It is SCHAR_MAX + 1. static const size_t table_size = 1 + static_cast<unsigned char>(-1); - explicit + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param table If non-zero, table is used as the per-char mask. + * Else classic_table() is used. + * @param del If true, passes ownership of table to this facet. + * @param refs Passed to the base facet class. + */ + explicit ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0); - explicit - ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false, + /** + * @brief Constructor performs static initialization. + * + * This constructor is used to construct the initial C locale facet. + * + * @param cloc Handle to C locale data. + * @param table If non-zero, table is used as the per-char mask. + * @param del If true, passes ownership of table to this facet. + * @param refs Passed to the base facet class. + */ + explicit + ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false, size_t __refs = 0); - inline bool + /** + * @brief Test char classification. + * + * This function compares the mask table[c] to @a m. + * + * @param c The char to compare the mask of. + * @param m The mask to compare against. + * @return True if m & table[c] is true, false otherwise. + */ + inline bool is(mask __m, char __c) const; - + + /** + * @brief Return a mask array. + * + * This function finds the mask for each char in the range [lo, hi) and + * successively writes it to vec. vec must have as many elements as + * the char array. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param vec Pointer to an array of mask storage. + * @return @a hi. + */ inline const char* is(const char* __lo, const char* __hi, mask* __vec) const; - + + /** + * @brief Find char matching a mask + * + * This function searches for and returns the first char in [lo,hi) for + * which is(m,char) is true. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a matching char if found, else @a hi. + */ inline const char* scan_is(mask __m, const char* __lo, const char* __hi) const; + /** + * @brief Find char not matching a mask + * + * This function searches for and returns a pointer to the first char + * in [lo,hi) for which is(m,char) is false. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a non-matching char if found, else @a hi. + */ inline const char* scan_not(mask __m, const char* __lo, const char* __hi) const; - + + /** + * @brief Convert to uppercase. + * + * This function converts the char argument to uppercase if possible. + * If not possible (for example, '2'), returns the argument. + * + * toupper() acts as if it returns ctype<char>::do_toupper(c). + * do_toupper() must always return the same result for the same input. + * + * @param c The char to convert. + * @return The uppercase char if convertible, else @a c. + */ + char_type + toupper(char_type __c) const + { return this->do_toupper(__c); } + + /** + * @brief Convert array to uppercase. + * + * This function converts each char in the range [lo,hi) to uppercase + * if possible. Other chars remain untouched. + * + * toupper() acts as if it returns ctype<char>:: do_toupper(lo, hi). + * do_toupper() must always return the same result for the same input. + * + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + const char_type* + toupper(char_type *__lo, const char_type* __hi) const + { return this->do_toupper(__lo, __hi); } + + /** + * @brief Convert to lowercase. + * + * This function converts the char argument to lowercase if possible. + * If not possible (for example, '2'), returns the argument. + * + * tolower() acts as if it returns ctype<char>::do_tolower(c). + * do_tolower() must always return the same result for the same input. + * + * @param c The char to convert. + * @return The lowercase char if convertible, else @a c. + */ + char_type + tolower(char_type __c) const + { return this->do_tolower(__c); } + + /** + * @brief Convert array to lowercase. + * + * This function converts each char in the range [lo,hi) to lowercase + * if possible. Other chars remain untouched. + * + * tolower() acts as if it returns ctype<char>:: do_tolower(lo, hi). + * do_tolower() must always return the same result for the same input. + * + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @return @a hi. + */ + const char_type* + tolower(char_type* __lo, const char_type* __hi) const + { return this->do_tolower(__lo, __hi); } + + /** + * @brief Widen char + * + * This function converts the char to char_type using the simplest + * reasonable transformation. For an underived ctype<char> facet, the + * argument will be returned unchanged. + * + * This function works as if it returns ctype<char>::do_widen(c). + * do_widen() must always return the same result for the same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted character. + */ + char_type + widen(char __c) const + { + if (_M_widen_ok) return _M_widen[static_cast<unsigned char>(__c)]; + this->_M_widen_init(); + return this->do_widen(__c); + } + + /** + * @brief Widen char array + * + * This function converts each char in the input to char using the + * simplest reasonable transformation. For an underived ctype<char> + * facet, the argument will be copied unchanged. + * + * This function works as if it returns ctype<char>::do_widen(c). + * do_widen() must always return the same result for the same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ + const char* + widen(const char* __lo, const char* __hi, char_type* __to) const + { + if (_M_widen_ok == 1) + { + memcpy(__to, __lo, __hi - __lo); + return __hi; + } + if (!_M_widen_ok) _M_widen_init(); + return this->do_widen(__lo, __hi, __to); + } + + /** + * @brief Narrow char + * + * This function converts the char to char using the simplest + * reasonable transformation. If the conversion fails, dfault is + * returned instead. For an underived ctype<char> facet, @a c + * will be returned unchanged. + * + * This function works as if it returns ctype<char>::do_narrow(c). + * do_narrow() must always return the same result for the same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @param dfault Char to return if conversion fails. + * @return The converted character. + */ + char + narrow(char_type __c, char __dfault) const + { + if (_M_narrow[static_cast<unsigned char>(__c)]) + return _M_narrow[static_cast<unsigned char>(__c)]; + const char __t = do_narrow(__c, __dfault); + if (__t != __dfault) _M_narrow[static_cast<unsigned char>(__c)] = __t; + return __t; + } + + /** + * @brief Narrow char array + * + * This function converts each char in the input to char using the + * simplest reasonable transformation and writes the results to the + * destination array. For any char in the input that cannot be + * converted, @a dfault is used instead. For an underived ctype<char> + * facet, the argument will be copied unchanged. + * + * This function works as if it returns ctype<char>::do_narrow(lo, hi, + * dfault, to). do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ + const char_type* + narrow(const char_type* __lo, const char_type* __hi, + char __dfault, char *__to) const + { + if (__builtin_expect(_M_narrow_ok == 1,true)) + { + memcpy(__to, __lo, __hi - __lo); + return __hi; + } + if (!_M_narrow_ok) + _M_narrow_init(); + return this->do_narrow(__lo, __hi, __dfault, __to); + } + protected: - const mask* + /// Returns a pointer to the mask table provided to the constructor, or + /// the default from classic_table() if none was provided. + const mask* table() const throw() { return _M_table; } - static const mask* + /// Returns a pointer to the C locale mask table. + static const mask* classic_table() throw(); - virtual + /** + * @brief Destructor. + * + * This function deletes table() if @a del was true in the + * constructor. + */ + virtual ~ctype(); - virtual bool - do_is(mask __m, char_type __c) const; - - virtual const char_type* - do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const; - - virtual const char_type* - do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const; - - virtual const char_type* - do_scan_not(mask __m, const char_type* __lo, - const char_type* __hi) const; - - virtual char_type + /** + * @brief Convert to uppercase. + * + * This virtual function converts the char argument to uppercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param c The char to convert. + * @return The uppercase char if convertible, else @a c. + */ + virtual char_type do_toupper(char_type) const; + /** + * @brief Convert array to uppercase. + * + * This virtual function converts each char in the range [lo,hi) to + * uppercase if possible. Other chars remain untouched. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ virtual const char_type* do_toupper(char_type* __lo, const char_type* __hi) const; - virtual char_type + /** + * @brief Convert to lowercase. + * + * This virtual function converts the char argument to lowercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param c The char to convert. + * @return The lowercase char if convertible, else @a c. + */ + virtual char_type do_tolower(char_type) const; + /** + * @brief Convert array to lowercase. + * + * This virtual function converts each char in the range [lo,hi) to + * lowercase if possible. Other chars remain untouched. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param lo Pointer to first char in range. + * @param hi Pointer to end of range. + * @return @a hi. + */ virtual const char_type* do_tolower(char_type* __lo, const char_type* __hi) const; - - virtual char_type - do_widen(char) const; + /** + * @brief Widen char + * + * This virtual function converts the char to char using the simplest + * reasonable transformation. For an underived ctype<char> facet, the + * argument will be returned unchanged. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted character. + */ + virtual char_type + do_widen(char __c) const + { return __c; } + + /** + * @brief Widen char array + * + * This function converts each char in the range [lo,hi) to char using + * the simplest reasonable transformation. For an underived + * ctype<char> facet, the argument will be copied unchanged. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ virtual const char* - do_widen(const char* __lo, const char* __hi, char_type* __dest) const; - - virtual char - do_narrow(char_type, char __dfault) const; + do_widen(const char* __lo, const char* __hi, char_type* __dest) const + { + memcpy(__dest, __lo, __hi - __lo); + return __hi; + } + /** + * @brief Narrow char + * + * This virtual function converts the char to char using the simplest + * reasonable transformation. If the conversion fails, dfault is + * returned instead. For an underived ctype<char> facet, @a c will be + * returned unchanged. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @param dfault Char to return if conversion fails. + * @return The converted char. + */ + virtual char + do_narrow(char_type __c, char) const + { return __c; } + + /** + * @brief Narrow char array to char array + * + * This virtual function converts each char in the range [lo,hi) to + * char using the simplest reasonable transformation and writes the + * results to the destination array. For any char in the input that + * cannot be converted, @a dfault is used instead. For an underived + * ctype<char> facet, the argument will be copied unchanged. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ virtual const char_type* do_narrow(const char_type* __lo, const char_type* __hi, - char __dfault, char* __dest) const; + char, char* __dest) const + { + memcpy(__dest, __lo, __hi - __lo); + return __hi; + } + + private: + + void _M_widen_init() const + { + char __tmp[sizeof(_M_widen)]; + for (size_t __i = 0; __i < sizeof(_M_widen); ++__i) + __tmp[__i] = __i; + do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen); + + _M_widen_ok = 1; + // Set _M_widen_ok to 2 if memcpy can't be used. + for (size_t __j = 0; __j < sizeof(_M_widen); ++__j) + if (__tmp[__j] != _M_widen[__j]) + { + _M_widen_ok = 2; + break; + } + } + + // Fill in the narrowing cache and flag whether all values are + // valid or not. _M_narrow_ok is set to 1 if the whole table is + // narrowed, 2 if only some values could be narrowed. + void _M_narrow_init() const + { + char __tmp[sizeof(_M_narrow)]; + for (size_t __i = 0; __i < sizeof(_M_narrow); ++__i) + __tmp[__i] = __i; + do_narrow(__tmp, __tmp + sizeof(__tmp), 0, _M_narrow); + + // Check if any default values were created. Do this by + // renarrowing with a different default value and comparing. + bool __consecutive = true; + for (size_t __j = 0; __j < sizeof(_M_narrow); ++__j) + if (!_M_narrow[__j]) + { + char __c; + do_narrow(__tmp + __j, __tmp + __j + 1, 1, &__c); + if (__c == 1) + { + __consecutive = false; + break; + } + } + _M_narrow_ok = __consecutive ? 1 : 2; + } }; - + template<> const ctype<char>& use_facet<ctype<char> >(const locale& __loc); -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T // 22.2.1.3 ctype<wchar_t> specialization + /** + * @brief The ctype<wchar_t> specialization. + * + * This class defines classification and conversion functions for the + * wchar_t type. It gets used by wchar_t streams for many I/O operations. + * The wchar_t specialization provides a number of optimizations as well. + * + * ctype<wchar_t> inherits its public methods from + * __ctype_abstract_base<wchar_t>. + */ template<> class ctype<wchar_t> : public __ctype_abstract_base<wchar_t> { public: // Types: - typedef wchar_t char_type; - typedef wctype_t __wmask_type; + /// Typedef for the template parameter wchar_t. + typedef wchar_t char_type; + typedef wctype_t __wmask_type; protected: __c_locale _M_c_locale_ctype; + // Pre-computed narrowed and widened chars. + bool _M_narrow_ok; + char _M_narrow[128]; + wint_t _M_widen[1 + static_cast<unsigned char>(-1)]; + + // Pre-computed elements for do_is. + mask _M_bit[16]; + __wmask_type _M_wmask[16]; + public: // Data Members: - static locale::id id; + /// The facet id for ctype<wchar_t> + static locale::id id; - explicit + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit ctype(size_t __refs = 0); - explicit + /** + * @brief Constructor performs static initialization. + * + * This constructor is used to construct the initial C locale facet. + * + * @param cloc Handle to C locale data. + * @param refs Passed to the base facet class. + */ + explicit ctype(__c_locale __cloc, size_t __refs = 0); protected: __wmask_type _M_convert_to_wmask(const mask __m) const; - virtual + /// Destructor + virtual ~ctype(); - virtual bool + /** + * @brief Test wchar_t classification. + * + * This function finds a mask M for @a c and compares it to mask @a m. + * + * do_is() is a hook for a derived facet to change the behavior of + * classifying. do_is() must always return the same result for the + * same input. + * + * @param c The wchar_t to find the mask of. + * @param m The mask to compare against. + * @return (M & m) != 0. + */ + virtual bool do_is(mask __m, char_type __c) const; + /** + * @brief Return a mask array. + * + * This function finds the mask for each wchar_t in the range [lo,hi) + * and successively writes it to vec. vec must have as many elements + * as the input. + * + * do_is() is a hook for a derived facet to change the behavior of + * classifying. do_is() must always return the same result for the + * same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param vec Pointer to an array of mask storage. + * @return @a hi. + */ virtual const char_type* do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const; + /** + * @brief Find wchar_t matching mask + * + * This function searches for and returns the first wchar_t c in + * [lo,hi) for which is(m,c) is true. + * + * do_scan_is() is a hook for a derived facet to change the behavior of + * match searching. do_is() must always return the same result for the + * same input. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a matching wchar_t if found, else @a hi. + */ virtual const char_type* do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const; + /** + * @brief Find wchar_t not matching mask + * + * This function searches for and returns a pointer to the first + * wchar_t c of [lo,hi) for which is(m,c) is false. + * + * do_scan_is() is a hook for a derived facet to change the behavior of + * match searching. do_is() must always return the same result for the + * same input. + * + * @param m The mask to compare against. + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return Pointer to a non-matching wchar_t if found, else @a hi. + */ virtual const char_type* - do_scan_not(mask __m, const char_type* __lo, + do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const; - virtual char_type + /** + * @brief Convert to uppercase. + * + * This virtual function converts the wchar_t argument to uppercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param c The wchar_t to convert. + * @return The uppercase wchar_t if convertible, else @a c. + */ + virtual char_type do_toupper(char_type) const; + /** + * @brief Convert array to uppercase. + * + * This virtual function converts each wchar_t in the range [lo,hi) to + * uppercase if possible. Other elements remain untouched. + * + * do_toupper() is a hook for a derived facet to change the behavior of + * uppercasing. do_toupper() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ virtual const char_type* do_toupper(char_type* __lo, const char_type* __hi) const; - virtual char_type + /** + * @brief Convert to lowercase. + * + * This virtual function converts the argument to lowercase if + * possible. If not possible (for example, '2'), returns the argument. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param c The wchar_t to convert. + * @return The lowercase wchar_t if convertible, else @a c. + */ + virtual char_type do_tolower(char_type) const; + /** + * @brief Convert array to lowercase. + * + * This virtual function converts each wchar_t in the range [lo,hi) to + * lowercase if possible. Other elements remain untouched. + * + * do_tolower() is a hook for a derived facet to change the behavior of + * lowercasing. do_tolower() must always return the same result for + * the same input. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @return @a hi. + */ virtual const char_type* do_tolower(char_type* __lo, const char_type* __hi) const; - - virtual char_type + + /** + * @brief Widen char to wchar_t + * + * This virtual function converts the char to wchar_t using the + * simplest reasonable transformation. For an underived ctype<wchar_t> + * facet, the argument will be cast to wchar_t. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The char to convert. + * @return The converted wchar_t. + */ + virtual char_type do_widen(char) const; + /** + * @brief Widen char array to wchar_t array + * + * This function converts each char in the input to wchar_t using the + * simplest reasonable transformation. For an underived ctype<wchar_t> + * facet, the argument will be copied, casting each element to wchar_t. + * + * do_widen() is a hook for a derived facet to change the behavior of + * widening. do_widen() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start range. + * @param hi Pointer to end of range. + * @param to Pointer to the destination array. + * @return @a hi. + */ virtual const char* do_widen(const char* __lo, const char* __hi, char_type* __dest) const; - virtual char + /** + * @brief Narrow wchar_t to char + * + * This virtual function converts the argument to char using + * the simplest reasonable transformation. If the conversion + * fails, dfault is returned instead. For an underived + * ctype<wchar_t> facet, @a c will be cast to char and + * returned. + * + * do_narrow() is a hook for a derived facet to change the + * behavior of narrowing. do_narrow() must always return the + * same result for the same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param c The wchar_t to convert. + * @param dfault Char to return if conversion fails. + * @return The converted char. + */ + virtual char do_narrow(char_type, char __dfault) const; + /** + * @brief Narrow wchar_t array to char array + * + * This virtual function converts each wchar_t in the range [lo,hi) to + * char using the simplest reasonable transformation and writes the + * results to the destination array. For any wchar_t in the input that + * cannot be converted, @a dfault is used instead. For an underived + * ctype<wchar_t> facet, the argument will be copied, casting each + * element to char. + * + * do_narrow() is a hook for a derived facet to change the behavior of + * narrowing. do_narrow() must always return the same result for the + * same input. + * + * Note: this is not what you want for codepage conversions. See + * codecvt for that. + * + * @param lo Pointer to start of range. + * @param hi Pointer to end of range. + * @param dfault Char to use if conversion fails. + * @param to Pointer to the destination array. + * @return @a hi. + */ virtual const char_type* do_narrow(const char_type* __lo, const char_type* __hi, char __dfault, char* __dest) const; + // For use at construction time only. + void + _M_initialize_ctype(); }; template<> const ctype<wchar_t>& use_facet<ctype<wchar_t> >(const locale& __loc); -#endif //_GLIBCPP_USE_WCHAR_T +#endif //_GLIBCXX_USE_WCHAR_T // Include host and configuration specific ctype inlines. #include <bits/ctype_inline.h> @@ -507,13 +1516,13 @@ namespace std class ctype_byname : public ctype<_CharT> { public: - typedef _CharT char_type; + typedef _CharT char_type; - explicit + explicit ctype_byname(const char* __s, size_t __refs = 0); protected: - virtual + virtual ~ctype_byname() { }; }; @@ -528,26 +1537,26 @@ namespace std #include <bits/codecvt.h> // 22.2.2 The numeric category. - class __num_base + class __num_base { public: // NB: Code depends on the order of _S_atoms_out elements. // Below are the indices into _S_atoms_out. - enum - { - _S_minus, - _S_plus, - _S_x, - _S_X, - _S_digits, - _S_digits_end = _S_digits + 16, - _S_udigits = _S_digits_end, - _S_udigits_end = _S_udigits + 16, - _S_e = _S_digits + 14, // For scientific notation, 'e' - _S_E = _S_udigits + 14, // For scientific notation, 'E' - _S_end = _S_udigits_end + enum + { + _S_ominus, + _S_oplus, + _S_ox, + _S_oX, + _S_odigits, + _S_odigits_end = _S_odigits + 16, + _S_oudigits = _S_odigits_end, + _S_oudigits_end = _S_oudigits + 16, + _S_oe = _S_odigits + 14, // For scientific notation, 'e' + _S_oE = _S_oudigits + 14, // For scientific notation, 'E' + _S_oend = _S_oudigits_end }; - + // A list of valid numeric literals for output. This array // contains chars that will be passed through the current locale's // ctype<_CharT>.widen() and then used to render numbers. @@ -555,126 +1564,326 @@ namespace std // "-+xX0123456789abcdef0123456789ABCDEF". static const char* _S_atoms_out; - protected: // String literal of acceptable (narrow) input, for num_get. - // "0123456789eEabcdfABCDF" + // "-+xX0123456789abcdefABCDEF" static const char* _S_atoms_in; - enum - { - _M_zero, - _M_e = _M_zero + 10, - _M_E = _M_zero + 11, - _M_size = 21 + 1 + enum + { + _S_iminus, + _S_iplus, + _S_ix, + _S_iX, + _S_izero, + _S_ie = _S_izero + 14, + _S_iE = _S_izero + 20, + _S_iend = 26 }; // num_put // Construct and return valid scanf format for floating point types. static void - _S_format_float(const ios_base& __io, char* __fptr, char __mod, - streamsize __prec); - - // Construct and return valid scanf format for integer types. - static void - _S_format_int(const ios_base& __io, char* __fptr, char __mod, char __modl); + _S_format_float(const ios_base& __io, char* __fptr, char __mod); }; + template<typename _CharT> + struct __numpunct_cache : public locale::facet + { + const char* _M_grouping; + size_t _M_grouping_size; + bool _M_use_grouping; + const _CharT* _M_truename; + size_t _M_truename_size; + const _CharT* _M_falsename; + size_t _M_falsename_size; + _CharT _M_decimal_point; + _CharT _M_thousands_sep; + + // A list of valid numeric literals for output: in the standard + // "C" locale, this is "-+xX0123456789abcdef0123456789ABCDEF". + // This array contains the chars after having been passed + // through the current locale's ctype<_CharT>.widen(). + _CharT _M_atoms_out[__num_base::_S_oend]; + + // A list of valid numeric literals for input: in the standard + // "C" locale, this is "-+xX0123456789abcdefABCDEF" + // This array contains the chars after having been passed + // through the current locale's ctype<_CharT>.widen(). + _CharT _M_atoms_in[__num_base::_S_iend]; + + bool _M_allocated; + + __numpunct_cache(size_t __refs = 0) : facet(__refs), + _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false), + _M_truename(NULL), _M_truename_size(0), _M_falsename(NULL), + _M_falsename_size(0), _M_decimal_point(_CharT()), + _M_thousands_sep(_CharT()), _M_allocated(false) + { } + + ~__numpunct_cache(); + + void + _M_cache(const locale& __loc); + + private: + __numpunct_cache& + operator=(const __numpunct_cache&); + + explicit + __numpunct_cache(const __numpunct_cache&); + }; template<typename _CharT> - class __locale_cache; + __numpunct_cache<_CharT>::~__numpunct_cache() + { + if (_M_allocated) + { + delete [] _M_grouping; + delete [] _M_truename; + delete [] _M_falsename; + } + } + /** + * @brief Numpunct facet. + * + * This facet stores several pieces of information related to printing and + * scanning numbers, such as the decimal point character. It takes a + * template parameter specifying the char type. The numpunct facet is + * used by streams for many I/O operations involving numbers. + * + * The numpunct template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from a numpunct facet. + */ template<typename _CharT> class numpunct : public locale::facet { public: // Types: - typedef _CharT char_type; - typedef basic_string<_CharT> string_type; - - friend class __locale_cache<numpunct<_CharT> >; - - static locale::id id; + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + typedef __numpunct_cache<_CharT> __cache_type; - private: - char_type _M_decimal_point; - char_type _M_thousands_sep; - const char* _M_grouping; - const char_type* _M_truename; - const char_type* _M_falsename; + protected: + __cache_type* _M_data; public: - explicit - numpunct(size_t __refs = 0) : locale::facet(__refs) + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Numpunct constructor. + * + * @param refs Refcount to pass to the base class. + */ + explicit + numpunct(size_t __refs = 0) : facet(__refs), _M_data(NULL) + { _M_initialize_numpunct(); } + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up the + * predefined locale facets. + * + * @param cache __numpunct_cache object. + * @param refs Refcount to pass to the base class. + */ + explicit + numpunct(__cache_type* __cache, size_t __refs = 0) + : facet(__refs), _M_data(__cache) { _M_initialize_numpunct(); } - explicit - numpunct(__c_locale __cloc, size_t __refs = 0) : locale::facet(__refs) + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param refs Refcount to pass to the base class. + */ + explicit + numpunct(__c_locale __cloc, size_t __refs = 0) + : facet(__refs), _M_data(NULL) { _M_initialize_numpunct(__cloc); } - char_type + /** + * @brief Return decimal point character. + * + * This function returns a char_type to use as a decimal point. It + * does so by returning returning + * numpunct<char_type>::do_decimal_point(). + * + * @return @a char_type representing a decimal point. + */ + char_type decimal_point() const { return this->do_decimal_point(); } - char_type + /** + * @brief Return thousands separator character. + * + * This function returns a char_type to use as a thousands + * separator. It does so by returning returning + * numpunct<char_type>::do_thousands_sep(). + * + * @return char_type representing a thousands separator. + */ + char_type thousands_sep() const { return this->do_thousands_sep(); } - string + /** + * @brief Return grouping specification. + * + * This function returns a string representing groupings for the + * integer part of a number. Groupings indicate where thousands + * separators should be inserted in the integer part of a number. + * + * Each char in the return string is interpret as an integer + * rather than a character. These numbers represent the number + * of digits in a group. The first char in the string + * represents the number of digits in the least significant + * group. If a char is negative, it indicates an unlimited + * number of digits for the group. If more chars from the + * string are required to group a number, the last char is used + * repeatedly. + * + * For example, if the grouping() returns "\003\002" and is + * applied to the number 123456789, this corresponds to + * 12,34,56,789. Note that if the string was "32", this would + * put more than 50 digits into the least significant group if + * the character set is ASCII. + * + * The string is returned by calling + * numpunct<char_type>::do_grouping(). + * + * @return string representing grouping specification. + */ + string grouping() const { return this->do_grouping(); } - string_type + /** + * @brief Return string representation of bool true. + * + * This function returns a string_type containing the text + * representation for true bool variables. It does so by calling + * numpunct<char_type>::do_truename(). + * + * @return string_type representing printed form of true. + */ + string_type truename() const { return this->do_truename(); } - string_type + /** + * @brief Return string representation of bool false. + * + * This function returns a string_type containing the text + * representation for false bool variables. It does so by calling + * numpunct<char_type>::do_falsename(). + * + * @return string_type representing printed form of false. + */ + string_type falsename() const { return this->do_falsename(); } protected: - virtual + /// Destructor. + virtual ~numpunct(); - virtual char_type + /** + * @brief Return decimal point character. + * + * Returns a char_type to use as a decimal point. This function is a + * hook for derived classes to change the value returned. + * + * @return @a char_type representing a decimal point. + */ + virtual char_type do_decimal_point() const - { return _M_decimal_point; } - - virtual char_type + { return _M_data->_M_decimal_point; } + + /** + * @brief Return thousands separator character. + * + * Returns a char_type to use as a thousands separator. This function + * is a hook for derived classes to change the value returned. + * + * @return @a char_type representing a thousands separator. + */ + virtual char_type do_thousands_sep() const - { return _M_thousands_sep; } - + { return _M_data->_M_thousands_sep; } + + /** + * @brief Return grouping specification. + * + * Returns a string representing groupings for the integer part of a + * number. This function is a hook for derived classes to change the + * value returned. @see grouping() for details. + * + * @return String representing grouping specification. + */ virtual string do_grouping() const - { return _M_grouping; } - - virtual string_type + { return _M_data->_M_grouping; } + + /** + * @brief Return string representation of bool true. + * + * Returns a string_type containing the text representation for true + * bool variables. This function is a hook for derived classes to + * change the value returned. + * + * @return string_type representing printed form of true. + */ + virtual string_type do_truename() const - { return _M_truename; } - - virtual string_type + { return _M_data->_M_truename; } + + /** + * @brief Return string representation of bool false. + * + * Returns a string_type containing the text representation for false + * bool variables. This function is a hook for derived classes to + * change the value returned. + * + * @return string_type representing printed form of false. + */ + virtual string_type do_falsename() const - { return _M_falsename; } + { return _M_data->_M_falsename; } // For use at construction time only. - void + void _M_initialize_numpunct(__c_locale __cloc = NULL); }; template<typename _CharT> locale::id numpunct<_CharT>::id; - template<> + template<> numpunct<char>::~numpunct(); - template<> + template<> void numpunct<char>::_M_initialize_numpunct(__c_locale __cloc); -#ifdef _GLIBCPP_USE_WCHAR_T - template<> +#ifdef _GLIBCXX_USE_WCHAR_T + template<> numpunct<wchar_t>::~numpunct(); - template<> + template<> void numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc); #endif @@ -682,342 +1891,675 @@ namespace std template<typename _CharT> class numpunct_byname : public numpunct<_CharT> { - // Data Member. - __c_locale _M_c_locale_numpunct; - public: - typedef _CharT char_type; - typedef basic_string<_CharT> string_type; + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; - explicit + explicit numpunct_byname(const char* __s, size_t __refs = 0) : numpunct<_CharT>(__refs) { - _S_create_c_locale(_M_c_locale_numpunct, __s); - _M_initialize_numpunct(_M_c_locale_numpunct); + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + __c_locale __tmp; + this->_S_create_c_locale(__tmp, __s); + this->_M_initialize_numpunct(__tmp); + this->_S_destroy_c_locale(__tmp); + } } protected: - virtual - ~numpunct_byname() - { _S_destroy_c_locale(_M_c_locale_numpunct); } + virtual + ~numpunct_byname() { } }; + /** + * @brief Facet for parsing number strings. + * + * This facet encapsulates the code to parse and return a number + * from a string. It is used by the istream numeric extraction + * operators. + * + * The num_get template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from the num_get facet. + */ template<typename _CharT, typename _InIter> - class num_get : public locale::facet, public __num_base + class num_get : public locale::facet { public: // Types: - typedef _CharT char_type; - typedef _InIter iter_type; - - static locale::id id; - - explicit - num_get(size_t __refs = 0) : locale::facet(__refs) { } - - iter_type + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _InIter iter_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + num_get(size_t __refs = 0) : facet(__refs) { } + + /** + * @brief Numeric parsing. + * + * Parses the input stream into the bool @a v. It does so by calling + * num_put::do_put(). + * + * If ios_base::boolalpha is set, attempts to read + * ctype<CharT>::truename() or ctype<CharT>::falsename(). Sets + * @a v to true or false if successful. Sets err to + * ios_base::failbit if reading the string fails. Sets err to + * ios_base::eofbit if the stream is emptied. + * + * If ios_base::boolalpha is not set, proceeds as with reading a long, + * except if the value is 1, sets @a v to true, if the value is 0, sets + * @a v to false, and otherwise set err to ios_base::failbit. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, bool& __v) const { return this->do_get(__in, __end, __io, __err, __v); } + //@{ + /** + * @brief Numeric parsing. + * + * Parses the input stream into the integral variable @a v. It does so + * by calling num_put::do_put(). + * + * Parsing is affected by the flag settings in @a io. + * + * The basic parse is affected by the value of io.flags() & + * ios_base::basefield. If equal to ios_base::oct, parses like the + * scanf %o specifier. Else if equal to ios_base::hex, parses like %X + * specifier. Else if basefield equal to 0, parses like the %i + * specifier. Otherwise, parses like %d for signed and %u for unsigned + * types. The matching type length modifier is also used. + * + * Digit grouping is intrepreted according to numpunct::grouping() and + * numpunct::thousands_sep(). If the pattern of digit groups isn't + * consistent, sets err to ios_base::failbit. + * + * If parsing the string yields a valid value for @a v, @a v is set. + * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. + * Sets err to ios_base::eofbit if the stream is emptied. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ iter_type - get(iter_type __in, iter_type __end, ios_base& __io, + get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, long& __v) const { return this->do_get(__in, __end, __io, __err, __v); } - iter_type + iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned short& __v) const { return this->do_get(__in, __end, __io, __err, __v); } - iter_type + iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned int& __v) const { return this->do_get(__in, __end, __io, __err, __v); } - iter_type + iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned long& __v) const { return this->do_get(__in, __end, __io, __err, __v); } -#ifdef _GLIBCPP_USE_LONG_LONG - iter_type +#ifdef _GLIBCXX_USE_LONG_LONG + iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, long long& __v) const { return this->do_get(__in, __end, __io, __err, __v); } - iter_type + iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned long long& __v) const { return this->do_get(__in, __end, __io, __err, __v); } #endif - - iter_type + //@} + + //@{ + /** + * @brief Numeric parsing. + * + * Parses the input stream into the integral variable @a v. It does so + * by calling num_put::do_put(). + * + * The input characters are parsed like the scanf %g specifier. The + * matching type length modifier is also used. + * + * The decimal point character used is numpunct::decimal_point(). + * Digit grouping is intrepreted according to numpunct::grouping() and + * numpunct::thousands_sep(). If the pattern of digit groups isn't + * consistent, sets err to ios_base::failbit. + * + * If parsing the string yields a valid value for @a v, @a v is set. + * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. + * Sets err to ios_base::eofbit if the stream is emptied. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, float& __v) const { return this->do_get(__in, __end, __io, __err, __v); } - iter_type + iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, double& __v) const { return this->do_get(__in, __end, __io, __err, __v); } - iter_type + iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, long double& __v) const { return this->do_get(__in, __end, __io, __err, __v); } - - iter_type + //@} + + /** + * @brief Numeric parsing. + * + * Parses the input stream into the pointer variable @a v. It does so + * by calling num_put::do_put(). + * + * The input characters are parsed like the scanf %p specifier. + * + * Digit grouping is intrepreted according to numpunct::grouping() and + * numpunct::thousands_sep(). If the pattern of digit groups isn't + * consistent, sets err to ios_base::failbit. + * + * Note that the digit grouping effect for pointers is a bit ambiguous + * in the standard and shouldn't be relied on. See DR 344. + * + * If parsing the string yields a valid value for @a v, @a v is set. + * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. + * Sets err to ios_base::eofbit if the stream is emptied. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, void*& __v) const - { return this->do_get(__in, __end, __io, __err, __v); } + { return this->do_get(__in, __end, __io, __err, __v); } protected: + /// Destructor. virtual ~num_get() { } - iter_type - _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&, + iter_type + _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&, string& __xtrc) const; - iter_type - _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&, - string& __xtrc, int& __base) const; - - virtual iter_type + template<typename _ValueT> + iter_type + _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&, + _ValueT& __v) const; + + //@{ + /** + * @brief Numeric parsing. + * + * Parses the input stream into the variable @a v. This function is a + * hook for derived classes to change the value returned. @see get() + * for more details. + * + * @param in Start of input stream. + * @param end End of input stream. + * @param io Source of locale and flags. + * @param err Error flags to set. + * @param v Value to format and insert. + * @return Iterator after reading. + */ + virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const; - virtual iter_type + virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const; - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, unsigned short&) const; - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, unsigned int&) const; - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, unsigned long&) const; -#ifdef _GLIBCPP_USE_LONG_LONG - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, +#ifdef _GLIBCXX_USE_LONG_LONG + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, long long&) const; - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, unsigned long long&) const; #endif - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, float&) const; - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, double&) const; - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, long double&) const; - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, + virtual iter_type + do_get(iter_type, iter_type, ios_base&, ios_base::iostate& __err, void*&) const; + //@} }; template<typename _CharT, typename _InIter> locale::id num_get<_CharT, _InIter>::id; -#if 0 - // Partial specialization for istreambuf_iterator, so can use traits_type. - template<typename _CharT> - class num_get<_CharT, istreambuf_iterator<_CharT> >; - - iter_type - _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&, - string& __xtrc) const; - - iter_type - _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&, - string& __xtrc, int& __base) const; - - virtual iter_type - do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const; -#endif + /** + * @brief Facet for converting numbers to strings. + * + * This facet encapsulates the code to convert a number to a string. It is + * used by the ostream numeric insertion operators. + * + * The num_put template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from the num_put facet. + */ template<typename _CharT, typename _OutIter> - class num_put : public locale::facet, public __num_base + class num_put : public locale::facet { public: // Types: - typedef _CharT char_type; - typedef _OutIter iter_type; - static locale::id id; + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _OutIter iter_type; + //@} - explicit - num_put(size_t __refs = 0) : locale::facet(__refs) { } + /// Numpunct facet id. + static locale::id id; - iter_type + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + num_put(size_t __refs = 0) : facet(__refs) { } + + /** + * @brief Numeric formatting. + * + * Formats the boolean @a v and inserts it into a stream. It does so + * by calling num_put::do_put(). + * + * If ios_base::boolalpha is set, writes ctype<CharT>::truename() or + * ctype<CharT>::falsename(). Otherwise formats @a v as an int. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + iter_type put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const { return this->do_put(__s, __f, __fill, __v); } - iter_type + //@{ + /** + * @brief Numeric formatting. + * + * Formats the integral value @a v and inserts it into a + * stream. It does so by calling num_put::do_put(). + * + * Formatting is affected by the flag settings in @a io. + * + * The basic format is affected by the value of io.flags() & + * ios_base::basefield. If equal to ios_base::oct, formats like the + * printf %o specifier. Else if equal to ios_base::hex, formats like + * %x or %X with ios_base::uppercase unset or set respectively. + * Otherwise, formats like %d, %ld, %lld for signed and %u, %lu, %llu + * for unsigned values. Note that if both oct and hex are set, neither + * will take effect. + * + * If ios_base::showpos is set, '+' is output before positive values. + * If ios_base::showbase is set, '0' precedes octal values (except 0) + * and '0[xX]' precedes hex values. + * + * Thousands separators are inserted according to numpunct::grouping() + * and numpunct::thousands_sep(). The decimal point character used is + * numpunct::decimal_point(). + * + * If io.width() is non-zero, enough @a fill characters are inserted to + * make the result at least that wide. If + * (io.flags() & ios_base::adjustfield) == ios_base::left, result is + * padded at the end. If ios_base::internal, then padding occurs + * immediately after either a '+' or '-' or after '0x' or '0X'. + * Otherwise, padding occurs at the beginning. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + iter_type put(iter_type __s, ios_base& __f, char_type __fill, long __v) const { return this->do_put(__s, __f, __fill, __v); } - iter_type - put(iter_type __s, ios_base& __f, char_type __fill, + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, unsigned long __v) const { return this->do_put(__s, __f, __fill, __v); } -#ifdef _GLIBCPP_USE_LONG_LONG - iter_type +#ifdef _GLIBCXX_USE_LONG_LONG + iter_type put(iter_type __s, ios_base& __f, char_type __fill, long long __v) const { return this->do_put(__s, __f, __fill, __v); } - iter_type - put(iter_type __s, ios_base& __f, char_type __fill, + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, unsigned long long __v) const { return this->do_put(__s, __f, __fill, __v); } #endif - - iter_type + //@} + + //@{ + /** + * @brief Numeric formatting. + * + * Formats the floating point value @a v and inserts it into a stream. + * It does so by calling num_put::do_put(). + * + * Formatting is affected by the flag settings in @a io. + * + * The basic format is affected by the value of io.flags() & + * ios_base::floatfield. If equal to ios_base::fixed, formats like the + * printf %f specifier. Else if equal to ios_base::scientific, formats + * like %e or %E with ios_base::uppercase unset or set respectively. + * Otherwise, formats like %g or %G depending on uppercase. Note that + * if both fixed and scientific are set, the effect will also be like + * %g or %G. + * + * The output precision is given by io.precision(). This precision is + * capped at numeric_limits::digits10 + 2 (different for double and + * long double). The default precision is 6. + * + * If ios_base::showpos is set, '+' is output before positive values. + * If ios_base::showpoint is set, a decimal point will always be + * output. + * + * Thousands separators are inserted according to numpunct::grouping() + * and numpunct::thousands_sep(). The decimal point character used is + * numpunct::decimal_point(). + * + * If io.width() is non-zero, enough @a fill characters are inserted to + * make the result at least that wide. If + * (io.flags() & ios_base::adjustfield) == ios_base::left, result is + * padded at the end. If ios_base::internal, then padding occurs + * immediately after either a '+' or '-' or after '0x' or '0X'. + * Otherwise, padding occurs at the beginning. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + iter_type put(iter_type __s, ios_base& __f, char_type __fill, double __v) const { return this->do_put(__s, __f, __fill, __v); } - iter_type - put(iter_type __s, ios_base& __f, char_type __fill, + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, long double __v) const { return this->do_put(__s, __f, __fill, __v); } - - iter_type - put(iter_type __s, ios_base& __f, char_type __fill, + //@} + + /** + * @brief Numeric formatting. + * + * Formats the pointer value @a v and inserts it into a stream. It + * does so by calling num_put::do_put(). + * + * This function formats @a v as an unsigned long with ios_base::hex + * and ios_base::showbase set. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __f, char_type __fill, const void* __v) const { return this->do_put(__s, __f, __fill, __v); } protected: template<typename _ValueT> iter_type - _M_convert_float(iter_type, ios_base& __io, char_type __fill, - char __mod, _ValueT __v) const; + _M_insert_float(iter_type, ios_base& __io, char_type __fill, + char __mod, _ValueT __v) const; void - _M_group_float(const string& __grouping, char_type __sep, - const char_type* __p, char_type* __new, char_type* __cs, - int& __len) const; + _M_group_float(const char* __grouping, size_t __grouping_size, + char_type __sep, const char_type* __p, char_type* __new, + char_type* __cs, int& __len) const; template<typename _ValueT> iter_type - _M_convert_int(iter_type, ios_base& __io, char_type __fill, - _ValueT __v) const; + _M_insert_int(iter_type, ios_base& __io, char_type __fill, + _ValueT __v) const; void - _M_group_int(const string& __grouping, char_type __sep, - ios_base& __io, char_type* __new, char_type* __cs, - int& __len) const; + _M_group_int(const char* __grouping, size_t __grouping_size, + char_type __sep, ios_base& __io, char_type* __new, + char_type* __cs, int& __len) const; void - _M_pad(char_type __fill, streamsize __w, ios_base& __io, + _M_pad(char_type __fill, streamsize __w, ios_base& __io, char_type* __new, const char_type* __cs, int& __len) const; -#if 1 - // XXX GLIBCXX_ABI Deprecated, compatibility only. - template<typename _ValueT> - iter_type - _M_convert_int(iter_type, ios_base& __io, char_type __fill, - char __mod, char __modl, _ValueT __v) const; - - iter_type - _M_widen_float(iter_type, ios_base& __io, char_type __fill, char* __cs, - int __len) const; - - iter_type - _M_widen_int(iter_type, ios_base& __io, char_type __fill, char* __cs, - int __len) const; - - iter_type - _M_insert(iter_type, ios_base& __io, char_type __fill, - const char_type* __ws, int __len) const; -#endif - - virtual + /// Destructor. + virtual ~num_put() { }; - virtual iter_type + //@{ + /** + * @brief Numeric formatting. + * + * These functions do the work of formatting numeric values and + * inserting them into a stream. This function is a hook for derived + * classes to change the value returned. + * + * @param s Stream to write to. + * @param io Source of locale and flags. + * @param fill Char_type to use for filling. + * @param v Value to format and insert. + * @return Iterator after writing. + */ + virtual iter_type do_put(iter_type, ios_base&, char_type __fill, bool __v) const; - virtual iter_type + virtual iter_type do_put(iter_type, ios_base&, char_type __fill, long __v) const; - virtual iter_type + virtual iter_type do_put(iter_type, ios_base&, char_type __fill, unsigned long) const; -#ifdef _GLIBCPP_USE_LONG_LONG - virtual iter_type +#ifdef _GLIBCXX_USE_LONG_LONG + virtual iter_type do_put(iter_type, ios_base&, char_type __fill, long long __v) const; virtual iter_type do_put(iter_type, ios_base&, char_type __fill, unsigned long long) const; #endif - virtual iter_type + virtual iter_type do_put(iter_type, ios_base&, char_type __fill, double __v) const; - virtual iter_type + virtual iter_type do_put(iter_type, ios_base&, char_type __fill, long double __v) const; - virtual iter_type + virtual iter_type do_put(iter_type, ios_base&, char_type __fill, const void* __v) const; + //@} }; template <typename _CharT, typename _OutIter> locale::id num_put<_CharT, _OutIter>::id; + /** + * @brief Facet for localized string comparison. + * + * This facet encapsulates the code to compare strings in a localized + * manner. + * + * The collate template uses protected virtual functions to provide + * the actual results. The public accessors forward the call to + * the virtual functions. These virtual functions are hooks for + * developers to implement the behavior they require from the + * collate facet. + */ template<typename _CharT> class collate : public locale::facet { public: // Types: - typedef _CharT char_type; - typedef basic_string<_CharT> string_type; + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} protected: // Underlying "C" library locale information saved from // initialization, needed by collate_byname as well. __c_locale _M_c_locale_collate; - - public: - static locale::id id; - explicit + public: + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit collate(size_t __refs = 0) - : locale::facet(__refs) - { _M_c_locale_collate = _S_c_locale; } + : facet(__refs), _M_c_locale_collate(_S_get_c_locale()) + { } - explicit - collate(__c_locale __cloc, size_t __refs = 0) - : locale::facet(__refs) - { _M_c_locale_collate = _S_clone_c_locale(__cloc); } + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param refs Passed to the base facet class. + */ + explicit + collate(__c_locale __cloc, size_t __refs = 0) + : facet(__refs), _M_c_locale_collate(_S_clone_c_locale(__cloc)) + { } - int + /** + * @brief Compare two strings. + * + * This function compares two strings and returns the result by calling + * collate::do_compare(). + * + * @param lo1 Start of string 1. + * @param hi1 End of string 1. + * @param lo2 Start of string 2. + * @param hi2 End of string 2. + * @return 1 if string1 > string2, -1 if string1 < string2, else 0. + */ + int compare(const _CharT* __lo1, const _CharT* __hi1, const _CharT* __lo2, const _CharT* __hi2) const { return this->do_compare(__lo1, __hi1, __lo2, __hi2); } - string_type + /** + * @brief Transform string to comparable form. + * + * This function is a wrapper for strxfrm functionality. It takes the + * input string and returns a modified string that can be directly + * compared to other transformed strings. In the "C" locale, this + * function just returns a copy of the input string. In some other + * locales, it may replace two chars with one, change a char for + * another, etc. It does so by returning collate::do_transform(). + * + * @param lo Start of string. + * @param hi End of string. + * @return Transformed string_type. + */ + string_type transform(const _CharT* __lo, const _CharT* __hi) const { return this->do_transform(__lo, __hi); } - long + /** + * @brief Return hash of a string. + * + * This function computes and returns a hash on the input string. It + * does so by returning collate::do_hash(). + * + * @param lo Start of string. + * @param hi End of string. + * @return Hash value. + */ + long hash(const _CharT* __lo, const _CharT* __hi) const { return this->do_hash(__lo, __hi); } - + // Used to abstract out _CharT bits in virtual member functions, below. int _M_compare(const _CharT*, const _CharT*) const; @@ -1026,18 +2568,53 @@ namespace std _M_transform(_CharT*, const _CharT*, size_t) const; protected: + /// Destructor. virtual - ~collate() + ~collate() { _S_destroy_c_locale(_M_c_locale_collate); } - virtual int + /** + * @brief Compare two strings. + * + * This function is a hook for derived classes to change the value + * returned. @see compare(). + * + * @param lo1 Start of string 1. + * @param hi1 End of string 1. + * @param lo2 Start of string 2. + * @param hi2 End of string 2. + * @return 1 if string1 > string2, -1 if string1 < string2, else 0. + */ + virtual int do_compare(const _CharT* __lo1, const _CharT* __hi1, const _CharT* __lo2, const _CharT* __hi2) const; - virtual string_type + /** + * @brief Transform string to comparable form. + * + * This function is a hook for derived classes to change the value + * returned. + * + * @param lo1 Start of string 1. + * @param hi1 End of string 1. + * @param lo2 Start of string 2. + * @param hi2 End of string 2. + * @return 1 if string1 > string2, -1 if string1 < string2, else 0. + */ + virtual string_type do_transform(const _CharT* __lo, const _CharT* __hi) const; - virtual long + /** + * @brief Return hash of a string. + * + * This function computes and returns a hash on the input string. This + * function is a hook for derived classes to change the value returned. + * + * @param lo Start of string. + * @param hi End of string. + * @return Hash value. + */ + virtual long do_hash(const _CharT* __lo, const _CharT* __hi) const; }; @@ -1046,16 +2623,16 @@ namespace std // Specializations. template<> - int + int collate<char>::_M_compare(const char*, const char*) const; template<> size_t collate<char>::_M_transform(char*, const char*, size_t) const; -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T template<> - int + int collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const; template<> @@ -1067,23 +2644,35 @@ namespace std class collate_byname : public collate<_CharT> { public: + //@{ + /// Public typedefs typedef _CharT char_type; typedef basic_string<_CharT> string_type; + //@} - explicit + explicit collate_byname(const char* __s, size_t __refs = 0) - : collate<_CharT>(__refs) - { - _S_destroy_c_locale(_M_c_locale_collate); - _S_create_c_locale(_M_c_locale_collate, __s); + : collate<_CharT>(__refs) + { + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + this->_S_destroy_c_locale(this->_M_c_locale_collate); + this->_S_create_c_locale(this->_M_c_locale_collate, __s); + } } protected: - virtual + virtual ~collate_byname() { } }; + /** + * @brief Time format ordering data. + * + * This class provides an enum representing different orderings of day, + * month, and year. + */ class time_base { public: @@ -1091,183 +2680,263 @@ namespace std }; template<typename _CharT> - class __timepunct : public locale::facet + struct __timepunct_cache : public locale::facet { - public: - // Types: - typedef _CharT __char_type; - typedef basic_string<_CharT> __string_type; - - static locale::id id; - // List of all known timezones, with GMT first. - static const _CharT* _S_timezones[14]; + static const _CharT* _S_timezones[14]; - protected: - __c_locale _M_c_locale_timepunct; - char* _M_name_timepunct; - const _CharT* _M_date_format; - const _CharT* _M_date_era_format; - const _CharT* _M_time_format; - const _CharT* _M_time_era_format; + const _CharT* _M_date_format; + const _CharT* _M_date_era_format; + const _CharT* _M_time_format; + const _CharT* _M_time_era_format; const _CharT* _M_date_time_format; const _CharT* _M_date_time_era_format; - const _CharT* _M_am; - const _CharT* _M_pm; + const _CharT* _M_am; + const _CharT* _M_pm; const _CharT* _M_am_pm_format; // Day names, starting with "C"'s Sunday. - const _CharT* _M_day1; - const _CharT* _M_day2; - const _CharT* _M_day3; - const _CharT* _M_day4; - const _CharT* _M_day5; - const _CharT* _M_day6; - const _CharT* _M_day7; + const _CharT* _M_day1; + const _CharT* _M_day2; + const _CharT* _M_day3; + const _CharT* _M_day4; + const _CharT* _M_day5; + const _CharT* _M_day6; + const _CharT* _M_day7; // Abbreviated day names, starting with "C"'s Sun. - const _CharT* _M_day_a1; - const _CharT* _M_day_a2; - const _CharT* _M_day_a3; - const _CharT* _M_day_a4; - const _CharT* _M_day_a5; - const _CharT* _M_day_a6; - const _CharT* _M_day_a7; + const _CharT* _M_aday1; + const _CharT* _M_aday2; + const _CharT* _M_aday3; + const _CharT* _M_aday4; + const _CharT* _M_aday5; + const _CharT* _M_aday6; + const _CharT* _M_aday7; // Month names, starting with "C"'s January. - const _CharT* _M_month01; - const _CharT* _M_month02; - const _CharT* _M_month03; - const _CharT* _M_month04; - const _CharT* _M_month05; - const _CharT* _M_month06; - const _CharT* _M_month07; - const _CharT* _M_month08; - const _CharT* _M_month09; - const _CharT* _M_month10; - const _CharT* _M_month11; - const _CharT* _M_month12; + const _CharT* _M_month01; + const _CharT* _M_month02; + const _CharT* _M_month03; + const _CharT* _M_month04; + const _CharT* _M_month05; + const _CharT* _M_month06; + const _CharT* _M_month07; + const _CharT* _M_month08; + const _CharT* _M_month09; + const _CharT* _M_month10; + const _CharT* _M_month11; + const _CharT* _M_month12; // Abbreviated month names, starting with "C"'s Jan. - const _CharT* _M_month_a01; - const _CharT* _M_month_a02; - const _CharT* _M_month_a03; - const _CharT* _M_month_a04; - const _CharT* _M_month_a05; - const _CharT* _M_month_a06; - const _CharT* _M_month_a07; - const _CharT* _M_month_a08; - const _CharT* _M_month_a09; - const _CharT* _M_month_a10; - const _CharT* _M_month_a11; - const _CharT* _M_month_a12; + const _CharT* _M_amonth01; + const _CharT* _M_amonth02; + const _CharT* _M_amonth03; + const _CharT* _M_amonth04; + const _CharT* _M_amonth05; + const _CharT* _M_amonth06; + const _CharT* _M_amonth07; + const _CharT* _M_amonth08; + const _CharT* _M_amonth09; + const _CharT* _M_amonth10; + const _CharT* _M_amonth11; + const _CharT* _M_amonth12; + + bool _M_allocated; + + __timepunct_cache(size_t __refs = 0) : facet(__refs), + _M_date_format(NULL), _M_date_era_format(NULL), _M_time_format(NULL), + _M_time_era_format(NULL), _M_date_time_format(NULL), + _M_date_time_era_format(NULL), _M_am(NULL), _M_pm(NULL), + _M_am_pm_format(NULL), _M_day1(NULL), _M_day2(NULL), _M_day3(NULL), + _M_day4(NULL), _M_day5(NULL), _M_day6(NULL), _M_day7(NULL), + _M_aday1(NULL), _M_aday2(NULL), _M_aday3(NULL), _M_aday4(NULL), + _M_aday5(NULL), _M_aday6(NULL), _M_aday7(NULL), _M_month01(NULL), + _M_month02(NULL), _M_month03(NULL), _M_month04(NULL), _M_month05(NULL), + _M_month06(NULL), _M_month07(NULL), _M_month08(NULL), _M_month09(NULL), + _M_month10(NULL), _M_month11(NULL), _M_month12(NULL), _M_amonth01(NULL), + _M_amonth02(NULL), _M_amonth03(NULL), _M_amonth04(NULL), + _M_amonth05(NULL), _M_amonth06(NULL), _M_amonth07(NULL), + _M_amonth08(NULL), _M_amonth09(NULL), _M_amonth10(NULL), + _M_amonth11(NULL), _M_amonth12(NULL), _M_allocated(false) + { } + + ~__timepunct_cache(); + + void + _M_cache(const locale& __loc); + + private: + __timepunct_cache& + operator=(const __timepunct_cache&); + + explicit + __timepunct_cache(const __timepunct_cache&); + }; + + template<typename _CharT> + __timepunct_cache<_CharT>::~__timepunct_cache() + { + if (_M_allocated) + { + // Unused. + } + } + + // Specializations. + template<> + const char* + __timepunct_cache<char>::_S_timezones[14]; +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + const wchar_t* + __timepunct_cache<wchar_t>::_S_timezones[14]; +#endif + + // Generic. + template<typename _CharT> + const _CharT* __timepunct_cache<_CharT>::_S_timezones[14]; + + template<typename _CharT> + class __timepunct : public locale::facet + { public: - explicit + // Types: + typedef _CharT __char_type; + typedef basic_string<_CharT> __string_type; + typedef __timepunct_cache<_CharT> __cache_type; + + protected: + __cache_type* _M_data; + __c_locale _M_c_locale_timepunct; + const char* _M_name_timepunct; + + public: + /// Numpunct facet id. + static locale::id id; + + explicit __timepunct(size_t __refs = 0); - explicit + explicit + __timepunct(__cache_type* __cache, size_t __refs = 0); + + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param s The name of a locale. + * @param refs Passed to the base facet class. + */ + explicit __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0); void - _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format, + _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format, const tm* __tm) const; void _M_date_formats(const _CharT** __date) const { // Always have default first. - __date[0] = _M_date_format; - __date[1] = _M_date_era_format; + __date[0] = _M_data->_M_date_format; + __date[1] = _M_data->_M_date_era_format; } void _M_time_formats(const _CharT** __time) const { // Always have default first. - __time[0] = _M_time_format; - __time[1] = _M_time_era_format; + __time[0] = _M_data->_M_time_format; + __time[1] = _M_data->_M_time_era_format; } void - _M_ampm(const _CharT** __ampm) const - { - __ampm[0] = _M_am; - __ampm[1] = _M_pm; - } - - void _M_date_time_formats(const _CharT** __dt) const { // Always have default first. - __dt[0] = _M_date_time_format; - __dt[1] = _M_date_time_era_format; + __dt[0] = _M_data->_M_date_time_format; + __dt[1] = _M_data->_M_date_time_era_format; + } + + void + _M_am_pm_format(const _CharT* __ampm) const + { __ampm = _M_data->_M_am_pm_format; } + + void + _M_am_pm(const _CharT** __ampm) const + { + __ampm[0] = _M_data->_M_am; + __ampm[1] = _M_data->_M_pm; } void _M_days(const _CharT** __days) const - { - __days[0] = _M_day1; - __days[1] = _M_day2; - __days[2] = _M_day3; - __days[3] = _M_day4; - __days[4] = _M_day5; - __days[5] = _M_day6; - __days[6] = _M_day7; + { + __days[0] = _M_data->_M_day1; + __days[1] = _M_data->_M_day2; + __days[2] = _M_data->_M_day3; + __days[3] = _M_data->_M_day4; + __days[4] = _M_data->_M_day5; + __days[5] = _M_data->_M_day6; + __days[6] = _M_data->_M_day7; } void _M_days_abbreviated(const _CharT** __days) const - { - __days[0] = _M_day_a1; - __days[1] = _M_day_a2; - __days[2] = _M_day_a3; - __days[3] = _M_day_a4; - __days[4] = _M_day_a5; - __days[5] = _M_day_a6; - __days[6] = _M_day_a7; + { + __days[0] = _M_data->_M_aday1; + __days[1] = _M_data->_M_aday2; + __days[2] = _M_data->_M_aday3; + __days[3] = _M_data->_M_aday4; + __days[4] = _M_data->_M_aday5; + __days[5] = _M_data->_M_aday6; + __days[6] = _M_data->_M_aday7; } void _M_months(const _CharT** __months) const - { - __months[0] = _M_month01; - __months[1] = _M_month02; - __months[2] = _M_month03; - __months[3] = _M_month04; - __months[4] = _M_month05; - __months[5] = _M_month06; - __months[6] = _M_month07; - __months[7] = _M_month08; - __months[8] = _M_month09; - __months[9] = _M_month10; - __months[10] = _M_month11; - __months[11] = _M_month12; + { + __months[0] = _M_data->_M_month01; + __months[1] = _M_data->_M_month02; + __months[2] = _M_data->_M_month03; + __months[3] = _M_data->_M_month04; + __months[4] = _M_data->_M_month05; + __months[5] = _M_data->_M_month06; + __months[6] = _M_data->_M_month07; + __months[7] = _M_data->_M_month08; + __months[8] = _M_data->_M_month09; + __months[9] = _M_data->_M_month10; + __months[10] = _M_data->_M_month11; + __months[11] = _M_data->_M_month12; } void _M_months_abbreviated(const _CharT** __months) const - { - __months[0] = _M_month_a01; - __months[1] = _M_month_a02; - __months[2] = _M_month_a03; - __months[3] = _M_month_a04; - __months[4] = _M_month_a05; - __months[5] = _M_month_a06; - __months[6] = _M_month_a07; - __months[7] = _M_month_a08; - __months[8] = _M_month_a09; - __months[9] = _M_month_a10; - __months[10] = _M_month_a11; - __months[11] = _M_month_a12; + { + __months[0] = _M_data->_M_amonth01; + __months[1] = _M_data->_M_amonth02; + __months[2] = _M_data->_M_amonth03; + __months[3] = _M_data->_M_amonth04; + __months[4] = _M_data->_M_amonth05; + __months[5] = _M_data->_M_amonth06; + __months[6] = _M_data->_M_amonth07; + __months[7] = _M_data->_M_amonth08; + __months[8] = _M_data->_M_amonth09; + __months[9] = _M_data->_M_amonth10; + __months[10] = _M_data->_M_amonth11; + __months[11] = _M_data->_M_amonth12; } protected: - virtual + virtual ~__timepunct(); // For use at construction time only. - void + void _M_initialize_timepunct(__c_locale __cloc = NULL); }; @@ -1275,11 +2944,7 @@ namespace std locale::id __timepunct<_CharT>::id; // Specializations. - template<> - const char* - __timepunct<char>::_S_timezones[14]; - - template<> + template<> void __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc); @@ -1287,117 +2952,338 @@ namespace std void __timepunct<char>::_M_put(char*, size_t, const char*, const tm*) const; -#ifdef _GLIBCPP_USE_WCHAR_T - template<> - const wchar_t* - __timepunct<wchar_t>::_S_timezones[14]; - - template<> +#ifdef _GLIBCXX_USE_WCHAR_T + template<> void __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc); template<> void - __timepunct<wchar_t>::_M_put(wchar_t*, size_t, const wchar_t*, + __timepunct<wchar_t>::_M_put(wchar_t*, size_t, const wchar_t*, const tm*) const; #endif - // Generic. - template<typename _CharT> - const _CharT* __timepunct<_CharT>::_S_timezones[14]; - // Include host and configuration specific timepunct functions. #include <bits/time_members.h> + /** + * @brief Facet for parsing dates and times. + * + * This facet encapsulates the code to parse and return a date or + * time from a string. It is used by the istream numeric + * extraction operators. + * + * The time_get template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from the time_get facet. + */ template<typename _CharT, typename _InIter> class time_get : public locale::facet, public time_base { public: // Types: - typedef _CharT char_type; - typedef _InIter iter_type; - typedef basic_string<_CharT> __string_type; - - static locale::id id; - - explicit - time_get(size_t __refs = 0) - : locale::facet (__refs) { } - - dateorder + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _InIter iter_type; + //@} + typedef basic_string<_CharT> __string_type; + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + time_get(size_t __refs = 0) + : facet (__refs) { } + + /** + * @brief Return preferred order of month, day, and year. + * + * This function returns an enum from timebase::dateorder giving the + * preferred ordering if the format "x" given to time_put::put() only + * uses month, day, and year. If the format "x" for the associated + * locale uses other fields, this function returns + * timebase::dateorder::noorder. + * + * NOTE: The library always returns noorder at the moment. + * + * @return A member of timebase::dateorder. + */ + dateorder date_order() const { return this->do_date_order(); } - iter_type - get_time(iter_type __beg, iter_type __end, ios_base& __io, + /** + * @brief Parse input time string. + * + * This function parses a time according to the format "x" and puts the + * results into a user-supplied struct tm. The result is returned by + * calling time_get::do_get_time(). + * + * If there is a valid time string according to format "x", @a tm will + * be filled in accordingly and the returned iterator will point to the + * first character beyond the time string. If an error occurs before + * the end, err |= ios_base::failbit. If parsing reads all the + * characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond time string. + */ + iter_type + get_time(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { return this->do_get_time(__beg, __end, __io, __err, __tm); } - iter_type + /** + * @brief Parse input date string. + * + * This function parses a date according to the format "X" and puts the + * results into a user-supplied struct tm. The result is returned by + * calling time_get::do_get_date(). + * + * If there is a valid date string according to format "X", @a tm will + * be filled in accordingly and the returned iterator will point to the + * first character beyond the date string. If an error occurs before + * the end, err |= ios_base::failbit. If parsing reads all the + * characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond date string. + */ + iter_type get_date(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { return this->do_get_date(__beg, __end, __io, __err, __tm); } - iter_type + /** + * @brief Parse input weekday string. + * + * This function parses a weekday name and puts the results into a + * user-supplied struct tm. The result is returned by calling + * time_get::do_get_weekday(). + * + * Parsing starts by parsing an abbreviated weekday name. If a valid + * abbreviation is followed by a character that would lead to the full + * weekday name, parsing continues until the full name is found or an + * error occurs. Otherwise parsing finishes at the end of the + * abbreviated name. + * + * If an error occurs before the end, err |= ios_base::failbit. If + * parsing reads all the characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond weekday name. + */ + iter_type get_weekday(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { return this->do_get_weekday(__beg, __end, __io, __err, __tm); } - iter_type - get_monthname(iter_type __beg, iter_type __end, ios_base& __io, + /** + * @brief Parse input month string. + * + * This function parses a month name and puts the results into a + * user-supplied struct tm. The result is returned by calling + * time_get::do_get_monthname(). + * + * Parsing starts by parsing an abbreviated month name. If a valid + * abbreviation is followed by a character that would lead to the full + * month name, parsing continues until the full name is found or an + * error occurs. Otherwise parsing finishes at the end of the + * abbreviated name. + * + * If an error occurs before the end, err |= ios_base::failbit. If + * parsing reads all the characters, err |= + * ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond month name. + */ + iter_type + get_monthname(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { return this->do_get_monthname(__beg, __end, __io, __err, __tm); } - iter_type + /** + * @brief Parse input year string. + * + * This function reads up to 4 characters to parse a year string and + * puts the results into a user-supplied struct tm. The result is + * returned by calling time_get::do_get_year(). + * + * 4 consecutive digits are interpreted as a full year. If there are + * exactly 2 consecutive digits, the library interprets this as the + * number of years since 1900. + * + * If an error occurs before the end, err |= ios_base::failbit. If + * parsing reads all the characters, err |= ios_base::eofbit. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond year. + */ + iter_type get_year(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { return this->do_get_year(__beg, __end, __io, __err, __tm); } protected: - virtual + /// Destructor. + virtual ~time_get() { } - virtual dateorder + /** + * @brief Return preferred order of month, day, and year. + * + * This function returns an enum from timebase::dateorder giving the + * preferred ordering if the format "x" given to time_put::put() only + * uses month, day, and year. This function is a hook for derived + * classes to change the value returned. + * + * @return A member of timebase::dateorder. + */ + virtual dateorder do_date_order() const; - virtual iter_type + /** + * @brief Parse input time string. + * + * This function parses a time according to the format "x" and puts the + * results into a user-supplied struct tm. This function is a hook for + * derived classes to change the value returned. @see get_time() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond time string. + */ + virtual iter_type do_get_time(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const; - virtual iter_type + /** + * @brief Parse input date string. + * + * This function parses a date according to the format "X" and puts the + * results into a user-supplied struct tm. This function is a hook for + * derived classes to change the value returned. @see get_date() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond date string. + */ + virtual iter_type do_get_date(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const; - virtual iter_type + /** + * @brief Parse input weekday string. + * + * This function parses a weekday name and puts the results into a + * user-supplied struct tm. This function is a hook for derived + * classes to change the value returned. @see get_weekday() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond weekday name. + */ + virtual iter_type do_get_weekday(iter_type __beg, iter_type __end, ios_base&, ios_base::iostate& __err, tm* __tm) const; - virtual iter_type - do_get_monthname(iter_type __beg, iter_type __end, ios_base&, + /** + * @brief Parse input month string. + * + * This function parses a month name and puts the results into a + * user-supplied struct tm. This function is a hook for derived + * classes to change the value returned. @see get_monthname() for + * details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond month name. + */ + virtual iter_type + do_get_monthname(iter_type __beg, iter_type __end, ios_base&, ios_base::iostate& __err, tm* __tm) const; - virtual iter_type + /** + * @brief Parse input year string. + * + * This function reads up to 4 characters to parse a year string and + * puts the results into a user-supplied struct tm. This function is a + * hook for derived classes to change the value returned. @see + * get_year() for details. + * + * @param beg Start of string to parse. + * @param end End of string to parse. + * @param io Source of the locale. + * @param err Error flags to set. + * @param tm Pointer to struct tm to fill in. + * @return Iterator to first char beyond year. + */ + virtual iter_type do_get_year(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const; // Extract numeric component of length __len. - void - _M_extract_num(iter_type& __beg, iter_type& __end, int& __member, + iter_type + _M_extract_num(iter_type __beg, iter_type __end, int& __member, int __min, int __max, size_t __len, - const ctype<_CharT>& __ctype, - ios_base::iostate& __err) const; - + ios_base& __io, ios_base::iostate& __err) const; + // Extract day or month name, or any unique array of string // literals in a const _CharT* array. - void - _M_extract_name(iter_type& __beg, iter_type& __end, int& __member, - const _CharT** __names, size_t __indexlen, - ios_base::iostate& __err) const; + iter_type + _M_extract_name(iter_type __beg, iter_type __end, int& __member, + const _CharT** __names, size_t __indexlen, + ios_base& __io, ios_base::iostate& __err) const; // Extract on a component-by-component basis, via __format argument. - void - _M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io, - ios_base::iostate& __err, tm* __tm, + iter_type + _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm, const _CharT* __format) const; }; @@ -1409,48 +3295,118 @@ namespace std { public: // Types: - typedef _CharT char_type; - typedef _InIter iter_type; + typedef _CharT char_type; + typedef _InIter iter_type; - explicit - time_get_byname(const char*, size_t __refs = 0) + explicit + time_get_byname(const char*, size_t __refs = 0) : time_get<_CharT, _InIter>(__refs) { } protected: - virtual + virtual ~time_get_byname() { } }; + /** + * @brief Facet for outputting dates and times. + * + * This facet encapsulates the code to format and output dates and times + * according to formats used by strftime(). + * + * The time_put template uses protected virtual functions to provide the + * actual results. The public accessors forward the call to the virtual + * functions. These virtual functions are hooks for developers to + * implement the behavior they require from the time_put facet. + */ template<typename _CharT, typename _OutIter> - class time_put : public locale::facet, public time_base + class time_put : public locale::facet { public: // Types: - typedef _CharT char_type; - typedef _OutIter iter_type; - - static locale::id id; - - explicit - time_put(size_t __refs = 0) - : locale::facet(__refs) { } - - iter_type - put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _OutIter iter_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + time_put(size_t __refs = 0) + : facet(__refs) { } + + /** + * @brief Format and output a time or date. + * + * This function formats the data in struct tm according to the + * provided format string. The format string is interpreted as by + * strftime(). + * + * @param s The stream to write to. + * @param io Source of locale. + * @param fill char_type to use for padding. + * @param tm Struct tm with date and time info to format. + * @param beg Start of format string. + * @param end End of format string. + * @return Iterator after writing. + */ + iter_type + put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, const _CharT* __beg, const _CharT* __end) const; - iter_type + /** + * @brief Format and output a time or date. + * + * This function formats the data in struct tm according to the + * provided format char and optional modifier. The format and modifier + * are interpreted as by strftime(). It does so by returning + * time_put::do_put(). + * + * @param s The stream to write to. + * @param io Source of locale. + * @param fill char_type to use for padding. + * @param tm Struct tm with date and time info to format. + * @param format Format char. + * @param mod Optional modifier char. + * @return Iterator after writing. + */ + iter_type put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, char __format, char __mod = 0) const { return this->do_put(__s, __io, __fill, __tm, __format, __mod); } protected: - virtual + /// Destructor. + virtual ~time_put() { } - virtual iter_type - do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, + /** + * @brief Format and output a time or date. + * + * This function formats the data in struct tm according to the + * provided format char and optional modifier. This function is a hook + * for derived classes to change the value returned. @see put() for + * more details. + * + * @param s The stream to write to. + * @param io Source of locale. + * @param fill char_type to use for padding. + * @param tm Struct tm with date and time info to format. + * @param format Format char. + * @param mod Optional modifier char. + * @return Iterator after writing. + */ + virtual iter_type + do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, char __format, char __mod) const; }; @@ -1462,20 +3418,30 @@ namespace std { public: // Types: - typedef _CharT char_type; - typedef _OutIter iter_type; + typedef _CharT char_type; + typedef _OutIter iter_type; - explicit - time_put_byname(const char* /*__s*/, size_t __refs = 0) - : time_put<_CharT, _OutIter>(__refs) + explicit + time_put_byname(const char*, size_t __refs = 0) + : time_put<_CharT, _OutIter>(__refs) { }; protected: - virtual + virtual ~time_put_byname() { } }; + /** + * @brief Money format ordering data. + * + * This class contains an ordered array of 4 fields to represent the + * pattern for formatting a money amount. Each field may contain one entry + * from the part enum. symbol, sign, and value must be present and the + * remaining field must contain either none or space. @see + * moneypunct::pos_format() and moneypunct::neg_format() for details of how + * these fields are interpreted. + */ class money_base { public: @@ -1484,123 +3450,435 @@ namespace std static const pattern _S_default_pattern; + enum + { + _S_minus, + _S_zero, + _S_end = 11 + }; + + // String literal of acceptable (narrow) input/output, for + // money_get/money_put. "-0123456789" + static const char* _S_atoms; + // Construct and return valid pattern consisting of some combination of: // space none symbol sign value - static pattern + static pattern _S_construct_pattern(char __precedes, char __space, char __posn); }; template<typename _CharT, bool _Intl> + struct __moneypunct_cache : public locale::facet + { + const char* _M_grouping; + size_t _M_grouping_size; + bool _M_use_grouping; + _CharT _M_decimal_point; + _CharT _M_thousands_sep; + const _CharT* _M_curr_symbol; + size_t _M_curr_symbol_size; + const _CharT* _M_positive_sign; + size_t _M_positive_sign_size; + const _CharT* _M_negative_sign; + size_t _M_negative_sign_size; + int _M_frac_digits; + money_base::pattern _M_pos_format; + money_base::pattern _M_neg_format; + + // A list of valid numeric literals for input and output: in the standard + // "C" locale, this is "-0123456789". This array contains the chars after + // having been passed through the current locale's ctype<_CharT>.widen(). + _CharT _M_atoms[money_base::_S_end]; + + bool _M_allocated; + + __moneypunct_cache(size_t __refs = 0) : facet(__refs), + _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false), + _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()), + _M_curr_symbol(NULL), _M_curr_symbol_size(0), + _M_positive_sign(NULL), _M_positive_sign_size(0), + _M_negative_sign(NULL), _M_negative_sign_size(0), + _M_frac_digits(0), + _M_pos_format(money_base::pattern()), + _M_neg_format(money_base::pattern()), _M_allocated(false) + { } + + ~__moneypunct_cache(); + + void + _M_cache(const locale& __loc); + + private: + __moneypunct_cache& + operator=(const __moneypunct_cache&); + + explicit + __moneypunct_cache(const __moneypunct_cache&); + }; + + template<typename _CharT, bool _Intl> + __moneypunct_cache<_CharT, _Intl>::~__moneypunct_cache() + { + if (_M_allocated) + { + delete [] _M_grouping; + delete [] _M_curr_symbol; + delete [] _M_positive_sign; + delete [] _M_negative_sign; + } + } + + /** + * @brief Facet for formatting data for money amounts. + * + * This facet encapsulates the punctuation, grouping and other formatting + * features of money amount string representations. + */ + template<typename _CharT, bool _Intl> class moneypunct : public locale::facet, public money_base { public: // Types: - typedef _CharT char_type; - typedef basic_string<_CharT> string_type; - - static const bool intl = _Intl; - static locale::id id; + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} + typedef __moneypunct_cache<_CharT, _Intl> __cache_type; private: - const char* _M_grouping; - char_type _M_decimal_point; - char_type _M_thousands_sep; - const char_type* _M_curr_symbol; - const char_type* _M_positive_sign; - const char_type* _M_negative_sign; - int _M_frac_digits; - pattern _M_pos_format; - pattern _M_neg_format; + __cache_type* _M_data; public: - explicit - moneypunct(size_t __refs = 0) : locale::facet(__refs) + /// This value is provided by the standard, but no reason for its + /// existence. + static const bool intl = _Intl; + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + moneypunct(size_t __refs = 0) : facet(__refs), _M_data(NULL) + { _M_initialize_moneypunct(); } + + /** + * @brief Constructor performs initialization. + * + * This is an internal constructor. + * + * @param cache Cache for optimization. + * @param refs Passed to the base facet class. + */ + explicit + moneypunct(__cache_type* __cache, size_t __refs = 0) + : facet(__refs), _M_data(__cache) { _M_initialize_moneypunct(); } - explicit - moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0) - : locale::facet(__refs) + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param s The name of a locale. + * @param refs Passed to the base facet class. + */ + explicit + moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0) + : facet(__refs), _M_data(NULL) { _M_initialize_moneypunct(__cloc, __s); } + /** + * @brief Return decimal point character. + * + * This function returns a char_type to use as a decimal point. It + * does so by returning returning + * moneypunct<char_type>::do_decimal_point(). + * + * @return @a char_type representing a decimal point. + */ char_type decimal_point() const { return this->do_decimal_point(); } - + + /** + * @brief Return thousands separator character. + * + * This function returns a char_type to use as a thousands + * separator. It does so by returning returning + * moneypunct<char_type>::do_thousands_sep(). + * + * @return char_type representing a thousands separator. + */ char_type thousands_sep() const { return this->do_thousands_sep(); } - - string + + /** + * @brief Return grouping specification. + * + * This function returns a string representing groupings for the + * integer part of an amount. Groupings indicate where thousands + * separators should be inserted. + * + * Each char in the return string is interpret as an integer rather + * than a character. These numbers represent the number of digits in a + * group. The first char in the string represents the number of digits + * in the least significant group. If a char is negative, it indicates + * an unlimited number of digits for the group. If more chars from the + * string are required to group a number, the last char is used + * repeatedly. + * + * For example, if the grouping() returns "\003\002" and is applied to + * the number 123456789, this corresponds to 12,34,56,789. Note that + * if the string was "32", this would put more than 50 digits into the + * least significant group if the character set is ASCII. + * + * The string is returned by calling + * moneypunct<char_type>::do_grouping(). + * + * @return string representing grouping specification. + */ + string grouping() const { return this->do_grouping(); } - string_type + /** + * @brief Return currency symbol string. + * + * This function returns a string_type to use as a currency symbol. It + * does so by returning returning + * moneypunct<char_type>::do_curr_symbol(). + * + * @return @a string_type representing a currency symbol. + */ + string_type curr_symbol() const { return this->do_curr_symbol(); } - string_type + /** + * @brief Return positive sign string. + * + * This function returns a string_type to use as a sign for positive + * amounts. It does so by returning returning + * moneypunct<char_type>::do_positive_sign(). + * + * If the return value contains more than one character, the first + * character appears in the position indicated by pos_format() and the + * remainder appear at the end of the formatted string. + * + * @return @a string_type representing a positive sign. + */ + string_type positive_sign() const { return this->do_positive_sign(); } - string_type + /** + * @brief Return negative sign string. + * + * This function returns a string_type to use as a sign for negative + * amounts. It does so by returning returning + * moneypunct<char_type>::do_negative_sign(). + * + * If the return value contains more than one character, the first + * character appears in the position indicated by neg_format() and the + * remainder appear at the end of the formatted string. + * + * @return @a string_type representing a negative sign. + */ + string_type negative_sign() const { return this->do_negative_sign(); } - int + /** + * @brief Return number of digits in fraction. + * + * This function returns the exact number of digits that make up the + * fractional part of a money amount. It does so by returning + * returning moneypunct<char_type>::do_frac_digits(). + * + * The fractional part of a money amount is optional. But if it is + * present, there must be frac_digits() digits. + * + * @return Number of digits in amount fraction. + */ + int frac_digits() const { return this->do_frac_digits(); } - pattern + //@{ + /** + * @brief Return pattern for money values. + * + * This function returns a pattern describing the formatting of a + * positive or negative valued money amount. It does so by returning + * returning moneypunct<char_type>::do_pos_format() or + * moneypunct<char_type>::do_neg_format(). + * + * The pattern has 4 fields describing the ordering of symbol, sign, + * value, and none or space. There must be one of each in the pattern. + * The none and space enums may not appear in the first field and space + * may not appear in the final field. + * + * The parts of a money string must appear in the order indicated by + * the fields of the pattern. The symbol field indicates that the + * value of curr_symbol() may be present. The sign field indicates + * that the value of positive_sign() or negative_sign() must be + * present. The value field indicates that the absolute value of the + * money amount is present. none indicates 0 or more whitespace + * characters, except at the end, where it permits no whitespace. + * space indicates that 1 or more whitespace characters must be + * present. + * + * For example, for the US locale and pos_format() pattern + * {symbol,sign,value,none}, curr_symbol() == '$' positive_sign() == + * '+', and value 10.01, and options set to force the symbol, the + * corresponding string is "$+10.01". + * + * @return Pattern for money values. + */ + pattern pos_format() const { return this->do_pos_format(); } - pattern + pattern neg_format() const { return this->do_neg_format(); } + //@} protected: - virtual + /// Destructor. + virtual ~moneypunct(); + /** + * @brief Return decimal point character. + * + * Returns a char_type to use as a decimal point. This function is a + * hook for derived classes to change the value returned. + * + * @return @a char_type representing a decimal point. + */ virtual char_type do_decimal_point() const - { return _M_decimal_point; } - + { return _M_data->_M_decimal_point; } + + /** + * @brief Return thousands separator character. + * + * Returns a char_type to use as a thousands separator. This function + * is a hook for derived classes to change the value returned. + * + * @return @a char_type representing a thousands separator. + */ virtual char_type do_thousands_sep() const - { return _M_thousands_sep; } - - virtual string + { return _M_data->_M_thousands_sep; } + + /** + * @brief Return grouping specification. + * + * Returns a string representing groupings for the integer part of a + * number. This function is a hook for derived classes to change the + * value returned. @see grouping() for details. + * + * @return String representing grouping specification. + */ + virtual string do_grouping() const - { return _M_grouping; } - - virtual string_type + { return _M_data->_M_grouping; } + + /** + * @brief Return currency symbol string. + * + * This function returns a string_type to use as a currency symbol. + * This function is a hook for derived classes to change the value + * returned. @see curr_symbol() for details. + * + * @return @a string_type representing a currency symbol. + */ + virtual string_type do_curr_symbol() const - { return _M_curr_symbol; } - - virtual string_type + { return _M_data->_M_curr_symbol; } + + /** + * @brief Return positive sign string. + * + * This function returns a string_type to use as a sign for positive + * amounts. This function is a hook for derived classes to change the + * value returned. @see positive_sign() for details. + * + * @return @a string_type representing a positive sign. + */ + virtual string_type do_positive_sign() const - { return _M_positive_sign; } - - virtual string_type + { return _M_data->_M_positive_sign; } + + /** + * @brief Return negative sign string. + * + * This function returns a string_type to use as a sign for negative + * amounts. This function is a hook for derived classes to change the + * value returned. @see negative_sign() for details. + * + * @return @a string_type representing a negative sign. + */ + virtual string_type do_negative_sign() const - { return _M_negative_sign; } - - virtual int + { return _M_data->_M_negative_sign; } + + /** + * @brief Return number of digits in fraction. + * + * This function returns the exact number of digits that make up the + * fractional part of a money amount. This function is a hook for + * derived classes to change the value returned. @see frac_digits() + * for details. + * + * @return Number of digits in amount fraction. + */ + virtual int do_frac_digits() const - { return _M_frac_digits; } - - virtual pattern + { return _M_data->_M_frac_digits; } + + /** + * @brief Return pattern for money values. + * + * This function returns a pattern describing the formatting of a + * positive valued money amount. This function is a hook for derived + * classes to change the value returned. @see pos_format() for + * details. + * + * @return Pattern for money values. + */ + virtual pattern do_pos_format() const - { return _M_pos_format; } - - virtual pattern + { return _M_data->_M_pos_format; } + + /** + * @brief Return pattern for money values. + * + * This function returns a pattern describing the formatting of a + * negative valued money amount. This function is a hook for derived + * classes to change the value returned. @see neg_format() for + * details. + * + * @return Pattern for money values. + */ + virtual pattern do_neg_format() const - { return _M_neg_format; } + { return _M_data->_M_neg_format; } // For use at construction time only. - void - _M_initialize_moneypunct(__c_locale __cloc = NULL, + void + _M_initialize_moneypunct(__c_locale __cloc = NULL, const char* __name = NULL); }; @@ -1616,196 +3894,513 @@ namespace std template<> moneypunct<char, false>::~moneypunct(); - template<> + template<> void moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*); - template<> + template<> void moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*); -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T template<> moneypunct<wchar_t, true>::~moneypunct(); template<> moneypunct<wchar_t, false>::~moneypunct(); - template<> + template<> void - moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale, + moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale, const char*); - template<> + template<> void - moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale, + moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale, const char*); #endif template<typename _CharT, bool _Intl> class moneypunct_byname : public moneypunct<_CharT, _Intl> { - __c_locale _M_c_locale_moneypunct; - public: - typedef _CharT char_type; - typedef basic_string<_CharT> string_type; + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; static const bool intl = _Intl; - explicit + explicit moneypunct_byname(const char* __s, size_t __refs = 0) : moneypunct<_CharT, _Intl>(__refs) { - _S_create_c_locale(_M_c_locale_moneypunct, __s); - _M_initialize_moneypunct(_M_c_locale_moneypunct); + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) + { + __c_locale __tmp; + this->_S_create_c_locale(__tmp, __s); + this->_M_initialize_moneypunct(__tmp); + this->_S_destroy_c_locale(__tmp); + } } protected: - virtual - ~moneypunct_byname() - { _S_destroy_c_locale(_M_c_locale_moneypunct); } + virtual + ~moneypunct_byname() { } }; template<typename _CharT, bool _Intl> const bool moneypunct_byname<_CharT, _Intl>::intl; + /** + * @brief Facet for parsing monetary amounts. + * + * This facet encapsulates the code to parse and return a monetary + * amount from a string. + * + * The money_get template uses protected virtual functions to + * provide the actual results. The public accessors forward the + * call to the virtual functions. These virtual functions are + * hooks for developers to implement the behavior they require from + * the money_get facet. + */ template<typename _CharT, typename _InIter> class money_get : public locale::facet { public: // Types: - typedef _CharT char_type; - typedef _InIter iter_type; - typedef basic_string<_CharT> string_type; - - static locale::id id; - - explicit - money_get(size_t __refs = 0) : locale::facet(__refs) { } - - iter_type - get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _InIter iter_type; + typedef basic_string<_CharT> string_type; + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + money_get(size_t __refs = 0) : facet(__refs) { } + + /** + * @brief Read and parse a monetary value. + * + * This function reads characters from @a s, interprets them as a + * monetary value according to moneypunct and ctype facets retrieved + * from io.getloc(), and returns the result in @a units as an integral + * value moneypunct::frac_digits() * the actual amount. For example, + * the string $10.01 in a US locale would store 1001 in @a units. + * + * Any characters not part of a valid money amount are not consumed. + * + * If a money value cannot be parsed from the input stream, sets + * err=(err|io.failbit). If the stream is consumed before finishing + * parsing, sets err=(err|io.failbit|io.eofbit). @a units is + * unchanged if parsing fails. + * + * This function works by returning the result of do_get(). + * + * @param s Start of characters to parse. + * @param end End of characters to parse. + * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. + * @param io Source of facets and io state. + * @param err Error field to set if parsing fails. + * @param units Place to store result of parsing. + * @return Iterator referencing first character beyond valid money + * amount. + */ + iter_type + get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, ios_base::iostate& __err, long double& __units) const { return this->do_get(__s, __end, __intl, __io, __err, __units); } - iter_type - get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + /** + * @brief Read and parse a monetary value. + * + * This function reads characters from @a s, interprets them as a + * monetary value according to moneypunct and ctype facets retrieved + * from io.getloc(), and returns the result in @a digits. For example, + * the string $10.01 in a US locale would store "1001" in @a digits. + * + * Any characters not part of a valid money amount are not consumed. + * + * If a money value cannot be parsed from the input stream, sets + * err=(err|io.failbit). If the stream is consumed before finishing + * parsing, sets err=(err|io.failbit|io.eofbit). + * + * This function works by returning the result of do_get(). + * + * @param s Start of characters to parse. + * @param end End of characters to parse. + * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. + * @param io Source of facets and io state. + * @param err Error field to set if parsing fails. + * @param digits Place to store result of parsing. + * @return Iterator referencing first character beyond valid money + * amount. + */ + iter_type + get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, ios_base::iostate& __err, string_type& __digits) const { return this->do_get(__s, __end, __intl, __io, __err, __digits); } protected: - virtual + /// Destructor. + virtual ~money_get() { } - virtual iter_type - do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + /** + * @brief Read and parse a monetary value. + * + * This function reads and parses characters representing a monetary + * value. This function is a hook for derived classes to change the + * value returned. @see get() for details. + */ + virtual iter_type + do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, ios_base::iostate& __err, long double& __units) const; - virtual iter_type - do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, + /** + * @brief Read and parse a monetary value. + * + * This function reads and parses characters representing a monetary + * value. This function is a hook for derived classes to change the + * value returned. @see get() for details. + */ + virtual iter_type + do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, ios_base::iostate& __err, string_type& __digits) const; + + template<bool _Intl> + iter_type + _M_extract(iter_type __s, iter_type __end, ios_base& __io, + ios_base::iostate& __err, string& __digits) const; }; template<typename _CharT, typename _InIter> locale::id money_get<_CharT, _InIter>::id; + /** + * @brief Facet for outputting monetary amounts. + * + * This facet encapsulates the code to format and output a monetary + * amount. + * + * The money_put template uses protected virtual functions to + * provide the actual results. The public accessors forward the + * call to the virtual functions. These virtual functions are + * hooks for developers to implement the behavior they require from + * the money_put facet. + */ template<typename _CharT, typename _OutIter> class money_put : public locale::facet { public: - typedef _CharT char_type; - typedef _OutIter iter_type; + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _OutIter iter_type; typedef basic_string<_CharT> string_type; - - static locale::id id; - - explicit - money_put(size_t __refs = 0) : locale::facet(__refs) { } - - iter_type + //@} + + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit + money_put(size_t __refs = 0) : facet(__refs) { } + + /** + * @brief Format and output a monetary value. + * + * This function formats @a units as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the value 1001 in a + * US locale would write "$10.01" to @a s. + * + * This function works by returning the result of do_put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ + iter_type put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, long double __units) const { return this->do_put(__s, __intl, __io, __fill, __units); } - iter_type + /** + * @brief Format and output a monetary value. + * + * This function formats @a digits as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the string "1001" in + * a US locale would write "$10.01" to @a s. + * + * This function works by returning the result of do_put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ + iter_type put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, const string_type& __digits) const { return this->do_put(__s, __intl, __io, __fill, __digits); } protected: - virtual + /// Destructor. + virtual ~money_put() { } + /** + * @brief Format and output a monetary value. + * + * This function formats @a units as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the value 1001 in a + * US locale would write "$10.01" to @a s. + * + * This function is a hook for derived classes to change the value + * returned. @see put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, long double __units) const; + /** + * @brief Format and output a monetary value. + * + * This function formats @a digits as a monetary value according to + * moneypunct and ctype facets retrieved from io.getloc(), and writes + * the resulting characters to @a s. For example, the string "1001" in + * a US locale would write "$10.01" to @a s. + * + * This function is a hook for derived classes to change the value + * returned. @see put(). + * + * @param s The stream to write to. + * @param intl Parameter to use_facet<moneypunct<CharT,intl> >. + * @param io Source of facets and io state. + * @param fill char_type to use for padding. + * @param units Place to store result of parsing. + * @return Iterator after writing. + */ virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, const string_type& __digits) const; + + template<bool _Intl> + iter_type + _M_insert(iter_type __s, ios_base& __io, char_type __fill, + const string_type& __digits) const; }; template<typename _CharT, typename _OutIter> locale::id money_put<_CharT, _OutIter>::id; - + /** + * @brief Messages facet base class providing catalog typedef. + */ struct messages_base { typedef int catalog; }; + /** + * @brief Facet for handling message catalogs + * + * This facet encapsulates the code to retrieve messages from + * message catalogs. The only thing defined by the standard for this facet + * is the interface. All underlying functionality is + * implementation-defined. + * + * This library currently implements 3 versions of the message facet. The + * first version (gnu) is a wrapper around gettext, provided by libintl. + * The second version (ieee) is a wrapper around catgets. The final + * version (default) does no actual translation. These implementations are + * only provided for char and wchar_t instantiations. + * + * The messages template uses protected virtual functions to + * provide the actual results. The public accessors forward the + * call to the virtual functions. These virtual functions are + * hooks for developers to implement the behavior they require from + * the messages facet. + */ template<typename _CharT> class messages : public locale::facet, public messages_base { public: // Types: - typedef _CharT char_type; - typedef basic_string<_CharT> string_type; + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; + //@} protected: // Underlying "C" library locale information saved from // initialization, needed by messages_byname as well. __c_locale _M_c_locale_messages; - char* _M_name_messages; + const char* _M_name_messages; public: - static locale::id id; - - explicit + /// Numpunct facet id. + static locale::id id; + + /** + * @brief Constructor performs initialization. + * + * This is the constructor provided by the standard. + * + * @param refs Passed to the base facet class. + */ + explicit messages(size_t __refs = 0); // Non-standard. - explicit + /** + * @brief Internal constructor. Not for general use. + * + * This is a constructor for use by the library itself to set up new + * locales. + * + * @param cloc The "C" locale. + * @param s The name of a locale. + * @param refs Refcount to pass to the base class. + */ + explicit messages(__c_locale __cloc, const char* __s, size_t __refs = 0); - catalog + /* + * @brief Open a message catalog. + * + * This function opens and returns a handle to a message catalog by + * returning do_open(s, loc). + * + * @param s The catalog to open. + * @param loc Locale to use for character set conversions. + * @return Handle to the catalog or value < 0 if open fails. + */ + catalog open(const basic_string<char>& __s, const locale& __loc) const { return this->do_open(__s, __loc); } // Non-standard and unorthodox, yet effective. - catalog + /* + * @brief Open a message catalog. + * + * This non-standard function opens and returns a handle to a message + * catalog by returning do_open(s, loc). The third argument provides a + * message catalog root directory for gnu gettext and is ignored + * otherwise. + * + * @param s The catalog to open. + * @param loc Locale to use for character set conversions. + * @param dir Message catalog root directory. + * @return Handle to the catalog or value < 0 if open fails. + */ + catalog open(const basic_string<char>&, const locale&, const char*) const; - string_type + /* + * @brief Look up a string in a message catalog. + * + * This function retrieves and returns a message from a catalog by + * returning do_get(c, set, msgid, s). + * + * For gnu, @a set and @a msgid are ignored. Returns gettext(s). + * For default, returns s. For ieee, returns catgets(c,set,msgid,s). + * + * @param c The catalog to access. + * @param set Implementation-defined. + * @param msgid Implementation-defined. + * @param s Default return value if retrieval fails. + * @return Retrieved message or @a s if get fails. + */ + string_type get(catalog __c, int __set, int __msgid, const string_type& __s) const { return this->do_get(__c, __set, __msgid, __s); } - void + /* + * @brief Close a message catalog. + * + * Closes catalog @a c by calling do_close(c). + * + * @param c The catalog to close. + */ + void close(catalog __c) const { return this->do_close(__c); } protected: - virtual + /// Destructor. + virtual ~messages(); - virtual catalog + /* + * @brief Open a message catalog. + * + * This function opens and returns a handle to a message catalog in an + * implementation-defined manner. This function is a hook for derived + * classes to change the value returned. + * + * @param s The catalog to open. + * @param loc Locale to use for character set conversions. + * @return Handle to the opened catalog, value < 0 if open failed. + */ + virtual catalog do_open(const basic_string<char>&, const locale&) const; - virtual string_type + /* + * @brief Look up a string in a message catalog. + * + * This function retrieves and returns a message from a catalog in an + * implementation-defined manner. This function is a hook for derived + * classes to change the value returned. + * + * For gnu, @a set and @a msgid are ignored. Returns gettext(s). + * For default, returns s. For ieee, returns catgets(c,set,msgid,s). + * + * @param c The catalog to access. + * @param set Implementation-defined. + * @param msgid Implementation-defined. + * @param s Default return value if retrieval fails. + * @return Retrieved message or @a s if get fails. + */ + virtual string_type do_get(catalog, int, int, const string_type& __dfault) const; - virtual void + /* + * @brief Close a message catalog. + * + * @param c The catalog to close. + */ + virtual void do_close(catalog) const; // Returns a locale and codeset-converted string, given a char* message. @@ -1818,23 +4413,24 @@ namespace std // Returns a locale and codeset-converted string, given a char* message. string_type - _M_convert_from_char(char* __msg) const + _M_convert_from_char(char*) const { +#if 0 // Length of message string without terminating null. size_t __len = char_traits<char>::length(__msg) - 1; // "everybody can easily convert the string using // mbsrtowcs/wcsrtombs or with iconv()" -#if 0 + // Convert char* to _CharT in locale used to open catalog. // XXX need additional template parameter on messages class for this.. // typedef typename codecvt<char, _CharT, _StateT> __codecvt_type; - typedef typename codecvt<char, _CharT, mbstate_t> __codecvt_type; + typedef typename codecvt<char, _CharT, mbstate_t> __codecvt_type; __codecvt_type::state_type __state; // XXX may need to initialize state. //initialize_state(__state._M_init()); - + char* __from_next; // XXX what size for this string? _CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1)); @@ -1865,7 +4461,7 @@ namespace std string messages<char>::do_get(catalog, int, int, const string&) const; -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T template<> wstring messages<wchar_t>::do_get(catalog, int, int, const wstring&) const; @@ -1875,15 +4471,15 @@ namespace std class messages_byname : public messages<_CharT> { public: - typedef _CharT char_type; - typedef basic_string<_CharT> string_type; + typedef _CharT char_type; + typedef basic_string<_CharT> string_type; - explicit + explicit messages_byname(const char* __s, size_t __refs = 0); protected: - virtual - ~messages_byname() + virtual + ~messages_byname() { } }; @@ -1895,23 +4491,25 @@ namespace std // NB: These are inline because, when used in a loop, some compilers // can hoist the body out of the loop; then it's just as fast as the // C is*() function. + //@{ + /// Convenience interface to ctype.is(). template<typename _CharT> - inline bool + inline bool isspace(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); } template<typename _CharT> - inline bool + inline bool isprint(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); } template<typename _CharT> - inline bool + inline bool iscntrl(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); } template<typename _CharT> - inline bool + inline bool isupper(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); } @@ -1920,131 +4518,45 @@ namespace std { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); } template<typename _CharT> - inline bool + inline bool isalpha(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); } template<typename _CharT> - inline bool + inline bool isdigit(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); } template<typename _CharT> - inline bool + inline bool ispunct(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); } template<typename _CharT> - inline bool + inline bool isxdigit(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); } template<typename _CharT> - inline bool + inline bool isalnum(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); } template<typename _CharT> - inline bool + inline bool isgraph(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); } template<typename _CharT> - inline _CharT + inline _CharT toupper(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).toupper(__c); } template<typename _CharT> - inline _CharT + inline _CharT tolower(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).tolower(__c); } - - /** - * @if maint - * __locale_cache objects hold information extracted from facets in - * a form optimized for parsing and formatting. They are stored in - * a locale's facet array and accessed via __use_cache<_Facet>. - * - * The intent twofold: to avoid the costs of creating a locale - * object and to avoid calling the virtual functions in a locale's - * facet to look up data. - * @endif - */ - class __locale_cache_base - { - friend class std::locale::_Impl; - friend class locale; - - public: - virtual - ~__locale_cache_base() { } - - }; - - // This template doesn't really get used for anything except a - // placeholder for specializations - template<typename _Facet> - class __locale_cache : public __locale_cache_base - { - // ctor - __locale_cache(const locale&) {} - }; - - template<typename _CharT> - class __locale_cache<numpunct<_CharT> > : public __locale_cache_base - { - // Types: - typedef _CharT char_type; - typedef char_traits<_CharT> traits_type; - typedef basic_string<_CharT> string_type; - - public: - // Data Members: - - // The sign used to separate decimal values: for standard US - // locales, this would usually be: "." Abstracted from - // numpunct::decimal_point(). - _CharT _M_decimal_point; - - // The sign used to separate groups of digits into smaller - // strings that the eye can parse with less difficulty: for - // standard US locales, this would usually be: "," Abstracted - // from numpunct::thousands_sep(). - _CharT _M_thousands_sep; - - // However the US's "false" and "true" are translated. From - // numpunct::truename() and numpunct::falsename(), respectively. - const _CharT* _M_truename; - const _CharT* _M_falsename; - - // If we are checking groupings. This should be equivalent to - // numpunct::groupings().size() != 0 - bool _M_use_grouping; - - // If we are using numpunct's groupings, this is the current - // grouping string in effect (from numpunct::grouping()). - const char* _M_grouping; - - // A list of valid numeric literals: for the standard "C" - // locale, this is "-+xX0123456789abcdef0123456789ABCDEF". This - // array contains the chars after having been passed through the - // current locale's ctype<_CharT>.widen(). - - // Copied here from __locale_cache<ctype> to save multiple cache - // access in num_put functions. - _CharT _M_atoms_out[__num_base::_S_end]; - - // ctor - __locale_cache(const locale& __loc); - __locale_cache(const locale& __loc, bool); - - ~__locale_cache() - { - delete [] _M_truename; - delete [] _M_falsename; - delete [] _M_grouping; - } - }; + //@} } // namespace std #endif diff --git a/contrib/libstdc++/include/bits/locale_facets.tcc b/contrib/libstdc++/include/bits/locale_facets.tcc index 2563a9595d1d..f0f5e3a9ef53 100644 --- a/contrib/libstdc++/include/bits/locale_facets.tcc +++ b/contrib/libstdc++/include/bits/locale_facets.tcc @@ -1,6 +1,6 @@ // Locale support -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -30,18 +30,13 @@ // Warning: this file is not meant for user inclusion. Use <locale>. -#ifndef _CPP_BITS_LOCFACETS_TCC -#define _CPP_BITS_LOCFACETS_TCC 1 +#ifndef _LOCALE_FACETS_TCC +#define _LOCALE_FACETS_TCC 1 #pragma GCC system_header -#include <cerrno> -#include <clocale> // For localeconv -#include <cstdlib> // For strof, strtold -#include <cmath> // For ceil -#include <cctype> // For isspace -#include <limits> // For numeric_limits -#include <typeinfo> // For bad_cast. +#include <limits> // For numeric_limits +#include <typeinfo> // For bad_cast. #include <bits/streambuf_iterator.h> namespace std @@ -51,7 +46,15 @@ namespace std locale::combine(const locale& __other) const { _Impl* __tmp = new _Impl(*_M_impl, 1); - __tmp->_M_replace_facet(__other._M_impl, &_Facet::id); + try + { + __tmp->_M_replace_facet(__other._M_impl, &_Facet::id); + } + catch(...) + { + __tmp->_M_remove_reference(); + __throw_exception_again; + } return locale(__tmp); } @@ -66,158 +69,335 @@ namespace std __s2.data(), __s2.data() + __s2.length()) < 0); } + /** + * @brief Test for the presence of a facet. + * + * has_facet tests the locale argument for the presence of the facet type + * provided as the template parameter. Facets derived from the facet + * parameter will also return true. + * + * @param Facet The facet type to test the presence of. + * @param locale The locale to test. + * @return true if locale contains a facet of type Facet, else false. + */ + template<typename _Facet> + inline bool + has_facet(const locale& __loc) throw() + { + const size_t __i = _Facet::id._M_id(); + const locale::facet** __facets = __loc._M_impl->_M_facets; + return (__i < __loc._M_impl->_M_facets_size && __facets[__i]); + } + + /** + * @brief Return a facet. + * + * use_facet looks for and returns a reference to a facet of type Facet + * where Facet is the template parameter. If has_facet(locale) is true, + * there is a suitable facet to return. It throws std::bad_cast if the + * locale doesn't contain a facet of type Facet. + * + * @param Facet The facet type to access. + * @param locale The locale to use. + * @return Reference to facet of type Facet. + * @throw std::bad_cast if locale doesn't contain a facet of type Facet. + */ template<typename _Facet> - const _Facet& + inline const _Facet& use_facet(const locale& __loc) { - size_t __i = _Facet::id._M_id(); - locale::facet** __facets = __loc._M_impl->_M_facets; + const size_t __i = _Facet::id._M_id(); + const locale::facet** __facets = __loc._M_impl->_M_facets; if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i])) __throw_bad_cast(); return static_cast<const _Facet&>(*__facets[__i]); } + // Routine to access a cache for the facet. If the cache didn't + // exist before, it gets constructed on the fly. template<typename _Facet> - bool - has_facet(const locale& __loc) throw() + struct __use_cache { - size_t __i = _Facet::id._M_id(); - locale::facet** __facets = __loc._M_impl->_M_facets; - return (__i < __loc._M_impl->_M_facets_size && __facets[__i]); + const _Facet* + operator() (const locale& __loc) const; + }; + + // Specializations. + template<typename _CharT> + struct __use_cache<__numpunct_cache<_CharT> > + { + const __numpunct_cache<_CharT>* + operator() (const locale& __loc) const + { + const size_t __i = numpunct<_CharT>::id._M_id(); + const locale::facet** __caches = __loc._M_impl->_M_caches; + if (!__caches[__i]) + { + __numpunct_cache<_CharT>* __tmp = NULL; + try + { + __tmp = new __numpunct_cache<_CharT>; + __tmp->_M_cache(__loc); + } + catch(...) + { + delete __tmp; + __throw_exception_again; + } + __loc._M_impl->_M_install_cache(__tmp, __i); + } + return static_cast<const __numpunct_cache<_CharT>*>(__caches[__i]); + } + }; + + template<typename _CharT, bool _Intl> + struct __use_cache<__moneypunct_cache<_CharT, _Intl> > + { + const __moneypunct_cache<_CharT, _Intl>* + operator() (const locale& __loc) const + { + const size_t __i = moneypunct<_CharT, _Intl>::id._M_id(); + const locale::facet** __caches = __loc._M_impl->_M_caches; + if (!__caches[__i]) + { + __moneypunct_cache<_CharT, _Intl>* __tmp = NULL; + try + { + __tmp = new __moneypunct_cache<_CharT, _Intl>; + __tmp->_M_cache(__loc); + } + catch(...) + { + delete __tmp; + __throw_exception_again; + } + __loc._M_impl->_M_install_cache(__tmp, __i); + } + return static_cast< + const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]); + } + }; + + template<typename _CharT> + void + __numpunct_cache<_CharT>::_M_cache(const locale& __loc) + { + _M_allocated = true; + + const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); + + _M_grouping_size = __np.grouping().size(); + char* __grouping = new char[_M_grouping_size]; + __np.grouping().copy(__grouping, _M_grouping_size); + _M_grouping = __grouping; + _M_use_grouping = _M_grouping_size && __np.grouping()[0] != 0; + + _M_truename_size = __np.truename().size(); + _CharT* __truename = new _CharT[_M_truename_size]; + __np.truename().copy(__truename, _M_truename_size); + _M_truename = __truename; + + _M_falsename_size = __np.falsename().size(); + _CharT* __falsename = new _CharT[_M_falsename_size]; + __np.falsename().copy(__falsename, _M_falsename_size); + _M_falsename = __falsename; + + _M_decimal_point = __np.decimal_point(); + _M_thousands_sep = __np.thousands_sep(); + + const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc); + __ct.widen(__num_base::_S_atoms_out, + __num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out); + __ct.widen(__num_base::_S_atoms_in, + __num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in); } - // Routine to access a cache for the locale. If the cache didn't - // exist before, it gets constructed on the fly. - template<typename _Facet> - inline const __locale_cache<_Facet>& - __use_cache(const locale& __loc) + template<typename _CharT, bool _Intl> + void + __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc) { - size_t __i = _Facet::id._M_id(); - if (__builtin_expect(__i >= __loc._M_impl->_M_facets_size,false)) - __throw_bad_cast(); - __locale_cache_base* __cache = __loc._M_impl->_M_get_cache(__i); - if (__builtin_expect(!__cache, false)) - { - __cache = new __locale_cache<_Facet>(__loc); - __loc._M_impl->_M_install_cache(__cache, __i); - } - return static_cast<const __locale_cache<_Facet>&>(*__cache); + _M_allocated = true; + + const moneypunct<_CharT, _Intl>& __mp = + use_facet<moneypunct<_CharT, _Intl> >(__loc); + + _M_grouping_size = __mp.grouping().size(); + char* __grouping = new char[_M_grouping_size]; + __mp.grouping().copy(__grouping, _M_grouping_size); + _M_grouping = __grouping; + _M_use_grouping = _M_grouping_size && __mp.grouping()[0] != 0; + + _M_decimal_point = __mp.decimal_point(); + _M_thousands_sep = __mp.thousands_sep(); + _M_frac_digits = __mp.frac_digits(); + + _M_curr_symbol_size = __mp.curr_symbol().size(); + _CharT* __curr_symbol = new _CharT[_M_curr_symbol_size]; + __mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size); + _M_curr_symbol = __curr_symbol; + + _M_positive_sign_size = __mp.positive_sign().size(); + _CharT* __positive_sign = new _CharT[_M_positive_sign_size]; + __mp.positive_sign().copy(__positive_sign, _M_positive_sign_size); + _M_positive_sign = __positive_sign; + + _M_negative_sign_size = __mp.negative_sign().size(); + _CharT* __negative_sign = new _CharT[_M_negative_sign_size]; + __mp.negative_sign().copy(__negative_sign, _M_negative_sign_size); + _M_negative_sign = __negative_sign; + + _M_pos_format = __mp.pos_format(); + _M_neg_format = __mp.neg_format(); + + const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc); + __ct.widen(money_base::_S_atoms, + money_base::_S_atoms + money_base::_S_end, _M_atoms); } - // Stage 1: Determine a conversion specifier. + + // Used by both numeric and monetary facets. + // Check to make sure that the __grouping_tmp string constructed in + // money_get or num_get matches the canonical grouping for a given + // locale. + // __grouping_tmp is parsed L to R + // 1,222,444 == __grouping_tmp of "\1\3\3" + // __grouping is parsed R to L + // 1,222,444 == __grouping of "\3" == "\3\3\3" + static bool + __verify_grouping(const char* __grouping, size_t __grouping_size, + const string& __grouping_tmp); + template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io, ios_base::iostate& __err, string& __xtrc) const { - typedef char_traits<_CharT> __traits_type; - const locale __loc = __io.getloc(); - const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); - const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); + typedef char_traits<_CharT> __traits_type; + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + const _CharT* __lit = __lc->_M_atoms_in; + + // True if a mantissa is found. + bool __found_mantissa = false; // First check for sign. - const char_type __plus = __ctype.widen('+'); - const char_type __minus = __ctype.widen('-'); - int __pos = 0; - char_type __c = *__beg; - if ((__traits_type::eq(__c, __plus) || __traits_type::eq(__c, __minus)) - && __beg != __end) + if (__beg != __end) { - __xtrc += __ctype.narrow(__c, char()); - ++__pos; - __c = *(++__beg); + const char_type __c = *__beg; + const bool __plus = __c == __lit[__num_base::_S_iplus]; + if ((__plus || __c == __lit[__num_base::_S_iminus]) + && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + && !(__c == __lc->_M_decimal_point)) + { + __xtrc += __plus ? '+' : '-'; + ++__beg; + } } - // Next, strip leading zeros. - const char_type __zero = __ctype.widen(_S_atoms_in[_M_zero]); - bool __found_zero = false; - while (__traits_type::eq(__c, __zero) && __beg != __end) - { - __c = *(++__beg); - __found_zero = true; - } - if (__found_zero) + // Next, look for leading zeros. + while (__beg != __end) { - __xtrc += _S_atoms_in[_M_zero]; - ++__pos; + const char_type __c = *__beg; + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep + || __c == __lc->_M_decimal_point) + break; + else if (__c == __lit[__num_base::_S_izero]) + { + if (!__found_mantissa) + { + __xtrc += '0'; + __found_mantissa = true; + } + ++__beg; + } + else + break; } // Only need acceptable digits for floating point numbers. - const size_t __len = _M_E - _M_zero + 1; - char_type __watoms[__len]; - __ctype.widen(_S_atoms_in, _S_atoms_in + __len, __watoms); bool __found_dec = false; bool __found_sci = false; - const char_type __dec = __np.decimal_point(); - string __found_grouping; - const string __grouping = __np.grouping(); - bool __check_grouping = __grouping.size(); + if (__lc->_M_use_grouping) + __found_grouping.reserve(32); int __sep_pos = 0; - const char_type __sep = __np.thousands_sep(); - + const char_type* __lit_zero = __lit + __num_base::_S_izero; + const char_type* __q; while (__beg != __end) { - // Only look in digits. - const char_type* __p = __traits_type::find(__watoms, 10, __c); - - // NB: strchr returns true for __c == 0x0 - if (__p && !__traits_type::eq(__c, char_type())) + // According to 22.2.2.1.2, p8-9, first look for thousands_sep + // and decimal_point. + const char_type __c = *__beg; + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) { - // Try first for acceptable digit; record it if found. - ++__pos; - __xtrc += _S_atoms_in[__p - __watoms]; - ++__sep_pos; - __c = *(++__beg); - } - else if (__traits_type::eq(__c, __sep) - && __check_grouping && !__found_dec) - { - // NB: Thousands separator at the beginning of a string - // is a no-no, as is two consecutive thousands separators. - if (__sep_pos) - { - __found_grouping += static_cast<char>(__sep_pos); - __sep_pos = 0; - __c = *(++__beg); - } - else + if (!__found_dec && !__found_sci) { - __err |= ios_base::failbit; - break; + // NB: Thousands separator at the beginning of a string + // is a no-no, as is two consecutive thousands separators. + if (__sep_pos) + { + __found_grouping += static_cast<char>(__sep_pos); + __sep_pos = 0; + ++__beg; + } + else + { + __err |= ios_base::failbit; + break; + } } + else + break; } - else if (__traits_type::eq(__c, __dec) && !__found_dec) + else if (__c == __lc->_M_decimal_point) { - // According to the standard, if no grouping chars are seen, - // no grouping check is applied. Therefore __found_grouping - // must be adjusted only if __dec comes after some __sep. - if (__found_grouping.size()) - __found_grouping += static_cast<char>(__sep_pos); - ++__pos; - __xtrc += '.'; - __c = *(++__beg); - __found_dec = true; + if (!__found_dec && !__found_sci) + { + // If no grouping chars are seen, no grouping check + // is applied. Therefore __found_grouping is adjusted + // only if decimal_point comes after some thousands_sep. + if (__found_grouping.size()) + __found_grouping += static_cast<char>(__sep_pos); + __xtrc += '.'; + __found_dec = true; + ++__beg; + } + else + break; + } + else if (__q = __traits_type::find(__lit_zero, 10, __c)) + { + __xtrc += __num_base::_S_atoms_in[__q - __lit]; + __found_mantissa = true; + ++__sep_pos; + ++__beg; } - else if ((__traits_type::eq(__c, __watoms[_M_e]) - || __traits_type::eq(__c, __watoms[_M_E])) - && !__found_sci && __pos) + else if ((__c == __lit[__num_base::_S_ie] + || __c == __lit[__num_base::_S_iE]) + && __found_mantissa && !__found_sci) { // Scientific notation. - ++__pos; - __xtrc += __ctype.narrow(__c, char()); - __c = *(++__beg); + if (__found_grouping.size() && !__found_dec) + __found_grouping += static_cast<char>(__sep_pos); + __xtrc += 'e'; + __found_sci = true; // Remove optional plus or minus sign, if they exist. - if (__traits_type::eq(__c, __plus) - || __traits_type::eq(__c, __minus)) + if (++__beg != __end) { - ++__pos; - __xtrc += __ctype.narrow(__c, char()); - __c = *(++__beg); + const bool __plus = *__beg == __lit[__num_base::_S_iplus]; + if ((__plus || *__beg == __lit[__num_base::_S_iminus]) + && !(__lc->_M_use_grouping + && *__beg == __lc->_M_thousands_sep) + && !(*__beg == __lc->_M_decimal_point)) + { + __xtrc += __plus ? '+' : '-'; + ++__beg; + } } - __found_sci = true; } else // Not a valid input item. @@ -226,345 +406,340 @@ namespace std // Digit grouping is checked. If grouping and found_grouping don't // match, then get very very upset, and set failbit. - if (__check_grouping && __found_grouping.size()) + if (__lc->_M_use_grouping && __found_grouping.size()) { - // Add the ending grouping if a decimal wasn't found. - if (!__found_dec) + // Add the ending grouping if a decimal or 'e'/'E' wasn't found. + if (!__found_dec && !__found_sci) __found_grouping += static_cast<char>(__sep_pos); - if (!__verify_grouping(__grouping, __found_grouping)) + + if (!std::__verify_grouping(__lc->_M_grouping, + __lc->_M_grouping_size, + __found_grouping)) __err |= ios_base::failbit; } - // Finish up - __xtrc += char(); + // Finish up. if (__beg == __end) __err |= ios_base::eofbit; return __beg; } - // Stage 1: Determine a conversion specifier. template<typename _CharT, typename _InIter> - _InIter - num_get<_CharT, _InIter>:: - _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io, - ios_base::iostate& __err, string& __xtrc, int& __base) const - { - typedef char_traits<_CharT> __traits_type; - const locale __loc = __io.getloc(); - const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); - const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); - - // NB: Iff __basefield == 0, this can change based on contents. - ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield; - if (__basefield == ios_base::oct) - __base = 8; - else if (__basefield == ios_base::hex) - __base = 16; - else - __base = 10; - - // First check for sign. - int __pos = 0; - char_type __c = *__beg; - const char_type __plus = __ctype.widen('+'); - const char_type __minus = __ctype.widen('-'); - - if ((__traits_type::eq(__c, __plus) || __traits_type::eq(__c, __minus)) - && __beg != __end) - { - __xtrc += __ctype.narrow(__c, char()); - ++__pos; - __c = *(++__beg); - } + template<typename _ValueT> + _InIter + num_get<_CharT, _InIter>:: + _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io, + ios_base::iostate& __err, _ValueT& __v) const + { + typedef char_traits<_CharT> __traits_type; + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + const _CharT* __lit = __lc->_M_atoms_in; + + // NB: Iff __basefield == 0, __base can change based on contents. + const ios_base::fmtflags __basefield = __io.flags() + & ios_base::basefield; + const bool __oct = __basefield == ios_base::oct; + int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10); + + // True if numeric digits are found. + bool __found_num = false; + + // First check for sign. + bool __negative = false; + if (__beg != __end) + { + const char_type __c = *__beg; + if (numeric_limits<_ValueT>::is_signed) + __negative = __c == __lit[__num_base::_S_iminus]; + if ((__negative || __c == __lit[__num_base::_S_iplus]) + && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + && !(__c == __lc->_M_decimal_point)) + ++__beg; + } - // Next, strip leading zeros and check required digits for base formats. - const char_type __zero = __ctype.widen(_S_atoms_in[_M_zero]); - const char_type __x = __ctype.widen('x'); - const char_type __X = __ctype.widen('X'); - if (__base == 10) - { - bool __found_zero = false; - while (__traits_type::eq(__c, __zero) && __beg != __end) - { - __c = *(++__beg); - __found_zero = true; - } - if (__found_zero) - { - __xtrc += _S_atoms_in[_M_zero]; - ++__pos; - if (__basefield == 0) - { - if ((__traits_type::eq(__c, __x) - || __traits_type::eq(__c, __X)) - && __beg != __end) - { - __xtrc += __ctype.narrow(__c, char()); - ++__pos; - __c = *(++__beg); + // Next, look for leading zeros and check required digits + // for base formats. + while (__beg != __end) + { + const char_type __c = *__beg; + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep + || __c == __lc->_M_decimal_point) + break; + else if (__c == __lit[__num_base::_S_izero] + && (!__found_num || __base == 10)) + { + __found_num = true; + ++__beg; + } + else if (__found_num) + { + if (__c == __lit[__num_base::_S_ix] + || __c == __lit[__num_base::_S_iX]) + { + if (__basefield == 0) __base = 16; - } - else - __base = 8; - } - } - } - else if (__base == 16) - { - if (__traits_type::eq(__c, __zero) && __beg != __end) - { - __xtrc += _S_atoms_in[_M_zero]; - ++__pos; - __c = *(++__beg); - if ((__traits_type::eq(__c, __x) || __traits_type::eq(__c, __X)) - && __beg != __end) - { - __xtrc += __ctype.narrow(__c, char()); - ++__pos; - __c = *(++__beg); - } - } - } + if (__base == 16) + { + __found_num = false; + ++__beg; + } + } + else if (__basefield == 0) + __base = 8; + break; + } + else + break; + } - // At this point, base is determined. If not hex, only allow - // base digits as valid input. - size_t __len; - if (__base == 16) - __len = _M_size; - else - __len = __base; + // At this point, base is determined. If not hex, only allow + // base digits as valid input. + const size_t __len = __base == 16 ? (__num_base::_S_iend + - __num_base::_S_izero) + : __base; + + // Extract. + string __found_grouping; + if (__lc->_M_use_grouping) + __found_grouping.reserve(32); + int __sep_pos = 0; + bool __overflow = false; + _ValueT __result = 0; + const char_type* __lit_zero = __lit + __num_base::_S_izero; + const char_type* __q; + if (__negative) + { + const _ValueT __min = numeric_limits<_ValueT>::min() / __base; + for (; __beg != __end; ++__beg) + { + // According to 22.2.2.1.2, p8-9, first look for thousands_sep + // and decimal_point. + const char_type __c = *__beg; + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + { + // NB: Thousands separator at the beginning of a string + // is a no-no, as is two consecutive thousands separators. + if (__sep_pos) + { + __found_grouping += static_cast<char>(__sep_pos); + __sep_pos = 0; + } + else + { + __err |= ios_base::failbit; + break; + } + } + else if (__c == __lc->_M_decimal_point) + break; + else if (__q = __traits_type::find(__lit_zero, __len, __c)) + { + int __digit = __q - __lit_zero; + if (__digit > 15) + __digit -= 6; + if (__result < __min) + __overflow = true; + else + { + const _ValueT __new_result = __result * __base + - __digit; + __overflow |= __new_result > __result; + __result = __new_result; + ++__sep_pos; + __found_num = true; + } + } + else + // Not a valid input item. + break; + } + } + else + { + const _ValueT __max = numeric_limits<_ValueT>::max() / __base; + for (; __beg != __end; ++__beg) + { + const char_type __c = *__beg; + if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) + { + if (__sep_pos) + { + __found_grouping += static_cast<char>(__sep_pos); + __sep_pos = 0; + } + else + { + __err |= ios_base::failbit; + break; + } + } + else if (__c == __lc->_M_decimal_point) + break; + else if (__q = __traits_type::find(__lit_zero, __len, __c)) + { + int __digit = __q - __lit_zero; + if (__digit > 15) + __digit -= 6; + if (__result > __max) + __overflow = true; + else + { + const _ValueT __new_result = __result * __base + + __digit; + __overflow |= __new_result < __result; + __result = __new_result; + ++__sep_pos; + __found_num = true; + } + } + else + break; + } + } - // Extract. - char_type __watoms[_M_size]; - __ctype.widen(_S_atoms_in, _S_atoms_in + __len, __watoms); - string __found_grouping; - const string __grouping = __np.grouping(); - bool __check_grouping = __grouping.size(); - int __sep_pos = 0; - const char_type __sep = __np.thousands_sep(); - while (__beg != __end) - { - const char_type* __p = __traits_type::find(__watoms, __len, __c); + // Digit grouping is checked. If grouping and found_grouping don't + // match, then get very very upset, and set failbit. + if (__lc->_M_use_grouping && __found_grouping.size()) + { + // Add the ending grouping. + __found_grouping += static_cast<char>(__sep_pos); - // NB: strchr returns true for __c == 0x0 - if (__p && !__traits_type::eq(__c, char_type())) - { - // Try first for acceptable digit; record it if found. - __xtrc += _S_atoms_in[__p - __watoms]; - ++__pos; - ++__sep_pos; - __c = *(++__beg); - } - else if (__traits_type::eq(__c, __sep) && __check_grouping) - { - // NB: Thousands separator at the beginning of a string - // is a no-no, as is two consecutive thousands separators. - if (__sep_pos) - { - __found_grouping += static_cast<char>(__sep_pos); - __sep_pos = 0; - __c = *(++__beg); - } - else - { - __err |= ios_base::failbit; - break; - } - } - else - // Not a valid input item. - break; - } + if (!std::__verify_grouping(__lc->_M_grouping, + __lc->_M_grouping_size, + __found_grouping)) + __err |= ios_base::failbit; + } - // Digit grouping is checked. If grouping and found_grouping don't - // match, then get very very upset, and set failbit. - if (__check_grouping && __found_grouping.size()) - { - // Add the ending grouping. - __found_grouping += static_cast<char>(__sep_pos); - if (!__verify_grouping(__grouping, __found_grouping)) - __err |= ios_base::failbit; - } + if (!(__err & ios_base::failbit) && !__overflow + && __found_num) + __v = __result; + else + __err |= ios_base::failbit; - // Finish up. - __xtrc += char(); - if (__beg == __end) - __err |= ios_base::eofbit; - return __beg; - } + if (__beg == __end) + __err |= ios_base::eofbit; + return __beg; + } -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS - //17. Bad bool parsing + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 17. Bad bool parsing template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, bool& __v) const { - // Parse bool values as unsigned long if (!(__io.flags() & ios_base::boolalpha)) { + // Parse bool values as long. // NB: We can't just call do_get(long) here, as it might // refer to a derived class. - string __xtrc; - int __base; - __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); - - unsigned long __ul; - __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base); - if (!(__err & ios_base::failbit) && __ul <= 1) - __v = __ul; - else + long __l = -1; + __beg = _M_extract_int(__beg, __end, __io, __err, __l); + if (__l == 0 || __l == 1) + __v = __l; + else __err |= ios_base::failbit; } - - // Parse bool values as alphanumeric else { - typedef char_traits<_CharT> __traits_type; - typedef basic_string<_CharT> __string_type; - - locale __loc = __io.getloc(); - const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); - const __string_type __true = __np.truename(); - const __string_type __false = __np.falsename(); - const char_type* __trues = __true.c_str(); - const char_type* __falses = __false.c_str(); - const size_t __truen = __true.size() - 1; - const size_t __falsen = __false.size() - 1; - - for (size_t __n = 0; __beg != __end; ++__n) + // Parse bool values as alphanumeric. + typedef char_traits<_CharT> __traits_type; + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + + bool __testf = true; + bool __testt = true; + size_t __n; + for (__n = 0; __beg != __end; ++__n, ++__beg) { - char_type __c = *__beg++; - bool __testf = __n <= __falsen - ? __traits_type::eq(__c, __falses[__n]) : false; - bool __testt = __n <= __truen - ? __traits_type::eq(__c, __trues[__n]) : false; - if (!(__testf || __testt)) - { - __err |= ios_base::failbit; - break; - } - else if (__testf && __n == __falsen) - { - __v = 0; - break; - } - else if (__testt && __n == __truen) - { - __v = 1; - break; - } + if (__testf) + if (__n < __lc->_M_falsename_size) + __testf = *__beg == __lc->_M_falsename[__n]; + else + break; + + if (__testt) + if (__n < __lc->_M_truename_size) + __testt = *__beg == __lc->_M_truename[__n]; + else + break; + + if (!__testf && !__testt) + break; } + if (__testf && __n == __lc->_M_falsename_size) + __v = 0; + else if (__testt && __n == __lc->_M_truename_size) + __v = 1; + else + __err |= ios_base::failbit; + if (__beg == __end) __err |= ios_base::eofbit; } return __beg; } -#endif template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, long& __v) const - { - string __xtrc; - int __base; - __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); - __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base); - return __beg; - } + { return _M_extract_int(__beg, __end, __io, __err, __v); } template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned short& __v) const - { - string __xtrc; - int __base; - __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); - unsigned long __ul; - __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base); - if (!(__err & ios_base::failbit) - && __ul <= numeric_limits<unsigned short>::max()) - __v = static_cast<unsigned short>(__ul); - else - __err |= ios_base::failbit; - return __beg; - } + { return _M_extract_int(__beg, __end, __io, __err, __v); } template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned int& __v) const - { - string __xtrc; - int __base; - __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); - unsigned long __ul; - __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base); - if (!(__err & ios_base::failbit) - && __ul <= numeric_limits<unsigned int>::max()) - __v = static_cast<unsigned int>(__ul); - else - __err |= ios_base::failbit; - return __beg; - } + { return _M_extract_int(__beg, __end, __io, __err, __v); } template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned long& __v) const - { - string __xtrc; - int __base; - __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); - __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base); - return __beg; - } + { return _M_extract_int(__beg, __end, __io, __err, __v); } -#ifdef _GLIBCPP_USE_LONG_LONG +#ifdef _GLIBCXX_USE_LONG_LONG template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, long long& __v) const - { - string __xtrc; - int __base; - __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); - __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base); - return __beg; - } + { return _M_extract_int(__beg, __end, __io, __err, __v); } template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned long long& __v) const - { - string __xtrc; - int __base; - __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); - __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale, __base); - return __beg; - } + { return _M_extract_int(__beg, __end, __io, __err, __v); } #endif template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: - do_get(iter_type __beg, iter_type __end, ios_base& __io, + do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, float& __v) const { string __xtrc; __xtrc.reserve(32); __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); - __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); return __beg; } @@ -577,7 +752,7 @@ namespace std string __xtrc; __xtrc.reserve(32); __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); - __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); return __beg; } @@ -590,7 +765,7 @@ namespace std string __xtrc; __xtrc.reserve(32); __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); - __convert_to_v(__xtrc.c_str(), __v, __err, _S_c_locale); + std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); return __beg; } @@ -600,25 +775,20 @@ namespace std do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, void*& __v) const { - // Prepare for hex formatted input + // Prepare for hex formatted input. typedef ios_base::fmtflags fmtflags; - fmtflags __fmt = __io.flags(); - fmtflags __fmtmask = ~(ios_base::showpos | ios_base::basefield - | ios_base::uppercase | ios_base::internal); - __io.flags(__fmt & __fmtmask | (ios_base::hex | ios_base::showbase)); + const fmtflags __fmt = __io.flags(); + __io.flags(__fmt & ~ios_base::basefield | ios_base::hex); - string __xtrc; - int __base; - __beg = _M_extract_int(__beg, __end, __io, __err, __xtrc, __base); + unsigned long __ul; + __beg = _M_extract_int(__beg, __end, __io, __err, __ul); - // Reset from hex formatted input + // Reset from hex formatted input. __io.flags(__fmt); - unsigned long __ul; - __convert_to_v(__xtrc.c_str(), __ul, __err, _S_c_locale, __base); if (!(__err & ios_base::failbit)) __v = reinterpret_cast<void*>(__ul); - else + else __err |= ios_base::failbit; return __beg; } @@ -628,12 +798,12 @@ namespace std template<typename _CharT, typename _OutIter> void num_put<_CharT, _OutIter>:: - _M_pad(_CharT __fill, streamsize __w, ios_base& __io, + _M_pad(_CharT __fill, streamsize __w, ios_base& __io, _CharT* __new, const _CharT* __cs, int& __len) const { // [22.2.2.2.2] Stage 3. // If necessary, pad. - __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new, __cs, + __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new, __cs, __w, __len, true); __len = static_cast<int>(__w); } @@ -641,141 +811,143 @@ namespace std // Forwarding functions to peel signed from unsigned integer types. template<typename _CharT> inline int - __int_to_char(_CharT* __out, const int __size, long __v, - const _CharT* __lit, ios_base::fmtflags __flags) + __int_to_char(_CharT* __bufend, long __v, const _CharT* __lit, + ios_base::fmtflags __flags) { unsigned long __ul = static_cast<unsigned long>(__v); bool __neg = false; - if (__v < 0) + if (__v < 0) { __ul = -__ul; __neg = true; } - return __int_to_char(__out, __size, __ul, __lit, __flags, __neg); + return __int_to_char(__bufend, __ul, __lit, __flags, __neg); } template<typename _CharT> inline int - __int_to_char(_CharT* __out, const int __size, unsigned long __v, - const _CharT* __lit, ios_base::fmtflags __flags) - { return __int_to_char(__out, __size, __v, __lit, __flags, false); } + __int_to_char(_CharT* __bufend, unsigned long __v, const _CharT* __lit, + ios_base::fmtflags __flags) + { + // About showpos, see Table 60 and C99 7.19.6.1, p6 (+). + return __int_to_char(__bufend, __v, __lit, + __flags & ~ios_base::showpos, false); + } -#ifdef _GLIBCPP_USE_LONG_LONG +#ifdef _GLIBCXX_USE_LONG_LONG template<typename _CharT> inline int - __int_to_char(_CharT* __out, const int __size, long long __v, - const _CharT* __lit, ios_base::fmtflags __flags) - { + __int_to_char(_CharT* __bufend, long long __v, const _CharT* __lit, + ios_base::fmtflags __flags) + { unsigned long long __ull = static_cast<unsigned long long>(__v); bool __neg = false; - if (__v < 0) + if (__v < 0) { __ull = -__ull; __neg = true; } - return __int_to_char(__out, __size, __ull, __lit, __flags, __neg); + return __int_to_char(__bufend, __ull, __lit, __flags, __neg); } template<typename _CharT> inline int - __int_to_char(_CharT* __out, const int __size, unsigned long long __v, - const _CharT* __lit, ios_base::fmtflags __flags) - { return __int_to_char(__out, __size, __v, __lit, __flags, false); } + __int_to_char(_CharT* __bufend, unsigned long long __v, + const _CharT* __lit, ios_base::fmtflags __flags) + { return __int_to_char(__bufend, __v, __lit, + __flags & ~ios_base::showpos, false); } #endif - + template<typename _CharT, typename _ValueT> int - __int_to_char(_CharT* __out, const int __size, _ValueT __v, - const _CharT* __lit, ios_base::fmtflags __flags, bool __neg) + __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit, + ios_base::fmtflags __flags, bool __neg) { // Don't write base if already 0. const bool __showbase = (__flags & ios_base::showbase) && __v; const ios_base::fmtflags __basefield = __flags & ios_base::basefield; - _CharT* __buf = __out + __size - 1; - _CharT* __bufend = __out + __size; + _CharT* __buf = __bufend - 1; if (__builtin_expect(__basefield != ios_base::oct && __basefield != ios_base::hex, true)) { // Decimal. - do + do { - *__buf-- = __lit[(__v % 10) + __num_base::_S_digits]; + *__buf-- = __lit[(__v % 10) + __num_base::_S_odigits]; __v /= 10; - } + } while (__v != 0); if (__neg) - *__buf-- = __lit[__num_base::_S_minus]; + *__buf-- = __lit[__num_base::_S_ominus]; else if (__flags & ios_base::showpos) - *__buf-- = __lit[__num_base::_S_plus]; + *__buf-- = __lit[__num_base::_S_oplus]; } else if (__basefield == ios_base::oct) { // Octal. - do + do { - *__buf-- = __lit[(__v & 0x7) + __num_base::_S_digits]; + *__buf-- = __lit[(__v & 0x7) + __num_base::_S_odigits]; __v >>= 3; - } + } while (__v != 0); if (__showbase) - *__buf-- = __lit[__num_base::_S_digits]; + *__buf-- = __lit[__num_base::_S_odigits]; } else { // Hex. const bool __uppercase = __flags & ios_base::uppercase; - int __case_offset = __uppercase - ? __num_base::_S_udigits : __num_base::_S_digits; - do + const int __case_offset = __uppercase ? __num_base::_S_oudigits + : __num_base::_S_odigits; + do { *__buf-- = __lit[(__v & 0xf) + __case_offset]; __v >>= 4; - } + } while (__v != 0); if (__showbase) { // 'x' or 'X' - *__buf-- = __lit[__num_base::_S_x + __uppercase]; + *__buf-- = __lit[__num_base::_S_ox + __uppercase]; // '0' - *__buf-- = __lit[__num_base::_S_digits]; + *__buf-- = __lit[__num_base::_S_odigits]; } } - int __ret = __bufend - __buf - 1; - return __ret; + return __bufend - __buf - 1; } template<typename _CharT, typename _OutIter> void num_put<_CharT, _OutIter>:: - _M_group_int(const string& __grouping, _CharT __sep, ios_base& __io, - _CharT* __new, _CharT* __cs, int& __len) const + _M_group_int(const char* __grouping, size_t __grouping_size, _CharT __sep, + ios_base& __io, _CharT* __new, _CharT* __cs, int& __len) const { - // By itself __add_grouping cannot deal correctly with __ws when + // By itself __add_grouping cannot deal correctly with __cs when // ios::showbase is set and ios_base::oct || ios_base::hex. // Therefore we take care "by hand" of the initial 0, 0x or 0X. // However, remember that the latter do not occur if the number // printed is '0' (__len == 1). streamsize __off = 0; - const ios_base::fmtflags __basefield = __io.flags() + const ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield; if ((__io.flags() & ios_base::showbase) && __len > 1) if (__basefield == ios_base::oct) { __off = 1; - *__new = *__cs; + __new[0] = __cs[0]; } else if (__basefield == ios_base::hex) { __off = 2; - *__new = *__cs; - *(__new + 1) = *(__cs + 1); + __new[0] = __cs[0]; + __new[1] = __cs[1]; } _CharT* __p; - __p = __add_grouping(__new + __off, __sep, - __grouping.c_str(), - __grouping.c_str() + __grouping.size(), - __cs + __off, __cs + __len); + __p = std::__add_grouping(__new + __off, __sep, __grouping, + __grouping_size, __cs + __off, + __cs + __len); __len = __p - __new; } @@ -783,45 +955,44 @@ namespace std template<typename _ValueT> _OutIter num_put<_CharT, _OutIter>:: - _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, - _ValueT __v) const + _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill, + _ValueT __v) const { - typedef numpunct<_CharT> __facet_type; - typedef __locale_cache<numpunct<_CharT> > __cache_type; - const locale& __loc = __io._M_getloc(); - const __cache_type& __lc = __use_cache<__facet_type>(__loc); - const _CharT* __lit = __lc._M_atoms_out; + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + const _CharT* __lit = __lc->_M_atoms_out; // Long enough to hold hex, dec, and octal representations. - int __ilen = 4 * sizeof(_ValueT); - _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + const int __ilen = 4 * sizeof(_ValueT); + _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __ilen)); + // [22.2.2.2.2] Stage 1, numeric conversion to character. // Result is returned right-justified in the buffer. int __len; - __len = __int_to_char(&__cs[0], __ilen, __v, __lit, __io.flags()); - __cs = __cs + __ilen - __len; - - // Add grouping, if necessary. - _CharT* __cs2; - if (__lc._M_use_grouping) + __len = __int_to_char(__cs + __ilen, __v, __lit, __io.flags()); + __cs += __ilen - __len; + + // Add grouping, if necessary. + if (__lc->_M_use_grouping) { // Grouping can add (almost) as many separators as the // number of digits, but no more. - __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __len * 2)); - _M_group_int(__lc._M_grouping, __lc._M_thousands_sep, __io, - __cs2, __cs, __len); + _CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len * 2)); + _M_group_int(__lc->_M_grouping, __lc->_M_grouping_size, + __lc->_M_thousands_sep, __io, __cs2, __cs, __len); __cs = __cs2; } - + // Pad. - _CharT* __cs3; - streamsize __w = __io.width(); + const streamsize __w = __io.width(); if (__w > static_cast<streamsize>(__len)) { - __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __w)); + _CharT* __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); _M_pad(__fill, __w, __io, __cs3, __cs, __len); __cs = __cs3; } @@ -829,38 +1000,36 @@ namespace std // [22.2.2.2.2] Stage 4. // Write resulting, fully-formatted string to output iterator. - return __write(__s, __cs, __len); - } + return std::__write(__s, __cs, __len); + } template<typename _CharT, typename _OutIter> void num_put<_CharT, _OutIter>:: - _M_group_float(const string& __grouping, _CharT __sep, const _CharT* __p, - _CharT* __new, _CharT* __cs, int& __len) const + _M_group_float(const char* __grouping, size_t __grouping_size, + _CharT __sep, const _CharT* __p, _CharT* __new, + _CharT* __cs, int& __len) const { -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS - //282. What types does numpunct grouping refer to? - // Add grouping, if necessary. + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 282. What types does numpunct grouping refer to? + // Add grouping, if necessary. _CharT* __p2; - int __declen = __p ? __p - __cs : __len; - __p2 = __add_grouping(__new, __sep, - __grouping.c_str(), - __grouping.c_str() + __grouping.size(), - __cs, __cs + __declen); - + const int __declen = __p ? __p - __cs : __len; + __p2 = std::__add_grouping(__new, __sep, __grouping, __grouping_size, + __cs, __cs + __declen); + // Tack on decimal part. int __newlen = __p2 - __new; if (__p) { char_traits<_CharT>::copy(__p2, __p, __len - __declen); __newlen += __len - __declen; - } + } __len = __newlen; -#endif } // The following code uses snprintf (or sprintf(), when - // _GLIBCPP_USE_C99 is not defined) to convert floating point values + // _GLIBCXX_USE_C99 is not defined) to convert floating point values // for insertion into a stream. An optimization would be to replace // them with code that works directly on a wide buffer and then use // __pad to do the padding. It would be good to replace them anyway @@ -873,113 +1042,105 @@ namespace std template<typename _ValueT> _OutIter num_put<_CharT, _OutIter>:: - _M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod, + _M_insert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod, _ValueT __v) const { - // Note: digits10 is rounded down: add 1 to ensure the maximum - // available precision. Then, in general, one more 1 needs to - // be added since, when the %{g,G} conversion specifiers are - // chosen inside _S_format_float, the precision field is "the - // maximum number of significant digits", *not* the "number of - // digits to appear after the decimal point", as happens for - // %{e,E,f,F} (C99, 7.19.6.1,4). - const int __max_digits = numeric_limits<_ValueT>::digits10 + 2; + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); // Use default precision if out of range. streamsize __prec = __io.precision(); - if (__prec > static_cast<streamsize>(__max_digits)) - __prec = static_cast<streamsize>(__max_digits); - else if (__prec < static_cast<streamsize>(0)) + if (__prec < static_cast<streamsize>(0)) __prec = static_cast<streamsize>(6); - typedef numpunct<_CharT> __facet_type; - typedef __locale_cache<numpunct<_CharT> > __cache_type; - const locale __loc = __io._M_getloc(); - const __cache_type& __lc = __use_cache<__facet_type>(__loc); + const int __max_digits = numeric_limits<_ValueT>::digits10; // [22.2.2.2.2] Stage 1, numeric conversion to character. int __len; // Long enough for the max format spec. char __fbuf[16]; -#ifdef _GLIBCPP_USE_C99 - // First try a buffer perhaps big enough (for sure sufficient +#ifdef _GLIBCXX_USE_C99 + // First try a buffer perhaps big enough (most probably sufficient // for non-ios_base::fixed outputs) int __cs_size = __max_digits * 3; char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); - _S_format_float(__io, __fbuf, __mod, __prec); - __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, - _S_c_locale, __prec); + __num_base::_S_format_float(__io, __fbuf, __mod); + __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v, + _S_get_c_locale(), __prec); // If the buffer was not large enough, try again with the correct size. if (__len >= __cs_size) { - __cs_size = __len + 1; + __cs_size = __len + 1; __cs = static_cast<char*>(__builtin_alloca(__cs_size)); - __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, - _S_c_locale, __prec); + __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v, + _S_get_c_locale(), __prec); } #else // Consider the possibility of long ios_base::fixed outputs const bool __fixed = __io.flags() & ios_base::fixed; const int __max_exp = numeric_limits<_ValueT>::max_exponent10; - // ios_base::fixed outputs may need up to __max_exp+1 chars - // for the integer part + up to __max_digits chars for the - // fractional part + 3 chars for sign, decimal point, '\0'. On - // the other hand, for non-fixed outputs __max_digits*3 chars - // are largely sufficient. - const int __cs_size = __fixed ? __max_exp + __max_digits + 4 - : __max_digits * 3; + // The size of the output string is computed as follows. + // ios_base::fixed outputs may need up to __max_exp + 1 chars + // for the integer part + __prec chars for the fractional part + // + 3 chars for sign, decimal point, '\0'. On the other hand, + // for non-fixed outputs __max_digits * 2 + __prec chars are + // largely sufficient. + const int __cs_size = __fixed ? __max_exp + __prec + 4 + : __max_digits * 2 + __prec; char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); - _S_format_float(__io, __fbuf, __mod, __prec); - __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale, __prec); + __num_base::_S_format_float(__io, __fbuf, __mod); + __len = std::__convert_from_v(__cs, 0, __fbuf, __v, + _S_get_c_locale(), __prec); #endif // [22.2.2.2.2] Stage 2, convert to char_type, using correct // numpunct.decimal_point() values for '.' and adding grouping. const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); - _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len)); __ctype.widen(__cs, __cs + __len, __ws); - + // Replace decimal point. const _CharT __cdec = __ctype.widen('.'); - const _CharT __dec = __lc._M_decimal_point; + const _CharT __dec = __lc->_M_decimal_point; const _CharT* __p; if (__p = char_traits<_CharT>::find(__ws, __len, __cdec)) __ws[__p - __ws] = __dec; - // Add grouping, if necessary. - _CharT* __ws2; - if (__lc._M_use_grouping) + // Add grouping, if necessary. + if (__lc->_M_use_grouping) { - // Grouping can add (almost) as many separators as the - // number of digits, but no more. - __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __len * 2)); - _M_group_float(__lc._M_grouping, __lc._M_thousands_sep, __p, - __ws2, __ws, __len); - __ws = __ws2; + // Grouping can add (almost) as many separators as the + // number of digits, but no more. + _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len * 2)); + _M_group_float(__lc->_M_grouping, __lc->_M_grouping_size, + __lc->_M_thousands_sep, __p, __ws2, __ws, __len); + __ws = __ws2; } // Pad. - _CharT* __ws3; - streamsize __w = __io.width(); + const streamsize __w = __io.width(); if (__w > static_cast<streamsize>(__len)) { - __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w)); + _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); _M_pad(__fill, __w, __io, __ws3, __ws, __len); __ws = __ws3; } __io.width(0); - + // [22.2.2.2.2] Stage 4. // Write resulting, fully-formatted string to output iterator. - return __write(__s, __ws, __len); + return std::__write(__s, __ws, __len); } template<typename _CharT, typename _OutIter> @@ -987,39 +1148,35 @@ namespace std num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const { - ios_base::fmtflags __flags = __io.flags(); + const ios_base::fmtflags __flags = __io.flags(); if ((__flags & ios_base::boolalpha) == 0) { unsigned long __uv = __v; - __s = _M_convert_int(__s, __io, __fill, __uv); + __s = _M_insert_int(__s, __io, __fill, __uv); } else { - typedef numpunct<_CharT> __facet_type; - typedef __locale_cache<numpunct<_CharT> > __cache_type; - const locale __loc = __io._M_getloc(); - const __cache_type& __lc = __use_cache<__facet_type>(__loc); - - typedef basic_string<_CharT> __string_type; - __string_type __name; - if (__v) - __name = __lc._M_truename; - else - __name = __lc._M_falsename; - - const _CharT* __cs = __name.c_str(); - int __len = __name.size(); - _CharT* __cs3; - streamsize __w = __io.width(); + typedef typename numpunct<_CharT>::__cache_type __cache_type; + __use_cache<__cache_type> __uc; + const locale& __loc = __io._M_getloc(); + const __cache_type* __lc = __uc(__loc); + + const _CharT* __name = __v ? __lc->_M_truename + : __lc->_M_falsename; + int __len = __v ? __lc->_M_truename_size + : __lc->_M_falsename_size; + + const streamsize __w = __io.width(); if (__w > static_cast<streamsize>(__len)) { - __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __w)); - _M_pad(__fill, __w, __io, __cs3, __cs, __len); - __cs = __cs3; + _CharT* __cs + = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); + _M_pad(__fill, __w, __io, __cs, __name, __len); + __name = __cs; } __io.width(0); - __s = __write(__s, __cs, __len); + __s = std::__write(__s, __name, __len); } return __s; } @@ -1028,42 +1185,42 @@ namespace std _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const - { return _M_convert_int(__s, __io, __fill, __v); } + { return _M_insert_int(__s, __io, __fill, __v); } template<typename _CharT, typename _OutIter> _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, unsigned long __v) const - { return _M_convert_int(__s, __io, __fill, __v); } + { return _M_insert_int(__s, __io, __fill, __v); } -#ifdef _GLIBCPP_USE_LONG_LONG +#ifdef _GLIBCXX_USE_LONG_LONG template<typename _CharT, typename _OutIter> _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const - { return _M_convert_int(__s, __b, __fill, __v); } + { return _M_insert_int(__s, __b, __fill, __v); } template<typename _CharT, typename _OutIter> _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, unsigned long long __v) const - { return _M_convert_int(__s, __io, __fill, __v); } + { return _M_insert_int(__s, __io, __fill, __v); } #endif template<typename _CharT, typename _OutIter> _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const - { return _M_convert_float(__s, __io, __fill, char(), __v); } + { return _M_insert_float(__s, __io, __fill, char(), __v); } template<typename _CharT, typename _OutIter> _OutIter num_put<_CharT, _OutIter>:: - do_put(iter_type __s, ios_base& __io, char_type __fill, + do_put(iter_type __s, ios_base& __io, char_type __fill, long double __v) const - { return _M_convert_float(__s, __io, __fill, 'L', __v); } + { return _M_insert_float(__s, __io, __fill, 'L', __v); } template<typename _CharT, typename _OutIter> _OutIter @@ -1071,274 +1228,475 @@ namespace std do_put(iter_type __s, ios_base& __io, char_type __fill, const void* __v) const { - ios_base::fmtflags __flags = __io.flags(); - ios_base::fmtflags __fmt = ~(ios_base::showpos | ios_base::basefield - | ios_base::uppercase | ios_base::internal); + const ios_base::fmtflags __flags = __io.flags(); + const ios_base::fmtflags __fmt = ~(ios_base::showpos + | ios_base::basefield + | ios_base::uppercase + | ios_base::internal); __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase)); - try - { - __s = _M_convert_int(__s, __io, __fill, - reinterpret_cast<unsigned long>(__v)); - __io.flags(__flags); - } - catch (...) - { - __io.flags(__flags); - __throw_exception_again; - } - return __s; - } - - template<typename _CharT, typename _InIter> - _InIter - money_get<_CharT, _InIter>:: - do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, - ios_base::iostate& __err, long double& __units) const - { - string_type __str; - __beg = this->do_get(__beg, __end, __intl, __io, __err, __str); - - const int __cs_size = __str.size() + 1; - char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); - const locale __loc = __io.getloc(); - const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); - const _CharT* __wcs = __str.c_str(); - __ctype.narrow(__wcs, __wcs + __cs_size, char(), __cs); - __convert_to_v(__cs, __units, __err, _S_c_locale); - return __beg; + __s = _M_insert_int(__s, __io, __fill, + reinterpret_cast<unsigned long>(__v)); + __io.flags(__flags); + return __s; } template<typename _CharT, typename _InIter> - _InIter - money_get<_CharT, _InIter>:: - do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, - ios_base::iostate& __err, string_type& __units) const - { - // These contortions are quite unfortunate. - typedef moneypunct<_CharT, true> __money_true; - typedef moneypunct<_CharT, false> __money_false; - typedef money_base::part part; - typedef typename string_type::size_type size_type; - - const locale __loc = __io.getloc(); - const __money_true& __mpt = use_facet<__money_true>(__loc); - const __money_false& __mpf = use_facet<__money_false>(__loc); - const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); - - const money_base::pattern __p = __intl ? __mpt.neg_format() - : __mpf.neg_format(); - - const string_type __pos_sign =__intl ? __mpt.positive_sign() - : __mpf.positive_sign(); - const string_type __neg_sign =__intl ? __mpt.negative_sign() - : __mpf.negative_sign(); - const char_type __d = __intl ? __mpt.decimal_point() - : __mpf.decimal_point(); - const char_type __sep = __intl ? __mpt.thousands_sep() - : __mpf.thousands_sep(); - - const string __grouping = __intl ? __mpt.grouping() : __mpf.grouping(); - - // Set to deduced positive or negative sign, depending. - string_type __sign; - // String of grouping info from thousands_sep plucked from __units. - string __grouping_tmp; - // Marker for thousands_sep position. - int __sep_pos = 0; - // If input iterator is in a valid state. - bool __testvalid = true; - // Flag marking when a decimal point is found. - bool __testdecfound = false; - - // The tentative returned string is stored here. - string_type __temp_units; - - char_type __c = *__beg; - char_type __eof = static_cast<char_type>(char_traits<char_type>::eof()); - for (int __i = 0; __beg != __end && __i < 4 && __testvalid; ++__i) - { - part __which = static_cast<part>(__p.field[__i]); - switch (__which) - { - case money_base::symbol: - if (__io.flags() & ios_base::showbase - || __i < 2 || __sign.size() > 1 - || ((static_cast<part>(__p.field[3]) != money_base::none) - && __i == 2)) - { - // According to 22.2.6.1.2.2, symbol is required - // if (__io.flags() & ios_base::showbase), - // otherwise is optional and consumed only if - // other characters are needed to complete the - // format. - const string_type __symbol = __intl ? __mpt.curr_symbol() - : __mpf.curr_symbol(); - size_type __len = __symbol.size(); - size_type __j = 0; - while (__beg != __end - && __j < __len && __symbol[__j] == __c) - { - __c = *(++__beg); - ++__j; - } - // When (__io.flags() & ios_base::showbase) - // symbol is required. - if (__j != __len && (__io.flags() & ios_base::showbase)) - __testvalid = false; - } - break; - case money_base::sign: - // Sign might not exist, or be more than one character long. - if (__pos_sign.size() && __neg_sign.size()) + template<bool _Intl> + _InIter + money_get<_CharT, _InIter>:: + _M_extract(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, string& __units) const + { + typedef char_traits<_CharT> __traits_type; + typedef typename string_type::size_type size_type; + typedef money_base::part part; + typedef moneypunct<_CharT, _Intl> __moneypunct_type; + typedef typename __moneypunct_type::__cache_type __cache_type; + + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + + __use_cache<__cache_type> __uc; + const __cache_type* __lc = __uc(__loc); + const char_type* __lit = __lc->_M_atoms; + + // Deduced sign. + bool __negative = false; + // Sign size. + size_type __sign_size = 0; + // True if sign is mandatory. + const bool __mandatory_sign = (__lc->_M_positive_sign_size + && __lc->_M_negative_sign_size); + // String of grouping info from thousands_sep plucked from __units. + string __grouping_tmp; + if (__lc->_M_use_grouping) + __grouping_tmp.reserve(32); + // Last position before the decimal point. + int __last_pos = 0; + // Separator positions, then, possibly, fractional digits. + int __n = 0; + // If input iterator is in a valid state. + bool __testvalid = true; + // Flag marking when a decimal point is found. + bool __testdecfound = false; + + // The tentative returned string is stored here. + string __res; + __res.reserve(32); + + const char_type* __lit_zero = __lit + money_base::_S_zero; + const char_type* __q; + const money_base::pattern __p = __lc->_M_neg_format; + for (int __i = 0; __i < 4 && __testvalid; ++__i) + { + const part __which = static_cast<part>(__p.field[__i]); + switch (__which) + { + case money_base::symbol: + // According to 22.2.6.1.2, p2, symbol is required + // if (__io.flags() & ios_base::showbase), otherwise + // is optional and consumed only if other characters + // are needed to complete the format. + if (__io.flags() & ios_base::showbase || __sign_size > 1 + || __i == 0 + || (__i == 1 && (__mandatory_sign + || (static_cast<part>(__p.field[0]) + == money_base::sign) + || (static_cast<part>(__p.field[2]) + == money_base::space))) + || (__i == 2 && ((static_cast<part>(__p.field[3]) + == money_base::value) + || __mandatory_sign + && (static_cast<part>(__p.field[3]) + == money_base::sign)))) { - // Sign is mandatory. - if (__c == __pos_sign[0]) - { - __sign = __pos_sign; - __c = *(++__beg); - } - else if (__c == __neg_sign[0]) - { - __sign = __neg_sign; - __c = *(++__beg); - } - else + const size_type __len = __lc->_M_curr_symbol_size; + size_type __j = 0; + for (; __beg != __end && __j < __len + && *__beg == __lc->_M_curr_symbol[__j]; + ++__beg, ++__j); + if (__j != __len + && (__j || __io.flags() & ios_base::showbase)) __testvalid = false; } - else if (__pos_sign.size() && __c == __pos_sign[0]) + break; + case money_base::sign: + // Sign might not exist, or be more than one character long. + if (__lc->_M_positive_sign_size && __beg != __end + && *__beg == __lc->_M_positive_sign[0]) + { + __sign_size = __lc->_M_positive_sign_size; + ++__beg; + } + else if (__lc->_M_negative_sign_size && __beg != __end + && *__beg == __lc->_M_negative_sign[0]) + { + __negative = true; + __sign_size = __lc->_M_negative_sign_size; + ++__beg; + } + else if (__lc->_M_positive_sign_size + && !__lc->_M_negative_sign_size) + // "... if no sign is detected, the result is given the sign + // that corresponds to the source of the empty string" + __negative = true; + else if (__mandatory_sign) + __testvalid = false; + break; + case money_base::value: + // Extract digits, remove and stash away the + // grouping of found thousands separators. + for (; __beg != __end; ++__beg) + if (__q = __traits_type::find(__lit_zero, 10, *__beg)) { - __sign = __pos_sign; - __c = *(++__beg); + __res += money_base::_S_atoms[__q - __lit]; + ++__n; } - else if (__neg_sign.size() && __c == __neg_sign[0]) + else if (*__beg == __lc->_M_decimal_point && !__testdecfound) { - __sign = __neg_sign; - __c = *(++__beg); + __last_pos = __n; + __n = 0; + __testdecfound = true; } - break; - case money_base::value: - // Extract digits, remove and stash away the - // grouping of found thousands separators. - while (__beg != __end - && (__ctype.is(ctype_base::digit, __c) - || (__c == __d && !__testdecfound) - || __c == __sep)) + else if (__lc->_M_use_grouping + && *__beg == __lc->_M_thousands_sep + && !__testdecfound) { - if (__c == __d) - { - __grouping_tmp += static_cast<char>(__sep_pos); - __sep_pos = 0; - __testdecfound = true; - } - else if (__c == __sep) + if (__n) { - if (__grouping.size()) - { - // Mark position for later analysis. - __grouping_tmp += static_cast<char>(__sep_pos); - __sep_pos = 0; - } - else - { - __testvalid = false; - break; - } + // Mark position for later analysis. + __grouping_tmp += static_cast<char>(__n); + __n = 0; } else { - __temp_units += __c; - ++__sep_pos; + __testvalid = false; + break; } - __c = *(++__beg); } - break; - case money_base::space: - case money_base::none: - // Only if not at the end of the pattern. - if (__i != 3) - while (__beg != __end - && __ctype.is(ctype_base::space, __c)) - __c = *(++__beg); - break; - } - } + else + break; + if (__res.empty()) + __testvalid = false; + break; + case money_base::space: + // At least one space is required. + if (__beg != __end && __ctype.is(ctype_base::space, *__beg)) + ++__beg; + else + __testvalid = false; + case money_base::none: + // Only if not at the end of the pattern. + if (__i != 3) + for (; __beg != __end + && __ctype.is(ctype_base::space, *__beg); ++__beg); + break; + } + } - // Need to get the rest of the sign characters, if they exist. - if (__sign.size() > 1) - { - size_type __len = __sign.size(); - size_type __i = 1; - for (; __c != __eof && __i < __len; ++__i) - while (__beg != __end && __c != __sign[__i]) - __c = *(++__beg); - - if (__i != __len) - __testvalid = false; - } + // Need to get the rest of the sign characters, if they exist. + if (__sign_size > 1 && __testvalid) + { + const char_type* __sign = __negative ? __lc->_M_negative_sign + : __lc->_M_positive_sign; + size_type __i = 1; + for (; __beg != __end && __i < __sign_size + && *__beg == __sign[__i]; ++__beg, ++__i); + + if (__i != __sign_size) + __testvalid = false; + } + + if (__testvalid) + { + // Strip leading zeros. + if (__res.size() > 1) + { + const size_type __first = __res.find_first_not_of('0'); + const bool __only_zeros = __first == string::npos; + if (__first) + __res.erase(0, __only_zeros ? __res.size() - 1 : __first); + } + + // 22.2.6.1.2, p4 + if (__negative && __res[0] != '0') + __res.insert(__res.begin(), '-'); + + // Test for grouping fidelity. + if (__grouping_tmp.size()) + { + // Add the ending grouping. + __grouping_tmp += static_cast<char>(__testdecfound ? __last_pos + : __n); + if (!std::__verify_grouping(__lc->_M_grouping, + __lc->_M_grouping_size, + __grouping_tmp)) + __testvalid = false; + } + + // Iff not enough digits were supplied after the decimal-point. + if (__testdecfound && __lc->_M_frac_digits > 0 + && __n != __lc->_M_frac_digits) + __testvalid = false; + } + + // Iff no more characters are available. + if (__beg == __end) + __err |= ios_base::eofbit; + + // Iff valid sequence is not recognized. + if (!__testvalid) + __err |= ios_base::failbit; + else + __units.swap(__res); + + return __beg; + } + + template<typename _CharT, typename _InIter> + _InIter + money_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, long double& __units) const + { + string __str; + if (__intl) + __beg = _M_extract<true>(__beg, __end, __io, __err, __str); + else + __beg = _M_extract<false>(__beg, __end, __io, __err, __str); + std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); + return __beg; + } - // Strip leading zeros. - while (__temp_units.size() > 1 && __temp_units[0] == __ctype.widen('0')) - __temp_units.erase(__temp_units.begin()); + template<typename _CharT, typename _InIter> + _InIter + money_get<_CharT, _InIter>:: + do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, + ios_base::iostate& __err, string_type& __units) const + { + typedef typename string::size_type size_type; - if (__sign.size() && __sign == __neg_sign) - __temp_units.insert(__temp_units.begin(), __ctype.widen('-')); + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); - // Test for grouping fidelity. - if (__grouping.size() && __grouping_tmp.size()) + string __str; + const iter_type __ret = __intl ? _M_extract<true>(__beg, __end, __io, + __err, __str) + : _M_extract<false>(__beg, __end, __io, + __err, __str); + const size_type __len = __str.size(); + if (__len) { - if (!__verify_grouping(__grouping, __grouping_tmp)) - __testvalid = false; + _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __len)); + __ctype.widen(__str.data(), __str.data() + __len, __ws); + __units.assign(__ws, __len); } - // Iff no more characters are available. - if (__c == __eof) - __err |= ios_base::eofbit; + return __ret; + } - // Iff valid sequence is not recognized. - if (!__testvalid || !__temp_units.size()) - __err |= ios_base::failbit; - else - // Use the "swap trick" to copy __temp_units into __units. - __temp_units.swap(__units); + template<typename _CharT, typename _OutIter> + template<bool _Intl> + _OutIter + money_put<_CharT, _OutIter>:: + _M_insert(iter_type __s, ios_base& __io, char_type __fill, + const string_type& __digits) const + { + typedef typename string_type::size_type size_type; + typedef money_base::part part; + typedef moneypunct<_CharT, _Intl> __moneypunct_type; + typedef typename __moneypunct_type::__cache_type __cache_type; + + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); - return __beg; - } + __use_cache<__cache_type> __uc; + const __cache_type* __lc = __uc(__loc); + const char_type* __lit = __lc->_M_atoms; + + // Determine if negative or positive formats are to be used, and + // discard leading negative_sign if it is present. + const char_type* __beg = __digits.data(); + money_base::pattern __p; + const char_type* __sign; + size_type __sign_size; + if (*__beg != __lit[money_base::_S_minus]) + { + __p = __lc->_M_pos_format; + __sign = __lc->_M_positive_sign; + __sign_size = __lc->_M_positive_sign_size; + } + else + { + __p = __lc->_M_neg_format; + __sign = __lc->_M_negative_sign; + __sign_size = __lc->_M_negative_sign_size; + if (__digits.size()) + ++__beg; + } + + // Look for valid numbers in the ctype facet within input digits. + size_type __len = __ctype.scan_not(ctype_base::digit, __beg, + __beg + __digits.size()) - __beg; + if (__len) + { + // Assume valid input, and attempt to format. + // Break down input numbers into base components, as follows: + // final_value = grouped units + (decimal point) + (digits) + string_type __value; + __value.reserve(2 * __len); + + // Add thousands separators to non-decimal digits, per + // grouping rules. + int __paddec = __len - __lc->_M_frac_digits; + if (__paddec > 0) + { + if (__lc->_M_frac_digits < 0) + __paddec = __len; + if (__lc->_M_grouping_size) + { + _CharT* __ws = + static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * 2 * __len)); + _CharT* __ws_end = + std::__add_grouping(__ws, __lc->_M_thousands_sep, + __lc->_M_grouping, + __lc->_M_grouping_size, + __beg, __beg + __paddec); + __value.assign(__ws, __ws_end - __ws); + } + else + __value.assign(__beg, __paddec); + } + + // Deal with decimal point, decimal digits. + if (__lc->_M_frac_digits > 0) + { + __value += __lc->_M_decimal_point; + if (__paddec >= 0) + __value.append(__beg + __paddec, __lc->_M_frac_digits); + else + { + // Have to pad zeros in the decimal position. + __value.append(-__paddec, __lit[money_base::_S_zero]); + __value.append(__beg, __len); + } + } + + // Calculate length of resulting string. + const ios_base::fmtflags __f = __io.flags() + & ios_base::adjustfield; + __len = __value.size() + __sign_size; + __len += ((__io.flags() & ios_base::showbase) + ? __lc->_M_curr_symbol_size : 0); + + string_type __res; + __res.reserve(2 * __len); + + const size_type __width = static_cast<size_type>(__io.width()); + const bool __testipad = (__f == ios_base::internal + && __len < __width); + // Fit formatted digits into the required pattern. + for (int __i = 0; __i < 4; ++__i) + { + const part __which = static_cast<part>(__p.field[__i]); + switch (__which) + { + case money_base::symbol: + if (__io.flags() & ios_base::showbase) + __res.append(__lc->_M_curr_symbol, + __lc->_M_curr_symbol_size); + break; + case money_base::sign: + // Sign might not exist, or be more than one + // charater long. In that case, add in the rest + // below. + if (__sign_size) + __res += __sign[0]; + break; + case money_base::value: + __res += __value; + break; + case money_base::space: + // At least one space is required, but if internal + // formatting is required, an arbitrary number of + // fill spaces will be necessary. + if (__testipad) + __res.append(__width - __len, __fill); + else + __res += __fill; + break; + case money_base::none: + if (__testipad) + __res.append(__width - __len, __fill); + break; + } + } + + // Special case of multi-part sign parts. + if (__sign_size > 1) + __res.append(__sign + 1, __sign_size - 1); + + // Pad, if still necessary. + __len = __res.size(); + if (__width > __len) + { + if (__f == ios_base::left) + // After. + __res.append(__width - __len, __fill); + else + // Before. + __res.insert(0, __width - __len, __fill); + __len = __width; + } + + // Write resulting, fully-formatted string to output iterator. + __s = std::__write(__s, __res.data(), __len); + } + __io.width(0); + return __s; + } + template<typename _CharT, typename _OutIter> _OutIter money_put<_CharT, _OutIter>:: do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, long double __units) const - { + { const locale __loc = __io.getloc(); const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); -#ifdef _GLIBCPP_USE_C99 +#ifdef _GLIBCXX_USE_C99 // First try a buffer perhaps big enough. int __cs_size = 64; char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); - int __len = __convert_from_v(__cs, __cs_size, "%.01Lf", __units, - _S_c_locale); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 328. Bad sprintf format modifier in money_put<>::do_put() + int __len = std::__convert_from_v(__cs, __cs_size, "%.0Lf", __units, + _S_get_c_locale()); // If the buffer was not large enough, try again with the correct size. if (__len >= __cs_size) { __cs_size = __len + 1; __cs = static_cast<char*>(__builtin_alloca(__cs_size)); - __len = __convert_from_v(__cs, __cs_size, "%.01Lf", __units, - _S_c_locale); + __len = std::__convert_from_v(__cs, __cs_size, "%.0Lf", __units, + _S_get_c_locale()); } #else - // max_exponent10 + 1 for the integer part, + 4 for sign, decimal point, - // decimal digit, '\0'. - const int __cs_size = numeric_limits<long double>::max_exponent10 + 5; + // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'. + const int __cs_size = numeric_limits<long double>::max_exponent10 + 3; char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); - int __len = __convert_from_v(__cs, 0, "%.01Lf", __units, _S_c_locale); + int __len = std::__convert_from_v(__cs, 0, "%.0Lf", __units, + _S_get_c_locale()); #endif - _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __cs_size)); __ctype.widen(__cs, __cs + __len, __ws); - string_type __digits(__ws); - return this->do_put(__s, __intl, __io, __fill, __digits); + const string_type __digits(__ws, __len); + return __intl ? _M_insert<true>(__s, __io, __fill, __digits) + : _M_insert<false>(__s, __io, __fill, __digits); } template<typename _CharT, typename _OutIter> @@ -1346,163 +1704,8 @@ namespace std money_put<_CharT, _OutIter>:: do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, const string_type& __digits) const - { - typedef typename string_type::size_type size_type; - typedef money_base::part part; - - const locale __loc = __io.getloc(); - const size_type __width = static_cast<size_type>(__io.width()); - - // These contortions are quite unfortunate. - typedef moneypunct<_CharT, true> __money_true; - typedef moneypunct<_CharT, false> __money_false; - const __money_true& __mpt = use_facet<__money_true>(__loc); - const __money_false& __mpf = use_facet<__money_false>(__loc); - const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); - - // Determine if negative or positive formats are to be used, and - // discard leading negative_sign if it is present. - const char_type* __beg = __digits.data(); - const char_type* __end = __beg + __digits.size(); - money_base::pattern __p; - string_type __sign; - if (*__beg != __ctype.widen('-')) - { - __p = __intl ? __mpt.pos_format() : __mpf.pos_format(); - __sign =__intl ? __mpt.positive_sign() : __mpf.positive_sign(); - } - else - { - __p = __intl ? __mpt.neg_format() : __mpf.neg_format(); - __sign =__intl ? __mpt.negative_sign() : __mpf.negative_sign(); - ++__beg; - } - - // Look for valid numbers in the current ctype facet within input digits. - __end = __ctype.scan_not(ctype_base::digit, __beg, __end); - if (__beg != __end) - { - // Assume valid input, and attempt to format. - // Break down input numbers into base components, as follows: - // final_value = grouped units + (decimal point) + (digits) - string_type __res; - string_type __value; - const string_type __symbol = __intl ? __mpt.curr_symbol() - : __mpf.curr_symbol(); - - // Deal with decimal point, decimal digits. - const int __frac = __intl ? __mpt.frac_digits() - : __mpf.frac_digits(); - if (__frac > 0) - { - const char_type __d = __intl ? __mpt.decimal_point() - : __mpf.decimal_point(); - if (__end - __beg >= __frac) - { - __value = string_type(__end - __frac, __end); - __value.insert(__value.begin(), __d); - __end -= __frac; - } - else - { - // Have to pad zeros in the decimal position. - __value = string_type(__beg, __end); - int __paddec = __frac - (__end - __beg); - char_type __zero = __ctype.widen('0'); - __value.insert(__value.begin(), __paddec, __zero); - __value.insert(__value.begin(), __d); - __beg = __end; - } - } - - // Add thousands separators to non-decimal digits, per - // grouping rules. - if (__beg != __end) - { - const string __grouping = __intl ? __mpt.grouping() - : __mpf.grouping(); - if (__grouping.size()) - { - const char_type __sep = __intl ? __mpt.thousands_sep() - : __mpf.thousands_sep(); - const char* __gbeg = __grouping.c_str(); - const char* __gend = __gbeg + __grouping.size(); - const int __n = (__end - __beg) * 2; - _CharT* __ws2 = - static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n)); - _CharT* __ws_end = __add_grouping(__ws2, __sep, __gbeg, - __gend, __beg, __end); - __value.insert(0, __ws2, __ws_end - __ws2); - } - else - __value.insert(0, string_type(__beg, __end)); - } - - // Calculate length of resulting string. - ios_base::fmtflags __f = __io.flags() & ios_base::adjustfield; - size_type __len = __value.size() + __sign.size(); - __len += (__io.flags() & ios_base::showbase) ? __symbol.size() : 0; - bool __testipad = __f == ios_base::internal && __len < __width; - - // Fit formatted digits into the required pattern. - for (int __i = 0; __i < 4; ++__i) - { - part __which = static_cast<part>(__p.field[__i]); - switch (__which) - { - case money_base::symbol: - if (__io.flags() & ios_base::showbase) - __res += __symbol; - break; - case money_base::sign: - // Sign might not exist, or be more than one - // charater long. In that case, add in the rest - // below. - if (__sign.size()) - __res += __sign[0]; - break; - case money_base::value: - __res += __value; - break; - case money_base::space: - // At least one space is required, but if internal - // formatting is required, an arbitrary number of - // fill spaces will be necessary. - if (__testipad) - __res += string_type(__width - __len, __fill); - else - __res += __ctype.widen(__fill); - break; - case money_base::none: - if (__testipad) - __res += string_type(__width - __len, __fill); - break; - } - } - - // Special case of multi-part sign parts. - if (__sign.size() > 1) - __res += string_type(__sign.begin() + 1, __sign.end()); - - // Pad, if still necessary. - __len = __res.size(); - if (__width > __len) - { - if (__f == ios_base::left) - // After. - __res.append(__width - __len, __fill); - else - // Before. - __res.insert(0, string_type(__width - __len, __fill)); - __len = __width; - } - - // Write resulting, fully-formatted string to output iterator. - __s = __write(__s, __res.c_str(), __len); - } - __io.width(0); - return __s; - } + { return __intl ? _M_insert<true>(__s, __io, __fill, __digits) + : _M_insert<false>(__s, __io, __fill, __digits); } // NB: Not especially useful. Without an ios_base object or some @@ -1513,32 +1716,29 @@ namespace std time_get<_CharT, _InIter>::do_date_order() const { return time_base::no_order; } + // Expand a strftime format string and parse it. E.g., do_get_date() may + // pass %m/%d/%Y => extracted characters. template<typename _CharT, typename _InIter> - void + _InIter time_get<_CharT, _InIter>:: - _M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io, - ios_base::iostate& __err, tm* __tm, + _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm, const _CharT* __format) const - { - locale __loc = __io.getloc(); - __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); - const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); - size_t __len = char_traits<_CharT>::length(__format); + { + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + const size_t __len = char_traits<_CharT>::length(__format); for (size_t __i = 0; __beg != __end && __i < __len && !__err; ++__i) { - char __c = __format[__i]; - if (__c == '%') + if (__ctype.narrow(__format[__i], 0) == '%') { // Verify valid formatting code, attempt to extract. - __c = __format[++__i]; - char __mod = 0; - int __mem = 0; + char __c = __ctype.narrow(__format[++__i], 0); + int __mem = 0; if (__c == 'E' || __c == 'O') - { - __mod = __c; - __c = __format[++__i]; - } + __c = __ctype.narrow(__format[++__i], 0); switch (__c) { const char* __cs; @@ -1547,71 +1747,81 @@ namespace std // Abbreviated weekday name [tm_wday] const char_type* __days1[7]; __tp._M_days_abbreviated(__days1); - _M_extract_name(__beg, __end, __tm->tm_wday, __days1, 7, - __err); + __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days1, + 7, __io, __err); break; case 'A': // Weekday name [tm_wday]. const char_type* __days2[7]; __tp._M_days(__days2); - _M_extract_name(__beg, __end, __tm->tm_wday, __days2, 7, - __err); + __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days2, + 7, __io, __err); break; case 'h': case 'b': // Abbreviated month name [tm_mon] const char_type* __months1[12]; __tp._M_months_abbreviated(__months1); - _M_extract_name(__beg, __end, __tm->tm_mon, __months1, 12, - __err); + __beg = _M_extract_name(__beg, __end, __tm->tm_mon, + __months1, 12, __io, __err); break; case 'B': // Month name [tm_mon]. const char_type* __months2[12]; __tp._M_months(__months2); - _M_extract_name(__beg, __end, __tm->tm_mon, __months2, 12, - __err); + __beg = _M_extract_name(__beg, __end, __tm->tm_mon, + __months2, 12, __io, __err); break; case 'c': // Default time and date representation. const char_type* __dt[2]; __tp._M_date_time_formats(__dt); - _M_extract_via_format(__beg, __end, __io, __err, __tm, - __dt[0]); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __dt[0]); break; case 'd': // Day [01, 31]. [tm_mday] - _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2, - __ctype, __err); + __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2, + __io, __err); + break; + case 'e': + // Day [1, 31], with single digits preceded by + // space. [tm_mday] + if (__ctype.is(ctype_base::space, *__beg)) + __beg = _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9, + 1, __io, __err); + else + __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31, + 2, __io, __err); break; case 'D': // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year] __cs = "%m/%d/%y"; __ctype.widen(__cs, __cs + 9, __wcs); - _M_extract_via_format(__beg, __end, __io, __err, __tm, - __wcs); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __wcs); break; case 'H': // Hour [00, 23]. [tm_hour] - _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2, - __ctype, __err); + __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2, + __io, __err); break; case 'I': // Hour [01, 12]. [tm_hour] - _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2, - __ctype, __err); + __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2, + __io, __err); break; case 'm': // Month [01, 12]. [tm_mon] - _M_extract_num(__beg, __end, __mem, 1, 12, 2, __ctype, - __err); + __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, + __io, __err); if (!__err) __tm->tm_mon = __mem - 1; break; case 'M': // Minute [00, 59]. [tm_min] - _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2, - __ctype, __err); + __beg = _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2, + __io, __err); break; case 'n': if (__ctype.narrow(*__beg, 0) == '\n') @@ -1623,51 +1833,51 @@ namespace std // Equivalent to (%H:%M). __cs = "%H:%M"; __ctype.widen(__cs, __cs + 6, __wcs); - _M_extract_via_format(__beg, __end, __io, __err, __tm, - __wcs); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __wcs); break; case 'S': // Seconds. - _M_extract_num(__beg, __end, __tm->tm_sec, 0, 59, 2, - __ctype, __err); + __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 59, 2, + __io, __err); break; case 't': if (__ctype.narrow(*__beg, 0) == '\t') ++__beg; else - __err |= ios_base::failbit; + __err |= ios_base::failbit; break; case 'T': // Equivalent to (%H:%M:%S). __cs = "%H:%M:%S"; __ctype.widen(__cs, __cs + 9, __wcs); - _M_extract_via_format(__beg, __end, __io, __err, __tm, - __wcs); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __wcs); break; case 'x': // Locale's date. const char_type* __dates[2]; __tp._M_date_formats(__dates); - _M_extract_via_format(__beg, __end, __io, __err, __tm, - __dates[0]); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __dates[0]); break; case 'X': // Locale's time. const char_type* __times[2]; __tp._M_time_formats(__times); - _M_extract_via_format(__beg, __end, __io, __err, __tm, - __times[0]); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __times[0]); break; case 'y': + case 'C': // C99 // Two digit year. [tm_year] - _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2, - __ctype, __err); + __beg = _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2, + __io, __err); break; case 'Y': // Year [1900). [tm_year] - _M_extract_num(__beg, __end, __mem, 0, - numeric_limits<int>::max(), 4, - __ctype, __err); + __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4, + __io, __err); if (!__err) __tm->tm_year = __mem - 1900; break; @@ -1676,116 +1886,129 @@ namespace std if (__ctype.is(ctype_base::upper, *__beg)) { int __tmp; - _M_extract_name(__beg, __end, __tmp, - __timepunct<_CharT>::_S_timezones, - 14, __err); - + __beg = _M_extract_name(__beg, __end, __tmp, + __timepunct_cache<_CharT>::_S_timezones, + 14, __io, __err); + // GMT requires special effort. - char_type __c = *__beg; - if (!__err && __tmp == 0 - && (__c == __ctype.widen('-') - || __c == __ctype.widen('+'))) + if (__beg != __end && !__err && __tmp == 0 + && (*__beg == __ctype.widen('-') + || *__beg == __ctype.widen('+'))) { - _M_extract_num(__beg, __end, __tmp, 0, 23, 2, - __ctype, __err); - _M_extract_num(__beg, __end, __tmp, 0, 59, 2, - __ctype, __err); - } - } - else - __err |= ios_base::failbit; - break; - default: - // Not recognized. - __err |= ios_base::failbit; + __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2, + __io, __err); + __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2, + __io, __err); + } } - } - else - { - // Verify format and input match, extract and discard. - if (__c == __ctype.narrow(*__beg, 0)) - ++__beg; else __err |= ios_base::failbit; + break; + default: + // Not recognized. + __err |= ios_base::failbit; } + } + else + { + // Verify format and input match, extract and discard. + if (__format[__i] == *__beg) + ++__beg; + else + __err |= ios_base::failbit; + } } + return __beg; } template<typename _CharT, typename _InIter> - void + _InIter time_get<_CharT, _InIter>:: - _M_extract_num(iter_type& __beg, iter_type& __end, int& __member, - int __min, int __max, size_t __len, - const ctype<_CharT>& __ctype, - ios_base::iostate& __err) const + _M_extract_num(iter_type __beg, iter_type __end, int& __member, + int __min, int __max, size_t __len, + ios_base& __io, ios_base::iostate& __err) const { + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + + // As-is works for __len = 1, 2, 4, the values actually used. + int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1); + + ++__min; size_t __i = 0; - string __digits; - bool __testvalid = true; - char_type __c = *__beg; - while (__beg != __end && __i < __len - && __ctype.is(ctype_base::digit, __c)) + int __value = 0; + for (; __beg != __end && __i < __len; ++__beg, ++__i) { - __digits += __ctype.narrow(__c, 0); - __c = *(++__beg); - ++__i; - } - if (__i == __len) - { - int __value = atoi(__digits.c_str()); - if (__min <= __value && __value <= __max) - __member = __value; + const char __c = __ctype.narrow(*__beg, '*'); + if (__c >= '0' && __c <= '9') + { + __value = __value * 10 + (__c - '0'); + const int __valuec = __value * __mult; + if (__valuec > __max || __valuec + __mult < __min) + break; + __mult /= 10; + } else - __testvalid = false; + break; } + if (__i == __len) + __member = __value; else - __testvalid = false; - if (!__testvalid) __err |= ios_base::failbit; + return __beg; } // Assumptions: // All elements in __names are unique. template<typename _CharT, typename _InIter> - void + _InIter time_get<_CharT, _InIter>:: - _M_extract_name(iter_type& __beg, iter_type& __end, int& __member, - const _CharT** __names, size_t __indexlen, - ios_base::iostate& __err) const + _M_extract_name(iter_type __beg, iter_type __end, int& __member, + const _CharT** __names, size_t __indexlen, + ios_base& __io, ios_base::iostate& __err) const { - typedef char_traits<_CharT> __traits_type; - int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int) + typedef char_traits<_CharT> __traits_type; + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + + int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int) * __indexlen)); size_t __nmatches = 0; size_t __pos = 0; bool __testvalid = true; const char_type* __name; - char_type __c = *__beg; // Look for initial matches. - for (size_t __i1 = 0; __i1 < __indexlen; ++__i1) - if (__c == __names[__i1][0]) - __matches[__nmatches++] = __i1; - + // NB: Some of the locale data is in the form of all lowercase + // names, and some is in the form of initially-capitalized + // names. Look for both. + if (__beg != __end) + { + const char_type __c = *__beg; + for (size_t __i1 = 0; __i1 < __indexlen; ++__i1) + if (__c == __names[__i1][0] + || __c == __ctype.toupper(__names[__i1][0])) + __matches[__nmatches++] = __i1; + } + while (__nmatches > 1) { // Find smallest matching string. - size_t __minlen = 10; - for (size_t __i2 = 0; __i2 < __nmatches; ++__i2) - __minlen = min(__minlen, - __traits_type::length(__names[__matches[__i2]])); - + size_t __minlen = __traits_type::length(__names[__matches[0]]); + for (size_t __i2 = 1; __i2 < __nmatches; ++__i2) + __minlen = std::min(__minlen, + __traits_type::length(__names[__matches[__i2]])); + ++__pos; + ++__beg; if (__pos < __minlen && __beg != __end) - { - ++__pos; - __c = *(++__beg); - for (size_t __i3 = 0; __i3 < __nmatches; ++__i3) - { - __name = __names[__matches[__i3]]; - if (__name[__pos] != __c) - __matches[__i3] = __matches[--__nmatches]; - } - } + for (size_t __i3 = 0; __i3 < __nmatches;) + { + __name = __names[__matches[__i3]]; + if (__name[__pos] != *__beg) + __matches[__i3] = __matches[--__nmatches]; + else + ++__i3; + } else break; } @@ -1793,6 +2016,8 @@ namespace std if (__nmatches == 1) { // Make sure found name is completely extracted. + ++__pos; + ++__beg; __name = __names[__matches[0]]; const size_t __len = __traits_type::length(__name); while (__pos < __len && __beg != __end && __name[__pos] == *__beg) @@ -1807,6 +2032,7 @@ namespace std __testvalid = false; if (!__testvalid) __err |= ios_base::failbit; + return __beg; } template<typename _CharT, typename _InIter> @@ -1815,12 +2041,12 @@ namespace std do_get_time(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { - _CharT __wcs[3]; - const char* __cs = "%X"; - locale __loc = __io.getloc(); - ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); - __ctype.widen(__cs, __cs + 3, __wcs); - _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs); + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const char_type* __times[2]; + __tp._M_time_formats(__times); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __times[0]); if (__beg == __end) __err |= ios_base::eofbit; return __beg; @@ -1832,12 +2058,12 @@ namespace std do_get_date(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { - _CharT __wcs[3]; - const char* __cs = "%x"; - locale __loc = __io.getloc(); - ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); - __ctype.widen(__cs, __cs + 3, __wcs); - _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs); + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const char_type* __dates[2]; + __tp._M_date_formats(__dates); + __beg = _M_extract_via_format(__beg, __end, __io, __err, + __tm, __dates[0]); if (__beg == __end) __err |= ios_base::eofbit; return __beg; @@ -1846,23 +2072,24 @@ namespace std template<typename _CharT, typename _InIter> _InIter time_get<_CharT, _InIter>:: - do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io, + do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { - typedef char_traits<_CharT> __traits_type; - locale __loc = __io.getloc(); - __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); + typedef char_traits<_CharT> __traits_type; + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); const char_type* __days[7]; __tp._M_days_abbreviated(__days); int __tmpwday; - _M_extract_name(__beg, __end, __tmpwday, __days, 7, __err); + __beg = _M_extract_name(__beg, __end, __tmpwday, __days, 7, __io, __err); // Check to see if non-abbreviated name exists, and extract. // NB: Assumes both _M_days and _M_days_abbreviated organized in // exact same order, first to last, such that the resulting // __days array with the same index points to a day, and that // day's abbreviated form. - // NB: Also assumes that an abbreviated name is a subset of the name. + // NB: Also assumes that an abbreviated name is a subset of the name. if (!__err) { size_t __pos = __traits_type::length(__days[__tmpwday]); @@ -1872,7 +2099,7 @@ namespace std { // Extract the rest of it. const size_t __len = __traits_type::length(__name); - while (__pos < __len && __beg != __end + while (__pos < __len && __beg != __end && __name[__pos] == *__beg) ++__beg, ++__pos; if (__len != __pos) @@ -1892,20 +2119,22 @@ namespace std do_get_monthname(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { - typedef char_traits<_CharT> __traits_type; - locale __loc = __io.getloc(); - __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); + typedef char_traits<_CharT> __traits_type; + const locale& __loc = __io._M_getloc(); + const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); const char_type* __months[12]; __tp._M_months_abbreviated(__months); int __tmpmon; - _M_extract_name(__beg, __end, __tmpmon, __months, 12, __err); + __beg = _M_extract_name(__beg, __end, __tmpmon, __months, 12, + __io, __err); // Check to see if non-abbreviated name exists, and extract. // NB: Assumes both _M_months and _M_months_abbreviated organized in // exact same order, first to last, such that the resulting // __months array with the same index points to a month, and that // month's abbreviated form. - // NB: Also assumes that an abbreviated name is a subset of the name. + // NB: Also assumes that an abbreviated name is a subset of the name. if (!__err) { size_t __pos = __traits_type::length(__months[__tmpmon]); @@ -1915,7 +2144,7 @@ namespace std { // Extract the rest of it. const size_t __len = __traits_type::length(__name); - while (__pos < __len && __beg != __end + while (__pos < __len && __beg != __end && __name[__pos] == *__beg) ++__beg, ++__pos; if (__len != __pos) @@ -1924,7 +2153,7 @@ namespace std if (!__err) __tm->tm_mon = __tmpmon; } - + if (__beg == __end) __err |= ios_base::eofbit; return __beg; @@ -1933,31 +2162,24 @@ namespace std template<typename _CharT, typename _InIter> _InIter time_get<_CharT, _InIter>:: - do_get_year(iter_type __beg, iter_type __end, ios_base& __io, + do_get_year(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { - locale __loc = __io.getloc(); - const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); - char_type __c = *__beg; size_t __i = 0; - string __digits; - while (__i < 4 && __beg != __end && __ctype.is(ctype_base::digit, __c)) + int __value = 0; + for (; __beg != __end && __i < 4; ++__beg, ++__i) { - __digits += __ctype.narrow(__c, 0); - __c = *(++__beg); - ++__i; + const char __c = __ctype.narrow(*__beg, '*'); + if (__c >= '0' && __c <= '9') + __value = __value * 10 + (__c - '0'); + else + break; } if (__i == 2 || __i == 4) - { - long __l; - __convert_to_v(__digits.c_str(), __l, __err, _S_c_locale); - if (!(__err & ios_base::failbit) && __l <= INT_MAX) - { - __l = __i == 2 ? __l : __l - 1900; - __tm->tm_year = static_cast<int>(__l); - } - } + __tm->tm_year = __i == 2 ? __value : __value - 1900; else __err |= ios_base::failbit; if (__beg == __end) @@ -1968,55 +2190,53 @@ namespace std template<typename _CharT, typename _OutIter> _OutIter time_put<_CharT, _OutIter>:: - put(iter_type __s, ios_base& __io, char_type, const tm* __tm, + put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, const _CharT* __beg, const _CharT* __end) const { - locale __loc = __io.getloc(); + const locale& __loc = __io._M_getloc(); ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); - while (__beg != __end) - { - char __c = __ctype.narrow(*__beg, 0); - ++__beg; - if (__c == '%') - { - char __format; - char __mod = 0; - size_t __len = 1; - __c = __ctype.narrow(*__beg, 0); - ++__beg; - if (__c == 'E' || __c == 'O') - { - __mod = __c; - __format = __ctype.narrow(*__beg, 0); - ++__beg; - } - else - __format = __c; - __s = this->do_put(__s, __io, _CharT(), __tm, __format, __mod); - } - else - { - *__s = __c; - ++__s; - } - } + for (; __beg != __end; ++__beg) + if (__ctype.narrow(*__beg, 0) != '%') + { + *__s = *__beg; + ++__s; + } + else if (++__beg != __end) + { + char __format; + char __mod = 0; + const char __c = __ctype.narrow(*__beg, 0); + if (__c != 'E' && __c != 'O') + __format = __c; + else if (++__beg != __end) + { + __mod = __c; + __format = __ctype.narrow(*__beg, 0); + } + else + break; + __s = this->do_put(__s, __io, __fill, __tm, __format, __mod); + } + else + break; return __s; } template<typename _CharT, typename _OutIter> _OutIter time_put<_CharT, _OutIter>:: - do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, + do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, char __format, char __mod) const - { - locale __loc = __io.getloc(); + { + const locale& __loc = __io._M_getloc(); ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); // NB: This size is arbitrary. Should this be a data member, // initialized at construction? const size_t __maxlen = 64; - char_type* __res = static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __maxlen)); + char_type* __res = + static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __maxlen)); // NB: In IEE 1003.1-200x, and perhaps other locale models, it // is possible that the format character will be longer than one @@ -2024,7 +2244,7 @@ namespace std // format character: if __mod is not the default argument, assume // it's a valid modifier. char_type __fmt[4]; - __fmt[0] = __ctype.widen('%'); + __fmt[0] = __ctype.widen('%'); if (!__mod) { __fmt[1] = __format; @@ -2040,7 +2260,7 @@ namespace std __tp._M_put(__res, __maxlen, __fmt, __tm); // Write resulting, fully-formatted string to output iterator. - return __write(__s, __res, char_traits<char_type>::length(__res)); + return std::__write(__s, __res, char_traits<char_type>::length(__res)); } @@ -2059,25 +2279,25 @@ namespace std template<typename _CharT> int collate<_CharT>:: - do_compare(const _CharT* __lo1, const _CharT* __hi1, + do_compare(const _CharT* __lo1, const _CharT* __hi1, const _CharT* __lo2, const _CharT* __hi2) const - { + { // strcoll assumes zero-terminated strings so we make a copy // and then put a zero at the end. const string_type __one(__lo1, __hi1); const string_type __two(__lo2, __hi2); const _CharT* __p = __one.c_str(); - const _CharT* __pend = __one.c_str() + __one.length(); + const _CharT* __pend = __one.data() + __one.length(); const _CharT* __q = __two.c_str(); - const _CharT* __qend = __two.c_str() + __two.length(); + const _CharT* __qend = __two.data() + __two.length(); // strcoll stops when it sees a nul character so we break // the strings into zero-terminated substrings and pass those // to strcoll. for (;;) { - int __res = _M_compare(__p, __q); + const int __res = _M_compare(__p, __q); if (__res) return __res; @@ -2095,7 +2315,7 @@ namespace std } } - template<typename _CharT> + template<typename _CharT> typename collate<_CharT>::string_type collate<_CharT>:: do_transform(const _CharT* __lo, const _CharT* __hi) const @@ -2104,7 +2324,7 @@ namespace std string_type __str(__lo, __hi); const _CharT* __p = __str.c_str(); - const _CharT* __pend = __str.c_str() + __str.length(); + const _CharT* __pend = __str.data() + __str.length(); size_t __len = (__hi - __lo) * 2; @@ -2124,7 +2344,7 @@ namespace std if (__res >= __len) { __len = __res + 1; - __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len)); __res = _M_transform(__c, __p, __res + 1); } @@ -2139,20 +2359,20 @@ namespace std } } - template<typename _CharT> + template<typename _CharT> long collate<_CharT>:: do_hash(const _CharT* __lo, const _CharT* __hi) const - { + { unsigned long __val = 0; for (; __lo < __hi; ++__lo) - __val = *__lo + ((__val << 7) | + __val = *__lo + ((__val << 7) | (__val >> (numeric_limits<unsigned long>::digits - 7))); return static_cast<long>(__val); } // Construct correctly padded string, as per 22.2.2.2.2 - // Assumes + // Assumes // __newlen > __oldlen // __news is allocated for __newlen size // Used by both num_put and ostream inserters: if __num, @@ -2163,371 +2383,105 @@ namespace std // NB: Of the two parameters, _CharT can be deduced from the // function arguments. The other (_Traits) has to be explicitly specified. template<typename _CharT, typename _Traits> - void - __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill, - _CharT* __news, const _CharT* __olds, - const streamsize __newlen, + void + __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill, + _CharT* __news, const _CharT* __olds, + const streamsize __newlen, const streamsize __oldlen, const bool __num) { - size_t __plen = static_cast<size_t>(__newlen - __oldlen); - _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __plen)); - _Traits::assign(__pads, __plen, __fill); - - _CharT* __beg; - _CharT* __end; - size_t __mod = 0; - size_t __beglen; //either __plen or __oldlen - ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield; + const size_t __plen = static_cast<size_t>(__newlen - __oldlen); + const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield; + // Padding last. if (__adjust == ios_base::left) { - // Padding last. - __beg = const_cast<_CharT*>(__olds); - __beglen = __oldlen; - __end = __pads; + _Traits::copy(__news, const_cast<_CharT*>(__olds), __oldlen); + _Traits::assign(__news + __oldlen, __plen, __fill); + return; } - else if (__adjust == ios_base::internal && __num) + + size_t __mod = 0; + if (__adjust == ios_base::internal && __num) { // Pad after the sign, if there is one. // Pad after 0[xX], if there is one. // Who came up with these rules, anyway? Jeeze. - locale __loc = __io.getloc(); - const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); - const _CharT __minus = __ctype.widen('-'); - const _CharT __plus = __ctype.widen('+'); - bool __testsign = _Traits::eq(__olds[0], __minus) - || _Traits::eq(__olds[0], __plus); - - bool __testhex = _Traits::eq(__ctype.widen('0'), __olds[0]) - && (_Traits::eq(__ctype.widen('x'), __olds[1]) - || _Traits::eq(__ctype.widen('X'), __olds[1])); + const locale& __loc = __io._M_getloc(); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + + const bool __testsign = (__ctype.widen('-') == __olds[0] + || __ctype.widen('+') == __olds[0]); + const bool __testhex = (__ctype.widen('0') == __olds[0] + && __oldlen > 1 + && (__ctype.widen('x') == __olds[1] + || __ctype.widen('X') == __olds[1])); if (__testhex) { - __news[0] = __olds[0]; + __news[0] = __olds[0]; __news[1] = __olds[1]; - __mod += 2; + __mod = 2; __news += 2; - __beg = __pads; - __beglen = __plen; - __end = const_cast<_CharT*>(__olds + __mod); } else if (__testsign) { - _Traits::eq((__news[0] = __olds[0]), __plus) ? __plus : __minus; - ++__mod; + __news[0] = __olds[0]; + __mod = 1; ++__news; - __beg = __pads; - __beglen = __plen; - __end = const_cast<_CharT*>(__olds + __mod); - } - else - { - // Padding first. - __beg = __pads; - __beglen = __plen; - __end = const_cast<_CharT*>(__olds); } + // else Padding first. } - else - { - // Padding first. - __beg = __pads; - __beglen = __plen; - __end = const_cast<_CharT*>(__olds); - } - _Traits::copy(__news, __beg, __beglen); - _Traits::copy(__news + __beglen, __end, - __newlen - __beglen - __mod); + _Traits::assign(__news, __plen, __fill); + _Traits::copy(__news + __plen, const_cast<_CharT*>(__olds + __mod), + __oldlen - __mod); } - template<typename _CharT> - bool - __verify_grouping(const basic_string<_CharT>& __grouping, - basic_string<_CharT>& __grouping_tmp) - { - int __i = 0; - int __j = 0; - const int __len = __grouping.size(); - const int __n = __grouping_tmp.size(); - bool __test = true; - - // Parsed number groupings have to match the - // numpunct::grouping string exactly, starting at the - // right-most point of the parsed sequence of elements ... - while (__test && __i < __n - 1) - for (__j = 0; __test && __j < __len && __i < __n - 1; ++__j,++__i) - __test &= __grouping[__j] == __grouping_tmp[__n - __i - 1]; - // ... but the last parsed grouping can be <= numpunct - // grouping. - __j == __len ? __j = 0 : __j; - __test &= __grouping[__j] >= __grouping_tmp[__n - __i - 1]; - return __test; - } + bool + __verify_grouping(const char* __grouping, size_t __grouping_size, + const string& __grouping_tmp) + { + const size_t __n = __grouping_tmp.size() - 1; + const size_t __min = std::min(__n, __grouping_size - 1); + size_t __i = __n; + bool __test = true; + + // Parsed number groupings have to match the + // numpunct::grouping string exactly, starting at the + // right-most point of the parsed sequence of elements ... + for (size_t __j = 0; __j < __min && __test; --__i, ++__j) + __test = __grouping_tmp[__i] == __grouping[__j]; + for (; __i && __test; --__i) + __test = __grouping_tmp[__i] == __grouping[__min]; + // ... but the last parsed grouping can be <= numpunct + // grouping. + __test &= __grouping_tmp[0] <= __grouping[__min]; + return __test; + } template<typename _CharT> _CharT* - __add_grouping(_CharT* __s, _CharT __sep, - const char* __gbeg, const char* __gend, + __add_grouping(_CharT* __s, _CharT __sep, + const char* __gbeg, size_t __gsize, const _CharT* __first, const _CharT* __last) { if (__last - __first > *__gbeg) - { - __s = __add_grouping(__s, __sep, - (__gbeg + 1 == __gend ? __gbeg : __gbeg + 1), - __gend, __first, __last - *__gbeg); - __first = __last - *__gbeg; - *__s++ = __sep; - } + { + const bool __bump = __gsize != 1; + __s = std::__add_grouping(__s, __sep, __gbeg + __bump, + __gsize - __bump, __first, + __last - *__gbeg); + __first = __last - *__gbeg; + *__s++ = __sep; + } do *__s++ = *__first++; while (__first != __last); return __s; } -#if 1 - // XXX GLIBCXX_ABI Deprecated, compatibility only. - template<typename _CharT, typename _OutIter> - template<typename _ValueT> - _OutIter - num_put<_CharT, _OutIter>:: - _M_convert_int(_OutIter __s, ios_base& __io, _CharT __fill, char __mod, - char __modl, _ValueT __v) const - { - // [22.2.2.2.2] Stage 1, numeric conversion to character. - - // Long enough for the max format spec. - char __fbuf[16]; - _S_format_int(__io, __fbuf, __mod, __modl); -#ifdef _GLIBCPP_USE_C99 - // First try a buffer perhaps big enough. - int __cs_size = 64; - char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); - int __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, - _S_c_locale); - // If the buffer was not large enough, try again with the correct size. - if (__len >= __cs_size) - { - __cs_size = __len + 1; - __cs = static_cast<char*>(__builtin_alloca(__cs_size)); - __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, - _S_c_locale); - } -#else - // Leave room for "+/-," "0x," and commas. This size is - // arbitrary, but should be largely sufficient. - char __cs[128]; - int __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale); -#endif - return _M_widen_int(__s, __io, __fill, __cs, __len); - } - - template<typename _CharT, typename _OutIter> - _OutIter - num_put<_CharT, _OutIter>:: - _M_widen_float(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs, - int __len) const - { - typedef char_traits<_CharT> __traits_type; - // [22.2.2.2.2] Stage 2, convert to char_type, using correct - // numpunct.decimal_point() values for '.' and adding grouping. - const locale __loc = __io.getloc(); - const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); - _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __len)); - // Grouping can add (almost) as many separators as the number of - // digits, but no more. - _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __len * 2)); - __ctype.widen(__cs, __cs + __len, __ws); - - // Replace decimal point. - const _CharT* __p; - const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); - if (__p = __traits_type::find(__ws, __len, __ctype.widen('.'))) - __ws[__p - __ws] = __np.decimal_point(); - -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -//282. What types does numpunct grouping refer to? - // Add grouping, if necessary. - const string __grouping = __np.grouping(); - if (__grouping.size()) - { - _CharT* __p2; - int __declen = __p ? __p - __ws : __len; - __p2 = __add_grouping(__ws2, __np.thousands_sep(), - __grouping.c_str(), - __grouping.c_str() + __grouping.size(), - __ws, __ws + __declen); - int __newlen = __p2 - __ws2; - - // Tack on decimal part. - if (__p) - { - __traits_type::copy(__p2, __p, __len - __declen); - __newlen += __len - __declen; - } - - // Switch strings, establish correct new length. - __ws = __ws2; - __len = __newlen; - } -#endif - return _M_insert(__s, __io, __fill, __ws, __len); - } - - template<typename _CharT, typename _OutIter> - _OutIter - num_put<_CharT, _OutIter>:: - _M_widen_int(_OutIter __s, ios_base& __io, _CharT __fill, char* __cs, - int __len) const - { - // [22.2.2.2.2] Stage 2, convert to char_type, using correct - // numpunct.decimal_point() values for '.' and adding grouping. - const locale __loc = __io.getloc(); - const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); - _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __len)); - // Grouping can add (almost) as many separators as the number of - // digits, but no more. - _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __len * 2)); - __ctype.widen(__cs, __cs + __len, __ws); - - // Add grouping, if necessary. - const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); - const string __grouping = __np.grouping(); - if (__grouping.size()) - { - // By itself __add_grouping cannot deal correctly with __ws when - // ios::showbase is set and ios_base::oct || ios_base::hex. - // Therefore we take care "by hand" of the initial 0, 0x or 0X. - // However, remember that the latter do not occur if the number - // printed is '0' (__len == 1). - streamsize __off = 0; - const ios_base::fmtflags __basefield = __io.flags() - & ios_base::basefield; - if ((__io.flags() & ios_base::showbase) && __len > 1) - if (__basefield == ios_base::oct) - { - __off = 1; - *__ws2 = *__ws; - } - else if (__basefield == ios_base::hex) - { - __off = 2; - *__ws2 = *__ws; - *(__ws2 + 1) = *(__ws + 1); - } - _CharT* __p; - __p = __add_grouping(__ws2 + __off, __np.thousands_sep(), - __grouping.c_str(), - __grouping.c_str() + __grouping.size(), - __ws + __off, __ws + __len); - __len = __p - __ws2; - // Switch strings. - __ws = __ws2; - } - return _M_insert(__s, __io, __fill, __ws, __len); - } - - // For use by integer and floating-point types after they have been - // converted into a char_type string. - template<typename _CharT, typename _OutIter> - _OutIter - num_put<_CharT, _OutIter>:: - _M_insert(_OutIter __s, ios_base& __io, _CharT __fill, const _CharT* __ws, - int __len) const - { - typedef char_traits<_CharT> __traits_type; - // [22.2.2.2.2] Stage 3. - // If necessary, pad. - streamsize __w = __io.width(); - _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) - * __w)); - if (__w > static_cast<streamsize>(__len)) - { - __pad<_CharT, __traits_type>::_S_pad(__io, __fill, __ws2, __ws, - __w, __len, true); - __len = static_cast<int>(__w); - // Switch strings. - __ws = __ws2; - } - __io.width(0); - - // [22.2.2.2.2] Stage 4. - // Write resulting, fully-formatted string to output iterator. - return __write(__s, __ws, __len); - } -#endif - - template<typename _CharT> - __locale_cache<numpunct<_CharT> >::__locale_cache(const locale& __loc) - : _M_truename(0), _M_falsename(0), _M_use_grouping(false), - _M_grouping(0) - { - if (has_facet<numpunct<_CharT> >(__loc)) - { - const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); - _M_decimal_point = __np.decimal_point(); - _M_thousands_sep = __np.thousands_sep(); - - string_type __false = __np.falsename(); - _CharT* __falsename = new _CharT[__false.length() + 1]; - __false.copy(__falsename, __false.length()); - __falsename[__false.length()] = _CharT(); - _M_falsename = __falsename; - - string_type __true = __np.truename(); - _CharT* __truename = new _CharT[__true.length() + 1]; - __true.copy(__truename, __true.length()); - __truename[__true.length()] = _CharT(); - _M_truename = __truename; - - string __grouping = __np.grouping(); - char* __group = new char[__grouping.length() + 1]; - __grouping.copy(__group, __grouping.length()); - __group[__grouping.length()] = 0; - _M_grouping = __group; - - _M_use_grouping = __grouping.length() != 0 - && __grouping.data()[0] != 0; - } - - if (has_facet<ctype<_CharT> >(__loc)) - { - const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc); - __ct.widen(__num_base::_S_atoms_out, - __num_base::_S_atoms_out + __num_base::_S_end, - _M_atoms_out); - } - } - - // Static locale cache initialization. Only instantiated with char - // and wchar_t, so no need to check has_facet. - template<typename _CharT> - __locale_cache<numpunct<_CharT> >:: - __locale_cache(const locale& __loc, bool) - { - // Grab pointers to numpunct static strings - const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); - _M_thousands_sep = __np._M_thousands_sep; - _M_decimal_point = __np._M_decimal_point; - _M_falsename = __np._M_falsename; - _M_truename = __np._M_truename; - _M_grouping = __np._M_grouping; - _M_use_grouping = false; - - const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc); - __ct.widen(__num_base::_S_atoms_out, - __num_base::_S_atoms_out + __num_base::_S_end, - _M_atoms_out); - } - // Inhibit implicit instantiations for required instantiations, - // which are defined via explicit instantiations elsewhere. + // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. -#if _GLIBCPP_EXTERN_TEMPLATE +#if _GLIBCXX_EXTERN_TEMPLATE extern template class moneypunct<char, false>; extern template class moneypunct<char, true>; extern template class moneypunct_byname<char, false>; @@ -2537,7 +2491,7 @@ namespace std extern template class numpunct<char>; extern template class numpunct_byname<char>; extern template class num_get<char>; - extern template class num_put<char>; + extern template class num_put<char>; extern template class __timepunct<char>; extern template class time_put<char>; extern template class time_put_byname<char>; @@ -2551,110 +2505,110 @@ namespace std extern template class collate_byname<char>; extern template - const codecvt<char, char, mbstate_t>& + const codecvt<char, char, mbstate_t>& use_facet<codecvt<char, char, mbstate_t> >(const locale&); extern template - const collate<char>& + const collate<char>& use_facet<collate<char> >(const locale&); extern template - const numpunct<char>& + const numpunct<char>& use_facet<numpunct<char> >(const locale&); - extern template - const num_put<char>& + extern template + const num_put<char>& use_facet<num_put<char> >(const locale&); - extern template - const num_get<char>& + extern template + const num_get<char>& use_facet<num_get<char> >(const locale&); extern template - const moneypunct<char, true>& + const moneypunct<char, true>& use_facet<moneypunct<char, true> >(const locale&); extern template - const moneypunct<char, false>& + const moneypunct<char, false>& use_facet<moneypunct<char, false> >(const locale&); - extern template - const money_put<char>& + extern template + const money_put<char>& use_facet<money_put<char> >(const locale&); - extern template - const money_get<char>& + extern template + const money_get<char>& use_facet<money_get<char> >(const locale&); extern template - const __timepunct<char>& + const __timepunct<char>& use_facet<__timepunct<char> >(const locale&); - extern template - const time_put<char>& + extern template + const time_put<char>& use_facet<time_put<char> >(const locale&); - extern template - const time_get<char>& + extern template + const time_get<char>& use_facet<time_get<char> >(const locale&); - extern template - const messages<char>& + extern template + const messages<char>& use_facet<messages<char> >(const locale&); - extern template + extern template bool has_facet<ctype<char> >(const locale&); - extern template + extern template bool has_facet<codecvt<char, char, mbstate_t> >(const locale&); - extern template + extern template bool has_facet<collate<char> >(const locale&); - extern template + extern template bool has_facet<numpunct<char> >(const locale&); - extern template + extern template bool has_facet<num_put<char> >(const locale&); - extern template + extern template bool has_facet<num_get<char> >(const locale&); - extern template + extern template bool has_facet<moneypunct<char> >(const locale&); - extern template + extern template bool has_facet<money_put<char> >(const locale&); - extern template + extern template bool has_facet<money_get<char> >(const locale&); - extern template + extern template bool has_facet<__timepunct<char> >(const locale&); - extern template + extern template bool has_facet<time_put<char> >(const locale&); - extern template + extern template bool has_facet<time_get<char> >(const locale&); - extern template + extern template bool has_facet<messages<char> >(const locale&); -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T extern template class moneypunct<wchar_t, false>; extern template class moneypunct<wchar_t, true>; extern template class moneypunct_byname<wchar_t, false>; @@ -2678,106 +2632,106 @@ namespace std extern template class collate_byname<wchar_t>; extern template - const codecvt<wchar_t, char, mbstate_t>& + const codecvt<wchar_t, char, mbstate_t>& use_facet<codecvt<wchar_t, char, mbstate_t> >(locale const&); extern template - const collate<wchar_t>& + const collate<wchar_t>& use_facet<collate<wchar_t> >(const locale&); extern template - const numpunct<wchar_t>& + const numpunct<wchar_t>& use_facet<numpunct<wchar_t> >(const locale&); - extern template - const num_put<wchar_t>& + extern template + const num_put<wchar_t>& use_facet<num_put<wchar_t> >(const locale&); - extern template - const num_get<wchar_t>& + extern template + const num_get<wchar_t>& use_facet<num_get<wchar_t> >(const locale&); extern template - const moneypunct<wchar_t, true>& + const moneypunct<wchar_t, true>& use_facet<moneypunct<wchar_t, true> >(const locale&); extern template - const moneypunct<wchar_t, false>& + const moneypunct<wchar_t, false>& use_facet<moneypunct<wchar_t, false> >(const locale&); - - extern template - const money_put<wchar_t>& + + extern template + const money_put<wchar_t>& use_facet<money_put<wchar_t> >(const locale&); - extern template - const money_get<wchar_t>& + extern template + const money_get<wchar_t>& use_facet<money_get<wchar_t> >(const locale&); extern template - const __timepunct<wchar_t>& + const __timepunct<wchar_t>& use_facet<__timepunct<wchar_t> >(const locale&); - extern template - const time_put<wchar_t>& + extern template + const time_put<wchar_t>& use_facet<time_put<wchar_t> >(const locale&); - extern template - const time_get<wchar_t>& + extern template + const time_get<wchar_t>& use_facet<time_get<wchar_t> >(const locale&); - extern template - const messages<wchar_t>& + extern template + const messages<wchar_t>& use_facet<messages<wchar_t> >(const locale&); - extern template + extern template bool has_facet<ctype<wchar_t> >(const locale&); - extern template + extern template bool has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&); - extern template + extern template bool has_facet<collate<wchar_t> >(const locale&); - extern template + extern template bool has_facet<numpunct<wchar_t> >(const locale&); - extern template + extern template bool has_facet<num_put<wchar_t> >(const locale&); - extern template + extern template bool has_facet<num_get<wchar_t> >(const locale&); - extern template + extern template bool has_facet<moneypunct<wchar_t> >(const locale&); - extern template + extern template bool has_facet<money_put<wchar_t> >(const locale&); - extern template + extern template bool has_facet<money_get<wchar_t> >(const locale&); - extern template + extern template bool has_facet<__timepunct<wchar_t> >(const locale&); - extern template + extern template bool has_facet<time_put<wchar_t> >(const locale&); - extern template + extern template bool has_facet<time_get<wchar_t> >(const locale&); - extern template + extern template bool has_facet<messages<wchar_t> >(const locale&); #endif diff --git a/contrib/libstdc++/include/bits/localefwd.h b/contrib/libstdc++/include/bits/localefwd.h index ac9e1a95425a..247158df374c 100644 --- a/contrib/libstdc++/include/bits/localefwd.h +++ b/contrib/libstdc++/include/bits/localefwd.h @@ -37,14 +37,14 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_LOCALE_FWD_H -#define _CPP_BITS_LOCALE_FWD_H 1 +#ifndef _LOCALE_FWD_H +#define _LOCALE_FWD_H 1 #pragma GCC system_header #include <bits/c++config.h> #include <bits/c++locale.h> // Defines __c_locale, config-specific includes -#include <iosfwd> // For ostreambuf_iterator, istreambuf_iterator +#include <iosfwd> // For ostreambuf_iterator, istreambuf_iterator #include <bits/functexcept.h> namespace std @@ -53,67 +53,67 @@ namespace std class locale; // 22.1.3 Convenience interfaces - template<typename _CharT> - inline bool + template<typename _CharT> + inline bool isspace(_CharT, const locale&); - template<typename _CharT> - inline bool + template<typename _CharT> + inline bool isprint(_CharT, const locale&); - template<typename _CharT> - inline bool + template<typename _CharT> + inline bool iscntrl(_CharT, const locale&); - template<typename _CharT> - inline bool + template<typename _CharT> + inline bool isupper(_CharT, const locale&); - template<typename _CharT> - inline bool + template<typename _CharT> + inline bool islower(_CharT, const locale&); - template<typename _CharT> - inline bool + template<typename _CharT> + inline bool isalpha(_CharT, const locale&); - template<typename _CharT> - inline bool + template<typename _CharT> + inline bool isdigit(_CharT, const locale&); - template<typename _CharT> - inline bool + template<typename _CharT> + inline bool ispunct(_CharT, const locale&); - template<typename _CharT> - inline bool + template<typename _CharT> + inline bool isxdigit(_CharT, const locale&); - template<typename _CharT> - inline bool + template<typename _CharT> + inline bool isalnum(_CharT, const locale&); - template<typename _CharT> - inline bool + template<typename _CharT> + inline bool isgraph(_CharT, const locale&); - template<typename _CharT> - inline _CharT + template<typename _CharT> + inline _CharT toupper(_CharT, const locale&); - template<typename _CharT> - inline _CharT + template<typename _CharT> + inline _CharT tolower(_CharT, const locale&); // 22.2.1 and 22.2.1.3 ctype class ctype_base; - template<typename _CharT> + template<typename _CharT> class ctype; template<> class ctype<char>; -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T template<> class ctype<wchar_t>; #endif - template<typename _CharT> + template<typename _CharT> class ctype_byname; // NB: Specialized for char and wchar_t in locale_facets.h. @@ -122,7 +122,7 @@ namespace std template<typename _InternT, typename _ExternT, typename _StateT> class codecvt; template<> class codecvt<char, char, mbstate_t>; -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T template<> class codecvt<wchar_t, char, mbstate_t>; #endif template<typename _InternT, typename _ExternT, typename _StateT> @@ -137,9 +137,9 @@ namespace std template<typename _CharT> class numpunct_byname; // 22.2.4 collation - template<typename _CharT> + template<typename _CharT> class collate; - template<typename _CharT> class + template<typename _CharT> class collate_byname; // 22.2.5 date and time @@ -159,25 +159,34 @@ namespace std class money_get; template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > class money_put; - template<typename _CharT, bool _Intl = false> + template<typename _CharT, bool _Intl = false> class moneypunct; - template<typename _CharT, bool _Intl = false> + template<typename _CharT, bool _Intl = false> class moneypunct_byname; // 22.2.7 message retrieval class messages_base; - template<typename _CharT> + template<typename _CharT> class messages; - template<typename _CharT> + template<typename _CharT> class messages_byname; template<typename _Facet> + bool + has_facet(const locale& __loc) throw(); + + template<typename _Facet> const _Facet& use_facet(const locale& __loc); template<typename _Facet> - bool - has_facet(const locale& __loc) throw(); + inline const _Facet& + __check_facet(const _Facet* __f) + { + if (!__f) + __throw_bad_cast(); + return *__f; + } } // namespace std #endif diff --git a/contrib/libstdc++/include/bits/mask_array.h b/contrib/libstdc++/include/bits/mask_array.h index df23a46ef0bd..1a694f3c61ff 100644 --- a/contrib/libstdc++/include/bits/mask_array.h +++ b/contrib/libstdc++/include/bits/mask_array.h @@ -1,6 +1,6 @@ // The template and inlines for the -*- C++ -*- mask_array class. -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -35,34 +35,70 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_MASK_ARRAY_H -#define _CPP_BITS_MASK_ARRAY_H 1 +#ifndef _MASK_ARRAY_H +#define _MASK_ARRAY_H 1 #pragma GCC system_header namespace std { - template <class _Tp> + /** + * @brief Reference to selected subset of an array. + * + * A mask_array is a reference to the actual elements of an array specified + * by a bitmask in the form of an array of bool. The way to get a + * mask_array is to call operator[](valarray<bool>) on a valarray. The + * returned mask_array then permits carrying operations out on the + * referenced subset of elements in the original valarray. + * + * For example, if a mask_array is obtained using the array (false, true, + * false, true) as an argument, the mask array has two elements referring + * to array[1] and array[3] in the underlying array. + * + * @param Tp Element type. + */ + template <class _Tp> class mask_array - { + { public: typedef _Tp value_type; - + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 253. valarray helper functions are almost entirely useless + + /// Copy constructor. Both slices refer to the same underlying array. + mask_array (const mask_array&); + + /// Assignment operator. Assigns elements to corresponding elements + /// of @a a. + mask_array& operator=(const mask_array&); + void operator=(const valarray<_Tp>&) const; + /// Multiply slice elements by corresponding elements of @a v. void operator*=(const valarray<_Tp>&) const; + /// Divide slice elements by corresponding elements of @a v. void operator/=(const valarray<_Tp>&) const; + /// Modulo slice elements by corresponding elements of @a v. void operator%=(const valarray<_Tp>&) const; - void operator+=(const valarray<_Tp>&) const; + /// Add corresponding elements of @a v to slice elements. + void operator+=(const valarray<_Tp>&) const; + /// Subtract corresponding elements of @a v from slice elements. void operator-=(const valarray<_Tp>&) const; - void operator^=(const valarray<_Tp>&) const; + /// Logical xor slice elements with corresponding elements of @a v. + void operator^=(const valarray<_Tp>&) const; + /// Logical and slice elements with corresponding elements of @a v. void operator&=(const valarray<_Tp>&) const; + /// Logical or slice elements with corresponding elements of @a v. void operator|=(const valarray<_Tp>&) const; - void operator<<=(const valarray<_Tp>&) const; - void operator>>=(const valarray<_Tp>&) const; + /// Left shift slice elements by corresponding elements of @a v. + void operator<<=(const valarray<_Tp>&) const; + /// Right shift slice elements by corresponding elements of @a v. + void operator>>=(const valarray<_Tp>&) const; + /// Assign all slice elements to @a t. void operator=(const _Tp&) const; - + // ~mask_array (); - + template<class _Dom> void operator=(const _Expr<_Dom,_Tp>&) const; template<class _Dom> @@ -84,48 +120,54 @@ namespace std { template<class _Dom> void operator<<=(const _Expr<_Dom,_Tp>&) const; template<class _Dom> - void operator>>=(const _Expr<_Dom,_Tp>&) const; + void operator>>=(const _Expr<_Dom,_Tp>&) const; private: mask_array(_Array<_Tp>, size_t, _Array<bool>); friend class valarray<_Tp>; - + const size_t _M_sz; const _Array<bool> _M_mask; const _Array<_Tp> _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) {} + : _M_sz(a._M_sz), _M_mask(a._M_mask), _M_array(a._M_array) {} template<typename _Tp> - inline + inline mask_array<_Tp>::mask_array(_Array<_Tp> __a, size_t __s, _Array<bool> __m) - : _M_sz(__s), _M_mask(__m), _M_array(__a) {} - + : _M_sz(__s), _M_mask(__m), _M_array(__a) {} + + template<typename _Tp> + inline mask_array<_Tp>& + mask_array<_Tp>::operator=(const mask_array<_Tp>& __a) + { + std::__valarray_copy(__a._M_array, __a._M_mask, + _M_sz, _M_array, _M_mask); + return *this; + } + template<typename _Tp> inline void mask_array<_Tp>::operator=(const _Tp& __t) const - { __valarray_fill(_M_array, _M_sz, _M_mask, __t); } - + { std::__valarray_fill(_M_array, _M_sz, _M_mask, __t); } + template<typename _Tp> inline void mask_array<_Tp>::operator=(const valarray<_Tp>& __v) const - { __valarray_copy(_Array<_Tp>(__v), __v.size(), _M_array, _M_mask); } + { std::__valarray_copy(_Array<_Tp>(__v), __v.size(), _M_array, _M_mask); } template<typename _Tp> template<class _Ex> inline void mask_array<_Tp>::operator=(const _Expr<_Ex, _Tp>& __e) const - { __valarray_copy(__e, __e.size(), _M_array, _M_mask); } + { std::__valarray_copy(__e, __e.size(), _M_array, _M_mask); } #undef _DEFINE_VALARRAY_OPERATOR #define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \ @@ -156,11 +198,11 @@ _DEFINE_VALARRAY_OPERATOR(|, __bitwise_or) _DEFINE_VALARRAY_OPERATOR(<<, __shift_left) _DEFINE_VALARRAY_OPERATOR(>>, __shift_right) -#undef _DEFINE_VALARRAY_OPERATOR - +#undef _DEFINE_VALARRAY_OPERATOR + } // std:: -#endif /* _CPP_BITS_MASK_ARRAY_H */ +#endif /* _MASK_ARRAY_H */ // Local Variables: // mode:c++ diff --git a/contrib/libstdc++/include/bits/ostream.tcc b/contrib/libstdc++/include/bits/ostream.tcc index ab15ae8703be..2d1b5b419cfc 100644 --- a/contrib/libstdc++/include/bits/ostream.tcc +++ b/contrib/libstdc++/include/bits/ostream.tcc @@ -1,6 +1,6 @@ // ostream classes -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -32,16 +32,19 @@ // ISO C++ 14882: 27.6.2 Output streams // +#ifndef _OSTREAM_TCC +#define _OSTREAM_TCC 1 + #pragma GCC system_header #include <locale> -namespace std +namespace std { template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>::sentry:: - sentry(basic_ostream<_CharT,_Traits>& __os) - : _M_os(__os) + sentry(basic_ostream<_CharT, _Traits>& __os) + : _M_ok(false), _M_os(__os) { // XXX MT if (__os.tie() && __os.good()) @@ -50,418 +53,417 @@ namespace std if (__os.good()) _M_ok = true; else - { - _M_ok = false; - __os.setstate(ios_base::failbit); - } + __os.setstate(ios_base::failbit); } - + template<typename _CharT, typename _Traits> - basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>:: operator<<(__ostream_type& (*__pf)(__ostream_type&)) { - sentry __cerb(*this); - if (__cerb) - { - try - { __pf(*this); } - catch(...) - { - // 27.6.2.5.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } - } - return *this; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // The inserters for manipulators are *not* formatted output functions. + return __pf(*this); } - + template<typename _CharT, typename _Traits> - basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>:: operator<<(__ios_type& (*__pf)(__ios_type&)) { - sentry __cerb(*this); - if (__cerb) - { - try - { __pf(*this); } - catch(...) - { - // 27.6.2.5.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } - } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // The inserters for manipulators are *not* formatted output functions. + __pf(*this); return *this; } template<typename _CharT, typename _Traits> - basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>:: operator<<(ios_base& (*__pf)(ios_base&)) { - sentry __cerb(*this); - if (__cerb) - { - try - { __pf(*this); } - catch(...) - { - // 27.6.2.5.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } - } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // The inserters for manipulators are *not* formatted output functions. + __pf(*this); return *this; } template<typename _CharT, typename _Traits> - basic_ostream<_CharT, _Traits>& - basic_ostream<_CharT, _Traits>::operator<<(__streambuf_type* __sbin) + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(bool __n) { sentry __cerb(*this); - if (__cerb && __sbin) + if (__cerb) { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); try { - if (!__copy_streambufs(*this, __sbin, this->rdbuf())) - this->setstate(ios_base::failbit); + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __n).failed()) + __err |= ios_base::badbit; } catch(...) - { - // 27.6.2.5.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } - else if (!__sbin) - this->setstate(ios_base::badbit); return *this; } template<typename _CharT, typename _Traits> - basic_ostream<_CharT, _Traits>& - basic_ostream<_CharT, _Traits>::operator<<(bool __n) + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(long __n) { sentry __cerb(*this); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - if (_M_check_facet(_M_fnumput)) - if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) - this->setstate(ios_base::badbit); + bool __b = false; + const char_type __c = this->fill(); + const ios_base::fmtflags __fmt = (this->flags() + & ios_base::basefield); + const __num_put_type& __np = __check_facet(this->_M_num_put); + if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex)) + { + const unsigned long __l = static_cast<unsigned long>(__n); + __b = __np.put(*this, *this, __c, __l).failed(); + } + else + __b = __np.put(*this, *this, __c, __n).failed(); + if (__b) + __err |= ios_base::badbit; } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> - basic_ostream<_CharT, _Traits>& - basic_ostream<_CharT, _Traits>::operator<<(long __n) + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(unsigned long __n) { sentry __cerb(*this); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - char_type __c = this->fill(); - ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; - if (_M_check_facet(_M_fnumput)) - { - bool __b = false; - if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex)) - { - unsigned long __l = static_cast<unsigned long>(__n); - __b = _M_fnumput->put(*this, *this, __c, __l).failed(); - } - else - __b = _M_fnumput->put(*this, *this, __c, __n).failed(); - if (__b) - this->setstate(ios_base::badbit); - } + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __n).failed()) + __err |= ios_base::badbit; } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } +#ifdef _GLIBCXX_USE_LONG_LONG template<typename _CharT, typename _Traits> - basic_ostream<_CharT, _Traits>& - basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n) + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(long long __n) { sentry __cerb(*this); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - if (_M_check_facet(_M_fnumput)) - if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) - this->setstate(ios_base::badbit); + bool __b = false; + const char_type __c = this->fill(); + const ios_base::fmtflags __fmt = (this->flags() + & ios_base::basefield); + const __num_put_type& __np = __check_facet(this->_M_num_put); + if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex)) + { + const unsigned long long __l = (static_cast< + unsigned long long>(__n)); + __b = __np.put(*this, *this, __c, __l).failed(); + } + else + __b = __np.put(*this, *this, __c, __n).failed(); + if (__b) + __err |= ios_base::badbit; } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } -#ifdef _GLIBCPP_USE_LONG_LONG template<typename _CharT, typename _Traits> - basic_ostream<_CharT, _Traits>& - basic_ostream<_CharT, _Traits>::operator<<(long long __n) + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(unsigned long long __n) { sentry __cerb(*this); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - char_type __c = this->fill(); - ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; - if (_M_check_facet(_M_fnumput)) - { - bool __b = false; - if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex)) - { - unsigned long long __l; - __l = static_cast<unsigned long long>(__n); - __b = _M_fnumput->put(*this, *this, __c, __l).failed(); - } - else - __b = _M_fnumput->put(*this, *this, __c, __n).failed(); - if (__b) - this->setstate(ios_base::badbit); - } + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __n).failed()) + __err |= ios_base::badbit; } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } +#endif template<typename _CharT, typename _Traits> - basic_ostream<_CharT, _Traits>& - basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n) + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(double __n) { sentry __cerb(*this); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - if (_M_check_facet(_M_fnumput)) - if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) - this->setstate(ios_base::badbit); + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __n).failed()) + __err |= ios_base::badbit; } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } -#endif - + template<typename _CharT, typename _Traits> - basic_ostream<_CharT, _Traits>& - basic_ostream<_CharT, _Traits>::operator<<(double __n) + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(long double __n) { sentry __cerb(*this); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - if (_M_check_facet(_M_fnumput)) - if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) - this->setstate(ios_base::badbit); + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __n).failed()) + __err |= ios_base::badbit; } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } - + template<typename _CharT, typename _Traits> - basic_ostream<_CharT, _Traits>& - basic_ostream<_CharT, _Traits>::operator<<(long double __n) + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(const void* __n) { sentry __cerb(*this); - if (__cerb) + if (__cerb) { - try + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { - if (_M_check_facet(_M_fnumput)) - if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) - this->setstate(ios_base::badbit); + const __num_put_type& __np = __check_facet(this->_M_num_put); + if (__np.put(*this, *this, this->fill(), __n).failed()) + __err |= ios_base::badbit; } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> - basic_ostream<_CharT, _Traits>& - basic_ostream<_CharT, _Traits>::operator<<(const void* __n) + basic_ostream<_CharT, _Traits>& + basic_ostream<_CharT, _Traits>:: + operator<<(__streambuf_type* __sbin) { + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); sentry __cerb(*this); - if (__cerb) + if (__cerb && __sbin) { - try + try { - if (_M_check_facet(_M_fnumput)) - if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) - this->setstate(ios_base::badbit); + if (!__copy_streambufs(__sbin, this->rdbuf())) + __err |= ios_base::failbit; } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - this->_M_setstate(ios_base::badbit); - if ((this->exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { this->_M_setstate(ios_base::failbit); } } + else if (!__sbin) + __err |= ios_base::badbit; + if (__err) + this->setstate(__err); return *this; } template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>& - basic_ostream<_CharT, _Traits>::put(char_type __c) - { + basic_ostream<_CharT, _Traits>:: + put(char_type __c) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // basic_ostream::put(char_type) is an unformatted output function. + // DR 63. Exception-handling policy for unformatted output. + // Unformatted output functions should catch exceptions thrown + // from streambuf members. sentry __cerb(*this); - if (__cerb) + if (__cerb) { - int_type __put = rdbuf()->sputc(__c); - if (traits_type::eq_int_type(__put, traits_type::eof())) - this->setstate(ios_base::badbit); + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try + { + const int_type __put = this->rdbuf()->sputc(__c); + if (traits_type::eq_int_type(__put, traits_type::eof())) + __err |= ios_base::badbit; + } + catch (...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>& - basic_ostream<_CharT, _Traits>::write(const _CharT* __s, streamsize __n) + basic_ostream<_CharT, _Traits>:: + write(const _CharT* __s, streamsize __n) { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // basic_ostream::write(const char_type*, streamsize) is an + // unformatted output function. + // DR 63. Exception-handling policy for unformatted output. + // Unformatted output functions should catch exceptions thrown + // from streambuf members. sentry __cerb(*this); if (__cerb) { - streamsize __put = this->rdbuf()->sputn(__s, __n); - if ( __put != __n) - this->setstate(ios_base::badbit); + try + { _M_write(__s, __n); } + catch (...) + { this->_M_setstate(ios_base::badbit); } } return *this; } template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>& - basic_ostream<_CharT, _Traits>::flush() + basic_ostream<_CharT, _Traits>:: + flush() { - sentry __cerb(*this); - if (__cerb) + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // basic_ostream::flush() is *not* an unformatted output function. + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { if (this->rdbuf() && this->rdbuf()->pubsync() == -1) - this->setstate(ios_base::badbit); + __err |= ios_base::badbit; } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); return *this; } - + template<typename _CharT, typename _Traits> typename basic_ostream<_CharT, _Traits>::pos_type - basic_ostream<_CharT, _Traits>::tellp() + basic_ostream<_CharT, _Traits>:: + tellp() { pos_type __ret = pos_type(-1); - if (!this->fail()) - __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out); + try + { + if (!this->fail()) + __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out); + } + catch(...) + { this->_M_setstate(ios_base::badbit); } return __ret; } - template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>& - basic_ostream<_CharT, _Traits>::seekp(pos_type __pos) + basic_ostream<_CharT, _Traits>:: + seekp(pos_type __pos) { - if (!this->fail()) + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -// 136. seekp, seekg setting wrong streams? - pos_type __err = this->rdbuf()->pubseekpos(__pos, ios_base::out); + if (!this->fail()) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 136. seekp, seekg setting wrong streams? + const pos_type __p = this->rdbuf()->pubseekpos(__pos, + ios_base::out); -// 129. Need error indication from seekp() and seekg() - if (__err == pos_type(off_type(-1))) - this->setstate(ios_base::failbit); -#endif + // 129. Need error indication from seekp() and seekg() + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); return *this; } template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>:: - seekp(off_type __off, ios_base::seekdir __d) + seekp(off_type __off, ios_base::seekdir __dir) { - if (!this->fail()) + ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); + try { -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -// 136. seekp, seekg setting wrong streams? - pos_type __err = this->rdbuf()->pubseekoff(__off, __d, - ios_base::out); - -// 129. Need error indication from seekp() and seekg() - if (__err == pos_type(off_type(-1))) - this->setstate(ios_base::failbit); -#endif + if (!this->fail()) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 136. seekp, seekg setting wrong streams? + const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, + ios_base::out); + + // 129. Need error indication from seekp() and seekg() + if (__p == pos_type(off_type(-1))) + __err |= ios_base::failbit; + } } + catch(...) + { this->_M_setstate(ios_base::badbit); } + if (__err) + this->setstate(__err); return *this; } @@ -474,35 +476,30 @@ namespace std typename __ostream_type::sentry __cerb(__out); if (__cerb) { - try + try { - const streamsize __w = __out.width() > 0 ? __out.width() : 0; - _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__w + 1))); - __pads[0] = __c; + const streamsize __w = __out.width(); streamsize __len = 1; + _CharT* __cs = &__c; if (__w > __len) { - __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __pads, + __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __w)); + __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs, &__c, __w, __len, false); __len = __w; } - __out.write(__pads, __len); + __out._M_write(__cs, __len); __out.width(0); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - __out._M_setstate(ios_base::badbit); - if ((__out.exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { __out._M_setstate(ios_base::badbit); } } return __out; } - + // Specializations. - template <class _Traits> + template <class _Traits> basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>& __out, char __c) { @@ -510,29 +507,23 @@ namespace std typename __ostream_type::sentry __cerb(__out); if (__cerb) { - try + try { - const streamsize __w = __out.width() > 0 ? __out.width() : 0; - char* __pads = static_cast<char*>(__builtin_alloca(__w + 1)); - __pads[0] = __c; + const streamsize __w = __out.width(); streamsize __len = 1; + char* __cs = &__c; if (__w > __len) { - __pad<char, _Traits>::_S_pad(__out, __out.fill(), __pads, + __cs = static_cast<char*>(__builtin_alloca(__w)); + __pad<char, _Traits>::_S_pad(__out, __out.fill(), __cs, &__c, __w, __len, false); __len = __w; } - __out.write(__pads, __len); + __out._M_write(__cs, __len); __out.width(0); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - __out._M_setstate(ios_base::badbit); - if ((__out.exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { __out._M_setstate(ios_base::badbit); } } return __out; } @@ -545,29 +536,25 @@ namespace std typename __ostream_type::sentry __cerb(__out); if (__cerb && __s) { - try + try { - const streamsize __w = __out.width() > 0 ? __out.width() : 0; - _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w)); + const streamsize __w = __out.width(); streamsize __len = static_cast<streamsize>(_Traits::length(__s)); if (__w > __len) { - __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __pads, + _CharT* __cs = (static_cast< + _CharT*>(__builtin_alloca(sizeof(_CharT) + * __w))); + __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs, __s, __w, __len, false); - __s = __pads; + __s = __cs; __len = __w; } - __out.write(__s, __len); + __out._M_write(__s, __len); __out.width(0); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - __out._M_setstate(ios_base::badbit); - if ((__out.exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { __out._M_setstate(ios_base::badbit); } } else if (!__s) __out.setstate(ios_base::badbit); @@ -579,44 +566,39 @@ namespace std operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s) { typedef basic_ostream<_CharT, _Traits> __ostream_type; -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -// 167. Improper use of traits_type::length() -// Note that this is only in 'Review' status. + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 167. Improper use of traits_type::length() + // Note that this is only in 'Review' status. typedef char_traits<char> __traits_type; -#endif typename __ostream_type::sentry __cerb(__out); if (__cerb && __s) { size_t __clen = __traits_type::length(__s); - _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__clen + 1))); + _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) + * __clen)); for (size_t __i = 0; __i < __clen; ++__i) __ws[__i] = __out.widen(__s[__i]); _CharT* __str = __ws; - - try + + try { + const streamsize __w = __out.width(); streamsize __len = static_cast<streamsize>(__clen); - const streamsize __w = __out.width() > 0 ? __out.width() : 0; - _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w)); - if (__w > __len) { - __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __pads, + _CharT* __cs = (static_cast< + _CharT*>(__builtin_alloca(sizeof(_CharT) + * __w))); + __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs, __ws, __w, __len, false); - __str = __pads; + __str = __cs; __len = __w; } - __out.write(__str, __len); + __out._M_write(__str, __len); __out.width(0); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - __out._M_setstate(ios_base::badbit); - if ((__out.exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { __out._M_setstate(ios_base::badbit); } } else if (!__s) __out.setstate(ios_base::badbit); @@ -632,30 +614,23 @@ namespace std typename __ostream_type::sentry __cerb(__out); if (__cerb && __s) { - try + try { - const streamsize __w = __out.width() > 0 ? __out.width() : 0; - char* __pads = static_cast<char*>(__builtin_alloca(__w)); + const streamsize __w = __out.width(); streamsize __len = static_cast<streamsize>(_Traits::length(__s)); - if (__w > __len) { - __pad<char, _Traits>::_S_pad(__out, __out.fill(), __pads, + char* __cs = static_cast<char*>(__builtin_alloca(__w)); + __pad<char, _Traits>::_S_pad(__out, __out.fill(), __cs, __s, __w, __len, false); - __s = __pads; + __s = __cs; __len = __w; } - __out.write(__s, __len); + __out._M_write(__s, __len); __out.width(0); } catch(...) - { - // 27.6.1.2.1 Common requirements. - // Turn this on without causing an ios::failure to be thrown. - __out._M_setstate(ios_base::badbit); - if ((__out.exceptions() & ios_base::badbit) != 0) - __throw_exception_again; - } + { __out._M_setstate(ios_base::badbit); } } else if (!__s) __out.setstate(ios_base::badbit); @@ -667,37 +642,36 @@ namespace std basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __out, const basic_string<_CharT, _Traits, _Alloc>& __str) - { + { typedef basic_ostream<_CharT, _Traits> __ostream_type; typename __ostream_type::sentry __cerb(__out); if (__cerb) { - const _CharT* __s = __str.data(); - const streamsize __w = __out.width() > 0 ? __out.width() : 0; - _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w)); + const streamsize __w = __out.width(); streamsize __len = static_cast<streamsize>(__str.size()); -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + const _CharT* __s = __str.data(); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS // 25. String operator<< uses width() value wrong -#endif if (__w > __len) { - __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __pads, __s, + _CharT* __cs = (static_cast< + _CharT*>(__builtin_alloca(sizeof(_CharT) * __w))); + __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs, __s, __w, __len, false); - __s = __pads; + __s = __cs; __len = __w; } - streamsize __res = __out.rdbuf()->sputn(__s, __len); + __out._M_write(__s, __len); __out.width(0); - if (__res != __len) - __out.setstate(ios_base::failbit); } return __out; } // Inhibit implicit instantiations for required instantiations, - // which are defined via explicit instantiations elsewhere. + // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. -#if _GLIBCPP_EXTERN_TEMPLATE +#if _GLIBCXX_EXTERN_TEMPLATE extern template class basic_ostream<char>; extern template ostream& endl(ostream&); extern template ostream& ends(ostream&); @@ -709,7 +683,7 @@ namespace std extern template ostream& operator<<(ostream&, const unsigned char*); extern template ostream& operator<<(ostream&, const signed char*); -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T extern template class basic_ostream<wchar_t>; extern template wostream& endl(wostream&); extern template wostream& ends(wostream&); @@ -721,3 +695,5 @@ namespace std #endif #endif } // namespace std + +#endif diff --git a/contrib/libstdc++/include/bits/postypes.h b/contrib/libstdc++/include/bits/postypes.h new file mode 100644 index 000000000000..0cfb61b2df2e --- /dev/null +++ b/contrib/libstdc++/include/bits/postypes.h @@ -0,0 +1,215 @@ +// Position types -*- C++ -*- + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.4.1 - Types +// ISO C++ 14882: 27.4.3 - Template class fpos +// + +/** @file postypes.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _GLIBCXX_POSTYPES_H +#define _GLIBCXX_POSTYPES_H 1 + +#pragma GCC system_header + +#include <cwchar> // For mbstate_t + +#ifdef _GLIBCXX_HAVE_STDINT_H +#include <stdint.h> // For int64_t +#endif + +namespace std +{ + // The types streamoff, streampos and wstreampos and the class + // template fpos<> are described in clauses 21.1.2, 21.1.3, 27.1.2, + // 27.2, 27.4.1, 27.4.3 and D.6. Despite all this verbage, the + // behaviour of these types is mostly implementation defined or + // unspecified. The behaviour in this implementation is as noted + // below. + + /** + * @brief Type used by fpos, char_traits<char>, and char_traits<wchar_t>. + * + * @if maint + * In clauses 21.1.3.1 and 27.4.1 streamoff is described as an + * implementation defined type. + * Note: In versions of GCC up to and including GCC 3.3, streamoff + * was typedef long. + * @endif + */ +#ifdef _GLIBCXX_HAVE_INT64_T + typedef int64_t streamoff; +#else + typedef long long streamoff; +#endif + + /// Integral type for I/O operation counts and buffer sizes. + typedef ptrdiff_t streamsize; // Signed integral type + + template<typename _StateT> + class fpos; + + /** + * @brief Class representing stream positions. + * + * The standard places no requirements upon the template parameter StateT. + * In this implementation StateT must be DefaultConstructible, + * CopyConstructible and Assignable. The standard only requires that fpos + * should contain a member of type StateT. In this implementation it also + * contains an offset stored as a signed integer. + * + * @param StateT Type passed to and returned from state(). + */ + template<typename _StateT> + class fpos + { + private: + streamoff _M_off; + _StateT _M_state; + + public: + // The standard doesn't require that fpos objects can be default + // constructed. This implementation provides a default + // constructor that initializes the offset to 0 and default + // constructs the state. + fpos() + : _M_off(0), _M_state() { } + + // The standard requires that fpos objects can be constructed + // from streamoff objects using the constructor syntax, and + // fails to give any meaningful semantics. In this + // implementation implicit conversion is also allowed, and this + // constructor stores the streamoff as the offset and default + // constructs the state. + /// Construct position from offset. + fpos(streamoff __off) + : _M_off(__off), _M_state() { } + + /// Convert to streamoff. + operator streamoff() const { return _M_off; } + + /// Remember the value of @a st. + void + state(_StateT __st) + { _M_state = __st; } + + /// Return the last set value of @a st. + _StateT + state() const + { return _M_state; } + + // The standard only requires that operator== must be an + // equivalence relation. In this implementation two fpos<StateT> + // objects belong to the same equivalence class if the contained + // offsets compare equal. + /// Test if equivalent to another position. + bool + operator==(const fpos& __other) const + { return _M_off == __other._M_off; } + + /// Test if not equivalent to another position. + bool + operator!=(const fpos& __other) const + { return _M_off != __other._M_off; } + + // The standard requires that this operator must be defined, but + // gives no semantics. In this implemenation it just adds it's + // argument to the stored offset and returns *this. + /// Add offset to this position. + fpos& + operator+=(streamoff __off) + { + _M_off += __off; + return *this; + } + + // The standard requires that this operator must be defined, but + // gives no semantics. In this implemenation it just subtracts + // it's argument from the stored offset and returns *this. + /// Subtract offset from this position. + fpos& + operator-=(streamoff __off) + { + _M_off -= __off; + return *this; + } + + // The standard requires that this operator must be defined, but + // defines it's semantics only in terms of operator-. In this + // implementation it constructs a copy of *this, adds the + // argument to that copy using operator+= and then returns the + // copy. + /// Add position and offset. + fpos + operator+(streamoff __off) const + { + fpos __pos(*this); + __pos += __off; + return __pos; + } + + // The standard requires that this operator must be defined, but + // defines it's semantics only in terms of operator+. In this + // implementation it constructs a copy of *this, subtracts the + // argument from that copy using operator-= and then returns the + // copy. + /// Subtract offset from position. + fpos + operator-(streamoff __off) const + { + fpos __pos(*this); + __pos -= __off; + return __pos; + } + + // The standard requires that this operator must be defined, but + // defines it's semantics only in terms of operator+. In this + // implementation it returns the difference between the offset + // stored in *this and in the argument. + /// Subtract position to return offset. + streamoff + operator-(const fpos& __other) const + { return _M_off - __other._M_off; } + }; + + // Clauses 21.1.3.1 and 21.1.3.2 describe streampos and wstreampos + // as implementation defined types, but clause 27.2 requires that + // they must both be typedefs for fpos<mbstate_t> + /// File position for char streams. + typedef fpos<mbstate_t> streampos; + /// File position for wchar_t streams. + typedef fpos<mbstate_t> wstreampos; +} // namespace std + +#endif diff --git a/contrib/libstdc++/include/bits/slice_array.h b/contrib/libstdc++/include/bits/slice_array.h index 2502ef4ebee9..31c89bcdb61d 100644 --- a/contrib/libstdc++/include/bits/slice_array.h +++ b/contrib/libstdc++/include/bits/slice_array.h @@ -1,6 +1,7 @@ // The template and inlines for the -*- C++ -*- slice_array class. -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004 +// Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -34,23 +35,48 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_SLICE_ARRAY_H -#define _CPP_BITS_SLICE_ARRAY_H 1 +#ifndef _SLICE_ARRAY_H +#define _SLICE_ARRAY_H 1 #pragma GCC system_header namespace std { + /** + * @brief Class defining one-dimensional subset of an array. + * + * The slice class represents a one-dimensional subset of an array, + * specified by three parameters: start offset, size, and stride. The + * start offset is the index of the first element of the array that is part + * of the subset. The size is the total number of elements in the subset. + * Stride is the distance between each successive array element to include + * in the subset. + * + * For example, with an array of size 10, and a slice with offset 1, size 3 + * and stride 2, the subset consists of array elements 1, 3, and 5. + */ class slice { public: + /// Construct an empty slice. slice(); + + /** + * @brief Construct a slice. + * + * @param o Offset in array of first element. + * @param d Number of elements in slice. + * @param s Stride between array elements. + */ slice(size_t, size_t, size_t); - + + /// Return array offset of first slice element. size_t start() const; + /// Return size of slice. size_t size() const; + /// Return array stride of slice. size_t stride() const; - + private: size_t _M_off; // offset size_t _M_sz; // size @@ -59,48 +85,77 @@ namespace std // The default constructor constructor is not required to initialize // data members with any meaningful values, so we choose to do nothing. - inline + inline slice::slice() {} - - inline + + 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; } + /** + * @brief Reference to one-dimensional subset of an array. + * + * A slice_array is a reference to the actual elements of an array + * specified by a slice. The way to get a slice_array is to call + * operator[](slice) on a valarray. The returned slice_array then permits + * carrying operations out on the referenced subset of elements in the + * original valarray. For example, operator+=(valarray) will add values + * to the subset of elements in the underlying valarray this slice_array + * refers to. + * + * @param Tp Element type. + */ template<typename _Tp> class slice_array { public: typedef _Tp value_type; - // This constructor is implemented since we need to return a value. + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 253. valarray helper functions are almost entirely useless + + /// Copy constructor. Both slices refer to the same underlying array. slice_array(const slice_array&); - // This operator must be public. See DR-253. + /// Assignment operator. Assigns slice elements to corresponding + /// elements of @a a. slice_array& operator=(const slice_array&); + /// Assign slice elements to corresponding elements of @a v. void operator=(const valarray<_Tp>&) const; + /// Multiply slice elements by corresponding elements of @a v. void operator*=(const valarray<_Tp>&) const; + /// Divide slice elements by corresponding elements of @a v. void operator/=(const valarray<_Tp>&) const; + /// Modulo slice elements by corresponding elements of @a v. void operator%=(const valarray<_Tp>&) const; + /// Add corresponding elements of @a v to slice elements. void operator+=(const valarray<_Tp>&) const; + /// Subtract corresponding elements of @a v from slice elements. void operator-=(const valarray<_Tp>&) const; + /// Logical xor slice elements with corresponding elements of @a v. void operator^=(const valarray<_Tp>&) const; + /// Logical and slice elements with corresponding elements of @a v. void operator&=(const valarray<_Tp>&) const; + /// Logical or slice elements with corresponding elements of @a v. void operator|=(const valarray<_Tp>&) const; + /// Left shift slice elements by corresponding elements of @a v. void operator<<=(const valarray<_Tp>&) const; + /// Right shift slice elements by corresponding elements of @a v. void operator>>=(const valarray<_Tp>&) const; + /// Assign all slice elements to @a t. void operator=(const _Tp &) const; // ~slice_array (); @@ -140,16 +195,16 @@ namespace std }; template<typename _Tp> - inline + inline slice_array<_Tp>::slice_array(_Array<_Tp> __a, const slice& __s) - : _M_sz(__s.size()), _M_stride(__s.stride()), - _M_array(__a.begin() + __s.start()) {} + : _M_sz(__s.size()), _M_stride(__s.stride()), + _M_array(__a.begin() + __s.start()) {} template<typename _Tp> - inline + 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) {} - + : _M_sz(a._M_sz), _M_stride(a._M_stride), _M_array(a._M_array) {} + // template<typename _Tp> // inline slice_array<_Tp>::~slice_array () {} @@ -157,26 +212,26 @@ namespace std inline slice_array<_Tp>& slice_array<_Tp>::operator=(const slice_array<_Tp>& __a) { - __valarray_copy(__a._M_array, __a._M_sz, __a._M_stride, - _M_array, _M_stride); + std::__valarray_copy(__a._M_array, __a._M_sz, __a._M_stride, + _M_array, _M_stride); return *this; } template<typename _Tp> inline void slice_array<_Tp>::operator=(const _Tp& __t) const - { __valarray_fill(_M_array, _M_sz, _M_stride, __t); } - + { std::__valarray_fill(_M_array, _M_sz, _M_stride, __t); } + template<typename _Tp> inline void slice_array<_Tp>::operator=(const valarray<_Tp>& __v) const - { __valarray_copy(_Array<_Tp>(__v), _M_array, _M_sz, _M_stride); } - + { std::__valarray_copy(_Array<_Tp>(__v), _M_array, _M_sz, _M_stride); } + template<typename _Tp> template<class _Dom> inline void slice_array<_Tp>::operator=(const _Expr<_Dom,_Tp>& __e) const - { __valarray_copy(__e, _M_sz, _M_array, _M_stride); } + { std::__valarray_copy(__e, _M_sz, _M_array, _M_stride); } #undef _DEFINE_VALARRAY_OPERATOR #define _DEFINE_VALARRAY_OPERATOR(_Op,_Name) \ @@ -194,7 +249,7 @@ namespace std { \ _Array_augmented_##_Name(_M_array, _M_stride, __e, _M_sz); \ } - + _DEFINE_VALARRAY_OPERATOR(*, __multiplies) _DEFINE_VALARRAY_OPERATOR(/, __divides) @@ -211,7 +266,7 @@ _DEFINE_VALARRAY_OPERATOR(>>, __shift_right) } // std:: -#endif /* _CPP_BITS_SLICE_ARRAY_H */ +#endif /* _SLICE_ARRAY_H */ // Local Variables: // mode:c++ diff --git a/contrib/libstdc++/include/bits/sstream.tcc b/contrib/libstdc++/include/bits/sstream.tcc index 606705c02e91..04cd6ec92a29 100644 --- a/contrib/libstdc++/include/bits/sstream.tcc +++ b/contrib/libstdc++/include/bits/sstream.tcc @@ -1,6 +1,6 @@ // String based streams -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2001, 2002 +// Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -32,8 +32,8 @@ // ISO C++ 14882: 27.7 String-based streams // -#ifndef _CPP_BITS_SSTREAM_TCC -#define _CPP_BITS_SSTREAM_TCC 1 +#ifndef _SSTREAM_TCC +#define _SSTREAM_TCC 1 #pragma GCC system_header @@ -42,75 +42,89 @@ namespace std { template <class _CharT, class _Traits, class _Alloc> - typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type + typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type basic_stringbuf<_CharT, _Traits, _Alloc>:: pbackfail(int_type __c) { int_type __ret = traits_type::eof(); - bool __testeof = traits_type::eq_int_type(__c, traits_type::eof()); - bool __testpos = _M_in_cur && _M_in_beg < _M_in_cur; - - // Try to put back __c into input sequence in one of three ways. - // Order these tests done in is unspecified by the standard. - if (__testpos) + const bool __testeof = traits_type::eq_int_type(__c, __ret); + + if (this->eback() < this->gptr()) { - if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]) - && !__testeof) - { - --_M_in_cur; - __ret = __c; - } - else if (!__testeof) - { - --_M_in_cur; - *_M_in_cur = traits_type::to_char_type(__c); - __ret = __c; - } + const bool __testeq = traits_type::eq(traits_type::to_char_type(__c), + this->gptr()[-1]); + this->gbump(-1); + + // Try to put back __c into input sequence in one of three ways. + // Order these tests done in is unspecified by the standard. + if (!__testeof && __testeq) + __ret = __c; else if (__testeof) + __ret = traits_type::not_eof(__c); + else { - --_M_in_cur; - __ret = traits_type::not_eof(__c); + *this->gptr() = traits_type::to_char_type(__c); + __ret = __c; } } return __ret; } - + template <class _CharT, class _Traits, class _Alloc> - typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type + typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type basic_stringbuf<_CharT, _Traits, _Alloc>:: overflow(int_type __c) { - int_type __ret = traits_type::eof(); - bool __testeof = traits_type::eq_int_type(__c, __ret); - bool __testwrite = _M_out_cur < _M_buf + _M_buf_size; - bool __testout = _M_mode & ios_base::out; + const bool __testout = this->_M_mode & ios_base::out; + if (__builtin_expect(!__testout, false)) + return traits_type::eof(); + + const bool __testeof = traits_type::eq_int_type(__c, traits_type::eof()); + if (__builtin_expect(__testeof, false)) + return traits_type::not_eof(__c); + + const __size_type __capacity = _M_string.capacity(); + const __size_type __max_size = _M_string.max_size(); + const bool __testput = this->pptr() < this->epptr(); + if (__builtin_expect(!__testput && __capacity == __max_size, false)) + return traits_type::eof(); // Try to append __c into output sequence in one of two ways. // Order these tests done in is unspecified by the standard. - if (__testout) + if (!__testput) { - if (!__testeof) - { - __size_type __len = max(_M_buf_size, _M_buf_size_opt); - __len *= 2; - - if (__testwrite) - __ret = this->sputc(traits_type::to_char_type(__c)); - else if (__len <= _M_string.max_size()) - { - // Force-allocate, re-sync. - _M_string = this->str(); - _M_string.reserve(__len); - _M_buf_size = __len; - _M_really_sync(_M_in_cur - _M_in_beg, - _M_out_cur - _M_out_beg); - *_M_out_cur = traits_type::to_char_type(__c); - _M_out_cur_move(1); - __ret = __c; - } - } - else - __ret = traits_type::not_eof(__c); + // NB: Start ostringstream buffers at 512 chars. This is an + // experimental value (pronounced "arbitrary" in some of the + // hipper english-speaking countries), and can be changed to + // suit particular needs. + // Then, in virtue of DR 169 (TC) we are allowed to grow more + // than one char. + const __size_type __opt_len = std::max(__size_type(2 * __capacity), + __size_type(512)); + const __size_type __len = std::min(__opt_len, __max_size); + __string_type __tmp; + __tmp.reserve(__len); + __tmp.assign(_M_string.data(), this->epptr() - this->pbase()); + _M_string.swap(__tmp); + _M_sync(const_cast<char_type*>(_M_string.data()), + this->gptr() - this->eback(), this->pptr() - this->pbase()); + } + return this->sputc(traits_type::to_char_type(__c)); + } + + template <class _CharT, class _Traits, class _Alloc> + typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type + basic_stringbuf<_CharT, _Traits, _Alloc>:: + underflow() + { + int_type __ret = traits_type::eof(); + const bool __testin = this->_M_mode & ios_base::in; + if (__testin) + { + // Update egptr() to match the actual string end. + _M_update_egptr(); + if (this->gptr() < this->egptr()) + __ret = traits_type::to_int_type(*this->gptr()); } return __ret; } @@ -120,55 +134,41 @@ namespace std basic_stringbuf<_CharT, _Traits, _Alloc>:: seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode) { - pos_type __ret = pos_type(off_type(-1)); - bool __testin = (ios_base::in & _M_mode & __mode) != 0; - bool __testout = (ios_base::out & _M_mode & __mode) != 0; - bool __testboth = __testin && __testout && __way != ios_base::cur; + pos_type __ret = pos_type(off_type(-1)); + bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; + bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; + const bool __testboth = __testin && __testout && __way != ios_base::cur; __testin &= !(__mode & ios_base::out); __testout &= !(__mode & ios_base::in); - if (_M_buf_size && (__testin || __testout || __testboth)) + if (_M_string.capacity() && (__testin || __testout || __testboth)) { - char_type* __beg = _M_buf; - char_type* __curi = NULL; - char_type* __curo = NULL; - char_type* __endi = NULL; - char_type* __endo = NULL; + char_type* __beg = __testin ? this->eback() : this->pbase(); - if (__testin || __testboth) - { - __curi = this->gptr(); - __endi = this->egptr(); - } - if (__testout || __testboth) - { - __curo = this->pptr(); - __endo = this->epptr(); - } + _M_update_egptr(); off_type __newoffi = 0; off_type __newoffo = 0; if (__way == ios_base::cur) { - __newoffi = __curi - __beg; - __newoffo = __curo - __beg; + __newoffi = this->gptr() - __beg; + __newoffo = this->pptr() - __beg; } else if (__way == ios_base::end) - { - __newoffi = __endi - __beg; - __newoffo = __endo - __beg; - } + __newoffo = __newoffi = this->egptr() - __beg; if ((__testin || __testboth) - && __newoffi + __off >= 0 && __endi - __beg >= __newoffi + __off) + && __newoffi + __off >= 0 + && this->egptr() - __beg >= __newoffi + __off) { - _M_in_cur = __beg + __newoffi + __off; + this->gbump((__beg + __newoffi + __off) - this->gptr()); __ret = pos_type(__newoffi); } if ((__testout || __testboth) - && __newoffo + __off >= 0 && __endo - __beg >= __newoffo + __off) + && __newoffo + __off >= 0 + && this->egptr() - __beg >= __newoffo + __off) { - _M_out_cur_move(__newoffo + __off - (_M_out_cur - __beg)); + this->pbump((__beg + __newoffo + __off) - this->pptr()); __ret = pos_type(__newoffo); } } @@ -180,42 +180,24 @@ namespace std basic_stringbuf<_CharT, _Traits, _Alloc>:: seekpos(pos_type __sp, ios_base::openmode __mode) { - pos_type __ret = pos_type(off_type(-1)); - - if (_M_buf_size) + pos_type __ret = pos_type(off_type(-1)); + if (_M_string.capacity()) { - off_type __pos = __sp; // Use streamoff operator to do conversion. - char_type* __beg = NULL; - char_type* __end = NULL; - bool __testin = (ios_base::in & _M_mode & __mode) != 0; - bool __testout = (ios_base::out & _M_mode & __mode) != 0; - bool __testboth = __testin && __testout; - __testin &= !(__mode & ios_base::out); - __testout &= !(__mode & ios_base::in); - - // NB: Ordered. - bool __testposi = false; - bool __testposo = false; - if (__testin || __testboth) - { - __beg = this->eback(); - __end = this->egptr(); - if (0 <= __pos && __pos <= __end - __beg) - __testposi = true; - } - if (__testout || __testboth) - { - __beg = this->pbase(); - __end = _M_buf + _M_buf_size; - if (0 <= __pos && __pos <= __end - __beg) - __testposo = true; - } - if (__testposi || __testposo) + off_type __pos (__sp); + const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; + const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; + char_type* __beg = __testin ? this->eback() : this->pbase(); + + _M_update_egptr(); + + const bool __testpos = 0 <= __pos + && __pos <= this->egptr() - __beg; + if ((__testin || __testout) && __testpos) { - if (__testposi) - _M_in_cur = _M_in_beg + __pos; - if (__testposo) - _M_out_cur_move((__pos) - (_M_out_cur - __beg)); + if (__testin) + this->gbump((__beg + __pos) - this->gptr()); + if (__testout) + this->pbump((__beg + __pos) - this->pptr()); __ret = pos_type(off_type(__pos)); } } @@ -223,19 +205,21 @@ namespace std } // Inhibit implicit instantiations for required instantiations, - // which are defined via explicit instantiations elsewhere. + // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. +#if _GLIBCXX_EXTERN_TEMPLATE extern template class basic_stringbuf<char>; extern template class basic_istringstream<char>; extern template class basic_ostringstream<char>; extern template class basic_stringstream<char>; -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T extern template class basic_stringbuf<wchar_t>; extern template class basic_istringstream<wchar_t>; extern template class basic_ostringstream<wchar_t>; extern template class basic_stringstream<wchar_t>; #endif +#endif } // namespace std #endif diff --git a/contrib/libstdc++/include/bits/stl_algo.h b/contrib/libstdc++/include/bits/stl_algo.h index 3d2269722518..6fed5786ebd1 100644 --- a/contrib/libstdc++/include/bits/stl_algo.h +++ b/contrib/libstdc++/include/bits/stl_algo.h @@ -1,6 +1,6 @@ // Algorithm implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,17 +58,17 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_ALGO_H -#define __GLIBCPP_INTERNAL_ALGO_H +#ifndef _ALGO_H +#define _ALGO_H 1 #include <bits/stl_heap.h> #include <bits/stl_tempbuf.h> // for _Temporary_buffer +#include <debug/debug.h> -// See concept_check.h for the __glibcpp_*_requires macros. +// See concept_check.h for the __glibcxx_*_requires macros. namespace std { - /** * @brief Find the median of three values. * @param a A value. @@ -82,11 +82,11 @@ namespace std * @ingroup SGIextensions */ template<typename _Tp> - inline const _Tp& + inline const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) { // concept requirements - __glibcpp_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) if (__a < __b) if (__b < __c) return __b; @@ -120,7 +120,7 @@ namespace std __median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) { // concept requirements - __glibcpp_function_requires(_BinaryFunctionConcept<_Compare,bool,_Tp,_Tp>) + __glibcxx_function_requires(_BinaryFunctionConcept<_Compare,bool,_Tp,_Tp>) if (__comp(__a, __b)) if (__comp(__b, __c)) return __b; @@ -147,12 +147,13 @@ namespace std * @p [first,last). @p f must not modify the order of the sequence. * If @p f has a return value it is ignored. */ - template<typename _InputIter, typename _Function> + template<typename _InputIterator, typename _Function> _Function - for_each(_InputIter __first, _InputIter __last, _Function __f) + for_each(_InputIterator __first, _InputIterator __last, _Function __f) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) __f(*__first); return __f; @@ -163,11 +164,10 @@ namespace std * This is an overload used by find() for the Input Iterator case. * @endif */ - template<typename _InputIter, typename _Tp> - inline _InputIter - find(_InputIter __first, _InputIter __last, - const _Tp& __val, - input_iterator_tag) + template<typename _InputIterator, typename _Tp> + inline _InputIterator + find(_InputIterator __first, _InputIterator __last, + const _Tp& __val, input_iterator_tag) { while (__first != __last && !(*__first == __val)) ++__first; @@ -179,11 +179,10 @@ namespace std * This is an overload used by find_if() for the Input Iterator case. * @endif */ - template<typename _InputIter, typename _Predicate> - inline _InputIter - find_if(_InputIter __first, _InputIter __last, - _Predicate __pred, - input_iterator_tag) + template<typename _InputIterator, typename _Predicate> + inline _InputIterator + find_if(_InputIterator __first, _InputIterator __last, + _Predicate __pred, input_iterator_tag) { while (__first != __last && !__pred(*__first)) ++__first; @@ -195,43 +194,51 @@ namespace std * This is an overload used by find() for the RAI case. * @endif */ - template<typename _RandomAccessIter, typename _Tp> - _RandomAccessIter - find(_RandomAccessIter __first, _RandomAccessIter __last, - const _Tp& __val, - random_access_iterator_tag) + template<typename _RandomAccessIterator, typename _Tp> + _RandomAccessIterator + find(_RandomAccessIterator __first, _RandomAccessIterator __last, + const _Tp& __val, random_access_iterator_tag) { - typename iterator_traits<_RandomAccessIter>::difference_type __trip_count - = (__last - __first) >> 2; + typename iterator_traits<_RandomAccessIterator>::difference_type + __trip_count = (__last - __first) >> 2; - for ( ; __trip_count > 0 ; --__trip_count) { - if (*__first == __val) return __first; - ++__first; + 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; + 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; - } + 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; + } } /** @@ -239,43 +246,51 @@ namespace std * This is an overload used by find_if() for the RAI case. * @endif */ - template<typename _RandomAccessIter, typename _Predicate> - _RandomAccessIter - find_if(_RandomAccessIter __first, _RandomAccessIter __last, - _Predicate __pred, - random_access_iterator_tag) + template<typename _RandomAccessIterator, typename _Predicate> + _RandomAccessIterator + find_if(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Predicate __pred, random_access_iterator_tag) { - typename iterator_traits<_RandomAccessIter>::difference_type __trip_count - = (__last - __first) >> 2; + typename iterator_traits<_RandomAccessIterator>::difference_type + __trip_count = (__last - __first) >> 2; - for ( ; __trip_count > 0 ; --__trip_count) { - if (__pred(*__first)) return __first; - ++__first; + 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; + 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; - } + 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; + } } /** @@ -286,16 +301,18 @@ namespace std * @return The first iterator @c i in the range @p [first,last) * such that @c *i == @p val, or @p last if no such iterator exists. */ - template<typename _InputIter, typename _Tp> - inline _InputIter - find(_InputIter __first, _InputIter __last, + template<typename _InputIterator, typename _Tp> + inline _InputIterator + find(_InputIterator __first, _InputIterator __last, const _Tp& __val) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_EqualOpConcept< - typename iterator_traits<_InputIter>::value_type, _Tp>) - return find(__first, __last, __val, __iterator_category(__first)); + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + return std::find(__first, __last, __val, + std::__iterator_category(__first)); } /** @@ -306,16 +323,18 @@ namespace std * @return The first iterator @c i in the range @p [first,last) * such that @p pred(*i) is true, or @p last if no such iterator exists. */ - template<typename _InputIter, typename _Predicate> - inline _InputIter - find_if(_InputIter __first, _InputIter __last, + template<typename _InputIterator, typename _Predicate> + inline _InputIterator + find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_UnaryPredicateConcept<_Predicate, - typename iterator_traits<_InputIter>::value_type>) - return find_if(__first, __last, __pred, __iterator_category(__first)); + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + return std::find_if(__first, __last, __pred, + std::__iterator_category(__first)); } /** @@ -326,22 +345,24 @@ namespace std * valid iterators in @p [first,last) and such that @c *i == @c *(i+1), * or @p last if no such iterator exists. */ - template<typename _ForwardIter> - _ForwardIter - adjacent_find(_ForwardIter __first, _ForwardIter __last) + template<typename _ForwardIterator> + _ForwardIterator + adjacent_find(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_EqualityComparableConcept< - typename iterator_traits<_ForwardIter>::value_type>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __last; - _ForwardIter __next = __first; - while(++__next != __last) { - if (*__first == *__next) - return __first; - __first = __next; - } + _ForwardIterator __next = __first; + while(++__next != __last) + { + if (*__first == *__next) + return __first; + __first = __next; + } return __last; } @@ -355,24 +376,26 @@ namespace std * @p binary_pred(*i,*(i+1)) is true, or @p last if no such iterator * exists. */ - template<typename _ForwardIter, typename _BinaryPredicate> - _ForwardIter - adjacent_find(_ForwardIter __first, _ForwardIter __last, + template<typename _ForwardIterator, typename _BinaryPredicate> + _ForwardIterator + adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __binary_pred) { // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPredicate, - typename iterator_traits<_ForwardIter>::value_type, - typename iterator_traits<_ForwardIter>::value_type>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __last; - _ForwardIter __next = __first; - while(++__next != __last) { - if (__binary_pred(*__first, *__next)) - return __first; - __first = __next; - } + _ForwardIterator __next = __first; + while(++__next != __last) + { + if (__binary_pred(*__first, *__next)) + return __first; + __first = __next; + } return __last; } @@ -384,16 +407,17 @@ namespace std * @return The number of iterators @c i in the range @p [first,last) * for which @c *i == @p value */ - template<typename _InputIter, typename _Tp> - typename iterator_traits<_InputIter>::difference_type - count(_InputIter __first, _InputIter __last, const _Tp& __value) + template<typename _InputIterator, typename _Tp> + typename iterator_traits<_InputIterator>::difference_type + count(_InputIterator __first, _InputIterator __last, const _Tp& __value) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_EqualityComparableConcept< - typename iterator_traits<_InputIter>::value_type >) - __glibcpp_function_requires(_EqualityComparableConcept<_Tp>) - typename iterator_traits<_InputIter>::difference_type __n = 0; + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_InputIterator>::value_type >) + __glibcxx_function_requires(_EqualityComparableConcept<_Tp>) + __glibcxx_requires_valid_range(__first, __last); + typename iterator_traits<_InputIterator>::difference_type __n = 0; for ( ; __first != __last; ++__first) if (*__first == __value) ++__n; @@ -408,22 +432,22 @@ namespace std * @return The number of iterators @c i in the range @p [first,last) * for which @p pred(*i) is true. */ - template<typename _InputIter, typename _Predicate> - typename iterator_traits<_InputIter>::difference_type - count_if(_InputIter __first, _InputIter __last, _Predicate __pred) + template<typename _InputIterator, typename _Predicate> + typename iterator_traits<_InputIterator>::difference_type + count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_UnaryPredicateConcept<_Predicate, - typename iterator_traits<_InputIter>::value_type>) - typename iterator_traits<_InputIter>::difference_type __n = 0; + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + typename iterator_traits<_InputIterator>::difference_type __n = 0; for ( ; __first != __last; ++__first) if (__pred(*__first)) ++__n; return __n; } - /** * @brief Search a sequence for a matching sub-sequence. * @param first1 A forward iterator. @@ -447,55 +471,54 @@ namespace std * This means that the returned iterator @c i will be in the range * @p [first1,last1-(last2-first2)) */ - template<typename _ForwardIter1, typename _ForwardIter2> - _ForwardIter1 - search(_ForwardIter1 __first1, _ForwardIter1 __last1, - _ForwardIter2 __first2, _ForwardIter2 __last2) + template<typename _ForwardIterator1, typename _ForwardIterator2> + _ForwardIterator1 + search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) { // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter1>) - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter2>) - __glibcpp_function_requires(_EqualOpConcept< - typename iterator_traits<_ForwardIter1>::value_type, - typename iterator_traits<_ForwardIter2>::value_type>) - + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); // Test for empty ranges if (__first1 == __last1 || __first2 == __last2) return __first1; // Test for a pattern of length 1. - _ForwardIter2 __tmp(__first2); + _ForwardIterator2 __tmp(__first2); ++__tmp; if (__tmp == __last2) - return find(__first1, __last1, *__first2); + return std::find(__first1, __last1, *__first2); // General case. - - _ForwardIter2 __p1, __p; - + _ForwardIterator2 __p1, __p; __p1 = __first2; ++__p1; + _ForwardIterator1 __current = __first1; - _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 (__first1 != __last1) + { + __first1 = std::find(__first1, __last1, *__first2); + if (__first1 == __last1) + return __last1; - while (*__current == *__p) { - if (++__p == __last2) - return __first1; + __p = __p1; + __current = __first1; if (++__current == __last1) return __last1; - } - ++__first1; - } + while (*__current == *__p) + { + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; + } + ++__first1; + } return __first1; } @@ -519,64 +542,68 @@ namespace std * * @see search(_ForwardIter1, _ForwardIter1, _ForwardIter2, _ForwardIter2) */ - template<typename _ForwardIter1, typename _ForwardIter2, typename _BinaryPred> - _ForwardIter1 - search(_ForwardIter1 __first1, _ForwardIter1 __last1, - _ForwardIter2 __first2, _ForwardIter2 __last2, - _BinaryPred __predicate) + template<typename _ForwardIterator1, typename _ForwardIterator2, + typename _BinaryPredicate> + _ForwardIterator1 + search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _BinaryPredicate __predicate) { // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter1>) - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter2>) - __glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPred, - typename iterator_traits<_ForwardIter1>::value_type, - typename iterator_traits<_ForwardIter2>::value_type>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); // Test for empty ranges if (__first1 == __last1 || __first2 == __last2) return __first1; // Test for a pattern of length 1. - _ForwardIter2 __tmp(__first2); + _ForwardIterator2 __tmp(__first2); ++__tmp; - if (__tmp == __last2) { - while (__first1 != __last1 && !__predicate(*__first1, *__first2)) - ++__first1; - return __first1; - } + if (__tmp == __last2) + { + while (__first1 != __last1 && !__predicate(*__first1, *__first2)) + ++__first1; + return __first1; + } // General case. - - _ForwardIter2 __p1, __p; - + _ForwardIterator2 __p1, __p; __p1 = __first2; ++__p1; + _ForwardIterator1 __current = __first1; - _ForwardIter1 __current = __first1; - - while (__first1 != __last1) { - while (__first1 != __last1) { - if (__predicate(*__first1, *__first2)) - break; - ++__first1; - } - while (__first1 != __last1 && !__predicate(*__first1, *__first2)) - ++__first1; - if (__first1 == __last1) - return __last1; - - __p = __p1; - __current = __first1; - if (++__current == __last1) return __last1; + while (__first1 != __last1) + { + while (__first1 != __last1) + { + if (__predicate(*__first1, *__first2)) + break; + ++__first1; + } + while (__first1 != __last1 && !__predicate(*__first1, *__first2)) + ++__first1; + if (__first1 == __last1) + return __last1; - while (__predicate(*__current, *__p)) { - if (++__p == __last2) - return __first1; + __p = __p1; + __current = __first1; if (++__current == __last1) return __last1; - } - ++__first1; - } + while (__predicate(*__current, *__p)) + { + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; + } + ++__first1; + } return __first1; } @@ -593,37 +620,41 @@ namespace std * Searches the range @p [first,last) for @p count consecutive elements * equal to @p val. */ - template<typename _ForwardIter, typename _Integer, typename _Tp> - _ForwardIter - search_n(_ForwardIter __first, _ForwardIter __last, + template<typename _ForwardIterator, typename _Integer, typename _Tp> + _ForwardIterator + search_n(_ForwardIterator __first, _ForwardIterator __last, _Integer __count, const _Tp& __val) { // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_EqualityComparableConcept< - typename iterator_traits<_ForwardIter>::value_type>) - __glibcpp_function_requires(_EqualityComparableConcept<_Tp>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_function_requires(_EqualityComparableConcept<_Tp>) + __glibcxx_requires_valid_range(__first, __last); if (__count <= 0) return __first; - else { - __first = find(__first, __last, __val); - while (__first != __last) { - typename iterator_traits<_ForwardIter>::difference_type __n = __count; - --__n; - _ForwardIter __i = __first; - ++__i; - while (__i != __last && __n != 0 && *__i == __val) { - ++__i; - --__n; - } - if (__n == 0) - return __first; - else - __first = find(__i, __last, __val); + else + { + __first = std::find(__first, __last, __val); + while (__first != __last) + { + typename iterator_traits<_ForwardIterator>::difference_type + __n = __count; + _ForwardIterator __i = __first; + ++__i; + while (__i != __last && __n != 1 && *__i == __val) + { + ++__i; + --__n; + } + if (__n == 1) + return __first; + else + __first = std::find(__i, __last, __val); + } + return __last; } - return __last; - } } /** @@ -641,48 +672,55 @@ namespace std * Searches the range @p [first,last) for @p count consecutive elements * for which the predicate returns true. */ - template<typename _ForwardIter, typename _Integer, typename _Tp, - typename _BinaryPred> - _ForwardIter - search_n(_ForwardIter __first, _ForwardIter __last, + template<typename _ForwardIterator, typename _Integer, typename _Tp, + typename _BinaryPredicate> + _ForwardIterator + search_n(_ForwardIterator __first, _ForwardIterator __last, _Integer __count, const _Tp& __val, - _BinaryPred __binary_pred) + _BinaryPredicate __binary_pred) { // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPred, - typename iterator_traits<_ForwardIter>::value_type, _Tp>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); if (__count <= 0) return __first; - else { - while (__first != __last) { - if (__binary_pred(*__first, __val)) - break; - ++__first; - } - while (__first != __last) { - typename iterator_traits<_ForwardIter>::difference_type __n = __count; - --__n; - _ForwardIter __i = __first; - ++__i; - while (__i != __last && __n != 0 && __binary_pred(*__i, __val)) { - ++__i; - --__n; - } - if (__n == 0) - return __first; - else { - while (__i != __last) { - if (__binary_pred(*__i, __val)) + else + { + while (__first != __last) + { + if (__binary_pred(*__first, __val)) break; + ++__first; + } + while (__first != __last) + { + typename iterator_traits<_ForwardIterator>::difference_type + __n = __count; + _ForwardIterator __i = __first; ++__i; + while (__i != __last && __n != 1 && __binary_pred(*__i, __val)) + { + ++__i; + --__n; + } + if (__n == 1) + return __first; + else + { + while (__i != __last) + { + if (__binary_pred(*__i, __val)) + break; + ++__i; + } + __first = __i; + } } - __first = __i; - } + return __last; } - return __last; - } } /** @@ -696,23 +734,26 @@ namespace std * corresponding element in the range @p [first2,(last1-first1)). * The ranges must not overlap. */ - template<typename _ForwardIter1, typename _ForwardIter2> - _ForwardIter2 - swap_ranges(_ForwardIter1 __first1, _ForwardIter1 __last1, - _ForwardIter2 __first2) + template<typename _ForwardIterator1, typename _ForwardIterator2> + _ForwardIterator2 + swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2) { // concept requirements - __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter1>) - __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter2>) - __glibcpp_function_requires(_ConvertibleConcept< - typename iterator_traits<_ForwardIter1>::value_type, - typename iterator_traits<_ForwardIter2>::value_type>) - __glibcpp_function_requires(_ConvertibleConcept< - typename iterator_traits<_ForwardIter2>::value_type, - typename iterator_traits<_ForwardIter1>::value_type>) + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator1>) + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator2>) + __glibcxx_function_requires(_ConvertibleConcept< + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_function_requires(_ConvertibleConcept< + typename iterator_traits<_ForwardIterator2>::value_type, + typename iterator_traits<_ForwardIterator1>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); for ( ; __first1 != __last1; ++__first1, ++__first2) - iter_swap(__first1, __first2); + std::iter_swap(__first1, __first2); return __first2; } @@ -731,16 +772,18 @@ namespace std * * @p unary_op must not alter its argument. */ - template<typename _InputIter, typename _OutputIter, typename _UnaryOperation> - _OutputIter - transform(_InputIter __first, _InputIter __last, - _OutputIter __result, _UnaryOperation __unary_op) + template<typename _InputIterator, typename _OutputIterator, + typename _UnaryOperation> + _OutputIterator + transform(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _UnaryOperation __unary_op) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, // "the type returned by a _UnaryOperation" __typeof__(__unary_op(*__first))>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first, ++__result) *__result = __unary_op(*__first); @@ -764,19 +807,20 @@ namespace std * * @p binary_op must not alter either of its arguments. */ - template<typename _InputIter1, typename _InputIter2, typename _OutputIter, - typename _BinaryOperation> - _OutputIter - transform(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, _OutputIter __result, + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, typename _BinaryOperation> + _OutputIterator + transform(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _OutputIterator __result, _BinaryOperation __binary_op) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, // "the type returned by a _BinaryOperation" __typeof__(__binary_op(*__first1,*__first2))>) + __glibcxx_requires_valid_range(__first1, __last1); for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result) *__result = __binary_op(*__first1, *__first2); @@ -795,17 +839,19 @@ namespace std * For each iterator @c i in the range @p [first,last) if @c *i == * @p old_value then the assignment @c *i = @p new_value is performed. */ - template<typename _ForwardIter, typename _Tp> + template<typename _ForwardIterator, typename _Tp> void - replace(_ForwardIter __first, _ForwardIter __last, + replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value) { // concept requirements - __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_EqualOpConcept< - typename iterator_traits<_ForwardIter>::value_type, _Tp>) - __glibcpp_function_requires(_ConvertibleConcept<_Tp, - typename iterator_traits<_ForwardIter>::value_type>) + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_function_requires(_ConvertibleConcept<_Tp, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) if (*__first == __old_value) @@ -824,17 +870,19 @@ namespace std * For each iterator @c i in the range @p [first,last) if @p pred(*i) * is true then the assignment @c *i = @p new_value is performed. */ - template<typename _ForwardIter, typename _Predicate, typename _Tp> + template<typename _ForwardIterator, typename _Predicate, typename _Tp> void - replace_if(_ForwardIter __first, _ForwardIter __last, + replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value) { // concept requirements - __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_ConvertibleConcept<_Tp, - typename iterator_traits<_ForwardIter>::value_type>) - __glibcpp_function_requires(_UnaryPredicateConcept<_Predicate, - typename iterator_traits<_ForwardIter>::value_type>) + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_ConvertibleConcept<_Tp, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) if (__pred(*__first)) @@ -855,18 +903,19 @@ namespace std * output range @p [result,result+(last-first)) replacing elements * equal to @p old_value with @p new_value. */ - template<typename _InputIter, typename _OutputIter, typename _Tp> - _OutputIter - replace_copy(_InputIter __first, _InputIter __last, - _OutputIter __result, + template<typename _InputIterator, typename _OutputIterator, typename _Tp> + _OutputIterator + replace_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, const _Tp& __old_value, const _Tp& __new_value) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_InputIter>::value_type>) - __glibcpp_function_requires(_EqualOpConcept< - typename iterator_traits<_InputIter>::value_type, _Tp>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first, ++__result) *__result = *__first == __old_value ? __new_value : *__first; @@ -887,19 +936,20 @@ namespace std * @p [result,result+(last-first)) replacing elements for which * @p pred returns true with @p new_value. */ - template<typename _InputIter, typename _OutputIter, typename _Predicate, - typename _Tp> - _OutputIter - replace_copy_if(_InputIter __first, _InputIter __last, - _OutputIter __result, + template<typename _InputIterator, typename _OutputIterator, + typename _Predicate, typename _Tp> + _OutputIterator + replace_copy_if(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Predicate __pred, const _Tp& __new_value) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_InputIter>::value_type>) - __glibcpp_function_requires(_UnaryPredicateConcept<_Predicate, - typename iterator_traits<_InputIter>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first, ++__result) *__result = __pred(*__first) ? __new_value : *__first; @@ -917,14 +967,16 @@ namespace std * Performs the assignment @c *i = @p gen() for each @c i in the range * @p [first,last). */ - template<typename _ForwardIter, typename _Generator> + template<typename _ForwardIterator, typename _Generator> void - generate(_ForwardIter __first, _ForwardIter __last, _Generator __gen) + generate(_ForwardIterator __first, _ForwardIterator __last, + _Generator __gen) { // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_GeneratorConcept<_Generator, - typename iterator_traits<_ForwardIter>::value_type>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_GeneratorConcept<_Generator, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) *__first = __gen(); @@ -941,14 +993,14 @@ namespace std * Performs the assignment @c *i = @p gen() for each @c i in the range * @p [first,first+n). */ - template<typename _OutputIter, typename _Size, typename _Generator> - _OutputIter - generate_n(_OutputIter __first, _Size __n, _Generator __gen) + template<typename _OutputIterator, typename _Size, typename _Generator> + _OutputIterator + generate_n(_OutputIterator __first, _Size __n, _Generator __gen) { // concept requirements - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, // "the type returned by a _Generator" - __typeof__(gen())>) + __typeof__(__gen())>) for ( ; __n > 0; --__n, ++__first) *__first = __gen(); @@ -968,23 +1020,25 @@ namespace std * remove_copy() is stable, so the relative order of elements that are * copied is unchanged. */ - template<typename _InputIter, typename _OutputIter, typename _Tp> - _OutputIter - remove_copy(_InputIter __first, _InputIter __last, - _OutputIter __result, const _Tp& __value) + template<typename _InputIterator, typename _OutputIterator, typename _Tp> + _OutputIterator + remove_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, const _Tp& __value) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_InputIter>::value_type>) - __glibcpp_function_requires(_EqualOpConcept< - typename iterator_traits<_InputIter>::value_type, _Tp>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) - if (!(*__first == __value)) { - *__result = *__first; - ++__result; - } + if (!(*__first == __value)) + { + *__result = *__first; + ++__result; + } return __result; } @@ -1002,23 +1056,26 @@ namespace std * remove_copy_if() is stable, so the relative order of elements that are * copied is unchanged. */ - template<typename _InputIter, typename _OutputIter, typename _Predicate> - _OutputIter - remove_copy_if(_InputIter __first, _InputIter __last, - _OutputIter __result, _Predicate __pred) + template<typename _InputIterator, typename _OutputIterator, + typename _Predicate> + _OutputIterator + remove_copy_if(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Predicate __pred) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_InputIter>::value_type>) - __glibcpp_function_requires(_UnaryPredicateConcept<_Predicate, - typename iterator_traits<_InputIter>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) - if (!__pred(*__first)) { - *__result = *__first; - ++__result; - } + if (!__pred(*__first)) + { + *__result = *__first; + ++__result; + } return __result; } @@ -1038,22 +1095,25 @@ namespace std * Elements between the end of the resulting sequence and @p last * are still present, but their value is unspecified. */ - template<typename _ForwardIter, typename _Tp> - _ForwardIter - remove(_ForwardIter __first, _ForwardIter __last, + template<typename _ForwardIterator, typename _Tp> + _ForwardIterator + remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { // concept requirements - __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_ConvertibleConcept<_Tp, - typename iterator_traits<_ForwardIter>::value_type>) - __glibcpp_function_requires(_EqualOpConcept< - typename iterator_traits<_ForwardIter>::value_type, _Tp>) - - __first = find(__first, __last, __value); - _ForwardIter __i = __first; + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_ConvertibleConcept<_Tp, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_requires_valid_range(__first, __last); + + __first = std::find(__first, __last, __value); + _ForwardIterator __i = __first; return __first == __last ? __first - : remove_copy(++__i, __last, __first, __value); + : std::remove_copy(++__i, __last, + __first, __value); } /** @@ -1072,55 +1132,61 @@ namespace std * Elements between the end of the resulting sequence and @p last * are still present, but their value is unspecified. */ - template<typename _ForwardIter, typename _Predicate> - _ForwardIter - remove_if(_ForwardIter __first, _ForwardIter __last, + template<typename _ForwardIterator, typename _Predicate> + _ForwardIterator + remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { // concept requirements - __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_UnaryPredicateConcept<_Predicate, - typename iterator_traits<_ForwardIter>::value_type>) - - __first = find_if(__first, __last, __pred); - _ForwardIter __i = __first; + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + __first = std::find_if(__first, __last, __pred); + _ForwardIterator __i = __first; return __first == __last ? __first - : remove_copy_if(++__i, __last, __first, __pred); + : std::remove_copy_if(++__i, __last, + __first, __pred); } /** * @if maint - * This is an uglified unique_copy(_InputIter, _InputIter, _OutputIter) + * This is an uglified unique_copy(_InputIterator, _InputIterator, + * _OutputIterator) * overloaded for output iterators. * @endif */ - template<typename _InputIter, typename _OutputIter> - _OutputIter - __unique_copy(_InputIter __first, _InputIter __last, - _OutputIter __result, + template<typename _InputIterator, typename _OutputIterator> + _OutputIterator + __unique_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, output_iterator_tag) { // concept requirements -- taken care of in dispatching function - typename iterator_traits<_InputIter>::value_type __value = *__first; + typename iterator_traits<_InputIterator>::value_type __value = *__first; *__result = __value; while (++__first != __last) - if (!(__value == *__first)) { - __value = *__first; - *++__result = __value; - } + if (!(__value == *__first)) + { + __value = *__first; + *++__result = __value; + } return ++__result; } /** * @if maint - * This is an uglified unique_copy(_InputIter, _InputIter, _OutputIter) + * This is an uglified unique_copy(_InputIterator, _InputIterator, + * _OutputIterator) * overloaded for forward iterators. * @endif */ - template<typename _InputIter, typename _ForwardIter> - _ForwardIter - __unique_copy(_InputIter __first, _InputIter __last, - _ForwardIter __result, + template<typename _InputIterator, typename _ForwardIterator> + _ForwardIterator + __unique_copy(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, forward_iterator_tag) { // concept requirements -- taken care of in dispatching function @@ -1132,83 +1198,57 @@ namespace std } /** - * @brief Copy a sequence, removing consecutive duplicate values. - * @param first An input iterator. - * @param last An input iterator. - * @param result An output iterator. - * @return An iterator designating the end of the resulting sequence. - * - * Copies each element in the range @p [first,last) to the range - * beginning at @p result, except that only the first element is copied - * from groups of consecutive elements that compare equal. - * unique_copy() is stable, so the relative order of elements that are - * copied is unchanged. - */ - template<typename _InputIter, typename _OutputIter> - inline _OutputIter - unique_copy(_InputIter __first, _InputIter __last, - _OutputIter __result) - { - // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_InputIter>::value_type>) - __glibcpp_function_requires(_EqualityComparableConcept< - typename iterator_traits<_InputIter>::value_type>) - - typedef typename iterator_traits<_OutputIter>::iterator_category _IterType; - - if (__first == __last) return __result; - return __unique_copy(__first, __last, __result, _IterType()); - } - - /** * @if maint * This is an uglified - * unique_copy(_InputIter, _InputIter, _OutputIter, _BinaryPredicate) + * unique_copy(_InputIterator, _InputIterator, _OutputIterator, + * _BinaryPredicate) * overloaded for output iterators. * @endif */ - template<typename _InputIter, typename _OutputIter, typename _BinaryPredicate> - _OutputIter - __unique_copy(_InputIter __first, _InputIter __last, - _OutputIter __result, + template<typename _InputIterator, typename _OutputIterator, + typename _BinaryPredicate> + _OutputIterator + __unique_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _BinaryPredicate __binary_pred, output_iterator_tag) { // concept requirements -- iterators already checked - __glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPredicate, - typename iterator_traits<_InputIter>::value_type, - typename iterator_traits<_InputIter>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_InputIterator>::value_type, + typename iterator_traits<_InputIterator>::value_type>) - typename iterator_traits<_InputIter>::value_type __value = *__first; + typename iterator_traits<_InputIterator>::value_type __value = *__first; *__result = __value; while (++__first != __last) - if (!__binary_pred(__value, *__first)) { - __value = *__first; - *++__result = __value; - } + if (!__binary_pred(__value, *__first)) + { + __value = *__first; + *++__result = __value; + } return ++__result; } /** * @if maint * This is an uglified - * unique_copy(_InputIter, _InputIter, _OutputIter, _BinaryPredicate) + * unique_copy(_InputIterator, _InputIterator, _OutputIterator, + * _BinaryPredicate) * overloaded for forward iterators. * @endif */ - template<typename _InputIter, typename _ForwardIter, typename _BinaryPredicate> - _ForwardIter - __unique_copy(_InputIter __first, _InputIter __last, - _ForwardIter __result, + template<typename _InputIterator, typename _ForwardIterator, + typename _BinaryPredicate> + _ForwardIterator + __unique_copy(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, _BinaryPredicate __binary_pred, forward_iterator_tag) { // concept requirements -- iterators already checked - __glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPredicate, - typename iterator_traits<_ForwardIter>::value_type, - typename iterator_traits<_InputIter>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_InputIterator>::value_type>) *__result = *__first; while (++__first != __last) @@ -1217,6 +1257,39 @@ namespace std } /** + * @brief Copy a sequence, removing consecutive duplicate values. + * @param first An input iterator. + * @param last An input iterator. + * @param result An output iterator. + * @return An iterator designating the end of the resulting sequence. + * + * Copies each element in the range @p [first,last) to the range + * beginning at @p result, except that only the first element is copied + * from groups of consecutive elements that compare equal. + * unique_copy() is stable, so the relative order of elements that are + * copied is unchanged. + */ + template<typename _InputIterator, typename _OutputIterator> + inline _OutputIterator + unique_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result) + { + // concept requirements + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + typedef typename iterator_traits<_OutputIterator>::iterator_category + _IterType; + + if (__first == __last) return __result; + return std::__unique_copy(__first, __last, __result, _IterType()); + } + + /** * @brief Copy a sequence, removing consecutive values using a predicate. * @param first An input iterator. * @param last An input iterator. @@ -1231,22 +1304,25 @@ namespace std * unique_copy() is stable, so the relative order of elements that are * copied is unchanged. */ - template<typename _InputIter, typename _OutputIter, typename _BinaryPredicate> - inline _OutputIter - unique_copy(_InputIter __first, _InputIter __last, - _OutputIter __result, + template<typename _InputIterator, typename _OutputIterator, + typename _BinaryPredicate> + inline _OutputIterator + unique_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _BinaryPredicate __binary_pred) { // concept requirements -- predicates checked later - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_InputIter>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); - typedef typename iterator_traits<_OutputIter>::iterator_category _IterType; + typedef typename iterator_traits<_OutputIterator>::iterator_category + _IterType; if (__first == __last) return __result; - return __unique_copy(__first, __last, -__result, __binary_pred, _IterType()); + return std::__unique_copy(__first, __last, __result, + __binary_pred, _IterType()); } /** @@ -1262,17 +1338,29 @@ __result, __binary_pred, _IterType()); * Elements between the end of the resulting sequence and @p last * are still present, but their value is unspecified. */ - template<typename _ForwardIter> - _ForwardIter - unique(_ForwardIter __first, _ForwardIter __last) + template<typename _ForwardIterator> + _ForwardIterator + unique(_ForwardIterator __first, _ForwardIterator __last) { - // concept requirements - __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_EqualityComparableConcept< - typename iterator_traits<_ForwardIter>::value_type>) + // concept requirements + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + // Skip the beginning, if already unique. + __first = std::adjacent_find(__first, __last); + if (__first == __last) + return __last; - __first = adjacent_find(__first, __last); - return unique_copy(__first, __last, __first); + // Do the real copy work. + _ForwardIterator __dest = __first; + ++__first; + while (++__first != __last) + if (!(*__dest == *__first)) + *++__dest = *__first; + return ++__dest; } /** @@ -1289,52 +1377,66 @@ __result, __binary_pred, _IterType()); * Elements between the end of the resulting sequence and @p last * are still present, but their value is unspecified. */ - template<typename _ForwardIter, typename _BinaryPredicate> - _ForwardIter - unique(_ForwardIter __first, _ForwardIter __last, + template<typename _ForwardIterator, typename _BinaryPredicate> + _ForwardIterator + unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __binary_pred) { // concept requirements - __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPredicate, - typename iterator_traits<_ForwardIter>::value_type, - typename iterator_traits<_ForwardIter>::value_type>) + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + // Skip the beginning, if already unique. + __first = std::adjacent_find(__first, __last, __binary_pred); + if (__first == __last) + return __last; - __first = adjacent_find(__first, __last, __binary_pred); - return unique_copy(__first, __last, __first, __binary_pred); + // Do the real copy work. + _ForwardIterator __dest = __first; + ++__first; + while (++__first != __last) + if (!__binary_pred(*__dest, *__first)) + *++__dest = *__first; + return ++__dest; } /** * @if maint - * This is an uglified reverse(_BidirectionalIter, _BidirectionalIter) + * This is an uglified reverse(_BidirectionalIterator, + * _BidirectionalIterator) * overloaded for bidirectional iterators. * @endif */ - template<typename _BidirectionalIter> + template<typename _BidirectionalIterator> void - __reverse(_BidirectionalIter __first, _BidirectionalIter __last, + __reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag) { - while (true) - if (__first == __last || __first == --__last) - return; - else - iter_swap(__first++, __last); + while (true) + if (__first == __last || __first == --__last) + return; + else + std::iter_swap(__first++, __last); } /** * @if maint - * This is an uglified reverse(_BidirectionalIter, _BidirectionalIter) + * This is an uglified reverse(_BidirectionalIterator, + * _BidirectionalIterator) * overloaded for bidirectional iterators. * @endif */ - template<typename _RandomAccessIter> + template<typename _RandomAccessIterator> void - __reverse(_RandomAccessIter __first, _RandomAccessIter __last, + __reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) { - while (__first < __last) - iter_swap(__first++, --__last); + while (__first < __last) + std::iter_swap(__first++, --__last); } /** @@ -1348,14 +1450,15 @@ __result, __binary_pred, _IterType()); * For every @c i such that @p 0<=i<=(last-first)/2), @p reverse() * swaps @p *(first+i) and @p *(last-(i+1)) */ - template<typename _BidirectionalIter> + template<typename _BidirectionalIterator> inline void - reverse(_BidirectionalIter __first, _BidirectionalIter __last) + reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) { - // concept requirements - __glibcpp_function_requires(_Mutable_BidirectionalIteratorConcept< - _BidirectionalIter>) - __reverse(__first, __last, __iterator_category(__first)); + // concept requirements + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_requires_valid_range(__first, __last); + std::__reverse(__first, __last, std::__iterator_category(__first)); } /** @@ -1373,21 +1476,24 @@ __result, __binary_pred, _IterType()); * The ranges @p [first,last) and @p [result,result+(last-first)) * must not overlap. */ - template<typename _BidirectionalIter, typename _OutputIter> - _OutputIter - reverse_copy(_BidirectionalIter __first, _BidirectionalIter __last, - _OutputIter __result) + template<typename _BidirectionalIterator, typename _OutputIterator> + _OutputIterator + reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, + _OutputIterator __result) { // concept requirements - __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_BidirectionalIter>::value_type>) - - while (__first != __last) { - --__last; - *__result = *__last; - ++__result; - } + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + while (__first != __last) + { + --__last; + *__result = *__last; + ++__result; + } return __result; } @@ -1402,11 +1508,12 @@ __result, __binary_pred, _IterType()); _EuclideanRingElement __gcd(_EuclideanRingElement __m, _EuclideanRingElement __n) { - while (__n != 0) { - _EuclideanRingElement __t = __m % __n; - __m = __n; - __n = __t; - } + while (__n != 0) + { + _EuclideanRingElement __t = __m % __n; + __m = __n; + __n = __t; + } return __m; } @@ -1415,32 +1522,35 @@ __result, __binary_pred, _IterType()); * This is a helper function for the rotate algorithm. * @endif */ - template<typename _ForwardIter> + template<typename _ForwardIterator> void - __rotate(_ForwardIter __first, - _ForwardIter __middle, - _ForwardIter __last, + __rotate(_ForwardIterator __first, + _ForwardIterator __middle, + _ForwardIterator __last, forward_iterator_tag) { if ((__first == __middle) || (__last == __middle)) return; - _ForwardIter __first2 = __middle; - do { - swap(*__first++, *__first2++); - if (__first == __middle) - __middle = __first2; - } while (__first2 != __last); + _ForwardIterator __first2 = __middle; + do + { + swap(*__first++, *__first2++); + if (__first == __middle) + __middle = __first2; + } + while (__first2 != __last); __first2 = __middle; - while (__first2 != __last) { - swap(*__first++, *__first2++); - if (__first == __middle) - __middle = __first2; - else if (__first2 == __last) - __first2 = __middle; - } + while (__first2 != __last) + { + swap(*__first++, *__first2++); + if (__first == __middle) + __middle = __first2; + else if (__first2 == __last) + __first2 = __middle; + } } /** @@ -1448,32 +1558,30 @@ __result, __binary_pred, _IterType()); * This is a helper function for the rotate algorithm. * @endif */ - template<typename _BidirectionalIter> + template<typename _BidirectionalIterator> void - __rotate(_BidirectionalIter __first, - _BidirectionalIter __middle, - _BidirectionalIter __last, + __rotate(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, bidirectional_iterator_tag) { // concept requirements - __glibcpp_function_requires(_Mutable_BidirectionalIteratorConcept< - _BidirectionalIter>) + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< + _BidirectionalIterator>) if ((__first == __middle) || (__last == __middle)) return; - __reverse(__first, __middle, bidirectional_iterator_tag()); - __reverse(__middle, __last, bidirectional_iterator_tag()); + std::__reverse(__first, __middle, bidirectional_iterator_tag()); + std::__reverse(__middle, __last, bidirectional_iterator_tag()); while (__first != __middle && __middle != __last) - swap (*__first++, *--__last); + swap(*__first++, *--__last); - if (__first == __middle) { - __reverse(__middle, __last, bidirectional_iterator_tag()); - } - else { - __reverse(__first, __middle, bidirectional_iterator_tag()); - } + if (__first == __middle) + std::__reverse(__middle, __last, bidirectional_iterator_tag()); + else + std::__reverse(__first, __middle, bidirectional_iterator_tag()); } /** @@ -1481,65 +1589,73 @@ __result, __binary_pred, _IterType()); * This is a helper function for the rotate algorithm. * @endif */ - template<typename _RandomAccessIter> + template<typename _RandomAccessIterator> void - __rotate(_RandomAccessIter __first, - _RandomAccessIter __middle, - _RandomAccessIter __last, + __rotate(_RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, random_access_iterator_tag) { // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< - _RandomAccessIter>) + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) if ((__first == __middle) || (__last == __middle)) return; - typedef typename iterator_traits<_RandomAccessIter>::difference_type _Distance; - typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType; - - _Distance __n = __last - __first; - _Distance __k = __middle - __first; - _Distance __l = __n - __k; - - if (__k == __l) { - swap_ranges(__first, __middle, __middle); - return; - } - - _Distance __d = __gcd(__n, __k); - - for (_Distance __i = 0; __i < __d; __i++) { - _ValueType __tmp = *__first; - _RandomAccessIter __p = __first; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; - if (__k < __l) { - for (_Distance __j = 0; __j < __l/__d; __j++) { - if (__p > __first + __l) { - *__p = *(__p - __l); - __p -= __l; - } + const _Distance __n = __last - __first; + const _Distance __k = __middle - __first; + const _Distance __l = __n - __k; - *__p = *(__p + __k); - __p += __k; - } + if (__k == __l) + { + std::swap_ranges(__first, __middle, __middle); + return; } - else { - for (_Distance __j = 0; __j < __k/__d - 1; __j ++) { - if (__p < __last - __k) { - *__p = *(__p + __k); - __p += __k; + const _Distance __d = __gcd(__n, __k); + + for (_Distance __i = 0; __i < __d; __i++) + { + const _ValueType __tmp = *__first; + _RandomAccessIterator __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 = * (__p - __l); - __p -= __l; - } + *__p = __tmp; + ++__first; } - - *__p = __tmp; - ++__first; - } } /** @@ -1560,15 +1676,20 @@ __result, __binary_pred, _IterType()); * Performs @p *(first+(n+(last-middle))%(last-first))=*(first+n) for * each @p n in the range @p [0,last-first). */ - template<typename _ForwardIter> + template<typename _ForwardIterator> inline void - rotate(_ForwardIter __first, _ForwardIter __middle, _ForwardIter __last) + rotate(_ForwardIterator __first, _ForwardIterator __middle, + _ForwardIterator __last) { // concept requirements - __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>) + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); - typedef typename iterator_traits<_ForwardIter>::iterator_category _IterType; - __rotate(__first, __middle, __last, _IterType()); + typedef typename iterator_traits<_ForwardIterator>::iterator_category + _IterType; + std::__rotate(__first, __middle, __last, _IterType()); } /** @@ -1588,41 +1709,21 @@ __result, __binary_pred, _IterType()); * Performs @p *(result+(n+(last-middle))%(last-first))=*(first+n) for * each @p n in the range @p [0,last-first). */ - template<typename _ForwardIter, typename _OutputIter> - _OutputIter - rotate_copy(_ForwardIter __first, _ForwardIter __middle, - _ForwardIter __last, _OutputIter __result) + template<typename _ForwardIterator, typename _OutputIterator> + _OutputIterator + rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, + _ForwardIterator __last, _OutputIterator __result) { // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_ForwardIter>::value_type>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); - return copy(__first, __middle, copy(__middle, __last, __result)); + return std::copy(__first, __middle, copy(__middle, __last, __result)); } - - /** - * @if maint - * 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). - * - * XXX There is no corresponding encapsulation fn to seed the generator. - * @endif - */ - template<typename _Distance> - inline _Distance - __random_number(_Distance __n) - { - #ifdef _GLIBCPP_HAVE_DRAND48 - return lrand48() % __n; - #else - return rand() % __n; - #endif - } - - /** * @brief Randomly shuffle the elements of a sequence. * @param first A forward iterator. @@ -1633,17 +1734,18 @@ __result, __binary_pred, _IterType()); * distribution, so that every possible ordering of the sequence is * equally likely. */ - template<typename _RandomAccessIter> + template<typename _RandomAccessIterator> inline void - random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last) + random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< - _RandomAccessIter>) + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); - if (__first == __last) return; - for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) - iter_swap(__i, __first + __random_number((__i - __first) + 1)); + if (__first != __last) + for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) + std::iter_swap(__i, __first + (std::rand() % ((__i - __first) + 1))); } /** @@ -1659,18 +1761,20 @@ __result, __binary_pred, _IterType()); * integer @p N should return a randomly chosen integer from the * range [0,N). */ - template<typename _RandomAccessIter, typename _RandomNumberGenerator> + template<typename _RandomAccessIterator, typename _RandomNumberGenerator> void - random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last, + random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, _RandomNumberGenerator& __rand) { // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< - _RandomAccessIter>) + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); - if (__first == __last) return; - for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) - iter_swap(__i, __first + __rand((__i - __first) + 1)); + if (__first == __last) + return; + for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) + std::iter_swap(__i, __first + __rand((__i - __first) + 1)); } @@ -1679,24 +1783,27 @@ __result, __binary_pred, _IterType()); * This is a helper function... * @endif */ - template<typename _ForwardIter, typename _Predicate> - _ForwardIter - __partition(_ForwardIter __first, _ForwardIter __last, - _Predicate __pred, + template<typename _ForwardIterator, typename _Predicate> + _ForwardIterator + __partition(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred, forward_iterator_tag) { - if (__first == __last) return __first; + if (__first == __last) + return __first; while (__pred(*__first)) - if (++__first == __last) return __first; + if (++__first == __last) + return __first; - _ForwardIter __next = __first; + _ForwardIterator __next = __first; while (++__next != __last) - if (__pred(*__next)) { - swap(*__first, *__next); - ++__first; - } + if (__pred(*__next)) + { + swap(*__first, *__next); + ++__first; + } return __first; } @@ -1706,31 +1813,32 @@ __result, __binary_pred, _IterType()); * This is a helper function... * @endif */ - template<typename _BidirectionalIter, typename _Predicate> - _BidirectionalIter - __partition(_BidirectionalIter __first, _BidirectionalIter __last, + template<typename _BidirectionalIterator, typename _Predicate> + _BidirectionalIterator + __partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, bidirectional_iterator_tag) { - while (true) { - while (true) - if (__first == __last) - return __first; - else if (__pred(*__first)) - ++__first; - else - break; - --__last; - while (true) - if (__first == __last) - return __first; - else if (!__pred(*__last)) - --__last; - else - break; - iter_swap(__first, __last); - ++__first; - } + while (true) + { + while (true) + if (__first == __last) + return __first; + else if (__pred(*__first)) + ++__first; + else + break; + --__last; + while (true) + if (__first == __last) + return __first; + else if (!__pred(*__last)) + --__last; + else + break; + std::iter_swap(__first, __last); + ++__first; + } } /** @@ -1742,22 +1850,25 @@ __result, __binary_pred, _IterType()); * @return An iterator @p middle such that @p pred(i) is true for each * iterator @p i in the range @p [first,middle) and false for each @p i * in the range @p [middle,last). - * + * * @p pred must not modify its operand. @p partition() does not preserve * the relative ordering of elements in each group, use * @p stable_partition() if this is needed. */ - template<typename _ForwardIter, typename _Predicate> - inline _ForwardIter - partition(_ForwardIter __first, _ForwardIter __last, + template<typename _ForwardIterator, typename _Predicate> + inline _ForwardIterator + partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { // concept requirements - __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_UnaryPredicateConcept<_Predicate, - typename iterator_traits<_ForwardIter>::value_type>) + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); - return __partition(__first, __last, __pred, __iterator_category(__first)); + return std::__partition(__first, __last, __pred, + std::__iterator_category(__first)); } @@ -1766,23 +1877,26 @@ __result, __binary_pred, _IterType()); * This is a helper function... * @endif */ - template<typename _ForwardIter, typename _Predicate, typename _Distance> - _ForwardIter - __inplace_stable_partition(_ForwardIter __first, _ForwardIter __last, + template<typename _ForwardIterator, typename _Predicate, typename _Distance> + _ForwardIterator + __inplace_stable_partition(_ForwardIterator __first, + _ForwardIterator __last, _Predicate __pred, _Distance __len) { if (__len == 1) return __pred(*__first) ? __last : __first; - _ForwardIter __middle = __first; - advance(__middle, __len / 2); - _ForwardIter __begin = __inplace_stable_partition(__first, __middle, - __pred, - __len / 2); - _ForwardIter __end = __inplace_stable_partition(__middle, __last, - __pred, - __len - __len / 2); - rotate(__begin, __middle, __end); - advance(__begin, distance(__middle, __end)); + _ForwardIterator __middle = __first; + std::advance(__middle, __len / 2); + _ForwardIterator __begin = std::__inplace_stable_partition(__first, + __middle, + __pred, + __len / 2); + _ForwardIterator __end = std::__inplace_stable_partition(__middle, __last, + __pred, + __len + - __len / 2); + std::rotate(__begin, __middle, __end); + std::advance(__begin, std::distance(__middle, __end)); return __begin; } @@ -1791,44 +1905,49 @@ __result, __binary_pred, _IterType()); * This is a helper function... * @endif */ - template<typename _ForwardIter, typename _Pointer, typename _Predicate, + template<typename _ForwardIterator, typename _Pointer, typename _Predicate, typename _Distance> - _ForwardIter - __stable_partition_adaptive(_ForwardIter __first, _ForwardIter __last, + _ForwardIterator + __stable_partition_adaptive(_ForwardIterator __first, + _ForwardIterator __last, _Predicate __pred, _Distance __len, _Pointer __buffer, _Distance __buffer_size) { - if (__len <= __buffer_size) { - _ForwardIter __result1 = __first; - _Pointer __result2 = __buffer; - for ( ; __first != __last ; ++__first) - if (__pred(*__first)) { - *__result1 = *__first; - ++__result1; - } - else { - *__result2 = *__first; - ++__result2; - } - copy(__buffer, __result2, __result1); - return __result1; - } - else { - _ForwardIter __middle = __first; - advance(__middle, __len / 2); - _ForwardIter __begin = __stable_partition_adaptive(__first, __middle, - __pred, - __len / 2, - __buffer, __buffer_size); - _ForwardIter __end = __stable_partition_adaptive( __middle, __last, - __pred, - __len - __len / 2, - __buffer, __buffer_size); - rotate(__begin, __middle, __end); - advance(__begin, distance(__middle, __end)); - return __begin; - } + if (__len <= __buffer_size) + { + _ForwardIterator __result1 = __first; + _Pointer __result2 = __buffer; + for ( ; __first != __last ; ++__first) + if (__pred(*__first)) + { + *__result1 = *__first; + ++__result1; + } + else + { + *__result2 = *__first; + ++__result2; + } + std::copy(__buffer, __result2, __result1); + return __result1; + } + else + { + _ForwardIterator __middle = __first; + std::advance(__middle, __len / 2); + _ForwardIterator __begin = + std::__stable_partition_adaptive(__first, __middle, __pred, + __len / 2, __buffer, + __buffer_size); + _ForwardIterator __end = + std::__stable_partition_adaptive(__middle, __last, __pred, + __len - __len / 2, + __buffer, __buffer_size); + std::rotate(__begin, __middle, __end); + std::advance(__begin, std::distance(__middle, __end)); + return __begin; + } } /** @@ -1840,39 +1959,46 @@ __result, __binary_pred, _IterType()); * @return An iterator @p middle such that @p pred(i) is true for each * iterator @p i in the range @p [first,middle) and false for each @p i * in the range @p [middle,last). - * + * * Performs the same function as @p partition() with the additional * guarantee that the relative ordering of elements in each group is * preserved, so any two elements @p x and @p y in the range * @p [first,last) such that @p pred(x)==pred(y) will have the same * relative ordering after calling @p stable_partition(). */ - template<typename _ForwardIter, typename _Predicate> - _ForwardIter - stable_partition(_ForwardIter __first, _ForwardIter __last, + template<typename _ForwardIterator, typename _Predicate> + _ForwardIterator + stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { // concept requirements - __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_UnaryPredicateConcept<_Predicate, - typename iterator_traits<_ForwardIter>::value_type>) + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __first; else - { - typedef typename iterator_traits<_ForwardIter>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType; - - _Temporary_buffer<_ForwardIter, _ValueType> __buf(__first, __last); + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + _Temporary_buffer<_ForwardIterator, _ValueType> __buf(__first, + __last); if (__buf.size() > 0) - return __stable_partition_adaptive(__first, __last, __pred, - _DistanceType(__buf.requested_size()), - __buf.begin(), __buf.size()); + return + std::__stable_partition_adaptive(__first, __last, __pred, + _DistanceType(__buf.requested_size()), + __buf.begin(), __buf.size()); else - return __inplace_stable_partition(__first, __last, __pred, - _DistanceType(__buf.requested_size())); - } + return + std::__inplace_stable_partition(__first, __last, __pred, + _DistanceType(__buf.requested_size())); + } } /** @@ -1880,22 +2006,23 @@ __result, __binary_pred, _IterType()); * This is a helper function... * @endif */ - template<typename _RandomAccessIter, typename _Tp> - _RandomAccessIter - __unguarded_partition(_RandomAccessIter __first, _RandomAccessIter __last, - _Tp __pivot) - { - while (true) { - while (*__first < __pivot) - ++__first; - --__last; - while (__pivot < *__last) + template<typename _RandomAccessIterator, typename _Tp> + _RandomAccessIterator + __unguarded_partition(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Tp __pivot) + { + while (true) + { + while (*__first < __pivot) + ++__first; --__last; - if (!(__first < __last)) - return __first; - iter_swap(__first, __last); - ++__first; - } + while (__pivot < *__last) + --__last; + if (!(__first < __last)) + return __first; + std::iter_swap(__first, __last); + ++__first; + } } /** @@ -1903,49 +2030,51 @@ __result, __binary_pred, _IterType()); * This is a helper function... * @endif */ - template<typename _RandomAccessIter, typename _Tp, typename _Compare> - _RandomAccessIter - __unguarded_partition(_RandomAccessIter __first, _RandomAccessIter __last, + template<typename _RandomAccessIterator, typename _Tp, typename _Compare> + _RandomAccessIterator + __unguarded_partition(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Tp __pivot, _Compare __comp) { - while (true) { - while (__comp(*__first, __pivot)) - ++__first; - --__last; - while (__comp(__pivot, *__last)) + while (true) + { + while (__comp(*__first, __pivot)) + ++__first; --__last; - if (!(__first < __last)) - return __first; - iter_swap(__first, __last); - ++__first; - } + while (__comp(__pivot, *__last)) + --__last; + if (!(__first < __last)) + return __first; + std::iter_swap(__first, __last); + ++__first; + } } - /** * @if maint * @doctodo * This controls some aspect of the sort routines. * @endif */ - enum { _M_threshold = 16 }; + enum { _S_threshold = 16 }; /** * @if maint * This is a helper function for the sort routine. * @endif */ - template<typename _RandomAccessIter, typename _Tp> + template<typename _RandomAccessIterator, typename _Tp> void - __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val) + __unguarded_linear_insert(_RandomAccessIterator __last, _Tp __val) { - _RandomAccessIter __next = __last; + _RandomAccessIterator __next = __last; --__next; - while (__val < *__next) { - *__last = *__next; - __last = __next; - --__next; - } + while (__val < *__next) + { + *__last = *__next; + __last = __next; + --__next; + } *__last = __val; } @@ -1954,17 +2083,19 @@ __result, __binary_pred, _IterType()); * This is a helper function for the sort routine. * @endif */ - template<typename _RandomAccessIter, typename _Tp, typename _Compare> + template<typename _RandomAccessIterator, typename _Tp, typename _Compare> void - __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val, _Compare __comp) + __unguarded_linear_insert(_RandomAccessIterator __last, _Tp __val, + _Compare __comp) { - _RandomAccessIter __next = __last; + _RandomAccessIterator __next = __last; --__next; - while (__comp(__val, *__next)) { - *__last = *__next; - __last = __next; - --__next; - } + while (__comp(__val, *__next)) + { + *__last = *__next; + __last = __next; + --__next; + } *__last = __val; } @@ -1973,22 +2104,26 @@ __result, __binary_pred, _IterType()); * This is a helper function for the sort routine. * @endif */ - template<typename _RandomAccessIter> + template<typename _RandomAccessIterator> void - __insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) + __insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last) { - if (__first == __last) return; + if (__first == __last) + return; - for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) - { - typename iterator_traits<_RandomAccessIter>::value_type __val = *__i; - if (__val < *__first) { - copy_backward(__first, __i, __i + 1); - *__first = __val; + for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) + { + typename iterator_traits<_RandomAccessIterator>::value_type + __val = *__i; + if (__val < *__first) + { + std::copy_backward(__first, __i, __i + 1); + *__first = __val; + } + else + std::__unguarded_linear_insert(__i, __val); } - else - __unguarded_linear_insert(__i, __val); - } } /** @@ -1996,23 +2131,25 @@ __result, __binary_pred, _IterType()); * This is a helper function for the sort routine. * @endif */ - template<typename _RandomAccessIter, typename _Compare> + template<typename _RandomAccessIterator, typename _Compare> void - __insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last, - _Compare __comp) + __insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) { if (__first == __last) return; - for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) - { - typename iterator_traits<_RandomAccessIter>::value_type __val = *__i; - if (__comp(__val, *__first)) { - copy_backward(__first, __i, __i + 1); - *__first = __val; + for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) + { + typename iterator_traits<_RandomAccessIterator>::value_type + __val = *__i; + if (__comp(__val, *__first)) + { + std::copy_backward(__first, __i, __i + 1); + *__first = __val; + } + else + std::__unguarded_linear_insert(__i, __val, __comp); } - else - __unguarded_linear_insert(__i, __val, __comp); - } } /** @@ -2020,14 +2157,16 @@ __result, __binary_pred, _IterType()); * This is a helper function for the sort routine. * @endif */ - template<typename _RandomAccessIter> + template<typename _RandomAccessIterator> inline void - __unguarded_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) + __unguarded_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last) { - typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; - for (_RandomAccessIter __i = __first; __i != __last; ++__i) - __unguarded_linear_insert(__i, _ValueType(*__i)); + for (_RandomAccessIterator __i = __first; __i != __last; ++__i) + std::__unguarded_linear_insert(__i, _ValueType(*__i)); } /** @@ -2035,15 +2174,16 @@ __result, __binary_pred, _IterType()); * This is a helper function for the sort routine. * @endif */ - template<typename _RandomAccessIter, typename _Compare> + template<typename _RandomAccessIterator, typename _Compare> inline void - __unguarded_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last, - _Compare __comp) + __unguarded_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) { - typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; - for (_RandomAccessIter __i = __first; __i != __last; ++__i) - __unguarded_linear_insert(__i, _ValueType(*__i), __comp); + for (_RandomAccessIterator __i = __first; __i != __last; ++__i) + std::__unguarded_linear_insert(__i, _ValueType(*__i), __comp); } /** @@ -2051,16 +2191,18 @@ __result, __binary_pred, _IterType()); * This is a helper function for the sort routine. * @endif */ - template<typename _RandomAccessIter> + template<typename _RandomAccessIterator> void - __final_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) + __final_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last) { - if (__last - __first > _M_threshold) { - __insertion_sort(__first, __first + _M_threshold); - __unguarded_insertion_sort(__first + _M_threshold, __last); - } + if (__last - __first > _S_threshold) + { + std::__insertion_sort(__first, __first + _S_threshold); + std::__unguarded_insertion_sort(__first + _S_threshold, __last); + } else - __insertion_sort(__first, __last); + std::__insertion_sort(__first, __last); } /** @@ -2068,17 +2210,19 @@ __result, __binary_pred, _IterType()); * This is a helper function for the sort routine. * @endif */ - template<typename _RandomAccessIter, typename _Compare> + template<typename _RandomAccessIterator, typename _Compare> void - __final_insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last, - _Compare __comp) - { - if (__last - __first > _M_threshold) { - __insertion_sort(__first, __first + _M_threshold, __comp); - __unguarded_insertion_sort(__first + _M_threshold, __last, __comp); - } + __final_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) + { + if (__last - __first > _S_threshold) + { + std::__insertion_sort(__first, __first + _S_threshold, __comp); + std::__unguarded_insertion_sort(__first + _S_threshold, __last, + __comp); + } else - __insertion_sort(__first, __last, __comp); + std::__insertion_sort(__first, __last, __comp); } /** @@ -2091,402 +2235,12 @@ __result, __binary_pred, _IterType()); __lg(_Size __n) { _Size __k; - for (__k = 0; __n != 1; __n >>= 1) ++__k; + for (__k = 0; __n != 1; __n >>= 1) + ++__k; return __k; } /** - * @if maint - * This is a helper function for the sort routine. - * @endif - */ - template<typename _RandomAccessIter, typename _Size> - void - __introsort_loop(_RandomAccessIter __first, _RandomAccessIter __last, - _Size __depth_limit) - { - typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType; - - while (__last - __first > _M_threshold) { - if (__depth_limit == 0) { - partial_sort(__first, __last, __last); - return; - } - --__depth_limit; - _RandomAccessIter __cut = - __unguarded_partition(__first, __last, - _ValueType(__median(*__first, - *(__first + (__last - __first)/2), - *(__last - 1)))); - __introsort_loop(__cut, __last, __depth_limit); - __last = __cut; - } - } - - /** - * @if maint - * This is a helper function for the sort routine. - * @endif - */ - template<typename _RandomAccessIter, typename _Size, typename _Compare> - void - __introsort_loop(_RandomAccessIter __first, _RandomAccessIter __last, - _Size __depth_limit, _Compare __comp) - { - typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType; - - while (__last - __first > _M_threshold) { - if (__depth_limit == 0) { - partial_sort(__first, __last, __last, __comp); - return; - } - --__depth_limit; - _RandomAccessIter __cut = - __unguarded_partition(__first, __last, - _ValueType(__median(*__first, - *(__first + (__last - __first)/2), - *(__last - 1), __comp)), - __comp); - __introsort_loop(__cut, __last, __depth_limit, __comp); - __last = __cut; - } - } - - /** - * @brief Sort the elements of a sequence. - * @param first An iterator. - * @param last Another iterator. - * @return Nothing. - * - * Sorts the elements in the range @p [first,last) in ascending order, - * such that @p *(i+1)<*i is false for each iterator @p i in the range - * @p [first,last-1). - * - * The relative ordering of equivalent elements is not preserved, use - * @p stable_sort() if this is needed. - */ - template<typename _RandomAccessIter> - inline void - sort(_RandomAccessIter __first, _RandomAccessIter __last) - { - typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType; - - // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< - _RandomAccessIter>) - __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>) - - if (__first != __last) { - __introsort_loop(__first, __last, __lg(__last - __first) * 2); - __final_insertion_sort(__first, __last); - } - } - - /** - * @brief Sort the elements of a sequence using a predicate for comparison. - * @param first An iterator. - * @param last Another iterator. - * @param comp A comparison functor. - * @return Nothing. - * - * Sorts the elements in the range @p [first,last) in ascending order, - * such that @p comp(*(i+1),*i) is false for every iterator @p i in the - * range @p [first,last-1). - * - * The relative ordering of equivalent elements is not preserved, use - * @p stable_sort() if this is needed. - */ - template<typename _RandomAccessIter, typename _Compare> - inline void - sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) - { - typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType; - - // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< - _RandomAccessIter>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, _ValueType>) - - if (__first != __last) { - __introsort_loop(__first, __last, __lg(__last - __first) * 2, __comp); - __final_insertion_sort(__first, __last, __comp); - } - } - - - /** - * @if maint - * This is a helper function for the stable sorting routines. - * @endif - */ - template<typename _RandomAccessIter> - void - __inplace_stable_sort(_RandomAccessIter __first, _RandomAccessIter __last) - { - if (__last - __first < 15) { - __insertion_sort(__first, __last); - return; - } - _RandomAccessIter __middle = __first + (__last - __first) / 2; - __inplace_stable_sort(__first, __middle); - __inplace_stable_sort(__middle, __last); - __merge_without_buffer(__first, __middle, __last, - __middle - __first, - __last - __middle); - } - - /** - * @if maint - * This is a helper function for the stable sorting routines. - * @endif - */ - template<typename _RandomAccessIter, typename _Compare> - void - __inplace_stable_sort(_RandomAccessIter __first, _RandomAccessIter __last, - _Compare __comp) - { - if (__last - __first < 15) { - __insertion_sort(__first, __last, __comp); - return; - } - _RandomAccessIter __middle = __first + (__last - __first) / 2; - __inplace_stable_sort(__first, __middle, __comp); - __inplace_stable_sort(__middle, __last, __comp); - __merge_without_buffer(__first, __middle, __last, - __middle - __first, - __last - __middle, - __comp); - } - - template<typename _RandomAccessIter1, typename _RandomAccessIter2, - typename _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; - } - - __step_size = min(_Distance(__last - __first), __step_size); - merge(__first, __first + __step_size, __first + __step_size, __last, - __result); - } - - template<typename _RandomAccessIter1, typename _RandomAccessIter2, - typename _Distance, typename _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; - } - __step_size = min(_Distance(__last - __first), __step_size); - - merge(__first, __first + __step_size, - __first + __step_size, __last, - __result, - __comp); - } - - enum { _M_chunk_size = 7 }; - - template<typename _RandomAccessIter, typename _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<typename _RandomAccessIter, typename _Distance, typename _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, __comp); - } - - template<typename _RandomAccessIter, typename _Pointer> - void - __merge_sort_with_buffer(_RandomAccessIter __first, _RandomAccessIter __last, - _Pointer __buffer) - { - typedef typename iterator_traits<_RandomAccessIter>::difference_type _Distance; - - _Distance __len = __last - __first; - _Pointer __buffer_last = __buffer + __len; - - _Distance __step_size = _M_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<typename _RandomAccessIter, typename _Pointer, typename _Compare> - void - __merge_sort_with_buffer(_RandomAccessIter __first, _RandomAccessIter __last, - _Pointer __buffer, _Compare __comp) - { - typedef typename iterator_traits<_RandomAccessIter>::difference_type _Distance; - - _Distance __len = __last - __first; - _Pointer __buffer_last = __buffer + __len; - - _Distance __step_size = _M_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<typename _RandomAccessIter, typename _Pointer, typename _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); - __merge_sort_with_buffer(__middle, __last, __buffer); - } - __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), - _Distance(__last - __middle), __buffer, __buffer_size); - } - - template<typename _RandomAccessIter, typename _Pointer, typename _Distance, - typename _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); - } - else { - __merge_sort_with_buffer(__first, __middle, __buffer, __comp); - __merge_sort_with_buffer(__middle, __last, __buffer, __comp); - } - __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), - _Distance(__last - __middle), __buffer, __buffer_size, - __comp); - } - - /** - * @brief Sort the elements of a sequence, preserving the relative order - * of equivalent elements. - * @param first An iterator. - * @param last Another iterator. - * @return Nothing. - * - * Sorts the elements in the range @p [first,last) in ascending order, - * such that @p *(i+1)<*i is false for each iterator @p i in the range - * @p [first,last-1). - * - * The relative ordering of equivalent elements is preserved, so any two - * elements @p x and @p y in the range @p [first,last) such that - * @p x<y is false and @p y<x is false will have the same relative - * ordering after calling @p stable_sort(). - */ - template<typename _RandomAccessIter> - inline void - stable_sort(_RandomAccessIter __first, _RandomAccessIter __last) - { - typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType; - typedef typename iterator_traits<_RandomAccessIter>::difference_type _DistanceType; - - // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< - _RandomAccessIter>) - __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>) - - _Temporary_buffer<_RandomAccessIter, _ValueType> buf(__first, __last); - if (buf.begin() == 0) - __inplace_stable_sort(__first, __last); - else - __stable_sort_adaptive(__first, __last, buf.begin(), _DistanceType(buf.size())); - } - - /** - * @brief Sort the elements of a sequence using a predicate for comparison, - * preserving the relative order of equivalent elements. - * @param first An iterator. - * @param last Another iterator. - * @param comp A comparison functor. - * @return Nothing. - * - * Sorts the elements in the range @p [first,last) in ascending order, - * such that @p comp(*(i+1),*i) is false for each iterator @p i in the - * range @p [first,last-1). - * - * The relative ordering of equivalent elements is preserved, so any two - * elements @p x and @p y in the range @p [first,last) such that - * @p comp(x,y) is false and @p comp(y,x) is false will have the same - * relative ordering after calling @p stable_sort(). - */ - template<typename _RandomAccessIter, typename _Compare> - inline void - stable_sort(_RandomAccessIter __first, _RandomAccessIter __last, _Compare __comp) - { - typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType; - typedef typename iterator_traits<_RandomAccessIter>::difference_type _DistanceType; - - // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< - _RandomAccessIter>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType, _ValueType>) - - _Temporary_buffer<_RandomAccessIter, _ValueType> buf(__first, __last); - if (buf.begin() == 0) - __inplace_stable_sort(__first, __last, __comp); - else - __stable_sort_adaptive(__first, __last, buf.begin(), _DistanceType(buf.size()), - __comp); - } - - /** * @brief Sort the smallest elements of a sequence. * @param first An iterator. * @param middle Another iterator. @@ -2501,24 +2255,27 @@ __result, __binary_pred, _IterType()); * @p [first,middle) such that @i precedes @j and @k is an iterator in * the range @p [middle,last) then @p *j<*i and @p *k<*i are both false. */ - template<typename _RandomAccessIter> + template<typename _RandomAccessIterator> void - partial_sort(_RandomAccessIter __first, - _RandomAccessIter __middle, - _RandomAccessIter __last) + partial_sort(_RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last) { - typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< - _RandomAccessIter>) - __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>) - - make_heap(__first, __middle); - for (_RandomAccessIter __i = __middle; __i < __last; ++__i) + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); + + std::make_heap(__first, __middle); + for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) if (*__i < *__first) - __pop_heap(__first, __middle, __i, _ValueType(*__i)); - sort_heap(__first, __middle); + std::__pop_heap(__first, __middle, __i, _ValueType(*__i)); + std::sort_heap(__first, __middle); } /** @@ -2539,26 +2296,29 @@ __result, __binary_pred, _IterType()); * the range @p [middle,last) then @p *comp(j,*i) and @p comp(*k,*i) * are both false. */ - template<typename _RandomAccessIter, typename _Compare> + template<typename _RandomAccessIterator, typename _Compare> void - partial_sort(_RandomAccessIter __first, - _RandomAccessIter __middle, - _RandomAccessIter __last, + partial_sort(_RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, _Compare __comp) { - typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< - _RandomAccessIter>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType, _ValueType>) + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _ValueType>) + __glibcxx_requires_valid_range(__first, __middle); + __glibcxx_requires_valid_range(__middle, __last); - make_heap(__first, __middle, __comp); - for (_RandomAccessIter __i = __middle; __i < __last; ++__i) + std::make_heap(__first, __middle, __comp); + for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) if (__comp(*__i, *__first)) - __pop_heap(__first, __middle, __i, _ValueType(*__i), __comp); - sort_heap(__first, __middle, __comp); + std::__pop_heap(__first, __middle, __i, _ValueType(*__i), __comp); + std::sort_heap(__first, __middle, __comp); } /** @@ -2578,38 +2338,48 @@ __result, __binary_pred, _IterType()); * @p *j<*i is false. * The value returned is @p result_first+N. */ - template<typename _InputIter, typename _RandomAccessIter> - _RandomAccessIter - partial_sort_copy(_InputIter __first, _InputIter __last, - _RandomAccessIter __result_first, - _RandomAccessIter __result_last) - { - typedef typename iterator_traits<_InputIter>::value_type _InputValueType; - typedef typename iterator_traits<_RandomAccessIter>::value_type _OutputValueType; - typedef typename iterator_traits<_RandomAccessIter>::difference_type _DistanceType; + template<typename _InputIterator, typename _RandomAccessIterator> + _RandomAccessIterator + partial_sort_copy(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __result_first, + _RandomAccessIterator __result_last) + { + typedef typename iterator_traits<_InputIterator>::value_type + _InputValueType; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _OutputValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_ConvertibleConcept<_InputValueType, _OutputValueType>) - __glibcpp_function_requires(_LessThanComparableConcept<_OutputValueType>) - __glibcpp_function_requires(_LessThanComparableConcept<_InputValueType>) - - 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, _DistanceType(0), - _DistanceType(__result_real_last - __result_first), - _InputValueType(*__first)); - ++__first; - } - sort_heap(__result_first, __result_real_last); + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, + _OutputValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_OutputValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_InputValueType>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__result_first, __result_last); + + 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; + } + std::make_heap(__result_first, __result_real_last); + while (__first != __last) + { + if (*__first < *__result_first) + std::__adjust_heap(__result_first, _DistanceType(0), + _DistanceType(__result_real_last + - __result_first), + _InputValueType(*__first)); + ++__first; + } + std::sort_heap(__result_first, __result_real_last); return __result_real_last; } @@ -2632,173 +2402,246 @@ __result, __binary_pred, _IterType()); * @p comp(*j,*i) is false. * The value returned is @p result_first+N. */ - template<typename _InputIter, typename _RandomAccessIter, typename _Compare> - _RandomAccessIter - partial_sort_copy(_InputIter __first, _InputIter __last, - _RandomAccessIter __result_first, - _RandomAccessIter __result_last, + template<typename _InputIterator, typename _RandomAccessIterator, typename _Compare> + _RandomAccessIterator + partial_sort_copy(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __result_first, + _RandomAccessIterator __result_last, _Compare __comp) { - typedef typename iterator_traits<_InputIter>::value_type _InputValueType; - typedef typename iterator_traits<_RandomAccessIter>::value_type _OutputValueType; - typedef typename iterator_traits<_RandomAccessIter>::difference_type _DistanceType; + typedef typename iterator_traits<_InputIterator>::value_type + _InputValueType; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _OutputValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<_RandomAccessIter>) - __glibcpp_function_requires(_ConvertibleConcept<_InputValueType, _OutputValueType>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, + _OutputValueType>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _OutputValueType, _OutputValueType>) - - 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, _DistanceType(0), - _DistanceType(__result_real_last - __result_first), - _InputValueType(*__first), - __comp); - ++__first; - } - sort_heap(__result_first, __result_real_last, __comp); + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__result_first, __result_last); + + 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; + } + std::make_heap(__result_first, __result_real_last, __comp); + while (__first != __last) + { + if (__comp(*__first, *__result_first)) + std::__adjust_heap(__result_first, _DistanceType(0), + _DistanceType(__result_real_last + - __result_first), + _InputValueType(*__first), + __comp); + ++__first; + } + std::sort_heap(__result_first, __result_real_last, __comp); return __result_real_last; } /** - * @brief Sort a sequence just enough to find a particular position. + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template<typename _RandomAccessIterator, typename _Size> + void + __introsort_loop(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Size __depth_limit) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + while (__last - __first > _S_threshold) + { + if (__depth_limit == 0) + { + std::partial_sort(__first, __last, __last); + return; + } + --__depth_limit; + _RandomAccessIterator __cut = + std::__unguarded_partition(__first, __last, + _ValueType(std::__median(*__first, + *(__first + + (__last + - __first) + / 2), + *(__last + - 1)))); + std::__introsort_loop(__cut, __last, __depth_limit); + __last = __cut; + } + } + + /** + * @if maint + * This is a helper function for the sort routine. + * @endif + */ + template<typename _RandomAccessIterator, typename _Size, typename _Compare> + void + __introsort_loop(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Size __depth_limit, _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + while (__last - __first > _S_threshold) + { + if (__depth_limit == 0) + { + std::partial_sort(__first, __last, __last, __comp); + return; + } + --__depth_limit; + _RandomAccessIterator __cut = + std::__unguarded_partition(__first, __last, + _ValueType(std::__median(*__first, + *(__first + + (__last + - __first) + / 2), + *(__last - 1), + __comp)), + __comp); + std::__introsort_loop(__cut, __last, __depth_limit, __comp); + __last = __cut; + } + } + + /** + * @brief Sort the elements of a sequence. * @param first An iterator. - * @param nth Another iterator. * @param last Another iterator. * @return Nothing. * - * Rearranges the elements in the range @p [first,last) so that @p *nth - * is the same element that would have been in that position had the - * whole sequence been sorted. - * whole sequence been sorted. The elements either side of @p *nth are - * not completely sorted, but for any iterator @i in the range - * @p [first,nth) and any iterator @j in the range @p [nth,last) it - * holds that @p *j<*i is false. + * Sorts the elements in the range @p [first,last) in ascending order, + * such that @p *(i+1)<*i is false for each iterator @p i in the range + * @p [first,last-1). + * + * The relative ordering of equivalent elements is not preserved, use + * @p stable_sort() if this is needed. */ - template<typename _RandomAccessIter> - void - nth_element(_RandomAccessIter __first, - _RandomAccessIter __nth, - _RandomAccessIter __last) + template<typename _RandomAccessIterator> + inline void + sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { - typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<_RandomAccessIter>) - __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>) - - while (__last - __first > 3) { - _RandomAccessIter __cut = - __unguarded_partition(__first, __last, - _ValueType(__median(*__first, - *(__first + (__last - __first)/2), - *(__last - 1)))); - if (__cut <= __nth) - __first = __cut; - else - __last = __cut; - } - __insertion_sort(__first, __last); + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first != __last) + { + std::__introsort_loop(__first, __last, __lg(__last - __first) * 2); + std::__final_insertion_sort(__first, __last); + } } /** - * @brief Sort a sequence just enough to find a particular position - * using a predicate for comparison. + * @brief Sort the elements of a sequence using a predicate for comparison. * @param first An iterator. - * @param nth Another iterator. * @param last Another iterator. * @param comp A comparison functor. * @return Nothing. * - * Rearranges the elements in the range @p [first,last) so that @p *nth - * is the same element that would have been in that position had the - * whole sequence been sorted. The elements either side of @p *nth are - * not completely sorted, but for any iterator @i in the range - * @p [first,nth) and any iterator @j in the range @p [nth,last) it - * holds that @p comp(*j,*i) is false. + * Sorts the elements in the range @p [first,last) in ascending order, + * such that @p comp(*(i+1),*i) is false for every iterator @p i in the + * range @p [first,last-1). + * + * The relative ordering of equivalent elements is not preserved, use + * @p stable_sort() if this is needed. */ - template<typename _RandomAccessIter, typename _Compare> - void - nth_element(_RandomAccessIter __first, - _RandomAccessIter __nth, - _RandomAccessIter __last, - _Compare __comp) + template<typename _RandomAccessIterator, typename _Compare> + inline void + sort(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) { - typedef typename iterator_traits<_RandomAccessIter>::value_type _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept<_RandomAccessIter>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, - _ValueType, _ValueType>) - - while (__last - __first > 3) { - _RandomAccessIter __cut = - __unguarded_partition(__first, __last, - _ValueType(__median(*__first, - *(__first + (__last - __first)/2), - *(__last - 1), - __comp)), + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, + _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__first != __last) + { + std::__introsort_loop(__first, __last, __lg(__last - __first) * 2, __comp); - if (__cut <= __nth) - __first = __cut; - else - __last = __cut; - } - __insertion_sort(__first, __last, __comp); + std::__final_insertion_sort(__first, __last, __comp); + } } - /** * @brief Finds the first position in which @a val could be inserted * without changing the ordering. * @param first An iterator. * @param last Another iterator. * @param val The search term. - * @return An iterator pointing to the first element "not less than" @a val. + * @return An iterator pointing to the first element "not less than" @a val, + * or end() if every element is less than @a val. * @ingroup binarysearch */ - template<typename _ForwardIter, typename _Tp> - _ForwardIter - lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) + template<typename _ForwardIterator, typename _Tp> + _ForwardIterator + lower_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val) { - typedef typename iterator_traits<_ForwardIter>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType; + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; // concept requirements // Note that these are slightly stricter than those of the 4-argument // version, defined next. The difference is in the strictness of the // comparison operations... so for looser checking, define your own // comparison function, as was intended. - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_SameTypeConcept<_Tp, _ValueType>) - __glibcpp_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_SameTypeConcept<_Tp, _ValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_requires_partitioned(__first, __last, __val); - _DistanceType __len = distance(__first, __last); + _DistanceType __len = std::distance(__first, __last); _DistanceType __half; - _ForwardIter __middle; - - while (__len > 0) { - __half = __len >> 1; - __middle = __first; - advance(__middle, __half); - if (*__middle < __val) { - __first = __middle; - ++__first; - __len = __len - __half - 1; + _ForwardIterator __middle; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (*__middle < __val) + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else + __len = __half; } - else - __len = __half; - } return __first; } @@ -2809,40 +2652,47 @@ __result, __binary_pred, _IterType()); * @param last Another iterator. * @param val The search term. * @param comp A functor to use for comparisons. - * @return An iterator pointing to the first element "not less than" @a val. + * @return An iterator pointing to the first element "not less than" @a val, + * or end() if every element is less than @a val. * @ingroup binarysearch * * The comparison function should have the same effects on ordering as * the function used for the initial sort. */ - template<typename _ForwardIter, typename _Tp, typename _Compare> - _ForwardIter - lower_bound(_ForwardIter __first, _ForwardIter __last, + template<typename _ForwardIterator, typename _Tp, typename _Compare> + _ForwardIterator + lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val, _Compare __comp) { - typedef typename iterator_traits<_ForwardIter>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType; + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, _Tp>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _Tp>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); - _DistanceType __len = distance(__first, __last); + _DistanceType __len = std::distance(__first, __last); _DistanceType __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; + _ForwardIterator __middle; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (__comp(*__middle, __val)) + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else + __len = __half; } - else - __len = __half; - } return __first; } @@ -2852,38 +2702,45 @@ __result, __binary_pred, _IterType()); * @param first An iterator. * @param last Another iterator. * @param val The search term. - * @return An iterator pointing to the first element greater than @a val. + * @return An iterator pointing to the first element greater than @a val, + * or end() if no elements are greater than @a val. * @ingroup binarysearch */ - template<typename _ForwardIter, typename _Tp> - _ForwardIter - upper_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) + template<typename _ForwardIterator, typename _Tp> + _ForwardIterator + upper_bound(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val) { - typedef typename iterator_traits<_ForwardIter>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType; + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; // concept requirements // See comments on lower_bound. - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_SameTypeConcept<_Tp, _ValueType>) - __glibcpp_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_SameTypeConcept<_Tp, _ValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_requires_partitioned(__first, __last, __val); - _DistanceType __len = distance(__first, __last); + _DistanceType __len = std::distance(__first, __last); _DistanceType __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; + _ForwardIterator __middle; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (__val < *__middle) + __len = __half; + else + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } } - } return __first; } @@ -2894,208 +2751,193 @@ __result, __binary_pred, _IterType()); * @param last Another iterator. * @param val The search term. * @param comp A functor to use for comparisons. - * @return An iterator pointing to the first element greater than @a val. + * @return An iterator pointing to the first element greater than @a val, + * or end() if no elements are greater than @a val. * @ingroup binarysearch * * The comparison function should have the same effects on ordering as * the function used for the initial sort. */ - template<typename _ForwardIter, typename _Tp, typename _Compare> - _ForwardIter - upper_bound(_ForwardIter __first, _ForwardIter __last, + template<typename _ForwardIterator, typename _Tp, typename _Compare> + _ForwardIterator + upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val, _Compare __comp) { - typedef typename iterator_traits<_ForwardIter>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType; + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, _Tp, _ValueType>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _Tp, _ValueType>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); - _DistanceType __len = distance(__first, __last); + _DistanceType __len = std::distance(__first, __last); _DistanceType __half; - _ForwardIter __middle; - - while (__len > 0) { - __half = __len >> 1; - __middle = __first; - advance(__middle, __half); - if (__comp(__val, *__middle)) - __len = __half; - else { - __first = __middle; - ++__first; - __len = __len - __half - 1; + _ForwardIterator __middle; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (__comp(__val, *__middle)) + __len = __half; + else + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } } - } return __first; } /** - * @brief Finds the largest subrange in which @a val could be inserted - * at any place in it without changing the ordering. - * @param first An iterator. - * @param last Another iterator. - * @param val The search term. - * @return An pair of iterators defining the subrange. - * @ingroup binarysearch - * - * This is equivalent to - * @code - * std::make_pair(lower_bound(first, last, val), - * upper_bound(first, last, val)) - * @endcode - * but does not actually call those functions. + * @if maint + * This is a helper function for the merge routines. + * @endif */ - template<typename _ForwardIter, typename _Tp> - pair<_ForwardIter, _ForwardIter> - equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) + template<typename _BidirectionalIterator, typename _Distance> + void + __merge_without_buffer(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Distance __len1, _Distance __len2) { - typedef typename iterator_traits<_ForwardIter>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType; - - // concept requirements - // See comments on lower_bound. - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_SameTypeConcept<_Tp, _ValueType>) - __glibcpp_function_requires(_LessThanComparableConcept<_Tp>) - - _DistanceType __len = distance(__first, __last); - _DistanceType __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; + if (__len1 == 0 || __len2 == 0) + return; + if (__len1 + __len2 == 2) + { + if (*__middle < *__first) + std::iter_swap(__first, __middle); + return; } - else if (__val < *__middle) - __len = __half; - else { - __left = lower_bound(__first, __middle, __val); - advance(__first, __len); - __right = upper_bound(++__middle, __first, __val); - return pair<_ForwardIter, _ForwardIter>(__left, __right); + _BidirectionalIterator __first_cut = __first; + _BidirectionalIterator __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) + { + __len11 = __len1 / 2; + std::advance(__first_cut, __len11); + __second_cut = std::lower_bound(__middle, __last, *__first_cut); + __len22 = std::distance(__middle, __second_cut); } - } - return pair<_ForwardIter, _ForwardIter>(__first, __first); + else + { + __len22 = __len2 / 2; + std::advance(__second_cut, __len22); + __first_cut = std::upper_bound(__first, __middle, *__second_cut); + __len11 = std::distance(__first, __first_cut); + } + std::rotate(__first_cut, __middle, __second_cut); + _BidirectionalIterator __new_middle = __first_cut; + std::advance(__new_middle, std::distance(__middle, __second_cut)); + std::__merge_without_buffer(__first, __first_cut, __new_middle, + __len11, __len22); + std::__merge_without_buffer(__new_middle, __second_cut, __last, + __len1 - __len11, __len2 - __len22); } /** - * @brief Finds the largest subrange in which @a val could be inserted - * at any place in it without changing the ordering. - * @param first An iterator. - * @param last Another iterator. - * @param val The search term. - * @param comp A functor to use for comparisons. - * @return An pair of iterators defining the subrange. - * @ingroup binarysearch - * - * This is equivalent to - * @code - * std::make_pair(lower_bound(first, last, val, comp), - * upper_bound(first, last, val, comp)) - * @endcode - * but does not actually call those functions. + * @if maint + * This is a helper function for the merge routines. + * @endif */ - template<typename _ForwardIter, typename _Tp, typename _Compare> - pair<_ForwardIter, _ForwardIter> - equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, - _Compare __comp) + template<typename _BidirectionalIterator, typename _Distance, + typename _Compare> + void + __merge_without_buffer(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Distance __len1, _Distance __len2, + _Compare __comp) { - typedef typename iterator_traits<_ForwardIter>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIter>::difference_type _DistanceType; - - // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, _Tp>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, _Tp, _ValueType>) - - _DistanceType __len = distance(__first, __last); - _DistanceType __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; + if (__len1 == 0 || __len2 == 0) + return; + if (__len1 + __len2 == 2) + { + if (__comp(*__middle, *__first)) + std::iter_swap(__first, __middle); + return; } - else if (__comp(__val, *__middle)) - __len = __half; - else { - __left = lower_bound(__first, __middle, __val, __comp); - advance(__first, __len); - __right = upper_bound(++__middle, __first, __val, __comp); - return pair<_ForwardIter, _ForwardIter>(__left, __right); + _BidirectionalIterator __first_cut = __first; + _BidirectionalIterator __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) + { + __len11 = __len1 / 2; + std::advance(__first_cut, __len11); + __second_cut = std::lower_bound(__middle, __last, *__first_cut, + __comp); + __len22 = std::distance(__middle, __second_cut); + } + else + { + __len22 = __len2 / 2; + std::advance(__second_cut, __len22); + __first_cut = std::upper_bound(__first, __middle, *__second_cut, + __comp); + __len11 = std::distance(__first, __first_cut); } - } - return pair<_ForwardIter, _ForwardIter>(__first, __first); + std::rotate(__first_cut, __middle, __second_cut); + _BidirectionalIterator __new_middle = __first_cut; + std::advance(__new_middle, std::distance(__middle, __second_cut)); + std::__merge_without_buffer(__first, __first_cut, __new_middle, + __len11, __len22, __comp); + std::__merge_without_buffer(__new_middle, __second_cut, __last, + __len1 - __len11, __len2 - __len22, __comp); } /** - * @brief Determines whether an element exists in a range. - * @param first An iterator. - * @param last Another iterator. - * @param val The search term. - * @return True if @a val (or its equivelent) is in [@a first,@a last ]. - * @ingroup binarysearch - * - * Note that this does not actually return an iterator to @a val. For - * that, use std::find or a container's specialized find member functions. + * @if maint + * This is a helper function for the stable sorting routines. + * @endif */ - template<typename _ForwardIter, typename _Tp> - bool - binary_search(_ForwardIter __first, _ForwardIter __last, - const _Tp& __val) + template<typename _RandomAccessIterator> + void + __inplace_stable_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last) { - // concept requirements - // See comments on lower_bound. - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_SameTypeConcept<_Tp, - typename iterator_traits<_ForwardIter>::value_type>) - __glibcpp_function_requires(_LessThanComparableConcept<_Tp>) - - _ForwardIter __i = lower_bound(__first, __last, __val); - return __i != __last && !(__val < *__i); + if (__last - __first < 15) + { + std::__insertion_sort(__first, __last); + return; + } + _RandomAccessIterator __middle = __first + (__last - __first) / 2; + std::__inplace_stable_sort(__first, __middle); + std::__inplace_stable_sort(__middle, __last); + std::__merge_without_buffer(__first, __middle, __last, + __middle - __first, + __last - __middle); } /** - * @brief Determines whether an element exists in a range. - * @param first An iterator. - * @param last Another iterator. - * @param val The search term. - * @param comp A functor to use for comparisons. - * @return True if @a val (or its equivelent) is in [@a first,@a last ]. - * @ingroup binarysearch - * - * Note that this does not actually return an iterator to @a val. For - * that, use std::find or a container's specialized find member functions. - * - * The comparison function should have the same effects on ordering as - * the function used for the initial sort. + * @if maint + * This is a helper function for the stable sorting routines. + * @endif */ - template<typename _ForwardIter, typename _Tp, typename _Compare> - bool - binary_search(_ForwardIter __first, _ForwardIter __last, - const _Tp& __val, _Compare __comp) + template<typename _RandomAccessIterator, typename _Compare> + void + __inplace_stable_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) { - // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, - typename iterator_traits<_ForwardIter>::value_type, _Tp>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, _Tp, - typename iterator_traits<_ForwardIter>::value_type>) - - _ForwardIter __i = lower_bound(__first, __last, __val, __comp); - return __i != __last && !__comp(__val, *__i); + if (__last - __first < 15) + { + std::__insertion_sort(__first, __last, __comp); + return; + } + _RandomAccessIterator __middle = __first + (__last - __first) / 2; + std::__inplace_stable_sort(__first, __middle, __comp); + std::__inplace_stable_sort(__middle, __last, __comp); + std::__merge_without_buffer(__first, __middle, __last, + __middle - __first, + __last - __middle, + __comp); } /** @@ -3114,35 +2956,42 @@ __result, __binary_pred, _IterType()); * elements in the two ranges, elements from the first range will always * come before elements from the second. */ - template<typename _InputIter1, typename _InputIter2, typename _OutputIter> - _OutputIter - merge(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, _InputIter2 __last2, - _OutputIter __result) + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator> + _OutputIterator + merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_InputIter1>::value_type>) - __glibcpp_function_requires(_SameTypeConcept< - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) - __glibcpp_function_requires(_LessThanComparableConcept< - typename iterator_traits<_InputIter1>::value_type>) - - while (__first1 != __last1 && __first2 != __last2) { - if (*__first2 < *__first1) { - *__result = *__first2; - ++__first2; - } - else { - *__result = *__first1; - ++__first1; + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + { + if (*__first2 < *__first1) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + } + ++__result; } - ++__result; - } - return copy(__first2, __last2, copy(__first1, __last1, __result)); + return std::copy(__first2, __last2, std::copy(__first1, __last1, + __result)); } /** @@ -3165,159 +3014,172 @@ __result, __binary_pred, _IterType()); * The comparison function should have the same effects on ordering as * the function used for the initial sort. */ - template<typename _InputIter1, typename _InputIter2, typename _OutputIter, - typename _Compare> - _OutputIter - merge(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, _InputIter2 __last2, - _OutputIter __result, _Compare __comp) + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, typename _Compare> + _OutputIterator + merge(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) - __glibcpp_function_requires(_SameTypeConcept< - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_InputIter1>::value_type>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) - - while (__first1 != __last1 && __first2 != __last2) { - if (__comp(*__first2, *__first1)) { - *__result = *__first2; - ++__first2; + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + { + if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + } + ++__result; } - else { - *__result = *__first1; - ++__first1; + return std::copy(__first2, __last2, std::copy(__first1, __last1, + __result)); + } + + template<typename _RandomAccessIterator1, typename _RandomAccessIterator2, + typename _Distance> + void + __merge_sort_loop(_RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, + _Distance __step_size) + { + const _Distance __two_step = 2 * __step_size; + + while (__last - __first >= __two_step) + { + __result = std::merge(__first, __first + __step_size, + __first + __step_size, __first + __two_step, + __result); + __first += __two_step; } - ++__result; - } - return copy(__first2, __last2, copy(__first1, __last1, __result)); + + __step_size = std::min(_Distance(__last - __first), __step_size); + std::merge(__first, __first + __step_size, __first + __step_size, __last, + __result); } - /** - * @if maint - * This is a helper function for the merge routines. - * @endif - */ - template<typename _BidirectionalIter, typename _Distance> + template<typename _RandomAccessIterator1, typename _RandomAccessIterator2, + typename _Distance, typename _Compare> void - __merge_without_buffer(_BidirectionalIter __first, - _BidirectionalIter __middle, - _BidirectionalIter __last, - _Distance __len1, _Distance __len2) + __merge_sort_loop(_RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, _Distance __step_size, + _Compare __comp) { - if (__len1 == 0 || __len2 == 0) - return; - if (__len1 + __len2 == 2) { - if (*__middle < *__first) - iter_swap(__first, __middle); - return; - } - _BidirectionalIter __first_cut = __first; - _BidirectionalIter __second_cut = __middle; - _Distance __len11 = 0; - _Distance __len22 = 0; - if (__len1 > __len2) { - __len11 = __len1 / 2; - advance(__first_cut, __len11); - __second_cut = lower_bound(__middle, __last, *__first_cut); - __len22 = distance(__middle, __second_cut); - } - else { - __len22 = __len2 / 2; - advance(__second_cut, __len22); - __first_cut = upper_bound(__first, __middle, *__second_cut); - __len11 = distance(__first, __first_cut); - } - rotate(__first_cut, __middle, __second_cut); - _BidirectionalIter __new_middle = __first_cut; - advance(__new_middle, distance(__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); + const _Distance __two_step = 2 * __step_size; + + while (__last - __first >= __two_step) + { + __result = std::merge(__first, __first + __step_size, + __first + __step_size, __first + __two_step, + __result, + __comp); + __first += __two_step; + } + __step_size = std::min(_Distance(__last - __first), __step_size); + + std::merge(__first, __first + __step_size, + __first + __step_size, __last, + __result, + __comp); } - /** - * @if maint - * This is a helper function for the merge routines. - * @endif - */ - template<typename _BidirectionalIter, typename _Distance, typename _Compare> + enum { _S_chunk_size = 7 }; + + template<typename _RandomAccessIterator, typename _Distance> void - __merge_without_buffer(_BidirectionalIter __first, - _BidirectionalIter __middle, - _BidirectionalIter __last, - _Distance __len1, _Distance __len2, - _Compare __comp) + __chunk_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Distance __chunk_size) { - if (__len1 == 0 || __len2 == 0) - return; - if (__len1 + __len2 == 2) { - if (__comp(*__middle, *__first)) - iter_swap(__first, __middle); - return; - } - _BidirectionalIter __first_cut = __first; - _BidirectionalIter __second_cut = __middle; - _Distance __len11 = 0; - _Distance __len22 = 0; - if (__len1 > __len2) { - __len11 = __len1 / 2; - advance(__first_cut, __len11); - __second_cut = lower_bound(__middle, __last, *__first_cut, __comp); - __len22 = distance(__middle, __second_cut); - } - else { - __len22 = __len2 / 2; - advance(__second_cut, __len22); - __first_cut = upper_bound(__first, __middle, *__second_cut, __comp); - __len11 = distance(__first, __first_cut); - } - rotate(__first_cut, __middle, __second_cut); - _BidirectionalIter __new_middle = __first_cut; - advance(__new_middle, distance(__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); + while (__last - __first >= __chunk_size) + { + std::__insertion_sort(__first, __first + __chunk_size); + __first += __chunk_size; + } + std::__insertion_sort(__first, __last); } - /** - * @if maint - * This is a helper function for the merge routines. - * @endif - */ - template<typename _BidirectionalIter1, typename _BidirectionalIter2, - typename _Distance> - _BidirectionalIter1 - __rotate_adaptive(_BidirectionalIter1 __first, - _BidirectionalIter1 __middle, - _BidirectionalIter1 __last, - _Distance __len1, _Distance __len2, - _BidirectionalIter2 __buffer, - _Distance __buffer_size) + template<typename _RandomAccessIterator, typename _Distance, typename _Compare> + void + __chunk_insertion_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Distance __chunk_size, _Compare __comp) { - _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 { - rotate(__first, __middle, __last); - advance(__first, distance(__middle, __last)); - return __first; - } + while (__last - __first >= __chunk_size) + { + std::__insertion_sort(__first, __first + __chunk_size, __comp); + __first += __chunk_size; + } + std::__insertion_sort(__first, __last, __comp); + } + + template<typename _RandomAccessIterator, typename _Pointer> + void + __merge_sort_with_buffer(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Pointer __buffer) + { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + + const _Distance __len = __last - __first; + const _Pointer __buffer_last = __buffer + __len; + + _Distance __step_size = _S_chunk_size; + std::__chunk_insertion_sort(__first, __last, __step_size); + + while (__step_size < __len) + { + std::__merge_sort_loop(__first, __last, __buffer, __step_size); + __step_size *= 2; + std::__merge_sort_loop(__buffer, __buffer_last, __first, __step_size); + __step_size *= 2; + } + } + + template<typename _RandomAccessIterator, typename _Pointer, typename _Compare> + void + __merge_sort_with_buffer(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Pointer __buffer, _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; + + const _Distance __len = __last - __first; + const _Pointer __buffer_last = __buffer + __len; + + _Distance __step_size = _S_chunk_size; + std::__chunk_insertion_sort(__first, __last, __step_size, __comp); + + while (__step_size < __len) + { + std::__merge_sort_loop(__first, __last, __buffer, + __step_size, __comp); + __step_size *= 2; + std::__merge_sort_loop(__buffer, __buffer_last, __first, + __step_size, __comp); + __step_size *= 2; + } } /** @@ -3325,33 +3187,38 @@ __result, __binary_pred, _IterType()); * This is a helper function for the merge routines. * @endif */ - template<typename _BidirectionalIter1, typename _BidirectionalIter2, - typename _BidirectionalIter3> - _BidirectionalIter3 - __merge_backward(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, - _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, - _BidirectionalIter3 __result) + template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, + typename _BidirectionalIterator3> + _BidirectionalIterator3 + __merge_backward(_BidirectionalIterator1 __first1, + _BidirectionalIterator1 __last1, + _BidirectionalIterator2 __first2, + _BidirectionalIterator2 __last2, + _BidirectionalIterator3 __result) { if (__first1 == __last1) - return copy_backward(__first2, __last2, __result); + return std::copy_backward(__first2, __last2, __result); if (__first2 == __last2) - return copy_backward(__first1, __last1, __result); + return std::copy_backward(__first1, __last1, __result); --__last1; --__last2; - while (true) { - if (*__last2 < *__last1) { - *--__result = *__last1; - if (__first1 == __last1) - return copy_backward(__first2, ++__last2, __result); - --__last1; - } - else { - *--__result = *__last2; - if (__first2 == __last2) - return copy_backward(__first1, ++__last1, __result); - --__last2; + while (true) + { + if (*__last2 < *__last1) + { + *--__result = *__last1; + if (__first1 == __last1) + return std::copy_backward(__first2, ++__last2, __result); + --__last1; + } + else + { + *--__result = *__last2; + if (__first2 == __last2) + return std::copy_backward(__first1, ++__last1, __result); + --__last2; + } } - } } /** @@ -3359,34 +3226,75 @@ __result, __binary_pred, _IterType()); * This is a helper function for the merge routines. * @endif */ - template<typename _BidirectionalIter1, typename _BidirectionalIter2, - typename _BidirectionalIter3, typename _Compare> - _BidirectionalIter3 - __merge_backward(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, - _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, - _BidirectionalIter3 __result, + template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, + typename _BidirectionalIterator3, typename _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); + return std::copy_backward(__first2, __last2, __result); if (__first2 == __last2) - return copy_backward(__first1, __last1, __result); + return std::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; + while (true) + { + if (__comp(*__last2, *__last1)) + { + *--__result = *__last1; + if (__first1 == __last1) + return std::copy_backward(__first2, ++__last2, __result); + --__last1; + } + else + { + *--__result = *__last2; + if (__first2 == __last2) + return std::copy_backward(__first1, ++__last1, __result); + --__last2; + } } - else { - *--__result = *__last2; - if (__first2 == __last2) - return copy_backward(__first1, ++__last1, __result); - --__last2; + } + + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ + template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, + typename _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 = std::copy(__middle, __last, __buffer); + std::copy_backward(__first, __middle, __last); + return std::copy(__buffer, __buffer_end, __first); + } + else if (__len1 <= __buffer_size) + { + __buffer_end = std::copy(__first, __middle, __buffer); + std::copy(__middle, __last, __first); + return std::copy_backward(__buffer, __buffer_end, __last); + } + else + { + std::rotate(__first, __middle, __last); + std::advance(__first, std::distance(__middle, __last)); + return __first; } - } } /** @@ -3394,48 +3302,58 @@ __result, __binary_pred, _IterType()); * This is a helper function for the merge routines. * @endif */ - template<typename _BidirectionalIter, typename _Distance, typename _Pointer> + template<typename _BidirectionalIterator, typename _Distance, + typename _Pointer> void - __merge_adaptive(_BidirectionalIter __first, - _BidirectionalIter __middle, - _BidirectionalIter __last, + __merge_adaptive(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, _Distance __len1, _Distance __len2, _Pointer __buffer, _Distance __buffer_size) { - if (__len1 <= __len2 && __len1 <= __buffer_size) { - _Pointer __buffer_end = copy(__first, __middle, __buffer); - merge(__buffer, __buffer_end, __middle, __last, __first); - } - else if (__len2 <= __buffer_size) { - _Pointer __buffer_end = copy(__middle, __last, __buffer); - __merge_backward(__first, __middle, __buffer, __buffer_end, __last); - } - else { - _BidirectionalIter __first_cut = __first; - _BidirectionalIter __second_cut = __middle; - _Distance __len11 = 0; - _Distance __len22 = 0; - if (__len1 > __len2) { - __len11 = __len1 / 2; - advance(__first_cut, __len11); - __second_cut = lower_bound(__middle, __last, *__first_cut); - __len22 = distance(__middle, __second_cut); + if (__len1 <= __len2 && __len1 <= __buffer_size) + { + _Pointer __buffer_end = std::copy(__first, __middle, __buffer); + std::merge(__buffer, __buffer_end, __middle, __last, __first); + } + else if (__len2 <= __buffer_size) + { + _Pointer __buffer_end = std::copy(__middle, __last, __buffer); + std::__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; + std::advance(__first_cut, __len11); + __second_cut = std::lower_bound(__middle, __last, + *__first_cut); + __len22 = std::distance(__middle, __second_cut); } - else { - __len22 = __len2 / 2; - advance(__second_cut, __len22); - __first_cut = upper_bound(__first, __middle, *__second_cut); - __len11 = distance(__first, __first_cut); + else + { + __len22 = __len2 / 2; + std::advance(__second_cut, __len22); + __first_cut = std::upper_bound(__first, __middle, + *__second_cut); + __len11 = std::distance(__first, __first_cut); } - _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); - } + _BidirectionalIterator __new_middle = + std::__rotate_adaptive(__first_cut, __middle, __second_cut, + __len1 - __len11, __len22, __buffer, + __buffer_size); + std::__merge_adaptive(__first, __first_cut, __new_middle, __len11, + __len22, __buffer, __buffer_size); + std::__merge_adaptive(__new_middle, __second_cut, __last, + __len1 - __len11, + __len2 - __len22, __buffer, __buffer_size); + } } /** @@ -3443,51 +3361,60 @@ __result, __binary_pred, _IterType()); * This is a helper function for the merge routines. * @endif */ - template<typename _BidirectionalIter, typename _Distance, typename _Pointer, + template<typename _BidirectionalIterator, typename _Distance, typename _Pointer, typename _Compare> void - __merge_adaptive(_BidirectionalIter __first, - _BidirectionalIter __middle, - _BidirectionalIter __last, + __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 __buffer_end = copy(__first, __middle, __buffer); - merge(__buffer, __buffer_end, __middle, __last, __first, __comp); - } - else if (__len2 <= __buffer_size) { - _Pointer __buffer_end = copy(__middle, __last, __buffer); - __merge_backward(__first, __middle, __buffer, __buffer_end, __last, - __comp); - } - else { - _BidirectionalIter __first_cut = __first; - _BidirectionalIter __second_cut = __middle; - _Distance __len11 = 0; - _Distance __len22 = 0; - if (__len1 > __len2) { - __len11 = __len1 / 2; - advance(__first_cut, __len11); - __second_cut = lower_bound(__middle, __last, *__first_cut, __comp); - __len22 = distance(__middle, __second_cut); + if (__len1 <= __len2 && __len1 <= __buffer_size) + { + _Pointer __buffer_end = std::copy(__first, __middle, __buffer); + std::merge(__buffer, __buffer_end, __middle, __last, __first, __comp); + } + else if (__len2 <= __buffer_size) + { + _Pointer __buffer_end = std::copy(__middle, __last, __buffer); + std::__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; + std::advance(__first_cut, __len11); + __second_cut = std::lower_bound(__middle, __last, *__first_cut, + __comp); + __len22 = std::distance(__middle, __second_cut); } - else { - __len22 = __len2 / 2; - advance(__second_cut, __len22); - __first_cut = upper_bound(__first, __middle, *__second_cut, __comp); - __len11 = distance(__first, __first_cut); + else + { + __len22 = __len2 / 2; + std::advance(__second_cut, __len22); + __first_cut = std::upper_bound(__first, __middle, *__second_cut, + __comp); + __len11 = std::distance(__first, __first_cut); } - _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); - } + _BidirectionalIterator __new_middle = + std::__rotate_adaptive(__first_cut, __middle, __second_cut, + __len1 - __len11, __len22, __buffer, + __buffer_size); + std::__merge_adaptive(__first, __first_cut, __new_middle, __len11, + __len22, __buffer, __buffer_size, __comp); + std::__merge_adaptive(__new_middle, __second_cut, __last, + __len1 - __len11, + __len2 - __len22, __buffer, + __buffer_size, __comp); + } } /** @@ -3507,34 +3434,37 @@ __result, __binary_pred, _IterType()); * comparisons. Otherwise an NlogN algorithm is used, where N is * distance(first,last). */ - template<typename _BidirectionalIter> + template<typename _BidirectionalIterator> void - inplace_merge(_BidirectionalIter __first, - _BidirectionalIter __middle, - _BidirectionalIter __last) + inplace_merge(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last) { - typedef typename iterator_traits<_BidirectionalIter>::value_type + typedef typename iterator_traits<_BidirectionalIterator>::value_type _ValueType; - typedef typename iterator_traits<_BidirectionalIter>::difference_type + typedef typename iterator_traits<_BidirectionalIterator>::difference_type _DistanceType; // concept requirements - __glibcpp_function_requires(_Mutable_BidirectionalIteratorConcept< - _BidirectionalIter>) - __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_sorted(__first, __middle); + __glibcxx_requires_sorted(__middle, __last); if (__first == __middle || __middle == __last) return; - _DistanceType __len1 = distance(__first, __middle); - _DistanceType __len2 = distance(__middle, __last); + _DistanceType __len1 = std::distance(__first, __middle); + _DistanceType __len2 = std::distance(__middle, __last); - _Temporary_buffer<_BidirectionalIter, _ValueType> __buf(__first, __last); + _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first, + __last); if (__buf.begin() == 0) - __merge_without_buffer(__first, __middle, __last, __len1, __len2); + std::__merge_without_buffer(__first, __middle, __last, __len1, __len2); else - __merge_adaptive(__first, __middle, __last, __len1, __len2, - __buf.begin(), _DistanceType(__buf.size())); + std::__merge_adaptive(__first, __middle, __last, __len1, __len2, + __buf.begin(), _DistanceType(__buf.size())); } /** @@ -3558,37 +3488,468 @@ __result, __binary_pred, _IterType()); * The comparison function should have the same effects on ordering as * the function used for the initial sort. */ - template<typename _BidirectionalIter, typename _Compare> + template<typename _BidirectionalIterator, typename _Compare> void - inplace_merge(_BidirectionalIter __first, - _BidirectionalIter __middle, - _BidirectionalIter __last, + inplace_merge(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, _Compare __comp) { - typedef typename iterator_traits<_BidirectionalIter>::value_type + typedef typename iterator_traits<_BidirectionalIterator>::value_type _ValueType; - typedef typename iterator_traits<_BidirectionalIter>::difference_type + typedef typename iterator_traits<_BidirectionalIterator>::difference_type _DistanceType; // concept requirements - __glibcpp_function_requires(_Mutable_BidirectionalIteratorConcept< - _BidirectionalIter>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, _ValueType>) + __glibcxx_requires_sorted_pred(__first, __middle, __comp); + __glibcxx_requires_sorted_pred(__middle, __last, __comp); if (__first == __middle || __middle == __last) return; - _DistanceType __len1 = distance(__first, __middle); - _DistanceType __len2 = distance(__middle, __last); + const _DistanceType __len1 = std::distance(__first, __middle); + const _DistanceType __len2 = std::distance(__middle, __last); - _Temporary_buffer<_BidirectionalIter, _ValueType> __buf(__first, __last); + _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first, + __last); if (__buf.begin() == 0) - __merge_without_buffer(__first, __middle, __last, __len1, __len2, __comp); + std::__merge_without_buffer(__first, __middle, __last, __len1, + __len2, __comp); + else + std::__merge_adaptive(__first, __middle, __last, __len1, __len2, + __buf.begin(), _DistanceType(__buf.size()), + __comp); + } + + template<typename _RandomAccessIterator, typename _Pointer, + typename _Distance> + void + __stable_sort_adaptive(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Pointer __buffer, _Distance __buffer_size) + { + const _Distance __len = (__last - __first + 1) / 2; + const _RandomAccessIterator __middle = __first + __len; + if (__len > __buffer_size) + { + std::__stable_sort_adaptive(__first, __middle, + __buffer, __buffer_size); + std::__stable_sort_adaptive(__middle, __last, + __buffer, __buffer_size); + } else - __merge_adaptive(__first, __middle, __last, __len1, __len2, - __buf.begin(), _DistanceType(__buf.size()), - __comp); + { + std::__merge_sort_with_buffer(__first, __middle, __buffer); + std::__merge_sort_with_buffer(__middle, __last, __buffer); + } + std::__merge_adaptive(__first, __middle, __last, + _Distance(__middle - __first), + _Distance(__last - __middle), + __buffer, __buffer_size); + } + + template<typename _RandomAccessIterator, typename _Pointer, + typename _Distance, typename _Compare> + void + __stable_sort_adaptive(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Pointer __buffer, _Distance __buffer_size, + _Compare __comp) + { + const _Distance __len = (__last - __first + 1) / 2; + const _RandomAccessIterator __middle = __first + __len; + if (__len > __buffer_size) + { + std::__stable_sort_adaptive(__first, __middle, __buffer, + __buffer_size, __comp); + std::__stable_sort_adaptive(__middle, __last, __buffer, + __buffer_size, __comp); + } + else + { + std::__merge_sort_with_buffer(__first, __middle, __buffer, __comp); + std::__merge_sort_with_buffer(__middle, __last, __buffer, __comp); + } + std::__merge_adaptive(__first, __middle, __last, + _Distance(__middle - __first), + _Distance(__last - __middle), + __buffer, __buffer_size, + __comp); + } + + /** + * @brief Sort the elements of a sequence, preserving the relative order + * of equivalent elements. + * @param first An iterator. + * @param last Another iterator. + * @return Nothing. + * + * Sorts the elements in the range @p [first,last) in ascending order, + * such that @p *(i+1)<*i is false for each iterator @p i in the range + * @p [first,last-1). + * + * The relative ordering of equivalent elements is preserved, so any two + * elements @p x and @p y in the range @p [first,last) such that + * @p x<y is false and @p y<x is false will have the same relative + * ordering after calling @p stable_sort(). + */ + template<typename _RandomAccessIterator> + inline void + stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + _Temporary_buffer<_RandomAccessIterator, _ValueType> + buf(__first, __last); + if (buf.begin() == 0) + std::__inplace_stable_sort(__first, __last); + else + std::__stable_sort_adaptive(__first, __last, buf.begin(), + _DistanceType(buf.size())); + } + + /** + * @brief Sort the elements of a sequence using a predicate for comparison, + * preserving the relative order of equivalent elements. + * @param first An iterator. + * @param last Another iterator. + * @param comp A comparison functor. + * @return Nothing. + * + * Sorts the elements in the range @p [first,last) in ascending order, + * such that @p comp(*(i+1),*i) is false for each iterator @p i in the + * range @p [first,last-1). + * + * The relative ordering of equivalent elements is preserved, so any two + * elements @p x and @p y in the range @p [first,last) such that + * @p comp(x,y) is false and @p comp(y,x) is false will have the same + * relative ordering after calling @p stable_sort(). + */ + template<typename _RandomAccessIterator, typename _Compare> + inline void + stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, + _ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + _Temporary_buffer<_RandomAccessIterator, _ValueType> buf(__first, __last); + if (buf.begin() == 0) + std::__inplace_stable_sort(__first, __last, __comp); + else + std::__stable_sort_adaptive(__first, __last, buf.begin(), + _DistanceType(buf.size()), __comp); + } + + /** + * @brief Sort a sequence just enough to find a particular position. + * @param first An iterator. + * @param nth Another iterator. + * @param last Another iterator. + * @return Nothing. + * + * Rearranges the elements in the range @p [first,last) so that @p *nth + * is the same element that would have been in that position had the + * whole sequence been sorted. + * whole sequence been sorted. The elements either side of @p *nth are + * not completely sorted, but for any iterator @i in the range + * @p [first,nth) and any iterator @j in the range @p [nth,last) it + * holds that @p *j<*i is false. + */ + template<typename _RandomAccessIterator> + void + nth_element(_RandomAccessIterator __first, + _RandomAccessIterator __nth, + _RandomAccessIterator __last) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __nth); + __glibcxx_requires_valid_range(__nth, __last); + + while (__last - __first > 3) + { + _RandomAccessIterator __cut = + std::__unguarded_partition(__first, __last, + _ValueType(std::__median(*__first, + *(__first + + (__last + - __first) + / 2), + *(__last + - 1)))); + if (__cut <= __nth) + __first = __cut; + else + __last = __cut; + } + std::__insertion_sort(__first, __last); + } + + /** + * @brief Sort a sequence just enough to find a particular position + * using a predicate for comparison. + * @param first An iterator. + * @param nth Another iterator. + * @param last Another iterator. + * @param comp A comparison functor. + * @return Nothing. + * + * Rearranges the elements in the range @p [first,last) so that @p *nth + * is the same element that would have been in that position had the + * whole sequence been sorted. The elements either side of @p *nth are + * not completely sorted, but for any iterator @i in the range + * @p [first,nth) and any iterator @j in the range @p [nth,last) it + * holds that @p comp(*j,*i) is false. + */ + template<typename _RandomAccessIterator, typename _Compare> + void + nth_element(_RandomAccessIterator __first, + _RandomAccessIterator __nth, + _RandomAccessIterator __last, + _Compare __comp) + { + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + + // concept requirements + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _ValueType>) + __glibcxx_requires_valid_range(__first, __nth); + __glibcxx_requires_valid_range(__nth, __last); + + while (__last - __first > 3) + { + _RandomAccessIterator __cut = + std::__unguarded_partition(__first, __last, + _ValueType(std::__median(*__first, + *(__first + + (__last + - __first) + / 2), + *(__last - 1), + __comp)), __comp); + if (__cut <= __nth) + __first = __cut; + else + __last = __cut; + } + std::__insertion_sort(__first, __last, __comp); + } + + /** + * @brief Finds the largest subrange in which @a val could be inserted + * at any place in it without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @return An pair of iterators defining the subrange. + * @ingroup binarysearch + * + * This is equivalent to + * @code + * std::make_pair(lower_bound(first, last, val), + * upper_bound(first, last, val)) + * @endcode + * but does not actually call those functions. + */ + template<typename _ForwardIterator, typename _Tp> + pair<_ForwardIterator, _ForwardIterator> + equal_range(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + // See comments on lower_bound. + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_SameTypeConcept<_Tp, _ValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_requires_partitioned(__first, __last, __val); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle, __left, __right; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (*__middle < __val) + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else if (__val < *__middle) + __len = __half; + else + { + __left = std::lower_bound(__first, __middle, __val); + std::advance(__first, __len); + __right = std::upper_bound(++__middle, __first, __val); + return pair<_ForwardIterator, _ForwardIterator>(__left, __right); + } + } + return pair<_ForwardIterator, _ForwardIterator>(__first, __first); + } + + /** + * @brief Finds the largest subrange in which @a val could be inserted + * at any place in it without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @param comp A functor to use for comparisons. + * @return An pair of iterators defining the subrange. + * @ingroup binarysearch + * + * This is equivalent to + * @code + * std::make_pair(lower_bound(first, last, val, comp), + * upper_bound(first, last, val, comp)) + * @endcode + * but does not actually call those functions. + */ + template<typename _ForwardIterator, typename _Tp, typename _Compare> + pair<_ForwardIterator, _ForwardIterator> + equal_range(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, + _Compare __comp) + { + typedef typename iterator_traits<_ForwardIterator>::value_type + _ValueType; + typedef typename iterator_traits<_ForwardIterator>::difference_type + _DistanceType; + + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _ValueType, _Tp>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + _Tp, _ValueType>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); + + _DistanceType __len = std::distance(__first, __last); + _DistanceType __half; + _ForwardIterator __middle, __left, __right; + + while (__len > 0) + { + __half = __len >> 1; + __middle = __first; + std::advance(__middle, __half); + if (__comp(*__middle, __val)) + { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else if (__comp(__val, *__middle)) + __len = __half; + else + { + __left = std::lower_bound(__first, __middle, __val, __comp); + std::advance(__first, __len); + __right = std::upper_bound(++__middle, __first, __val, __comp); + return pair<_ForwardIterator, _ForwardIterator>(__left, __right); + } + } + return pair<_ForwardIterator, _ForwardIterator>(__first, __first); + } + + /** + * @brief Determines whether an element exists in a range. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @return True if @a val (or its equivelent) is in [@a first,@a last ]. + * @ingroup binarysearch + * + * Note that this does not actually return an iterator to @a val. For + * that, use std::find or a container's specialized find member functions. + */ + template<typename _ForwardIterator, typename _Tp> + bool + binary_search(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val) + { + // concept requirements + // See comments on lower_bound. + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_SameTypeConcept<_Tp, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_requires_partitioned(__first, __last, __val); + + _ForwardIterator __i = std::lower_bound(__first, __last, __val); + return __i != __last && !(__val < *__i); + } + + /** + * @brief Determines whether an element exists in a range. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @param comp A functor to use for comparisons. + * @return True if @a val (or its equivelent) is in [@a first,@a last ]. + * @ingroup binarysearch + * + * Note that this does not actually return an iterator to @a val. For + * that, use std::find or a container's specialized find member functions. + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ + template<typename _ForwardIterator, typename _Tp, typename _Compare> + bool + binary_search(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __val, _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_ForwardIterator>::value_type, _Tp>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _Tp, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp); + + _ForwardIterator __i = std::lower_bound(__first, __last, __val, __comp); + return __i != __last && !__comp(__val, *__i); } // Set algorithms: includes, set_union, set_intersection, set_difference, @@ -3596,19 +3957,37 @@ __result, __binary_pred, _IterType()); // that their input ranges are sorted and the postcondition that their output // ranges are sorted. - template<typename _InputIter1, typename _InputIter2> + /** + * @brief Determines whether all elements of a sequence exists in a range. + * @param first1 Start of search range. + * @param last1 End of search range. + * @param first2 Start of sequence + * @param last2 End of sequence. + * @return True if each element in [first2,last2) is contained in order + * within [first1,last1). False otherwise. + * @ingroup setoperations + * + * This operation expects both [first1,last1) and [first2,last2) to be + * sorted. Searches for the presence of each element in [first2,last2) + * within [first1,last1). The iterators over each range only move forward, + * so this is a linear algorithm. If an element in [first2,last2) is not + * found before the search iterator reaches @a last2, false is returned. + */ + template<typename _InputIterator1, typename _InputIterator2> bool - includes(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, _InputIter2 __last2) + includes(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) - __glibcpp_function_requires(_SameTypeConcept< - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) - __glibcpp_function_requires(_LessThanComparableConcept< - typename iterator_traits<_InputIter1>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); while (__first1 != __last1 && __first2 != __last2) if (*__first2 < *__first1) @@ -3621,20 +4000,42 @@ __result, __binary_pred, _IterType()); return __first2 == __last2; } - template<typename _InputIter1, typename _InputIter2, typename _Compare> + /** + * @brief Determines whether all elements of a sequence exists in a range + * using comparison. + * @param first1 Start of search range. + * @param last1 End of search range. + * @param first2 Start of sequence + * @param last2 End of sequence. + * @param comp Comparison function to use. + * @return True if each element in [first2,last2) is contained in order + * within [first1,last1) according to comp. False otherwise. + * @ingroup setoperations + * + * This operation expects both [first1,last1) and [first2,last2) to be + * sorted. Searches for the presence of each element in [first2,last2) + * within [first1,last1), using comp to decide. The iterators over each + * range only move forward, so this is a linear algorithm. If an element + * in [first2,last2) is not found before the search iterator reaches @a + * last2, false is returned. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _Compare> bool - includes(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) + includes(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) - __glibcpp_function_requires(_SameTypeConcept< - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); while (__first1 != __last1 && __first2 != __last2) if (__comp(*__first2, *__first1)) @@ -3647,351 +4048,574 @@ __result, __binary_pred, _IterType()); return __first2 == __last2; } - template<typename _InputIter1, typename _InputIter2, typename _OutputIter> - _OutputIter - set_union(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, _InputIter2 __last2, - _OutputIter __result) + /** + * @brief Return the union of two sorted ranges. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * each range in order to the output range. Iterators increment for each + * range. When the current element of one range is less than the other, + * that element is copied and the iterator advanced. If an element is + * contained in both ranges, the element from the first range is copied and + * both ranges advance. The output range may not overlap either input + * range. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator> + _OutputIterator + set_union(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_InputIter1>::value_type>) - __glibcpp_function_requires(_SameTypeConcept< - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) - __glibcpp_function_requires(_LessThanComparableConcept< - typename iterator_traits<_InputIter1>::value_type>) - - while (__first1 != __last1 && __first2 != __last2) { - if (*__first1 < *__first2) { - *__result = *__first1; - ++__first1; - } - else if (*__first2 < *__first1) { - *__result = *__first2; - ++__first2; - } - else { - *__result = *__first1; - ++__first1; - ++__first2; + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); + + while (__first1 != __last1 && __first2 != __last2) + { + if (*__first1 < *__first2) + { + *__result = *__first1; + ++__first1; + } + else if (*__first2 < *__first1) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + ++__first2; + } + ++__result; } - ++__result; - } - return copy(__first2, __last2, copy(__first1, __last1, __result)); + return std::copy(__first2, __last2, std::copy(__first1, __last1, + __result)); } - template<typename _InputIter1, typename _InputIter2, typename _OutputIter, - typename _Compare> - _OutputIter - set_union(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, _InputIter2 __last2, - _OutputIter __result, _Compare __comp) + /** + * @brief Return the union of two sorted ranges using a comparison functor. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @param comp The comparison functor. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * each range in order to the output range. Iterators increment for each + * range. When the current element of one range is less than the other + * according to @a comp, that element is copied and the iterator advanced. + * If an equivalent element according to @a comp is contained in both + * ranges, the element from the first range is copied and both ranges + * advance. The output range may not overlap either input range. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, typename _Compare> + _OutputIterator + set_union(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) - __glibcpp_function_requires(_SameTypeConcept< - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_InputIter1>::value_type>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) - - while (__first1 != __last1 && __first2 != __last2) { - if (__comp(*__first1, *__first2)) { - *__result = *__first1; - ++__first1; - } - else if (__comp(*__first2, *__first1)) { - *__result = *__first2; - ++__first2; - } - else { - *__result = *__first1; - ++__first1; - ++__first2; + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); + + while (__first1 != __last1 && __first2 != __last2) + { + if (__comp(*__first1, *__first2)) + { + *__result = *__first1; + ++__first1; + } + else if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__first2; + } + else + { + *__result = *__first1; + ++__first1; + ++__first2; + } + ++__result; } - ++__result; - } - return copy(__first2, __last2, copy(__first1, __last1, __result)); + return std::copy(__first2, __last2, std::copy(__first1, __last1, + __result)); } - template<typename _InputIter1, typename _InputIter2, typename _OutputIter> - _OutputIter - set_intersection(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, _InputIter2 __last2, - _OutputIter __result) + /** + * @brief Return the intersection of two sorted ranges. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * both ranges in order to the output range. Iterators increment for each + * range. When the current element of one range is less than the other, + * that iterator advances. If an element is contained in both ranges, the + * element from the first range is copied and both ranges advance. The + * output range may not overlap either input range. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator> + _OutputIterator + set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_InputIter1>::value_type>) - __glibcpp_function_requires(_SameTypeConcept< - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) - __glibcpp_function_requires(_LessThanComparableConcept< - typename iterator_traits<_InputIter1>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); while (__first1 != __last1 && __first2 != __last2) if (*__first1 < *__first2) ++__first1; else if (*__first2 < *__first1) ++__first2; - else { - *__result = *__first1; - ++__first1; - ++__first2; - ++__result; - } + else + { + *__result = *__first1; + ++__first1; + ++__first2; + ++__result; + } return __result; } - template<typename _InputIter1, typename _InputIter2, typename _OutputIter, - typename _Compare> - _OutputIter - set_intersection(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, _InputIter2 __last2, - _OutputIter __result, _Compare __comp) + /** + * @brief Return the intersection of two sorted ranges using comparison + * functor. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @param comp The comparison functor. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * both ranges in order to the output range. Iterators increment for each + * range. When the current element of one range is less than the other + * according to @a comp, that iterator advances. If an element is + * contained in both ranges according to @a comp, the element from the + * first range is copied and both ranges advance. The output range may not + * overlap either input range. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, typename _Compare> + _OutputIterator + set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) - __glibcpp_function_requires(_SameTypeConcept< - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_InputIter1>::value_type>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); while (__first1 != __last1 && __first2 != __last2) if (__comp(*__first1, *__first2)) ++__first1; else if (__comp(*__first2, *__first1)) ++__first2; - else { - *__result = *__first1; - ++__first1; - ++__first2; - ++__result; - } + else + { + *__result = *__first1; + ++__first1; + ++__first2; + ++__result; + } return __result; } - template<typename _InputIter1, typename _InputIter2, typename _OutputIter> - _OutputIter - set_difference(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, _InputIter2 __last2, - _OutputIter __result) + /** + * @brief Return the difference of two sorted ranges. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * the first range but not the second in order to the output range. + * Iterators increment for each range. When the current element of the + * first range is less than the second, that element is copied and the + * iterator advances. If the current element of the second range is less, + * the iterator advances, but no element is copied. If an element is + * contained in both ranges, no elements are copied and both ranges + * advance. The output range may not overlap either input range. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator> + _OutputIterator + set_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_InputIter1>::value_type>) - __glibcpp_function_requires(_SameTypeConcept< - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) - __glibcpp_function_requires(_LessThanComparableConcept< - typename iterator_traits<_InputIter1>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); while (__first1 != __last1 && __first2 != __last2) - if (*__first1 < *__first2) { - *__result = *__first1; - ++__first1; - ++__result; - } + if (*__first1 < *__first2) + { + *__result = *__first1; + ++__first1; + ++__result; + } else if (*__first2 < *__first1) ++__first2; - else { - ++__first1; - ++__first2; - } - return copy(__first1, __last1, __result); + else + { + ++__first1; + ++__first2; + } + return std::copy(__first1, __last1, __result); } - template<typename _InputIter1, typename _InputIter2, typename _OutputIter, - typename _Compare> - _OutputIter - set_difference(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, _InputIter2 __last2, - _OutputIter __result, _Compare __comp) + /** + * @brief Return the difference of two sorted ranges using comparison + * functor. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @param comp The comparison functor. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * the first range but not the second in order to the output range. + * Iterators increment for each range. When the current element of the + * first range is less than the second according to @a comp, that element + * is copied and the iterator advances. If the current element of the + * second range is less, no element is copied and the iterator advances. + * If an element is contained in both ranges according to @a comp, no + * elements are copied and both ranges advance. The output range may not + * overlap either input range. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, typename _Compare> + _OutputIterator + set_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) - __glibcpp_function_requires(_SameTypeConcept< - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_InputIter1>::value_type>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __comp); while (__first1 != __last1 && __first2 != __last2) - if (__comp(*__first1, *__first2)) { - *__result = *__first1; - ++__first1; - ++__result; - } + if (__comp(*__first1, *__first2)) + { + *__result = *__first1; + ++__first1; + ++__result; + } else if (__comp(*__first2, *__first1)) ++__first2; - else { - ++__first1; - ++__first2; - } - return copy(__first1, __last1, __result); + else + { + ++__first1; + ++__first2; + } + return std::copy(__first1, __last1, __result); } - template<typename _InputIter1, typename _InputIter2, typename _OutputIter> - _OutputIter - set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, _InputIter2 __last2, - _OutputIter __result) + /** + * @brief Return the symmetric difference of two sorted ranges. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * one range but not the other in order to the output range. Iterators + * increment for each range. When the current element of one range is less + * than the other, that element is copied and the iterator advances. If an + * element is contained in both ranges, no elements are copied and both + * ranges advance. The output range may not overlap either input range. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator> + _OutputIterator + set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_InputIter1>::value_type>) - __glibcpp_function_requires(_SameTypeConcept< - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) - __glibcpp_function_requires(_LessThanComparableConcept< - typename iterator_traits<_InputIter1>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_requires_sorted(__first1, __last1); + __glibcxx_requires_sorted(__first2, __last2); while (__first1 != __last1 && __first2 != __last2) - if (*__first1 < *__first2) { - *__result = *__first1; - ++__first1; - ++__result; - } - else if (*__first2 < *__first1) { - *__result = *__first2; - ++__first2; - ++__result; - } - else { - ++__first1; - ++__first2; - } - return copy(__first2, __last2, copy(__first1, __last1, __result)); + if (*__first1 < *__first2) + { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (*__first2 < *__first1) + { + *__result = *__first2; + ++__first2; + ++__result; + } + else + { + ++__first1; + ++__first2; + } + return std::copy(__first2, __last2, std::copy(__first1, + __last1, __result)); } - template<typename _InputIter1, typename _InputIter2, typename _OutputIter, - typename _Compare> - _OutputIter - set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, _InputIter2 __last2, - _OutputIter __result, + /** + * @brief Return the symmetric difference of two sorted ranges using + * comparison functor. + * @param first1 Start of first range. + * @param last1 End of first range. + * @param first2 Start of second range. + * @param last2 End of second range. + * @param comp The comparison functor. + * @return End of the output range. + * @ingroup setoperations + * + * This operation iterates over both ranges, copying elements present in + * one range but not the other in order to the output range. Iterators + * increment for each range. When the current element of one range is less + * than the other according to @a comp, that element is copied and the + * iterator advances. If an element is contained in both ranges according + * to @a comp, no elements are copied and both ranges advance. The output + * range may not overlap either input range. + */ + template<typename _InputIterator1, typename _InputIterator2, + typename _OutputIterator, typename _Compare> + _OutputIterator + set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, + _OutputIterator __result, _Compare __comp) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) - __glibcpp_function_requires(_SameTypeConcept< - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_InputIter1>::value_type>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_SameTypeConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_sorted_pred(__first1, __last1, __comp); + __glibcxx_requires_sorted_pred(__first2, __last2, __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)); + if (__comp(*__first1, *__first2)) + { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (__comp(*__first2, *__first1)) + { + *__result = *__first2; + ++__first2; + ++__result; + } + else + { + ++__first1; + ++__first2; + } + return std::copy(__first2, __last2, std::copy(__first1, + __last1, __result)); } // min_element and max_element, with and without an explicitly supplied // comparison function. - template<typename _ForwardIter> - _ForwardIter - max_element(_ForwardIter __first, _ForwardIter __last) + /** + * @brief Return the maximum element in a range. + * @param first Start of range. + * @param last End of range. + * @return Iterator referencing the first instance of the largest value. + */ + template<typename _ForwardIterator> + _ForwardIterator + max_element(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_LessThanComparableConcept< - typename iterator_traits<_ForwardIter>::value_type>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); - if (__first == __last) return __first; - _ForwardIter __result = __first; + if (__first == __last) + return __first; + _ForwardIterator __result = __first; while (++__first != __last) if (*__result < *__first) __result = __first; return __result; } - template<typename _ForwardIter, typename _Compare> - _ForwardIter - max_element(_ForwardIter __first, _ForwardIter __last, + /** + * @brief Return the maximum element in a range using comparison functor. + * @param first Start of range. + * @param last End of range. + * @param comp Comparison functor. + * @return Iterator referencing the first instance of the largest value + * according to comp. + */ + template<typename _ForwardIterator, typename _Compare> + _ForwardIterator + max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, - typename iterator_traits<_ForwardIter>::value_type, - typename iterator_traits<_ForwardIter>::value_type>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __first; - _ForwardIter __result = __first; + _ForwardIterator __result = __first; while (++__first != __last) if (__comp(*__result, *__first)) __result = __first; return __result; } - template<typename _ForwardIter> - _ForwardIter - min_element(_ForwardIter __first, _ForwardIter __last) + /** + * @brief Return the minimum element in a range. + * @param first Start of range. + * @param last End of range. + * @return Iterator referencing the first instance of the smallest value. + */ + template<typename _ForwardIterator> + _ForwardIterator + min_element(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_LessThanComparableConcept< - typename iterator_traits<_ForwardIter>::value_type>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); - if (__first == __last) return __first; - _ForwardIter __result = __first; + if (__first == __last) + return __first; + _ForwardIterator __result = __first; while (++__first != __last) if (*__first < *__result) __result = __first; return __result; } - template<typename _ForwardIter, typename _Compare> - _ForwardIter - min_element(_ForwardIter __first, _ForwardIter __last, + /** + * @brief Return the minimum element in a range using comparison functor. + * @param first Start of range. + * @param last End of range. + * @param comp Comparison functor. + * @return Iterator referencing the first instance of the smallest value + * according to comp. + */ + template<typename _ForwardIterator, typename _Compare> + _ForwardIterator + min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, - typename iterator_traits<_ForwardIter>::value_type, - typename iterator_traits<_ForwardIter>::value_type>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); - if (__first == __last) return __first; - _ForwardIter __result = __first; + if (__first == __last) + return __first; + _ForwardIterator __result = __first; while (++__first != __last) if (__comp(*__first, *__result)) __result = __first; @@ -4001,193 +4625,300 @@ __result, __binary_pred, _IterType()); // next_permutation and prev_permutation, with and without an explicitly // supplied comparison function. - template<typename _BidirectionalIter> + /** + * @brief Permute range into the next "dictionary" ordering. + * @param first Start of range. + * @param last End of range. + * @return False if wrapped to first permutation, true otherwise. + * + * Treats all permutations of the range as a set of "dictionary" sorted + * sequences. Permutes the current sequence into the next one of this set. + * Returns true if there are more sequences to generate. If the sequence + * is the largest of the set, the smallest is generated and false returned. + */ + template<typename _BidirectionalIterator> bool - next_permutation(_BidirectionalIter __first, _BidirectionalIter __last) + next_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last) { // concept requirements - __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter>) - __glibcpp_function_requires(_LessThanComparableConcept< - typename iterator_traits<_BidirectionalIter>::value_type>) + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return false; - _BidirectionalIter __i = __first; + _BidirectionalIterator __i = __first; ++__i; if (__i == __last) return false; __i = __last; --__i; - for(;;) { - _BidirectionalIter __ii = __i; - --__i; - if (*__i < *__ii) { - _BidirectionalIter __j = __last; - while (!(*__i < *--__j)) - {} - iter_swap(__i, __j); - reverse(__ii, __last); - return true; - } - if (__i == __first) { - reverse(__first, __last); - return false; + for(;;) + { + _BidirectionalIterator __ii = __i; + --__i; + if (*__i < *__ii) + { + _BidirectionalIterator __j = __last; + while (!(*__i < *--__j)) + {} + std::iter_swap(__i, __j); + std::reverse(__ii, __last); + return true; + } + if (__i == __first) + { + std::reverse(__first, __last); + return false; + } } - } } - template<typename _BidirectionalIter, typename _Compare> + /** + * @brief Permute range into the next "dictionary" ordering using + * comparison functor. + * @param first Start of range. + * @param last End of range. + * @param comp + * @return False if wrapped to first permutation, true otherwise. + * + * Treats all permutations of the range [first,last) as a set of + * "dictionary" sorted sequences ordered by @a comp. Permutes the current + * sequence into the next one of this set. Returns true if there are more + * sequences to generate. If the sequence is the largest of the set, the + * smallest is generated and false returned. + */ + template<typename _BidirectionalIterator, typename _Compare> bool - next_permutation(_BidirectionalIter __first, _BidirectionalIter __last, - _Compare __comp) + next_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last, _Compare __comp) { // concept requirements - __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, - typename iterator_traits<_BidirectionalIter>::value_type, - typename iterator_traits<_BidirectionalIter>::value_type>) + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_BidirectionalIterator>::value_type, + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return false; - _BidirectionalIter __i = __first; + _BidirectionalIterator __i = __first; ++__i; if (__i == __last) return false; __i = __last; --__i; - for(;;) { - _BidirectionalIter __ii = __i; - --__i; - if (__comp(*__i, *__ii)) { - _BidirectionalIter __j = __last; - while (!__comp(*__i, *--__j)) - {} - iter_swap(__i, __j); - reverse(__ii, __last); - return true; - } - if (__i == __first) { - reverse(__first, __last); - return false; + for(;;) + { + _BidirectionalIterator __ii = __i; + --__i; + if (__comp(*__i, *__ii)) + { + _BidirectionalIterator __j = __last; + while (!__comp(*__i, *--__j)) + {} + std::iter_swap(__i, __j); + std::reverse(__ii, __last); + return true; + } + if (__i == __first) + { + std::reverse(__first, __last); + return false; + } } - } } - template<typename _BidirectionalIter> + /** + * @brief Permute range into the previous "dictionary" ordering. + * @param first Start of range. + * @param last End of range. + * @return False if wrapped to last permutation, true otherwise. + * + * Treats all permutations of the range as a set of "dictionary" sorted + * sequences. Permutes the current sequence into the previous one of this + * set. Returns true if there are more sequences to generate. If the + * sequence is the smallest of the set, the largest is generated and false + * returned. + */ + template<typename _BidirectionalIterator> bool - prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last) + prev_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last) { // concept requirements - __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter>) - __glibcpp_function_requires(_LessThanComparableConcept< - typename iterator_traits<_BidirectionalIter>::value_type>) + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return false; - _BidirectionalIter __i = __first; + _BidirectionalIterator __i = __first; ++__i; if (__i == __last) return false; __i = __last; --__i; - for(;;) { - _BidirectionalIter __ii = __i; - --__i; - if (*__ii < *__i) { - _BidirectionalIter __j = __last; - while (!(*--__j < *__i)) - {} - iter_swap(__i, __j); - reverse(__ii, __last); - return true; - } - if (__i == __first) { - reverse(__first, __last); - return false; + for(;;) + { + _BidirectionalIterator __ii = __i; + --__i; + if (*__ii < *__i) + { + _BidirectionalIterator __j = __last; + while (!(*--__j < *__i)) + {} + std::iter_swap(__i, __j); + std::reverse(__ii, __last); + return true; + } + if (__i == __first) + { + std::reverse(__first, __last); + return false; + } } - } } - template<typename _BidirectionalIter, typename _Compare> + /** + * @brief Permute range into the previous "dictionary" ordering using + * comparison functor. + * @param first Start of range. + * @param last End of range. + * @param comp + * @return False if wrapped to last permutation, true otherwise. + * + * Treats all permutations of the range [first,last) as a set of + * "dictionary" sorted sequences ordered by @a comp. Permutes the current + * sequence into the previous one of this set. Returns true if there are + * more sequences to generate. If the sequence is the smallest of the set, + * the largest is generated and false returned. + */ + template<typename _BidirectionalIterator, typename _Compare> bool - prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last, - _Compare __comp) + prev_permutation(_BidirectionalIterator __first, + _BidirectionalIterator __last, _Compare __comp) { // concept requirements - __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter>) - __glibcpp_function_requires(_BinaryPredicateConcept<_Compare, - typename iterator_traits<_BidirectionalIter>::value_type, - typename iterator_traits<_BidirectionalIter>::value_type>) + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, + typename iterator_traits<_BidirectionalIterator>::value_type, + typename iterator_traits<_BidirectionalIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return false; - _BidirectionalIter __i = __first; + _BidirectionalIterator __i = __first; ++__i; if (__i == __last) return false; __i = __last; --__i; - for(;;) { - _BidirectionalIter __ii = __i; - --__i; - if (__comp(*__ii, *__i)) { - _BidirectionalIter __j = __last; - while (!__comp(*--__j, *__i)) - {} - iter_swap(__i, __j); - reverse(__ii, __last); - return true; - } - if (__i == __first) { - reverse(__first, __last); - return false; + for(;;) + { + _BidirectionalIterator __ii = __i; + --__i; + if (__comp(*__ii, *__i)) + { + _BidirectionalIterator __j = __last; + while (!__comp(*--__j, *__i)) + {} + std::iter_swap(__i, __j); + std::reverse(__ii, __last); + return true; + } + if (__i == __first) + { + std::reverse(__first, __last); + return false; + } } - } } // find_first_of, with and without an explicitly supplied comparison function. - template<typename _InputIter, typename _ForwardIter> - _InputIter - find_first_of(_InputIter __first1, _InputIter __last1, - _ForwardIter __first2, _ForwardIter __last2) + /** + * @brief Find element from a set in a sequence. + * @param first1 Start of range to search. + * @param last1 End of range to search. + * @param first2 Start of match candidates. + * @param last2 End of match candidates. + * @return The first iterator @c i in the range + * @p [first1,last1) such that @c *i == @p *(i2) such that i2 is an + * interator in [first2,last2), or @p last1 if no such iterator exists. + * + * Searches the range @p [first1,last1) for an element that is equal to + * some element in the range [first2,last2). If found, returns an iterator + * in the range [first1,last1), otherwise returns @p last1. + */ + template<typename _InputIterator, typename _ForwardIterator> + _InputIterator + find_first_of(_InputIterator __first1, _InputIterator __last1, + _ForwardIterator __first2, _ForwardIterator __last2) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_EqualOpConcept< - typename iterator_traits<_InputIter>::value_type, - typename iterator_traits<_ForwardIter>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); for ( ; __first1 != __last1; ++__first1) - for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter) + for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter) if (*__first1 == *__iter) return __first1; return __last1; } - template<typename _InputIter, typename _ForwardIter, typename _BinaryPredicate> - _InputIter - find_first_of(_InputIter __first1, _InputIter __last1, - _ForwardIter __first2, _ForwardIter __last2, + /** + * @brief Find element from a set in a sequence using a predicate. + * @param first1 Start of range to search. + * @param last1 End of range to search. + * @param first2 Start of match candidates. + * @param last2 End of match candidates. + * @param comp Predicate to use. + * @return The first iterator @c i in the range + * @p [first1,last1) such that @c comp(*i, @p *(i2)) is true and i2 is an + * interator in [first2,last2), or @p last1 if no such iterator exists. + * + * Searches the range @p [first1,last1) for an element that is equal to + * some element in the range [first2,last2). If found, returns an iterator in + * the range [first1,last1), otherwise returns @p last1. + */ + template<typename _InputIterator, typename _ForwardIterator, + typename _BinaryPredicate> + _InputIterator + find_first_of(_InputIterator __first1, _InputIterator __last1, + _ForwardIterator __first2, _ForwardIterator __last2, _BinaryPredicate __comp) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_EqualOpConcept< - typename iterator_traits<_InputIter>::value_type, - typename iterator_traits<_ForwardIter>::value_type>) - __glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPredicate, - typename iterator_traits<_InputIter>::value_type, - typename iterator_traits<_ForwardIter>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_InputIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); for ( ; __first1 != __last1; ++__first1) - for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter) + for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter) if (__comp(*__first1, *__iter)) return __first1; return __last1; @@ -4200,154 +4931,223 @@ __result, __binary_pred, _IterType()); // is much faster than for forward iterators. // find_end for forward iterators. - template<typename _ForwardIter1, typename _ForwardIter2> - _ForwardIter1 - __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, - _ForwardIter2 __first2, _ForwardIter2 __last2, + template<typename _ForwardIterator1, typename _ForwardIterator2> + _ForwardIterator1 + __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, forward_iterator_tag, forward_iterator_tag) { if (__first2 == __last2) return __last1; - else { - _ForwardIter1 __result = __last1; - while (1) { - _ForwardIter1 __new_result - = search(__first1, __last1, __first2, __last2); - if (__new_result == __last1) - return __result; - else { - __result = __new_result; - __first1 = __new_result; - ++__first1; - } + else + { + _ForwardIterator1 __result = __last1; + while (1) + { + _ForwardIterator1 __new_result + = std::search(__first1, __last1, __first2, __last2); + if (__new_result == __last1) + return __result; + else + { + __result = __new_result; + __first1 = __new_result; + ++__first1; + } + } } - } } - template<typename _ForwardIter1, typename _ForwardIter2, + template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> - _ForwardIter1 - __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, - _ForwardIter2 __first2, _ForwardIter2 __last2, + _ForwardIterator1 + __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, forward_iterator_tag, forward_iterator_tag, _BinaryPredicate __comp) { if (__first2 == __last2) return __last1; - else { - _ForwardIter1 __result = __last1; - while (1) { - _ForwardIter1 __new_result - = search(__first1, __last1, __first2, __last2, __comp); - if (__new_result == __last1) - return __result; - else { - __result = __new_result; - __first1 = __new_result; - ++__first1; - } + else + { + _ForwardIterator1 __result = __last1; + while (1) + { + _ForwardIterator1 __new_result + = std::search(__first1, __last1, __first2, __last2, __comp); + if (__new_result == __last1) + return __result; + else + { + __result = __new_result; + __first1 = __new_result; + ++__first1; + } + } } - } } // find_end for bidirectional iterators. Requires partial specialization. - template<typename _BidirectionalIter1, typename _BidirectionalIter2> - _BidirectionalIter1 - __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, - _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, + template<typename _BidirectionalIterator1, typename _BidirectionalIterator2> + _BidirectionalIterator1 + __find_end(_BidirectionalIterator1 __first1, + _BidirectionalIterator1 __last1, + _BidirectionalIterator2 __first2, + _BidirectionalIterator2 __last2, bidirectional_iterator_tag, bidirectional_iterator_tag) { // concept requirements - __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter1>) - __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter2>) + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator1>) + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator2>) - typedef reverse_iterator<_BidirectionalIter1> _RevIter1; - typedef reverse_iterator<_BidirectionalIter2> _RevIter2; + typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1; + typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2; - _RevIter1 __rlast1(__first1); - _RevIter2 __rlast2(__first2); - _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1, - _RevIter2(__last2), __rlast2); + _RevIterator1 __rlast1(__first1); + _RevIterator2 __rlast2(__first2); + _RevIterator1 __rresult = std::search(_RevIterator1(__last1), __rlast1, + _RevIterator2(__last2), __rlast2); if (__rresult == __rlast1) return __last1; - else { - _BidirectionalIter1 __result = __rresult.base(); - advance(__result, -distance(__first2, __last2)); - return __result; - } + else + { + _BidirectionalIterator1 __result = __rresult.base(); + std::advance(__result, -std::distance(__first2, __last2)); + return __result; + } } - template<typename _BidirectionalIter1, typename _BidirectionalIter2, + template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, typename _BinaryPredicate> - _BidirectionalIter1 - __find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, - _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, + _BidirectionalIterator1 + __find_end(_BidirectionalIterator1 __first1, + _BidirectionalIterator1 __last1, + _BidirectionalIterator2 __first2, + _BidirectionalIterator2 __last2, bidirectional_iterator_tag, bidirectional_iterator_tag, _BinaryPredicate __comp) { // concept requirements - __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter1>) - __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIter2>) + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator1>) + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator2>) - typedef reverse_iterator<_BidirectionalIter1> _RevIter1; - typedef reverse_iterator<_BidirectionalIter2> _RevIter2; + typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1; + typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2; - _RevIter1 __rlast1(__first1); - _RevIter2 __rlast2(__first2); - _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1, - _RevIter2(__last2), __rlast2, - __comp); + _RevIterator1 __rlast1(__first1); + _RevIterator2 __rlast2(__first2); + _RevIterator1 __rresult = std::search(_RevIterator1(__last1), __rlast1, + _RevIterator2(__last2), __rlast2, + __comp); if (__rresult == __rlast1) return __last1; - else { - _BidirectionalIter1 __result = __rresult.base(); - advance(__result, -distance(__first2, __last2)); - return __result; - } + else + { + _BidirectionalIterator1 __result = __rresult.base(); + std::advance(__result, -std::distance(__first2, __last2)); + return __result; + } } // Dispatching functions for find_end. - template<typename _ForwardIter1, typename _ForwardIter2> - inline _ForwardIter1 - find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, - _ForwardIter2 __first2, _ForwardIter2 __last2) + /** + * @brief Find last matching subsequence in a sequence. + * @param first1 Start of range to search. + * @param last1 End of range to search. + * @param first2 Start of sequence to match. + * @param last2 End of sequence to match. + * @return The last iterator @c i in the range + * @p [first1,last1-(last2-first2)) such that @c *(i+N) == @p *(first2+N) + * for each @c N in the range @p [0,last2-first2), or @p last1 if no + * such iterator exists. + * + * Searches the range @p [first1,last1) for a sub-sequence that compares + * equal value-by-value with the sequence given by @p [first2,last2) and + * returns an iterator to the first element of the sub-sequence, or + * @p last1 if the sub-sequence is not found. The sub-sequence will be the + * last such subsequence contained in [first,last1). + * + * Because the sub-sequence must lie completely within the range + * @p [first1,last1) it must start at a position less than + * @p last1-(last2-first2) where @p last2-first2 is the length of the + * sub-sequence. + * This means that the returned iterator @c i will be in the range + * @p [first1,last1-(last2-first2)) + */ + template<typename _ForwardIterator1, typename _ForwardIterator2> + inline _ForwardIterator1 + find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2) { // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter1>) - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter2>) - __glibcpp_function_requires(_EqualOpConcept< - typename iterator_traits<_ForwardIter1>::value_type, - typename iterator_traits<_ForwardIter2>::value_type>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); - return __find_end(__first1, __last1, __first2, __last2, - __iterator_category(__first1), - __iterator_category(__first2)); + return std::__find_end(__first1, __last1, __first2, __last2, + std::__iterator_category(__first1), + std::__iterator_category(__first2)); } - template<typename _ForwardIter1, typename _ForwardIter2, + /** + * @brief Find last matching subsequence in a sequence using a predicate. + * @param first1 Start of range to search. + * @param last1 End of range to search. + * @param first2 Start of sequence to match. + * @param last2 End of sequence to match. + * @param comp The predicate to use. + * @return The last iterator @c i in the range + * @p [first1,last1-(last2-first2)) such that @c predicate(*(i+N), @p + * (first2+N)) is true for each @c N in the range @p [0,last2-first2), or + * @p last1 if no such iterator exists. + * + * Searches the range @p [first1,last1) for a sub-sequence that compares + * equal value-by-value with the sequence given by @p [first2,last2) using + * comp as a predicate and returns an iterator to the first element of the + * sub-sequence, or @p last1 if the sub-sequence is not found. The + * sub-sequence will be the last such subsequence contained in + * [first,last1). + * + * Because the sub-sequence must lie completely within the range + * @p [first1,last1) it must start at a position less than + * @p last1-(last2-first2) where @p last2-first2 is the length of the + * sub-sequence. + * This means that the returned iterator @c i will be in the range + * @p [first1,last1-(last2-first2)) + */ + template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> - inline _ForwardIter1 - find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, - _ForwardIter2 __first2, _ForwardIter2 __last2, + inline _ForwardIterator1 + find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __comp) { // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter1>) - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter2>) - __glibcpp_function_requires(_BinaryPredicateConcept<_BinaryPredicate, - typename iterator_traits<_ForwardIter1>::value_type, - typename iterator_traits<_ForwardIter2>::value_type>) - - return __find_end(__first1, __last1, __first2, __last2, - __iterator_category(__first1), - __iterator_category(__first2), - __comp); + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_ForwardIterator1>::value_type, + typename iterator_traits<_ForwardIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + return std::__find_end(__first1, __last1, __first2, __last2, + std::__iterator_category(__first1), + std::__iterator_category(__first2), + __comp); } } // namespace std -#endif /* __GLIBCPP_INTERNAL_ALGO_H */ - +#endif /* _ALGO_H */ diff --git a/contrib/libstdc++/include/bits/stl_algobase.h b/contrib/libstdc++/include/bits/stl_algobase.h index 6e488eae355f..17c3007f1f4d 100644 --- a/contrib/libstdc++/include/bits/stl_algobase.h +++ b/contrib/libstdc++/include/bits/stl_algobase.h @@ -1,6 +1,6 @@ // Bits and pieces used in algorithms -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,8 +58,8 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_ALGOBASE_H -#define __GLIBCPP_INTERNAL_ALGOBASE_H +#ifndef _ALGOBASE_H +#define _ALGOBASE_H 1 #include <bits/c++config.h> #include <cstring> @@ -74,11 +74,10 @@ #include <bits/stl_iterator_base_funcs.h> #include <bits/stl_iterator.h> #include <bits/concept_check.h> +#include <debug/debug.h> namespace std { - // swap and iter_swap - /** * @brief Swaps the contents of two iterators. * @param a An iterator. @@ -88,20 +87,26 @@ namespace std * This function swaps the values pointed to by two iterators, not the * iterators themselves. */ - template<typename _ForwardIter1, typename _ForwardIter2> + template<typename _ForwardIterator1, typename _ForwardIterator2> inline void - iter_swap(_ForwardIter1 __a, _ForwardIter2 __b) + iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) { - typedef typename iterator_traits<_ForwardIter1>::value_type _ValueType1; - typedef typename iterator_traits<_ForwardIter2>::value_type _ValueType2; + typedef typename iterator_traits<_ForwardIterator1>::value_type + _ValueType1; + typedef typename iterator_traits<_ForwardIterator2>::value_type + _ValueType2; // concept requirements - __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter1>) - __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter2>) - __glibcpp_function_requires(_ConvertibleConcept<_ValueType1, _ValueType2>) - __glibcpp_function_requires(_ConvertibleConcept<_ValueType2, _ValueType1>) - - _ValueType1 __tmp = *__a; + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator1>) + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator2>) + __glibcxx_function_requires(_ConvertibleConcept<_ValueType1, + _ValueType2>) + __glibcxx_function_requires(_ConvertibleConcept<_ValueType2, + _ValueType1>) + + const _ValueType1 __tmp = *__a; *__a = *__b; *__b = __tmp; } @@ -120,16 +125,13 @@ namespace std swap(_Tp& __a, _Tp& __b) { // concept requirements - __glibcpp_function_requires(_SGIAssignableConcept<_Tp>) - - _Tp __tmp = __a; + __glibcxx_function_requires(_SGIAssignableConcept<_Tp>) + + const _Tp __tmp = __a; __a = __b; __b = __tmp; } - //-------------------------------------------------- - // min and max - #undef min #undef max @@ -148,9 +150,11 @@ namespace std min(const _Tp& __a, const _Tp& __b) { // concept requirements - __glibcpp_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) //return __b < __a ? __b : __a; - if (__b < __a) return __b; return __a; + if (__b < __a) + return __b; + return __a; } /** @@ -165,12 +169,14 @@ namespace std */ template<typename _Tp> inline const _Tp& - max(const _Tp& __a, const _Tp& __b) + max(const _Tp& __a, const _Tp& __b) { // concept requirements - __glibcpp_function_requires(_LessThanComparableConcept<_Tp>) + __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) //return __a < __b ? __b : __a; - if (__a < __b) return __b; return __a; + if (__a < __b) + return __b; + return __a; } /** @@ -188,7 +194,9 @@ namespace std min(const _Tp& __a, const _Tp& __b, _Compare __comp) { //return __comp(__b, __a) ? __b : __a; - if (__comp(__b, __a)) return __b; return __a; + if (__comp(__b, __a)) + return __b; + return __a; } /** @@ -206,42 +214,40 @@ namespace std max(const _Tp& __a, const _Tp& __b, _Compare __comp) { //return __comp(__a, __b) ? __b : __a; - if (__comp(__a, __b)) return __b; return __a; + if (__comp(__a, __b)) + return __b; + return __a; } - //-------------------------------------------------- - // copy - // All of these auxiliary functions serve two purposes. (1) Replace // calls to copy with memmove whenever possible. (Memmove, not memcpy, // because the input and output ranges are permitted to overlap.) // (2) If we're using random access iterators, then write the loop as // a for loop with an explicit count. - template<typename _InputIter, typename _OutputIter> - inline _OutputIter - __copy(_InputIter __first, _InputIter __last, - _OutputIter __result, - input_iterator_tag) + template<typename _InputIterator, typename _OutputIterator> + inline _OutputIterator + __copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, input_iterator_tag) { - for ( ; __first != __last; ++__result, ++__first) + for (; __first != __last; ++__result, ++__first) *__result = *__first; return __result; } - template<typename _RandomAccessIter, typename _OutputIter> - inline _OutputIter - __copy(_RandomAccessIter __first, _RandomAccessIter __last, - _OutputIter __result, - random_access_iterator_tag) + template<typename _RandomAccessIterator, typename _OutputIterator> + inline _OutputIterator + __copy(_RandomAccessIterator __first, _RandomAccessIterator __last, + _OutputIterator __result, random_access_iterator_tag) { - typedef typename iterator_traits<_RandomAccessIter>::difference_type + typedef typename iterator_traits<_RandomAccessIterator>::difference_type _Distance; - for (_Distance __n = __last - __first; __n > 0; --__n) { - *__result = *__first; - ++__first; - ++__result; - } + for (_Distance __n = __last - __first; __n > 0; --__n) + { + *__result = *__first; + ++__first; + ++__result; + } return __result; } @@ -249,78 +255,76 @@ namespace std inline _Tp* __copy_trivial(const _Tp* __first, const _Tp* __last, _Tp* __result) { - memmove(__result, __first, sizeof(_Tp) * (__last - __first)); + std::memmove(__result, __first, sizeof(_Tp) * (__last - __first)); return __result + (__last - __first); } - template<typename _InputIter, typename _OutputIter> - inline _OutputIter - __copy_aux2(_InputIter __first, _InputIter __last, - _OutputIter __result, __false_type) - { return __copy(__first, __last, __result, __iterator_category(__first)); } + template<typename _InputIterator, typename _OutputIterator> + inline _OutputIterator + __copy_aux2(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, __false_type) + { return std::__copy(__first, __last, __result, + std::__iterator_category(__first)); } - template<typename _InputIter, typename _OutputIter> - inline _OutputIter - __copy_aux2(_InputIter __first, _InputIter __last, - _OutputIter __result, __true_type) - { return __copy(__first, __last, __result, __iterator_category(__first)); } + template<typename _InputIterator, typename _OutputIterator> + inline _OutputIterator + __copy_aux2(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, __true_type) + { return std::__copy(__first, __last, __result, + std::__iterator_category(__first)); } template<typename _Tp> inline _Tp* - __copy_aux2(_Tp* __first, _Tp* __last, - _Tp* __result, __true_type) - { return __copy_trivial(__first, __last, __result); } + __copy_aux2(_Tp* __first, _Tp* __last, _Tp* __result, __true_type) + { return std::__copy_trivial(__first, __last, __result); } template<typename _Tp> inline _Tp* - __copy_aux2(const _Tp* __first, const _Tp* __last, - _Tp* __result, __true_type) - { return __copy_trivial(__first, __last, __result); } - - template<typename _InputIter, typename _OutputIter> - inline _OutputIter - __copy_ni2(_InputIter __first, _InputIter __last, - _OutputIter __result, __true_type) - { - typedef typename iterator_traits<_InputIter>::value_type - _ValueType; - typedef typename __type_traits<_ValueType>::has_trivial_assignment_operator - _Trivial; - return _OutputIter(__copy_aux2(__first, __last, - __result.base(), - _Trivial())); + __copy_aux2(const _Tp* __first, const _Tp* __last, _Tp* __result, + __true_type) + { return std::__copy_trivial(__first, __last, __result); } + + template<typename _InputIterator, typename _OutputIterator> + inline _OutputIterator + __copy_ni2(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, __true_type) + { + typedef typename iterator_traits<_InputIterator>::value_type + _ValueType; + typedef typename __type_traits< + _ValueType>::has_trivial_assignment_operator _Trivial; + return _OutputIterator(std::__copy_aux2(__first, __last, __result.base(), + _Trivial())); } - template<typename _InputIter, typename _OutputIter> - inline _OutputIter - __copy_ni2(_InputIter __first, _InputIter __last, - _OutputIter __result, __false_type) - { - typedef typename iterator_traits<_InputIter>::value_type - _ValueType; - typedef typename __type_traits<_ValueType>::has_trivial_assignment_operator - _Trivial; - return __copy_aux2(__first, __last, - __result, - _Trivial()); + template<typename _InputIterator, typename _OutputIterator> + inline _OutputIterator + __copy_ni2(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, __false_type) + { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType; + typedef typename __type_traits< + _ValueType>::has_trivial_assignment_operator _Trivial; + return std::__copy_aux2(__first, __last, __result, _Trivial()); } - template<typename _InputIter, typename _OutputIter> - inline _OutputIter - __copy_ni1(_InputIter __first, _InputIter __last, - _OutputIter __result, __true_type) + template<typename _InputIterator, typename _OutputIterator> + inline _OutputIterator + __copy_ni1(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, __true_type) { - typedef typename _Is_normal_iterator<_OutputIter>::_Normal __Normal; - return __copy_ni2(__first.base(), __last.base(), __result, __Normal()); + typedef typename _Is_normal_iterator<_OutputIterator>::_Normal __Normal; + return std::__copy_ni2(__first.base(), __last.base(), + __result, __Normal()); } - template<typename _InputIter, typename _OutputIter> - inline _OutputIter - __copy_ni1(_InputIter __first, _InputIter __last, - _OutputIter __result, __false_type) + template<typename _InputIterator, typename _OutputIterator> + inline _OutputIterator + __copy_ni1(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, __false_type) { - typedef typename _Is_normal_iterator<_OutputIter>::_Normal __Normal; - return __copy_ni2(__first, __last, __result, __Normal()); + typedef typename _Is_normal_iterator<_OutputIterator>::_Normal __Normal; + return std::__copy_ni2(__first, __last, __result, __Normal()); } /** @@ -333,29 +337,32 @@ namespace std * This inline function will boil down to a call to @c memmove whenever * possible. Failing that, if random access iterators are passed, then the * loop count will be known (and therefore a candidate for compiler - * optimizations such as unrolling). If the input range and the output - * range overlap, then the copy_backward function should be used instead. + * optimizations such as unrolling). Result may not be contained within + * [first,last); the copy_backward function should be used instead. + * + * Note that the end of the output range is permitted to be contained + * within [first,last). */ - template<typename _InputIter, typename _OutputIter> - inline _OutputIter - copy(_InputIter __first, _InputIter __last, _OutputIter __result) + template<typename _InputIterator, typename _OutputIterator> + inline _OutputIterator + copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_InputIter>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); - typedef typename _Is_normal_iterator<_InputIter>::_Normal __Normal; - return __copy_ni1(__first, __last, __result, __Normal()); + typedef typename _Is_normal_iterator<_InputIterator>::_Normal __Normal; + return std::__copy_ni1(__first, __last, __result, __Normal()); } - //-------------------------------------------------- - // copy_backward - - template<typename _BidirectionalIter1, typename _BidirectionalIter2> - inline _BidirectionalIter2 - __copy_backward(_BidirectionalIter1 __first, _BidirectionalIter1 __last, - _BidirectionalIter2 __result, + template<typename _BidirectionalIterator1, typename _BidirectionalIterator2> + inline _BidirectionalIterator2 + __copy_backward(_BidirectionalIterator1 __first, + _BidirectionalIterator1 __last, + _BidirectionalIterator2 __result, bidirectional_iterator_tag) { while (__first != __last) @@ -363,36 +370,31 @@ namespace std return __result; } - template<typename _RandomAccessIter, typename _BidirectionalIter> - inline _BidirectionalIter - __copy_backward(_RandomAccessIter __first, _RandomAccessIter __last, - _BidirectionalIter __result, - random_access_iterator_tag) + template<typename _RandomAccessIterator, typename _BidirectionalIterator> + inline _BidirectionalIterator + __copy_backward(_RandomAccessIterator __first, _RandomAccessIterator __last, + _BidirectionalIterator __result, random_access_iterator_tag) { - typename iterator_traits<_RandomAccessIter>::difference_type __n; + typename iterator_traits<_RandomAccessIterator>::difference_type __n; for (__n = __last - __first; __n > 0; --__n) *--__result = *--__last; return __result; } - // This dispatch class is a workaround for compilers that do not + // 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<typename _BidirectionalIter1, typename _BidirectionalIter2, + template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, typename _BoolType> struct __copy_backward_dispatch { - static _BidirectionalIter2 - copy(_BidirectionalIter1 __first, _BidirectionalIter1 __last, - _BidirectionalIter2 __result) - { - return __copy_backward(__first, __last, - __result, - __iterator_category(__first)); - } + static _BidirectionalIterator2 + copy(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, + _BidirectionalIterator2 __result) + { return std::__copy_backward(__first, __last, __result, + std::__iterator_category(__first)); } }; template<typename _Tp> @@ -402,7 +404,7 @@ namespace std copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { const ptrdiff_t _Num = __last - __first; - memmove(__result - _Num, __first, sizeof(_Tp) * _Num); + std::memmove(__result - _Num, __first, sizeof(_Tp) * _Num); return __result - _Num; } }; @@ -413,7 +415,7 @@ namespace std static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { - return __copy_backward_dispatch<_Tp*, _Tp*, __true_type> + return std::__copy_backward_dispatch<_Tp*, _Tp*, __true_type> ::copy(__first, __last, __result); } }; @@ -424,21 +426,23 @@ namespace std { 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); + return + std::__copy_backward_dispatch<_BI1, _BI2, _Trivial>::copy(__first, + __last, + __result); } template <typename _BI1, typename _BI2> inline _BI2 __copy_backward_output_normal_iterator(_BI1 __first, _BI1 __last, _BI2 __result, __true_type) - { return _BI2(__copy_backward_aux(__first, __last, __result.base())); } + { return _BI2(std::__copy_backward_aux(__first, __last, __result.base())); } template <typename _BI1, typename _BI2> inline _BI2 __copy_backward_output_normal_iterator(_BI1 __first, _BI1 __last, _BI2 __result, __false_type) - { return __copy_backward_aux(__first, __last, __result); } + { return std::__copy_backward_aux(__first, __last, __result); } template <typename _BI1, typename _BI2> inline _BI2 @@ -446,8 +450,9 @@ namespace std _BI2 __result, __true_type) { typedef typename _Is_normal_iterator<_BI2>::_Normal __Normal; - return __copy_backward_output_normal_iterator(__first.base(), __last.base(), - __result, __Normal()); + return std::__copy_backward_output_normal_iterator(__first.base(), + __last.base(), + __result, __Normal()); } template <typename _BI1, typename _BI2> @@ -456,15 +461,15 @@ namespace std _BI2 __result, __false_type) { typedef typename _Is_normal_iterator<_BI2>::_Normal __Normal; - return __copy_backward_output_normal_iterator(__first, __last, __result, - __Normal()); + return std::__copy_backward_output_normal_iterator(__first, __last, + __result, __Normal()); } /** * @brief Copies the range [first,last) into result. - * @param first An input iterator. - * @param last An input iterator. - * @param result An output iterator. + * @param first A bidirectional iterator. + * @param last A bidirectional iterator. + * @param result A bidirectional iterator. * @return result - (first - last) * * The function has the same effect as copy, but starts at the end of the @@ -473,28 +478,28 @@ namespace std * possible. Failing that, if random access iterators are passed, then the * loop count will be known (and therefore a candidate for compiler * optimizations such as unrolling). + * + * Result may not be in the range [first,last). Use copy instead. Note + * that the start of the output range may overlap [first,last). */ template <typename _BI1, typename _BI2> inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) { // concept requirements - __glibcpp_function_requires(_BidirectionalIteratorConcept<_BI1>) - __glibcpp_function_requires(_Mutable_BidirectionalIteratorConcept<_BI2>) - __glibcpp_function_requires(_ConvertibleConcept< + __glibcxx_function_requires(_BidirectionalIteratorConcept<_BI1>) + __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<_BI2>) + __glibcxx_function_requires(_ConvertibleConcept< typename iterator_traits<_BI1>::value_type, typename iterator_traits<_BI2>::value_type>) + __glibcxx_requires_valid_range(__first, __last); typedef typename _Is_normal_iterator<_BI1>::_Normal __Normal; - return __copy_backward_input_normal_iterator(__first, __last, __result, - __Normal()); + return std::__copy_backward_input_normal_iterator(__first, __last, + __result, __Normal()); } - //-------------------------------------------------- - // fill and fill_n - - /** * @brief Fills the range [first,last) with copies of value. * @param first A forward iterator. @@ -506,12 +511,14 @@ namespace std * types filling contiguous areas of memory, this becomes an inline call to * @c memset. */ - template<typename _ForwardIter, typename _Tp> + template<typename _ForwardIterator, typename _Tp> void - fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __value) + fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { // concept requirements - __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>) + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< + _ForwardIterator>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) *__first = __value; @@ -528,12 +535,12 @@ namespace std * types filling contiguous areas of memory, this becomes an inline call to * @c memset. */ - template<typename _OutputIter, typename _Size, typename _Tp> - _OutputIter - fill_n(_OutputIter __first, _Size __n, const _Tp& __value) + template<typename _OutputIterator, typename _Size, typename _Tp> + _OutputIterator + fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) { // concept requirements - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,_Tp>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,_Tp>) for ( ; __n > 0; --__n, ++__first) *__first = __value; @@ -541,33 +548,35 @@ namespace std } // Specialization: for one-byte types we can use memset. - inline void fill(unsigned char* __first, unsigned char* __last, const unsigned char& __c) { - unsigned char __tmp = __c; - memset(__first, __tmp, __last - __first); + __glibcxx_requires_valid_range(__first, __last); + const unsigned char __tmp = __c; + std::memset(__first, __tmp, __last - __first); } inline void fill(signed char* __first, signed char* __last, const signed char& __c) { - signed char __tmp = __c; - memset(__first, static_cast<unsigned char>(__tmp), __last - __first); + __glibcxx_requires_valid_range(__first, __last); + const signed char __tmp = __c; + std::memset(__first, static_cast<unsigned char>(__tmp), __last - __first); } inline void fill(char* __first, char* __last, const char& __c) { - char __tmp = __c; - memset(__first, static_cast<unsigned char>(__tmp), __last - __first); + __glibcxx_requires_valid_range(__first, __last); + const char __tmp = __c; + std::memset(__first, static_cast<unsigned char>(__tmp), __last - __first); } template<typename _Size> inline unsigned char* fill_n(unsigned char* __first, _Size __n, const unsigned char& __c) { - fill(__first, __first + __n, __c); + std::fill(__first, __first + __n, __c); return __first + __n; } @@ -575,7 +584,7 @@ namespace std inline signed char* fill_n(char* __first, _Size __n, const signed char& __c) { - fill(__first, __first + __n, __c); + std::fill(__first, __first + __n, __c); return __first + __n; } @@ -583,14 +592,11 @@ namespace std inline char* fill_n(char* __first, _Size __n, const char& __c) { - fill(__first, __first + __n, __c); + std::fill(__first, __first + __n, __c); return __first + __n; } - //-------------------------------------------------- - // equal and mismatch - /** * @brief Finds the places in ranges which don't match. * @param first1 An input iterator. @@ -603,24 +609,26 @@ namespace std * second iterator points into the second range, and the elements pointed * to by the iterators are not equal. */ - template<typename _InputIter1, typename _InputIter2> - pair<_InputIter1, _InputIter2> - mismatch(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2) + template<typename _InputIterator1, typename _InputIterator2> + pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) - __glibcpp_function_requires(_EqualityComparableConcept< - typename iterator_traits<_InputIter1>::value_type>) - __glibcpp_function_requires(_EqualityComparableConcept< - typename iterator_traits<_InputIter2>::value_type>) - - while (__first1 != __last1 && *__first1 == *__first2) { - ++__first1; - ++__first2; - } - return pair<_InputIter1, _InputIter2>(__first1, __first2); + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + + while (__first1 != __last1 && *__first1 == *__first2) + { + ++__first1; + ++__first2; + } + return pair<_InputIterator1, _InputIterator2>(__first1, __first2); } /** @@ -637,21 +645,23 @@ namespace std * second iterator points into the second range, and the elements pointed * to by the iterators are not equal. */ - template<typename _InputIter1, typename _InputIter2, typename _BinaryPredicate> - pair<_InputIter1, _InputIter2> - mismatch(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, - _BinaryPredicate __binary_pred) + template<typename _InputIterator1, typename _InputIterator2, + typename _BinaryPredicate> + pair<_InputIterator1, _InputIterator2> + mismatch(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _BinaryPredicate __binary_pred) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) - - while (__first1 != __last1 && __binary_pred(*__first1, *__first2)) { - ++__first1; - ++__first2; - } - return pair<_InputIter1, _InputIter2>(__first1, __first2); + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); + + while (__first1 != __last1 && __binary_pred(*__first1, *__first2)) + { + ++__first1; + ++__first2; + } + return pair<_InputIterator1, _InputIterator2>(__first1, __first2); } /** @@ -665,17 +675,18 @@ namespace std * false depending on whether all of the corresponding elements of the * ranges are equal. */ - template<typename _InputIter1, typename _InputIter2> + template<typename _InputIterator1, typename _InputIterator2> inline bool - equal(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2) + equal(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) - __glibcpp_function_requires(_EqualOpConcept< - typename iterator_traits<_InputIter1>::value_type, - typename iterator_traits<_InputIter2>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_EqualOpConcept< + typename iterator_traits<_InputIterator1>::value_type, + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); for ( ; __first1 != __last1; ++__first1, ++__first2) if (!(*__first1 == *__first2)) @@ -696,15 +707,17 @@ namespace std * false depending on whether all of the corresponding elements of the * ranges are equal. */ - template<typename _InputIter1, typename _InputIter2, typename _BinaryPredicate> + template<typename _InputIterator1, typename _InputIterator2, + typename _BinaryPredicate> inline bool - equal(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, + equal(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _BinaryPredicate __binary_pred) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); for ( ; __first1 != __last1; ++__first1, ++__first2) if (!__binary_pred(*__first1, *__first2)) @@ -712,9 +725,6 @@ namespace std return true; } - //-------------------------------------------------- - // lexicographical_compare - /** * @brief Performs "dictionary" comparison on ranges. * @param first1 An input iterator. @@ -729,26 +739,28 @@ namespace std * (Quoted from [25.3.8]/1.) If the iterators are all character pointers, * then this is an inline call to @c memcmp. */ - template<typename _InputIter1, typename _InputIter2> + template<typename _InputIterator1, typename _InputIterator2> bool - lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, _InputIter2 __last2) + lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) - __glibcpp_function_requires(_LessThanComparableConcept< - typename iterator_traits<_InputIter1>::value_type>) - __glibcpp_function_requires(_LessThanComparableConcept< - typename iterator_traits<_InputIter2>::value_type>) - - for ( ; __first1 != __last1 && __first2 != __last2 - ; ++__first1, ++__first2) { - if (*__first1 < *__first2) - return true; - if (*__first2 < *__first1) - return false; - } + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + + for (;__first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) + { + if (*__first1 < *__first2) + return true; + if (*__first2 < *__first1) + return false; + } return __first1 == __last1 && __first2 != __last2; } @@ -764,33 +776,43 @@ namespace std * The same as the four-parameter @c lexigraphical_compare, but uses the * comp parameter instead of @c <. */ - template<typename _InputIter1, typename _InputIter2, typename _Compare> + template<typename _InputIterator1, typename _InputIterator2, + typename _Compare> bool - lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, _InputIter2 __last2, + lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); for ( ; __first1 != __last1 && __first2 != __last2 - ; ++__first1, ++__first2) { - if (__comp(*__first1, *__first2)) - return true; - if (__comp(*__first2, *__first1)) - return false; - } + ; ++__first1, ++__first2) + { + if (__comp(*__first1, *__first2)) + return true; + if (__comp(*__first2, *__first1)) + return false; + } return __first1 == __last1 && __first2 != __last2; } - inline bool - lexicographical_compare(const unsigned char* __first1, const unsigned char* __last1, - const unsigned char* __first2, const unsigned char* __last2) + inline bool + lexicographical_compare(const unsigned char* __first1, + const unsigned char* __last1, + const unsigned char* __first2, + const unsigned char* __last2) { + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); + const size_t __len1 = __last1 - __first1; const size_t __len2 = __last2 - __first2; - const int __result = memcmp(__first1, __first2, min(__len1, __len2)); + const int __result = std::memcmp(__first1, __first2, + std::min(__len1, __len2)); return __result != 0 ? __result < 0 : __len1 < __len2; } @@ -798,23 +820,22 @@ namespace std lexicographical_compare(const char* __first1, const char* __last1, const char* __first2, const char* __last2) { + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __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); + return std::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); + return std::lexicographical_compare((const unsigned char*) __first1, + (const unsigned char*) __last1, + (const unsigned char*) __first2, + (const unsigned char*) __last2); #endif /* CHAR_MAX == SCHAR_MAX */ } } // namespace std -#endif /* __GLIBCPP_INTERNAL_ALGOBASE_H */ - -// Local Variables: -// mode:C++ -// End: +#endif diff --git a/contrib/libstdc++/include/bits/stl_bvector.h b/contrib/libstdc++/include/bits/stl_bvector.h index 2c97d470582e..afae738418d5 100644 --- a/contrib/libstdc++/include/bits/stl_bvector.h +++ b/contrib/libstdc++/include/bits/stl_bvector.h @@ -1,6 +1,6 @@ -// bit_vector and vector<bool> specialization -*- C++ -*- +// vector<bool> specialization -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,528 +58,646 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_BVECTOR_H -#define __GLIBCPP_INTERNAL_BVECTOR_H +#ifndef _BVECTOR_H +#define _BVECTOR_H 1 -namespace std -{ +namespace _GLIBCXX_STD +{ typedef unsigned long _Bit_type; - enum { _M_word_bit = int(CHAR_BIT * sizeof(_Bit_type)) }; + enum { _S_word_bit = int(CHAR_BIT * sizeof(_Bit_type)) }; -struct _Bit_reference { + struct _Bit_reference + { + _Bit_type * _M_p; + _Bit_type _M_mask; - _Bit_type * _M_p; - _Bit_type _M_mask; - _Bit_reference(_Bit_type * __x, _Bit_type __y) - : _M_p(__x), _M_mask(__y) {} + _Bit_reference(_Bit_type * __x, _Bit_type __y) + : _M_p(__x), _M_mask(__y) { } -public: - _Bit_reference() : _M_p(0), _M_mask(0) {} - operator bool() const { return !!(*_M_p & _M_mask); } - _Bit_reference& operator=(bool __x) - { - if (__x) *_M_p |= _M_mask; - else *_M_p &= ~_M_mask; - return *this; - } - _Bit_reference& operator=(const _Bit_reference& __x) + _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 + + bool + operator==(const _Bit_reference& __x) const { return bool(*this) == bool(__x); } - bool operator<(const _Bit_reference& __x) const + + bool + operator<(const _Bit_reference& __x) const { return !bool(*this) && bool(__x); } - void flip() { *_M_p ^= _M_mask; } -}; -struct _Bit_iterator_base : public iterator<random_access_iterator_tag, bool> -{ - _Bit_type * _M_p; - unsigned int _M_offset; + void + flip() { *_M_p ^= _M_mask; } + }; - _Bit_iterator_base(_Bit_type * __x, unsigned int __y) - : _M_p(__x), _M_offset(__y) {} + struct _Bit_iterator_base : public iterator<random_access_iterator_tag, bool> + { + _Bit_type * _M_p; + unsigned int _M_offset; + + _Bit_iterator_base(_Bit_type * __x, unsigned int __y) + : _M_p(__x), _M_offset(__y) { } - void _M_bump_up() { - if (_M_offset++ == _M_word_bit - 1) { - _M_offset = 0; - ++_M_p; + void + _M_bump_up() + { + if (_M_offset++ == _S_word_bit - 1) + { + _M_offset = 0; + ++_M_p; + } } - } - void _M_bump_down() { - if (_M_offset-- == 0) { - _M_offset = _M_word_bit - 1; - --_M_p; + + void + _M_bump_down() + { + if (_M_offset-- == 0) + { + _M_offset = _S_word_bit - 1; + --_M_p; + } } - } - void _M_incr(ptrdiff_t __i) { - difference_type __n = __i + _M_offset; - _M_p += __n / _M_word_bit; - __n = __n % _M_word_bit; - if (__n < 0) { - _M_offset = (unsigned int) __n + _M_word_bit; - --_M_p; - } else - _M_offset = (unsigned int) __n; - } + void + _M_incr(ptrdiff_t __i) + { + difference_type __n = __i + _M_offset; + _M_p += __n / _S_word_bit; + __n = __n % _S_word_bit; + if (__n < 0) + { + _M_offset = static_cast<unsigned int>(__n + _S_word_bit); + --_M_p; + } + else + _M_offset = static_cast<unsigned int>(__n); + } - bool operator==(const _Bit_iterator_base& __i) const { - return _M_p == __i._M_p && _M_offset == __i._M_offset; - } - bool operator<(const _Bit_iterator_base& __i) const { - return _M_p < __i._M_p || (_M_p == __i._M_p && _M_offset < __i._M_offset); - } - bool operator!=(const _Bit_iterator_base& __i) const { - return !(*this == __i); - } - bool operator>(const _Bit_iterator_base& __i) const { - return __i < *this; - } - bool operator<=(const _Bit_iterator_base& __i) const { - return !(__i < *this); - } - bool operator>=(const _Bit_iterator_base& __i) const { - return !(*this < __i); - } -}; + bool + operator==(const _Bit_iterator_base& __i) const + { return _M_p == __i._M_p && _M_offset == __i._M_offset; } -inline ptrdiff_t -operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y) { - return _M_word_bit * (__x._M_p - __y._M_p) + __x._M_offset - __y._M_offset; -} + bool + operator<(const _Bit_iterator_base& __i) const + { + return _M_p < __i._M_p + || (_M_p == __i._M_p && _M_offset < __i._M_offset); + } + bool + operator!=(const _Bit_iterator_base& __i) const + { return !(*this == __i); } -struct _Bit_iterator : public _Bit_iterator_base -{ - typedef _Bit_reference reference; - typedef _Bit_reference* pointer; - typedef _Bit_iterator iterator; - - _Bit_iterator() : _Bit_iterator_base(0, 0) {} - _Bit_iterator(_Bit_type * __x, unsigned int __y) - : _Bit_iterator_base(__x, __y) {} - - reference operator*() const { return reference(_M_p, 1UL << _M_offset); } - iterator& operator++() { - _M_bump_up(); - return *this; - } - iterator operator++(int) { - iterator __tmp = *this; - _M_bump_up(); - return __tmp; - } - iterator& operator--() { - _M_bump_down(); - return *this; - } - iterator operator--(int) { - iterator __tmp = *this; - _M_bump_down(); - return __tmp; - } - iterator& operator+=(difference_type __i) { - _M_incr(__i); - return *this; - } - iterator& operator-=(difference_type __i) { - *this += -__i; - return *this; - } - iterator operator+(difference_type __i) const { - iterator __tmp = *this; - return __tmp += __i; - } - iterator operator-(difference_type __i) const { - iterator __tmp = *this; - return __tmp -= __i; + bool + operator>(const _Bit_iterator_base& __i) const + { return __i < *this; } + + bool + operator<=(const _Bit_iterator_base& __i) const + { return !(__i < *this); } + + bool + operator>=(const _Bit_iterator_base& __i) const + { return !(*this < __i); } + }; + + inline ptrdiff_t + operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y) + { + return _S_word_bit * (__x._M_p - __y._M_p) + __x._M_offset - __y._M_offset; } - reference operator[](difference_type __i) { return *(*this + __i); } -}; + struct _Bit_iterator : public _Bit_iterator_base + { + typedef _Bit_reference reference; + typedef _Bit_reference* pointer; + typedef _Bit_iterator iterator; -inline _Bit_iterator -operator+(ptrdiff_t __n, const _Bit_iterator& __x) { return __x + __n; } + _Bit_iterator() : _Bit_iterator_base(0, 0) { } + _Bit_iterator(_Bit_type * __x, unsigned int __y) + : _Bit_iterator_base(__x, __y) { } + reference + operator*() const { return reference(_M_p, 1UL << _M_offset); } -struct _Bit_const_iterator : public _Bit_iterator_base -{ - typedef bool reference; - typedef bool const_reference; - typedef const bool* pointer; - typedef _Bit_const_iterator const_iterator; - - _Bit_const_iterator() : _Bit_iterator_base(0, 0) {} - _Bit_const_iterator(_Bit_type * __x, unsigned int __y) - : _Bit_iterator_base(__x, __y) {} - _Bit_const_iterator(const _Bit_iterator& __x) - : _Bit_iterator_base(__x._M_p, __x._M_offset) {} - - const_reference operator*() const { - return _Bit_reference(_M_p, 1UL << _M_offset); - } - const_iterator& operator++() { - _M_bump_up(); - return *this; - } - const_iterator operator++(int) { - const_iterator __tmp = *this; - _M_bump_up(); - return __tmp; - } - const_iterator& operator--() { - _M_bump_down(); - return *this; - } - const_iterator operator--(int) { - const_iterator __tmp = *this; - _M_bump_down(); - return __tmp; - } - const_iterator& operator+=(difference_type __i) { - _M_incr(__i); - return *this; - } - const_iterator& operator-=(difference_type __i) { - *this += -__i; - return *this; - } - const_iterator operator+(difference_type __i) const { - const_iterator __tmp = *this; - return __tmp += __i; - } - const_iterator operator-(difference_type __i) const { - const_iterator __tmp = *this; - return __tmp -= __i; - } - const_reference operator[](difference_type __i) { - return *(*this + __i); - } -}; - -inline _Bit_const_iterator -operator+(ptrdiff_t __n, const _Bit_const_iterator& __x) { return __x + __n; } - - -// Bit-vector base class, which encapsulates the difference between -// old SGI-style allocators and standard-conforming 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: - _Bit_type * _M_bit_alloc(size_t __n) - { return _M_data_allocator.allocate((__n + _M_word_bit - 1)/_M_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<_Bit_type, _Allocator>::allocator_type - _M_data_allocator; - _Bit_iterator _M_start; - _Bit_iterator _M_finish; - _Bit_type * _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<_Bit_type, _Allocator>::_Alloc_type - _Alloc_type; - - _Bit_type * _M_bit_alloc(size_t __n) - { return _Alloc_type::allocate((__n + _M_word_bit - 1)/_M_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; - _Bit_type * _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; + iterator& + operator++() + { + _M_bump_up(); + return *this; + } + + iterator + operator++(int) + { + iterator __tmp = *this; + _M_bump_up(); + return __tmp; + } + + iterator& + operator--() + { + _M_bump_down(); + return *this; + } + + iterator + operator--(int) + { + iterator __tmp = *this; + _M_bump_down(); + return __tmp; + } + + iterator& + operator+=(difference_type __i) + { + _M_incr(__i); + return *this; + } + + iterator& + operator-=(difference_type __i) + { + *this += -__i; + return *this; + } + + iterator + operator+(difference_type __i) const + { + iterator __tmp = *this; + return __tmp += __i; + } + + iterator + operator-(difference_type __i) const + { + iterator __tmp = *this; + return __tmp -= __i; + } + + reference + operator[](difference_type __i) + { return *(*this + __i); } + }; + + inline _Bit_iterator + operator+(ptrdiff_t __n, const _Bit_iterator& __x) { return __x + __n; } + + + struct _Bit_const_iterator : public _Bit_iterator_base + { + typedef bool reference; + typedef bool const_reference; + typedef const bool* pointer; + typedef _Bit_const_iterator const_iterator; + + _Bit_const_iterator() : _Bit_iterator_base(0, 0) { } + _Bit_const_iterator(_Bit_type * __x, unsigned int __y) + : _Bit_iterator_base(__x, __y) { } + _Bit_const_iterator(const _Bit_iterator& __x) + : _Bit_iterator_base(__x._M_p, __x._M_offset) { } + + const_reference + operator*() const + { return _Bit_reference(_M_p, 1UL << _M_offset); } + + const_iterator& + operator++() + { + _M_bump_up(); + return *this; + } + + const_iterator + operator++(int) + { + const_iterator __tmp = *this; + _M_bump_up(); + return __tmp; + } + + const_iterator& + operator--() + { + _M_bump_down(); + return *this; + } + + const_iterator + operator--(int) + { + const_iterator __tmp = *this; + _M_bump_down(); + return __tmp; + } + + const_iterator& + operator+=(difference_type __i) + { + _M_incr(__i); + return *this; + } + + const_iterator& + operator-=(difference_type __i) + { + *this += -__i; + return *this; + } + + const_iterator + operator+(difference_type __i) const { + const_iterator __tmp = *this; + return __tmp += __i; + } + + const_iterator + operator-(difference_type __i) const + { + const_iterator __tmp = *this; + return __tmp -= __i; + } - _Bvector_base(const allocator_type& __a) : _Base(__a) {} - ~_Bvector_base() { _Base::_M_deallocate(); } -}; + const_reference + operator[](difference_type __i) + { return *(*this + __i); } + }; + + inline _Bit_const_iterator + operator+(ptrdiff_t __n, const _Bit_const_iterator& __x) + { return __x + __n; } + template<class _Alloc> + class _Bvector_base + { + typedef typename _Alloc::template rebind<_Bit_type>::other + _Bit_alloc_type; + + struct _Bvector_impl : public _Bit_alloc_type + { + _Bit_iterator _M_start; + _Bit_iterator _M_finish; + _Bit_type* _M_end_of_storage; + _Bvector_impl(const _Bit_alloc_type& __a) + : _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage(0) + { } + }; + + public: + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return *static_cast<const _Bit_alloc_type*>(&this->_M_impl); } + + _Bvector_base(const allocator_type& __a) : _M_impl(__a) { } + + ~_Bvector_base() { this->_M_deallocate(); } + + protected: + _Bvector_impl _M_impl; + + _Bit_type* + _M_allocate(size_t __n) + { return _M_impl.allocate((__n + _S_word_bit - 1) / _S_word_bit); } + + void + _M_deallocate() + { + if (_M_impl._M_start._M_p) + _M_impl.deallocate(_M_impl._M_start._M_p, + _M_impl._M_end_of_storage - _M_impl._M_start._M_p); + } + }; } // namespace std // Declare a partial specialization of vector<T, Alloc>. #include <bits/stl_vector.h> -namespace std -{ -template <typename _Alloc> - class vector<bool, _Alloc> : public _Bvector_base<_Alloc> +namespace _GLIBCXX_STD +{ + /** + * @brief A specialization of vector for booleans which offers fixed time + * access to individual elements in any order. + * + * Note that vector<bool> does not actually meet the requirements for being + * a container. This is because the reference and pointer types are not + * really references and pointers to bool. See DR96 for details. @see + * vector for function documentation. + * + * @ingroup Containers + * @ingroup Sequences + * + * In some terminology a %vector can be described as a dynamic + * C-style array, it offers fast and efficient access to individual + * elements in any order and saves the user from worrying about + * memory and size allocation. Subscripting ( @c [] ) access is + * also provided as with C-style arrays. + */ +template<typename _Alloc> + class vector<bool, _Alloc> : public _Bvector_base<_Alloc> { public: typedef bool value_type; typedef size_t size_type; - typedef ptrdiff_t difference_type; + typedef ptrdiff_t difference_type; typedef _Bit_reference reference; typedef bool const_reference; typedef _Bit_reference* pointer; typedef const bool* const_pointer; - + typedef _Bit_iterator iterator; typedef _Bit_const_iterator const_iterator; - + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; - + typedef typename _Bvector_base<_Alloc>::allocator_type allocator_type; - allocator_type get_allocator() const { - return _Bvector_base<_Alloc>::get_allocator(); - } - + + allocator_type get_allocator() const + { return _Bvector_base<_Alloc>::get_allocator(); } + protected: - using _Bvector_base<_Alloc>::_M_bit_alloc; + using _Bvector_base<_Alloc>::_M_allocate; using _Bvector_base<_Alloc>::_M_deallocate; - using _Bvector_base<_Alloc>::_M_start; - using _Bvector_base<_Alloc>::_M_finish; - using _Bvector_base<_Alloc>::_M_end_of_storage; - + protected: - void _M_initialize(size_type __n) { - _Bit_type * __q = _M_bit_alloc(__n); - _M_end_of_storage = __q + (__n + _M_word_bit - 1)/_M_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() : static_cast<size_type>(_M_word_bit); - _Bit_type * __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 + _M_word_bit - 1)/_M_word_bit; - _M_start = iterator(__q, 0); - } + void _M_initialize(size_type __n) + { + _Bit_type* __q = this->_M_allocate(__n); + this->_M_impl._M_end_of_storage = __q + + (__n + _S_word_bit - 1) / _S_word_bit; + this->_M_impl._M_start = iterator(__q, 0); + this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n); } - - template <class _InputIterator> + + void _M_insert_aux(iterator __position, bool __x) + { + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) + { + std::copy_backward(__position, this->_M_impl._M_finish, + this->_M_impl._M_finish + 1); + *__position = __x; + ++this->_M_impl._M_finish; + } + else + { + const size_type __len = size() ? 2 * size() + : static_cast<size_type>(_S_word_bit); + _Bit_type * __q = this->_M_allocate(__len); + iterator __i = std::copy(begin(), __position, iterator(__q, 0)); + *__i++ = __x; + this->_M_impl._M_finish = std::copy(__position, end(), __i); + this->_M_deallocate(); + this->_M_impl._M_end_of_storage = __q + (__len + _S_word_bit - 1) + / _S_word_bit; + this->_M_impl._M_start = iterator(__q, 0); + } + } + + 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) + input_iterator_tag) + { + this->_M_impl._M_start = iterator(); + this->_M_impl._M_finish = iterator(); + this->_M_impl._M_end_of_storage = 0; + for ( ; __first != __last; ++__first) push_back(*__first); } - - template <class _ForwardIterator> + + template<class _ForwardIterator> void _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last, - forward_iterator_tag) { - size_type __n = distance(__first, __last); + forward_iterator_tag) + { + const size_type __n = std::distance(__first, __last); _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; - } + std::copy(__first, __last, this->_M_impl._M_start); } - - template <class _ForwardIterator> - void _M_insert_range(iterator __position, - _ForwardIterator __first, _ForwardIterator __last, - forward_iterator_tag) { - if (__first != __last) { - size_type __n = distance(__first, __last); - 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); - _Bit_type * __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 + _M_word_bit - 1)/_M_word_bit; - _M_start = iterator(__q, 0); - } - } - } - + + 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 _M_insert_range(iterator __position, _ForwardIterator __first, + _ForwardIterator __last, forward_iterator_tag) + { + if (__first != __last) + { + size_type __n = std::distance(__first, __last); + if (capacity() - size() >= __n) + { + std::copy_backward(__position, end(), + this->_M_impl._M_finish + difference_type(__n)); + std::copy(__first, __last, __position); + this->_M_impl._M_finish += difference_type(__n); + } + else + { + const size_type __len = size() + std::max(size(), __n); + _Bit_type * __q = this->_M_allocate(__len); + iterator __i = std::copy(begin(), __position, iterator(__q, 0)); + __i = std::copy(__first, __last, __i); + this->_M_impl._M_finish = std::copy(__position, end(), __i); + this->_M_deallocate(); + this->_M_impl._M_end_of_storage = __q + (__len + _S_word_bit - 1) + / _S_word_bit; + this->_M_impl._M_start = iterator(__q, 0); + } + } + } + public: - iterator begin() { return _M_start; } - const_iterator begin() const { return _M_start; } - iterator end() { return _M_finish; } - const_iterator end() const { return _M_finish; } - - reverse_iterator rbegin() { return reverse_iterator(end()); } - const_reverse_iterator rbegin() const { - return const_reverse_iterator(end()); - } - reverse_iterator rend() { return reverse_iterator(begin()); } - const_reverse_iterator rend() const { - return const_reverse_iterator(begin()); - } - - size_type size() const { return size_type(end() - begin()); } - size_type max_size() const { return size_type(-1); } - size_type capacity() const { - return size_type(const_iterator(_M_end_of_storage, 0) - begin()); - } - bool empty() const { return begin() == end(); } - + iterator begin() + { return this->_M_impl._M_start; } + + const_iterator begin() const + { return this->_M_impl._M_start; } + + iterator end() + { return this->_M_impl._M_finish; } + + const_iterator end() const + { return this->_M_impl._M_finish; } + + reverse_iterator rbegin() + { return reverse_iterator(end()); } + + const_reverse_iterator rbegin() const + { return const_reverse_iterator(end()); } + + reverse_iterator rend() + { return reverse_iterator(begin()); } + + const_reverse_iterator rend() const + { return const_reverse_iterator(begin()); } + + size_type size() const + { return size_type(end() - begin()); } + + size_type max_size() const + { return size_type(-1); } + + size_type capacity() const + { return size_type(const_iterator(this->_M_impl._M_end_of_storage, 0) + - begin()); } + bool empty() const + { return begin() == end(); } + reference operator[](size_type __n) - { return *(begin() + difference_type(__n)); } + { return *(begin() + difference_type(__n)); } + const_reference operator[](size_type __n) const - { return *(begin() + difference_type(__n)); } - - void _M_range_check(size_type __n) const { + { return *(begin() + difference_type(__n)); } + + void _M_range_check(size_type __n) const + { if (__n >= this->size()) - __throw_out_of_range("vector<bool>"); + __throw_out_of_range(__N("vector<bool>::_M_range_check")); } - + reference at(size_type __n) - { _M_range_check(__n); return (*this)[__n]; } + { _M_range_check(__n); return (*this)[__n]; } + const_reference at(size_type __n) const - { _M_range_check(__n); return (*this)[__n]; } - + { _M_range_check(__n); return (*this)[__n]; } + explicit vector(const allocator_type& __a = allocator_type()) - : _Bvector_base<_Alloc>(__a) {} - - vector(size_type __n, bool __value, - const allocator_type& __a = allocator_type()) - : _Bvector_base<_Alloc>(__a) + : _Bvector_base<_Alloc>(__a) { } + + vector(size_type __n, bool __value, + const allocator_type& __a = allocator_type()) + : _Bvector_base<_Alloc>(__a) { _M_initialize(__n); - fill(_M_start._M_p, _M_end_of_storage, __value ? ~0 : 0); + std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_of_storage, + __value ? ~0 : 0); } - + explicit vector(size_type __n) - : _Bvector_base<_Alloc>(allocator_type()) + : _Bvector_base<_Alloc>(allocator_type()) { _M_initialize(__n); - fill(_M_start._M_p, _M_end_of_storage, 0); + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, 0); } - - vector(const vector& __x) : _Bvector_base<_Alloc>(__x.get_allocator()) { + + vector(const vector& __x) : _Bvector_base<_Alloc>(__x.get_allocator()) + { _M_initialize(__x.size()); - copy(__x.begin(), __x.end(), _M_start); + std::copy(__x.begin(), __x.end(), this->_M_impl._M_start); } - + // Check whether it's an integral type. If so, it's not an iterator. - - template <class _Integer> - void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { + 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); + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._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)); - } - - template <class _InputIterator> - vector(_InputIterator __first, _InputIterator __last, - const allocator_type& __a = allocator_type()) - : _Bvector_base<_Alloc>(__a) + + template<class _InputIterator> + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { _M_initialize_range(__first, __last, + std::__iterator_category(__first)); } + + template<class _InputIterator> + vector(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Bvector_base<_Alloc>(__a) { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_initialize_dispatch(__first, __last, _Integral()); } - + ~vector() { } - - vector& operator=(const vector& __x) { - if (&__x == this) return *this; - if (__x.size() > capacity()) { - _M_deallocate(); - _M_initialize(__x.size()); - } - copy(__x.begin(), __x.end(), begin()); - _M_finish = begin() + difference_type(__x.size()); + + vector& operator=(const vector& __x) + { + if (&__x == this) + return *this; + if (__x.size() > capacity()) + { + this->_M_deallocate(); + _M_initialize(__x.size()); + } + std::copy(__x.begin(), __x.end(), begin()); + this->_M_impl._M_finish = begin() + difference_type(__x.size()); return *this; } - + // assign(), a generalized assignment member function. Two // versions: one that takes a count, and one that takes a range. // The range version is a member template, so we dispatch on whether // or not the type is an integer. - - void _M_fill_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); - } + + void _M_fill_assign(size_t __n, bool __x) + { + if (__n > size()) + { + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, __x ? ~0 : 0); + insert(end(), __n - size(), __x); + } + else + { + erase(begin() + __n, end()); + std::fill(this->_M_impl._M_start._M_p, + this->_M_impl._M_end_of_storage, __x ? ~0 : 0); + } } - - void assign(size_t __n, bool __x) { _M_fill_assign(__n, __x); } - - template <class _InputIterator> - void assign(_InputIterator __first, _InputIterator __last) { + + void assign(size_t __n, bool __x) + { _M_fill_assign(__n, __x); } + + 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> + + template<class _Integer> void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) - { _M_fill_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> + { _M_fill_assign((size_t) __n, (bool) __val); } + + template<class _InputIterator> + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { _M_assign_aux(__first, __last, std::__iterator_category(__first)); } + + template<class _InputIterator> void _M_assign_aux(_InputIterator __first, _InputIterator __last, - input_iterator_tag) { + input_iterator_tag) + { iterator __cur = begin(); for ( ; __first != __last && __cur != end(); ++__cur, ++__first) *__cur = *__first; @@ -588,142 +706,171 @@ template <typename _Alloc> else insert(end(), __first, __last); } - - template <class _ForwardIterator> + + template<class _ForwardIterator> void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, - forward_iterator_tag) { - size_type __len = distance(__first, __last); + forward_iterator_tag) + { + const size_type __len = std::distance(__first, __last); if (__len < size()) - erase(copy(__first, __last, begin()), end()); - else { - _ForwardIterator __mid = __first; - advance(__mid, size()); - copy(__first, __mid, begin()); - insert(end(), __mid, __last); - } - } - - void reserve(size_type __n) { + erase(std::copy(__first, __last, begin()), end()); + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, size()); + std::copy(__first, __mid, begin()); + insert(end(), __mid, __last); + } + } + + void reserve(size_type __n) + { if (__n > this->max_size()) - __throw_length_error("vector::reserve"); - if (this->capacity() < __n) { - _Bit_type * __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 + _M_word_bit - 1)/_M_word_bit; - } + __throw_length_error(__N("vector::reserve")); + if (this->capacity() < __n) + { + _Bit_type* __q = this->_M_allocate(__n); + this->_M_impl._M_finish = std::copy(begin(), end(), + iterator(__q, 0)); + this->_M_deallocate(); + this->_M_impl._M_start = iterator(__q, 0); + this->_M_impl._M_end_of_storage = __q + (__n + _S_word_bit - 1) / _S_word_bit; + } } - - reference front() { return *begin(); } - const_reference front() const { return *begin(); } - reference back() { return *(end() - 1); } - const_reference back() const { return *(end() - 1); } - void push_back(bool __x) { - if (_M_finish._M_p != _M_end_of_storage) - *_M_finish++ = __x; + + 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 (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) + *this->_M_impl._M_finish++ = __x; else _M_insert_aux(end(), __x); } - void swap(vector<bool, _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); + + void swap(vector<bool, _Alloc>& __x) + { + std::swap(this->_M_impl._M_start, __x._M_impl._M_start); + std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); + std::swap(this->_M_impl._M_end_of_storage, + __x._M_impl._M_end_of_storage); } // [23.2.5]/1, third-to-last entry in synopsis listing - static void swap(reference __x, reference __y) { + static void swap(reference __x, reference __y) + { bool __tmp = __x; __x = __y; __y = __tmp; } - 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; + iterator insert(iterator __position, bool __x = bool()) + { + const difference_type __n = __position - begin(); + if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage + && __position == end()) + *this->_M_impl._M_finish++ = __x; else _M_insert_aux(__position, __x); return begin() + __n; } - + // Check whether it's an integral type. If so, it's not an iterator. - - template <class _Integer> + + template<class _Integer> void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, - __true_type) { - _M_fill_insert(__pos, __n, __x); - } - - template <class _InputIterator> + __true_type) + { _M_fill_insert(__pos, __n, __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)); - } - - template <class _InputIterator> + __false_type) + { _M_insert_range(__pos, __first, __last, + std::__iterator_category(__first)); } + + template<class _InputIterator> void insert(iterator __position, - _InputIterator __first, _InputIterator __last) { + _InputIterator __first, _InputIterator __last) + { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_insert_dispatch(__position, __first, __last, _Integral()); } - - void _M_fill_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); - _Bit_type * __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 + _M_word_bit - 1)/_M_word_bit; - _M_start = iterator(__q, 0); - } - } - - void insert(iterator __position, size_type __n, bool __x) { - _M_fill_insert(__position, __n, __x); - } - - void pop_back() { --_M_finish; } - iterator erase(iterator __position) { + + void _M_fill_insert(iterator __position, size_type __n, bool __x) + { + if (__n == 0) + return; + if (capacity() - size() >= __n) + { + std::copy_backward(__position, end(), + this->_M_impl._M_finish + difference_type(__n)); + std::fill(__position, __position + difference_type(__n), __x); + this->_M_impl._M_finish += difference_type(__n); + } + else + { + const size_type __len = size() + std::max(size(), __n); + _Bit_type * __q = this->_M_allocate(__len); + iterator __i = std::copy(begin(), __position, iterator(__q, 0)); + std::fill_n(__i, __n, __x); + this->_M_impl._M_finish = std::copy(__position, end(), + __i + difference_type(__n)); + this->_M_deallocate(); + this->_M_impl._M_end_of_storage = __q + (__len + _S_word_bit - 1) + / _S_word_bit; + this->_M_impl._M_start = iterator(__q, 0); + } + } + + void insert(iterator __position, size_type __n, bool __x) + { _M_fill_insert(__position, __n, __x); } + + void pop_back() + { --this->_M_impl._M_finish; } + + iterator erase(iterator __position) + { if (__position + 1 != end()) - copy(__position + 1, end(), __position); - --_M_finish; + std::copy(__position + 1, end(), __position); + --this->_M_impl._M_finish; return __position; } - iterator erase(iterator __first, iterator __last) { - _M_finish = copy(__last, end(), __first); + + iterator erase(iterator __first, iterator __last) + { + this->_M_impl._M_finish = std::copy(__last, end(), __first); return __first; } - void resize(size_type __new_size, bool __x = bool()) { - if (__new_size < size()) + + void resize(size_type __new_size, bool __x = bool()) + { + if (__new_size < size()) erase(begin() + difference_type(__new_size), end()); else insert(end(), __new_size - size(), __x); } - void flip() { - for (_Bit_type * __p = _M_start._M_p; __p != _M_end_of_storage; ++__p) + + void flip() + { + for (_Bit_type * __p = this->_M_impl._M_start._M_p; + __p != this->_M_impl._M_end_of_storage; ++__p) *__p = ~*__p; } - - void clear() { erase(begin(), end()); } - }; - -// This typedef is non-standard. It is provided for backward compatibility. -typedef vector<bool, __alloc> bit_vector; -} // namespace std - -#endif /* __GLIBCPP_INTERNAL_BVECTOR_H */ + void clear() + { erase(begin(), end()); } + }; +} // namespace std -// Local Variables: -// mode:C++ -// End: +#endif diff --git a/contrib/libstdc++/include/bits/stl_construct.h b/contrib/libstdc++/include/bits/stl_construct.h index 685913888c85..afb338798521 100644 --- a/contrib/libstdc++/include/bits/stl_construct.h +++ b/contrib/libstdc++/include/bits/stl_construct.h @@ -1,6 +1,6 @@ // nonstandard construct and destroy functions -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,8 +58,8 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_STL_CONSTRUCT_H -#define _CPP_BITS_STL_CONSTRUCT_H 1 +#ifndef _STL_CONSTRUCT_H +#define _STL_CONSTRUCT_H 1 #include <bits/type_traits.h> #include <new> @@ -72,33 +72,52 @@ namespace std * object's constructor with an initializer. * @endif */ - template <class _T1, class _T2> + template<typename _T1, typename _T2> inline void _Construct(_T1* __p, const _T2& __value) - { new (static_cast<void*>(__p)) _T1(__value); } - + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_]allocator::construct + ::new(static_cast<void*>(__p)) _T1(__value); + } + /** * @if maint * Constructs an object in existing memory by invoking an allocated * object's default constructor (no initializers). * @endif */ - template <class _T1> + template<typename _T1> inline void _Construct(_T1* __p) - { new (static_cast<void*>(__p)) _T1(); } + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_]allocator::construct + ::new(static_cast<void*>(__p)) _T1(); + } + + /** + * @if maint + * Destroy the object pointed to by a pointer type. + * @endif + */ + template<typename _Tp> + inline void + _Destroy(_Tp* __pointer) + { __pointer->~_Tp(); } /** * @if maint - * Destroy a range of objects with nontrivial destructors. + * Destroy a range of objects with nontrivial destructors. * * This is a helper function used only by _Destroy(). * @endif */ - template <class _ForwardIterator> + template<typename _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) std::_Destroy(&*__first); } /** * @if maint @@ -109,29 +128,19 @@ namespace std * This is a helper function used only by _Destroy(). * @endif */ - template <class _ForwardIterator> + template<typename _ForwardIterator> inline void __destroy_aux(_ForwardIterator, _ForwardIterator, __true_type) { } /** * @if maint - * Destroy the object pointed to by a pointer type. - * @endif - */ - template <class _Tp> - inline void - _Destroy(_Tp* __pointer) - { __pointer->~_Tp(); } - - /** - * @if maint * Destroy a range of objects. If the value_type of the object has * a trivial destructor, the compiler should optimize all of this * away, otherwise the objects' destructors must be invoked. * @endif */ - template <class _ForwardIterator> + template<typename _ForwardIterator> inline void _Destroy(_ForwardIterator __first, _ForwardIterator __last) { @@ -140,9 +149,9 @@ namespace std typedef typename __type_traits<_Value_type>::has_trivial_destructor _Has_trivial_destructor; - __destroy_aux(__first, __last, _Has_trivial_destructor()); + std::__destroy_aux(__first, __last, _Has_trivial_destructor()); } } // namespace std -#endif /* _CPP_BITS_STL_CONSTRUCT_H */ +#endif /* _STL_CONSTRUCT_H */ diff --git a/contrib/libstdc++/include/bits/stl_deque.h b/contrib/libstdc++/include/bits/stl_deque.h index 454fed31bf73..54dadf2c659c 100644 --- a/contrib/libstdc++/include/bits/stl_deque.h +++ b/contrib/libstdc++/include/bits/stl_deque.h @@ -1,6 +1,6 @@ // Deque implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,15 +58,15 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_DEQUE_H -#define __GLIBCPP_INTERNAL_DEQUE_H +#ifndef _DEQUE_H +#define _DEQUE_H 1 #include <bits/concept_check.h> #include <bits/stl_iterator_base_types.h> #include <bits/stl_iterator_base_funcs.h> -namespace std -{ +namespace _GLIBCXX_STD +{ /** * @if maint * @brief This function controls the size of memory nodes. @@ -79,11 +79,11 @@ namespace std * been done since inheriting the SGI code. * @endif */ - inline size_t - __deque_buf_size(size_t __size) + inline size_t + __deque_buf_size(size_t __size) { return __size < 512 ? size_t(512 / __size) : size_t(1); } - - + + /** * @brief A deque::iterator. * @@ -96,390 +96,337 @@ namespace std * All the functions are op overloads except for _M_set_node. * @endif */ - template <typename _Tp, typename _Ref, typename _Ptr> + template<typename _Tp, typename _Ref, typename _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(sizeof(_Tp)); } - - typedef random_access_iterator_tag iterator_category; - typedef _Tp value_type; - typedef _Ptr pointer; - typedef _Ref reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef _Tp** _Map_pointer; - typedef _Deque_iterator _Self; - - _Tp* _M_cur; - _Tp* _M_first; - _Tp* _M_last; - _Map_pointer _M_node; - - _Deque_iterator(_Tp* __x, _Map_pointer __y) + { + 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(sizeof(_Tp)); } + + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp** _Map_pointer; + typedef _Deque_iterator _Self; + + _Tp* _M_cur; + _Tp* _M_first; + _Tp* _M_last; + _Map_pointer _M_node; + + _Deque_iterator(_Tp* __x, _Map_pointer __y) : _M_cur(__x), _M_first(*__y), _M_last(*__y + _S_buffer_size()), _M_node(__y) {} - _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {} - _Deque_iterator(const iterator& __x) - : _M_cur(__x._M_cur), _M_first(__x._M_first), + + _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {} + + _Deque_iterator(const iterator& __x) + : _M_cur(__x._M_cur), _M_first(__x._M_first), _M_last(__x._M_last), _M_node(__x._M_node) {} - - reference operator*() const { return *_M_cur; } - pointer operator->() const { return _M_cur; } - - _Self& operator++() { - ++_M_cur; - if (_M_cur == _M_last) { - _M_set_node(_M_node + 1); - _M_cur = _M_first; + + reference + operator*() const + { return *_M_cur; } + + pointer + operator->() const + { return _M_cur; } + + _Self& + operator++() + { + ++_M_cur; + if (_M_cur == _M_last) + { + _M_set_node(_M_node + 1); + _M_cur = _M_first; + } + return *this; } - return *this; - } - _Self operator++(int) { - _Self __tmp = *this; - ++*this; - return __tmp; - } - - _Self& operator--() { - if (_M_cur == _M_first) { - _M_set_node(_M_node - 1); - _M_cur = _M_last; + + _Self + operator++(int) + { + _Self __tmp = *this; + ++*this; + return __tmp; } - --_M_cur; - return *this; - } - _Self operator--(int) { - _Self __tmp = *this; - --*this; - return __tmp; - } - - _Self& operator+=(difference_type __n) - { - difference_type __offset = __n + (_M_cur - _M_first); - if (__offset >= 0 && __offset < difference_type(_S_buffer_size())) - _M_cur += __n; - else { - difference_type __node_offset = - __offset > 0 ? __offset / difference_type(_S_buffer_size()) - : -difference_type((-__offset - 1) / _S_buffer_size()) - 1; - _M_set_node(_M_node + __node_offset); - _M_cur = _M_first + - (__offset - __node_offset * difference_type(_S_buffer_size())); + + _Self& + operator--() + { + if (_M_cur == _M_first) + { + _M_set_node(_M_node - 1); + _M_cur = _M_last; + } + --_M_cur; + return *this; } - return *this; - } - - _Self operator+(difference_type __n) const - { - _Self __tmp = *this; - return __tmp += __n; - } - - _Self& operator-=(difference_type __n) { return *this += -__n; } - - _Self operator-(difference_type __n) const { - _Self __tmp = *this; - return __tmp -= __n; - } - - reference operator[](difference_type __n) const { return *(*this + __n); } - - /** @if maint - * Prepares to traverse new_node. Sets everything except _M_cur, which - * should therefore be set by the caller immediately afterwards, based on - * _M_first and _M_last. - * @endif - */ - 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()); - } - }; - + + _Self + operator--(int) + { + _Self __tmp = *this; + --*this; + return __tmp; + } + + _Self& + operator+=(difference_type __n) + { + const difference_type __offset = __n + (_M_cur - _M_first); + if (__offset >= 0 && __offset < difference_type(_S_buffer_size())) + _M_cur += __n; + else + { + const difference_type __node_offset = + __offset > 0 ? __offset / difference_type(_S_buffer_size()) + : -difference_type((-__offset - 1) + / _S_buffer_size()) - 1; + _M_set_node(_M_node + __node_offset); + _M_cur = _M_first + (__offset - __node_offset + * difference_type(_S_buffer_size())); + } + return *this; + } + + _Self + operator+(difference_type __n) const + { + _Self __tmp = *this; + return __tmp += __n; + } + + _Self& + operator-=(difference_type __n) + { return *this += -__n; } + + _Self + operator-(difference_type __n) const + { + _Self __tmp = *this; + return __tmp -= __n; + } + + reference + operator[](difference_type __n) const + { return *(*this + __n); } + + /** @if maint + * Prepares to traverse new_node. Sets everything except _M_cur, which + * should therefore be set by the caller immediately afterwards, based on + * _M_first and _M_last. + * @endif + */ + 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()); + } + }; + // Note: we also provide overloads whose operands are of the same type in // order to avoid ambiguous overload resolution when std::rel_ops operators // are in scope (for additional details, see libstdc++/3628) - template <typename _Tp, typename _Ref, typename _Ptr> - inline bool - operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) - { - return __x._M_cur == __y._M_cur; - } - - template <typename _Tp, typename _RefL, typename _PtrL, - typename _RefR, typename _PtrR> - inline bool - operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) - { - return __x._M_cur == __y._M_cur; - } - - template <typename _Tp, typename _Ref, typename _Ptr> - inline bool - operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) - { - return !(__x == __y); - } - - template <typename _Tp, typename _RefL, typename _PtrL, - typename _RefR, typename _PtrR> - inline bool - operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) - { - return !(__x == __y); - } - - template <typename _Tp, typename _Ref, typename _Ptr> - inline bool - operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) - { - return (__x._M_node == __y._M_node) ? - (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node); - } - - template <typename _Tp, typename _RefL, typename _PtrL, - typename _RefR, typename _PtrR> - inline bool - operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) - { - return (__x._M_node == __y._M_node) ? - (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node); - } - - template <typename _Tp, typename _Ref, typename _Ptr> - inline bool - operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) - { - return __y < __x; - } - - template <typename _Tp, typename _RefL, typename _PtrL, - typename _RefR, typename _PtrR> - inline bool - operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) - { - return __y < __x; - } - - template <typename _Tp, typename _Ref, typename _Ptr> - inline bool - operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) - { - return !(__y < __x); - } - - template <typename _Tp, typename _RefL, typename _PtrL, - typename _RefR, typename _PtrR> - inline bool - operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) - { - return !(__y < __x); - } - - template <typename _Tp, typename _Ref, typename _Ptr> - inline bool - operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) - { - return !(__x < __y); - } - - template <typename _Tp, typename _RefL, typename _PtrL, - typename _RefR, typename _PtrR> - inline bool - operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) - { - return !(__x < __y); - } - - // _GLIBCPP_RESOLVE_LIB_DEFECTS + template<typename _Tp, typename _Ref, typename _Ptr> + inline bool + operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return __x._M_cur == __y._M_cur; } + + template<typename _Tp, typename _RefL, typename _PtrL, + typename _RefR, typename _PtrR> + inline bool + operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return __x._M_cur == __y._M_cur; } + + template<typename _Tp, typename _Ref, typename _Ptr> + inline bool + operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return !(__x == __y); } + + template<typename _Tp, typename _RefL, typename _PtrL, + typename _RefR, typename _PtrR> + inline bool + operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return !(__x == __y); } + + template<typename _Tp, typename _Ref, typename _Ptr> + inline bool + operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) + : (__x._M_node < __y._M_node); } + + template<typename _Tp, typename _RefL, typename _PtrL, + typename _RefR, typename _PtrR> + inline bool + operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) + : (__x._M_node < __y._M_node); } + + template<typename _Tp, typename _Ref, typename _Ptr> + inline bool + operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return __y < __x; } + + template<typename _Tp, typename _RefL, typename _PtrL, + typename _RefR, typename _PtrR> + inline bool + operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return __y < __x; } + + template<typename _Tp, typename _Ref, typename _Ptr> + inline bool + operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return !(__y < __x); } + + template<typename _Tp, typename _RefL, typename _PtrL, + typename _RefR, typename _PtrR> + inline bool + operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return !(__y < __x); } + + template<typename _Tp, typename _Ref, typename _Ptr> + inline bool + operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return !(__x < __y); } + + template<typename _Tp, typename _RefL, typename _PtrL, + typename _RefR, typename _PtrR> + inline bool + operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return !(__x < __y); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS // According to the resolution of DR179 not only the various comparison // operators but also operator- must accept mixed iterator/const_iterator // parameters. - template <typename _Tp, typename _RefL, typename _PtrL, - typename _RefR, typename _PtrR> - inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type - operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) - { - return _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type - (_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size()) * - (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) + - (__y._M_last - __y._M_cur); - } - - template <typename _Tp, typename _Ref, typename _Ptr> - inline _Deque_iterator<_Tp, _Ref, _Ptr> - operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x) - { - return __x + __n; - } - - - /// @if maint Primary default version. @endif - /** - * @if maint - * 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. (See stl_alloc.h for more on this topic.) There are two - * versions: this ordinary one, and the space-saving specialization for - * instanceless allocators. - * @endif - */ - template <typename _Tp, typename _Alloc, bool __is_static> - class _Deque_alloc_base - { - public: - typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type; - allocator_type get_allocator() const { return _M_node_allocator; } - - _Deque_alloc_base(const allocator_type& __a) - : _M_node_allocator(__a), _M_map_allocator(__a), - _M_map(0), _M_map_size(0) - {} - - protected: - typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type - _Map_allocator_type; - - _Tp* - _M_allocate_node() - { - return _M_node_allocator.allocate(__deque_buf_size(sizeof(_Tp))); - } - - void - _M_deallocate_node(_Tp* __p) - { - _M_node_allocator.deallocate(__p, __deque_buf_size(sizeof(_Tp))); - } - - _Tp** - _M_allocate_map(size_t __n) - { return _M_map_allocator.allocate(__n); } - - void - _M_deallocate_map(_Tp** __p, size_t __n) - { _M_map_allocator.deallocate(__p, __n); } - - allocator_type _M_node_allocator; - _Map_allocator_type _M_map_allocator; - _Tp** _M_map; - size_t _M_map_size; - }; - - /// @if maint Specialization for instanceless allocators. @endif - template <typename _Tp, typename _Alloc> - class _Deque_alloc_base<_Tp, _Alloc, 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(sizeof(_Tp))); - } - - void - _M_deallocate_node(_Tp* __p) + template<typename _Tp, typename _RefL, typename _PtrL, + typename _RefR, typename _PtrR> + inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type + operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) { - _Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp))); + return typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type + (_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size()) + * (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) + + (__y._M_last - __y._M_cur); } - - _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<typename _Tp, typename _Ref, typename _Ptr> + inline _Deque_iterator<_Tp, _Ref, _Ptr> + operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x) + { return __x + __n; } + /** * @if maint - * Deque base class. Using _Alloc_traits in the instantiation of the parent - * class provides the compile-time dispatching mentioned in the parent's - * docs. This class provides the unified face for %deque's allocation. + * Deque base class. This class provides the unified face for %deque's + * allocation. This class's constructor and destructor allocate and + * deallocate (but do not initialize) storage. This makes %exception + * safety easier. * * Nothing in this class ever constructs or destroys an actual Tp element. * (Deque handles that itself.) Only/All memory management is performed * here. * @endif */ - template <typename _Tp, typename _Alloc> + template<typename _Tp, typename _Alloc> class _Deque_base - : public _Deque_alloc_base<_Tp,_Alloc, - _Alloc_traits<_Tp, _Alloc>::_S_instanceless> - { - public: - typedef _Deque_alloc_base<_Tp,_Alloc, - _Alloc_traits<_Tp, _Alloc>::_S_instanceless> - _Base; - typedef typename _Base::allocator_type allocator_type; - typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator; - typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; - - _Deque_base(const allocator_type& __a, size_t __num_elements) - : _Base(__a), _M_start(), _M_finish() + { + public: + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return *static_cast<const _Alloc*>(&this->_M_impl); } + + typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator; + typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; + + _Deque_base(const allocator_type& __a, size_t __num_elements) + : _M_impl(__a) { _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 }; - - iterator _M_start; - iterator _M_finish; - }; - - - template <typename _Tp, typename _Alloc> + + _Deque_base(const allocator_type& __a) + : _M_impl(__a) + { } + + ~_Deque_base(); + + protected: + //This struct encapsulates the implementation of the std::deque + //standard container and at the same time makes use of the EBO + //for empty allocators. + struct _Deque_impl + : public _Alloc { + _Tp** _M_map; + size_t _M_map_size; + iterator _M_start; + iterator _M_finish; + + _Deque_impl(const _Alloc& __a) + : _Alloc(__a), _M_map(0), _M_map_size(0), _M_start(), _M_finish() + { } + }; + + typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type; + _Map_alloc_type _M_get_map_allocator() const + { return _Map_alloc_type(this->get_allocator()); } + + _Tp* + _M_allocate_node() + { return _M_impl._Alloc::allocate(__deque_buf_size(sizeof(_Tp))); } + + void + _M_deallocate_node(_Tp* __p) + { _M_impl._Alloc::deallocate(__p, __deque_buf_size(sizeof(_Tp))); } + + _Tp** + _M_allocate_map(size_t __n) + { return _M_get_map_allocator().allocate(__n); } + + void + _M_deallocate_map(_Tp** __p, size_t __n) + { _M_get_map_allocator().deallocate(__p, __n); } + + 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 }; + + _Deque_impl _M_impl; + }; + + template<typename _Tp, typename _Alloc> _Deque_base<_Tp,_Alloc>::~_Deque_base() { - if (_M_map) + if (this->_M_impl._M_map) { - _M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1); - _M_deallocate_map(_M_map, _M_map_size); + _M_destroy_nodes(this->_M_impl._M_start._M_node, this->_M_impl._M_finish._M_node + 1); + _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); } } - + /** * @if maint * @brief Layout storage. @@ -490,65 +437,66 @@ namespace std * The initial underlying memory layout is a bit complicated... * @endif */ - template <typename _Tp, typename _Alloc> - void - _Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements) - { - size_t __num_nodes = - __num_elements / __deque_buf_size(sizeof(_Tp)) + 1; - - _M_map_size = max((size_t) _S_initial_map_size, __num_nodes + 2); - _M_map = _M_allocate_map(_M_map_size); - - // For "small" maps (needing less than _M_map_size nodes), allocation - // starts in the middle elements and grows outwards. So nstart may be the - // beginning of _M_map, but for small maps it may be as far in as _M_map+3. - - _Tp** __nstart = _M_map + (_M_map_size - __num_nodes) / 2; - _Tp** __nfinish = __nstart + __num_nodes; - - try - { _M_create_nodes(__nstart, __nfinish); } - catch(...) - { - _M_deallocate_map(_M_map, _M_map_size); - _M_map = 0; - _M_map_size = 0; - __throw_exception_again; - } - - _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(sizeof(_Tp)); - } - - template <typename _Tp, typename _Alloc> - void _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish) - { - _Tp** __cur; - try - { - for (__cur = __nstart; __cur < __nfinish; ++__cur) - *__cur = _M_allocate_node(); - } - catch(...) - { - _M_destroy_nodes(__nstart, __cur); - __throw_exception_again; - } - } - - template <typename _Tp, typename _Alloc> - void - _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) - { - for (_Tp** __n = __nstart; __n < __nfinish; ++__n) - _M_deallocate_node(*__n); - } - - + template<typename _Tp, typename _Alloc> + void + _Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements) + { + size_t __num_nodes = __num_elements / __deque_buf_size(sizeof(_Tp)) + 1; + + this->_M_impl._M_map_size = std::max((size_t) _S_initial_map_size, + __num_nodes + 2); + this->_M_impl._M_map = _M_allocate_map(this->_M_impl._M_map_size); + + // For "small" maps (needing less than _M_map_size nodes), allocation + // starts in the middle elements and grows outwards. So nstart may be + // the beginning of _M_map, but for small maps it may be as far in as + // _M_map+3. + + _Tp** __nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size - __num_nodes) / 2; + _Tp** __nfinish = __nstart + __num_nodes; + + try + { _M_create_nodes(__nstart, __nfinish); } + catch(...) + { + _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); + this->_M_impl._M_map = 0; + this->_M_impl._M_map_size = 0; + __throw_exception_again; + } + + this->_M_impl._M_start._M_set_node(__nstart); + this->_M_impl._M_finish._M_set_node(__nfinish - 1); + this->_M_impl._M_start._M_cur = _M_impl._M_start._M_first; + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first + __num_elements + % __deque_buf_size(sizeof(_Tp)); + } + + template<typename _Tp, typename _Alloc> + void + _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish) + { + _Tp** __cur; + try + { + for (__cur = __nstart; __cur < __nfinish; ++__cur) + *__cur = this->_M_allocate_node(); + } + catch(...) + { + _M_destroy_nodes(__nstart, __cur); + __throw_exception_again; + } + } + + template<typename _Tp, typename _Alloc> + void + _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) + { + for (_Tp** __n = __nstart; __n < __nfinish; ++__n) + _M_deallocate_node(*__n); + } + /** * @brief A standard container using fixed-size memory allocation and * constant-time manipulation of elements at either end. @@ -568,15 +516,15 @@ namespace std * * @if maint * Here's how a deque<Tp> manages memory. Each deque has 4 members: - * + * * - Tp** _M_map * - size_t _M_map_size * - iterator _M_start, _M_finish - * + * * map_size is at least 8. %map is an array of map_size pointers-to-"nodes". * (The name %map has nothing to do with the std::map class, and "nodes" * should not be confused with std::list's usage of "node".) - * + * * A "node" has no specific type name as such, but it is referred to as * "node" in this file. It is a simple array-of-Tp. If Tp is very large, * there will be one Tp element per node (i.e., an "array" of one). @@ -584,11 +532,11 @@ namespace std * larger the Tp, the fewer Tp's will fit in a node. The goal here is to * keep the total size of a node relatively small and constant over different * Tp's, to improve allocator efficiency. - * + * * **** As I write this, the nodes are /not/ allocated using the high-speed * memory pool. There are 20 hours left in the year; perhaps I can fix * this before 2002. - * + * * Not every pointer in the %map array will point to a node. If the initial * number of elements in the deque is small, the /middle/ %map pointers will * be valid, and the ones at the edges will be unused. This same situation @@ -616,9 +564,9 @@ namespace std * that range are uninitialized storage. Otherwise, [start.cur, start.last) * and [finish.first, finish.cur) are initialized objects, and [start.first, * start.cur) and [finish.cur, finish.last) are uninitialized storage. - * - [%map, %map + map_size) is a valid, non-empty range. - * - [start.node, finish.node] is a valid range contained within - * [%map, %map + map_size). + * - [%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]. @@ -633,900 +581,853 @@ namespace std * and we can use other standard algorithms as well. * @endif */ - template <typename _Tp, typename _Alloc = allocator<_Tp> > + template<typename _Tp, typename _Alloc = allocator<_Tp> > class deque : protected _Deque_base<_Tp, _Alloc> - { - // concept requirements - __glibcpp_class_requires(_Tp, _SGIAssignableConcept) - - typedef _Deque_base<_Tp, _Alloc> _Base; - - public: - typedef _Tp value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef typename _Base::iterator iterator; - typedef typename _Base::const_iterator const_iterator; - typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - typedef std::reverse_iterator<iterator> reverse_iterator; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef typename _Base::allocator_type allocator_type; - - protected: - typedef pointer* _Map_pointer; - static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); } - - // Functions controlling memory layout, and nothing else. - 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; - - /** @if maint - * A total of four data members accumulated down the heirarchy. If the - * _Alloc type requires separate instances, then two of them will also be - * included in each deque. - * @endif - */ - using _Base::_M_map; - using _Base::_M_map_size; - using _Base::_M_start; - using _Base::_M_finish; - - public: - // [23.2.1.1] construct/copy/destroy - // (assign() and get_allocator() are also listed in this section) - /** - * @brief Default constructor creates no elements. - */ - explicit - deque(const allocator_type& __a = allocator_type()) + { + // concept requirements + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + + typedef _Deque_base<_Tp, _Alloc> _Base; + + public: + typedef _Tp value_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Base::iterator iterator; + typedef typename _Base::const_iterator const_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef typename _Base::allocator_type allocator_type; + + protected: + typedef pointer* _Map_pointer; + + static size_t _S_buffer_size() + { return __deque_buf_size(sizeof(_Tp)); } + + // Functions controlling memory layout, and nothing else. + 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; + + /** @if maint + * A total of four data members accumulated down the heirarchy. + * May be accessed via _M_impl.* + * @endif + */ + using _Base::_M_impl; + + public: + // [23.2.1.1] construct/copy/destroy + // (assign() and get_allocator() are also listed in this section) + /** + * @brief Default constructor creates no elements. + */ + explicit + deque(const allocator_type& __a = allocator_type()) : _Base(__a, 0) {} - - /** - * @brief Create a %deque with copies of an exemplar element. - * @param n The number of elements to initially create. - * @param value An element to copy. - * - * This constructor fills the %deque with @a n copies of @a value. - */ - deque(size_type __n, const value_type& __value, - const allocator_type& __a = allocator_type()) + + /** + * @brief Create a %deque with copies of an exemplar element. + * @param n The number of elements to initially create. + * @param value An element to copy. + * + * This constructor fills the %deque with @a n copies of @a value. + */ + deque(size_type __n, const value_type& __value, + const allocator_type& __a = allocator_type()) : _Base(__a, __n) { _M_fill_initialize(__value); } - - /** - * @brief Create a %deque with default elements. - * @param n The number of elements to initially create. - * - * This constructor fills the %deque with @a n copies of a - * default-constructed element. - */ - explicit - deque(size_type __n) + + /** + * @brief Create a %deque with default elements. + * @param n The number of elements to initially create. + * + * This constructor fills the %deque with @a n copies of a + * default-constructed element. + */ + explicit + deque(size_type __n) : _Base(allocator_type(), __n) { _M_fill_initialize(value_type()); } - - /** - * @brief %Deque copy constructor. - * @param x A %deque of identical element and allocator types. - * - * The newly-created %deque uses a copy of the allocation object used - * by @a x. - */ - deque(const deque& __x) - : _Base(__x.get_allocator(), __x.size()) - { uninitialized_copy(__x.begin(), __x.end(), _M_start); } - - /** - * @brief Builds a %deque from a range. - * @param first An input iterator. - * @param last An input iterator. - * - * Create a %deque consisting of copies of the elements from [first,last). - * - * If the iterators are forward, bidirectional, or random-access, then - * this will call the elements' copy constructor N times (where N is - * distance(first,last)) and do no memory reallocation. But if only - * input iterators are used, then this will do at most 2N calls to the - * copy constructor, and logN memory reallocations. - */ - template<typename _InputIterator> - deque(_InputIterator __first, _InputIterator __last, - const allocator_type& __a = allocator_type()) - : _Base(__a) + + /** + * @brief %Deque copy constructor. + * @param x A %deque of identical element and allocator types. + * + * The newly-created %deque uses a copy of the allocation object used + * by @a x. + */ + deque(const deque& __x) + : _Base(__x.get_allocator(), __x.size()) + { std::uninitialized_copy(__x.begin(), __x.end(), this->_M_impl._M_start); } + + /** + * @brief Builds a %deque from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %deque consisting of copies of the elements from [first, + * last). + * + * If the iterators are forward, bidirectional, or random-access, then + * this will call the elements' copy constructor N times (where N is + * distance(first,last)) and do no memory reallocation. But if only + * input iterators are used, then this will do at most 2N calls to the + * copy constructor, and logN memory reallocations. + */ + template<typename _InputIterator> + deque(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + /** + * The dtor only erases the elements, and note that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + ~deque() + { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); } + + /** + * @brief %Deque assignment operator. + * @param x A %deque of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + deque& + operator=(const deque& __x); + + /** + * @brief Assigns a given value to a %deque. + * @param n Number of elements to be assigned. + * @param val Value to be assigned. + * + * This function fills a %deque with @a n copies of the given value. + * Note that the assignment completely changes the %deque and that the + * resulting %deque's size is the same as the number of elements assigned. + * Old data may be lost. + */ + void + assign(size_type __n, const value_type& __val) + { _M_fill_assign(__n, __val); } + + /** + * @brief Assigns a range to a %deque. + * @param first An input iterator. + * @param last An input iterator. + * + * This function fills a %deque with copies of the elements in the + * range [first,last). + * + * Note that the assignment completely changes the %deque and that the + * resulting %deque's size is the same as the number of elements + * assigned. Old data may be lost. + */ + template<typename _InputIterator> + void + assign(_InputIterator __first, _InputIterator __last) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _Base::get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first element in the + * %deque. Iteration is done in ordinary element order. + */ + iterator + begin() + { return this->_M_impl._M_start; } + + /** + * Returns a read-only (constant) iterator that points to the first + * element in the %deque. Iteration is done in ordinary element order. + */ + const_iterator + begin() const + { return this->_M_impl._M_start; } + + /** + * Returns a read/write iterator that points one past the last element in + * the %deque. Iteration is done in ordinary element order. + */ + iterator + end() + { return this->_M_impl._M_finish; } + + /** + * Returns a read-only (constant) iterator that points one past the last + * element in the %deque. Iteration is done in ordinary element order. + */ + const_iterator + end() const + { return this->_M_impl._M_finish; } + + /** + * Returns a read/write reverse iterator that points to the last element + * in the %deque. Iteration is done in reverse element order. + */ + reverse_iterator + rbegin() + { return reverse_iterator(this->_M_impl._M_finish); } + + /** + * Returns a read-only (constant) reverse iterator that points to the + * last element in the %deque. Iteration is done in reverse element + * order. + */ + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(this->_M_impl._M_finish); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first element in the %deque. Iteration is done in reverse element + * order. + */ + reverse_iterator + rend() { return reverse_iterator(this->_M_impl._M_start); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first element in the %deque. Iteration is done in reverse + * element order. + */ + const_reverse_iterator + rend() const + { return const_reverse_iterator(this->_M_impl._M_start); } + + // [23.2.1.2] capacity + /** Returns the number of elements in the %deque. */ + size_type + size() const + { return this->_M_impl._M_finish - this->_M_impl._M_start; } + + /** Returns the size() of the largest possible %deque. */ + size_type + max_size() const + { return size_type(-1); } + + /** + * @brief Resizes the %deque to the specified number of elements. + * @param new_size Number of elements the %deque should contain. + * @param x Data with which new elements should be populated. + * + * This function will %resize the %deque to the specified number of + * elements. If the number is smaller than the %deque's current size the + * %deque is truncated, otherwise the %deque is extended and new elements + * are populated with given data. + */ + void + resize(size_type __new_size, const value_type& __x) { - // Check whether it's an integral type. If so, it's not an iterator. - typedef typename _Is_integer<_InputIterator>::_Integral _Integral; - _M_initialize_dispatch(__first, __last, _Integral()); + const size_type __len = size(); + if (__new_size < __len) + erase(this->_M_impl._M_start + __new_size, this->_M_impl._M_finish); + else + insert(this->_M_impl._M_finish, __new_size - __len, __x); } - - /** - * The dtor only erases the elements, and note that if the elements - * themselves are pointers, the pointed-to memory is not touched in any - * way. Managing the pointer is the user's responsibilty. - */ - ~deque() { _Destroy(_M_start, _M_finish); } - - /** - * @brief %Deque assignment operator. - * @param x A %deque of identical element and allocator types. - * - * All the elements of @a x are copied, but unlike the copy constructor, - * the allocator object is not copied. - */ - deque& - operator=(const deque& __x); - - /** - * @brief Assigns a given value to a %deque. - * @param n Number of elements to be assigned. - * @param val Value to be assigned. - * - * This function fills a %deque with @a n copies of the given value. - * Note that the assignment completely changes the %deque and that the - * resulting %deque's size is the same as the number of elements assigned. - * Old data may be lost. - */ - void - assign(size_type __n, const value_type& __val) { _M_fill_assign(__n, __val); } - - /** - * @brief Assigns a range to a %deque. - * @param first An input iterator. - * @param last An input iterator. - * - * This function fills a %deque with copies of the elements in the - * range [first,last). - * - * Note that the assignment completely changes the %deque and that the - * resulting %deque's size is the same as the number of elements assigned. - * Old data may be lost. - */ - template<typename _InputIterator> + + /** + * @brief Resizes the %deque to the specified number of elements. + * @param new_size Number of elements the %deque should contain. + * + * This function will resize the %deque to the specified number of + * elements. If the number is smaller than the %deque's current size the + * %deque is truncated, otherwise the %deque is extended and new elements + * are default-constructed. + */ + void + resize(size_type new_size) + { resize(new_size, value_type()); } + + /** + * Returns true if the %deque is empty. (Thus begin() would equal end().) + */ + bool + empty() const + { return this->_M_impl._M_finish == this->_M_impl._M_start; } + + // element access + /** + * @brief Subscript access to the data contained in the %deque. + * @param n The index of the element for which data should be accessed. + * @return Read/write reference to data. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and out_of_range + * lookups are not defined. (For checked lookups see at().) + */ + reference + operator[](size_type __n) + { return this->_M_impl._M_start[difference_type(__n)]; } + + /** + * @brief Subscript access to the data contained in the %deque. + * @param n The index of the element for which data should be accessed. + * @return Read-only (constant) reference to data. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and out_of_range + * lookups are not defined. (For checked lookups see at().) + */ + const_reference + operator[](size_type __n) const + { return this->_M_impl._M_start[difference_type(__n)]; } + + protected: + /// @if maint Safety check used only from at(). @endif void - assign(_InputIterator __first, _InputIterator __last) + _M_range_check(size_type __n) const { - typedef typename _Is_integer<_InputIterator>::_Integral _Integral; - _M_assign_dispatch(__first, __last, _Integral()); + if (__n >= this->size()) + __throw_out_of_range(__N("deque::_M_range_check")); } - - /// Get a copy of the memory allocation object. - allocator_type - get_allocator() const { return _Base::get_allocator(); } - - // iterators - /** - * Returns a read/write iterator that points to the first element in the - * %deque. Iteration is done in ordinary element order. - */ - iterator - begin() { return _M_start; } - - /** - * Returns a read-only (constant) iterator that points to the first element - * in the %deque. Iteration is done in ordinary element order. - */ - const_iterator - begin() const { return _M_start; } - - /** - * Returns a read/write iterator that points one past the last element in - * the %deque. Iteration is done in ordinary element order. - */ - iterator - end() { return _M_finish; } - - /** - * Returns a read-only (constant) iterator that points one past the last - * element in the %deque. Iteration is done in ordinary element order. - */ - const_iterator - end() const { return _M_finish; } - - /** - * Returns a read/write reverse iterator that points to the last element in - * the %deque. Iteration is done in reverse element order. - */ - reverse_iterator - rbegin() { return reverse_iterator(_M_finish); } - - /** - * Returns a read-only (constant) reverse iterator that points to the last - * element in the %deque. Iteration is done in reverse element order. - */ - const_reverse_iterator - rbegin() const { return const_reverse_iterator(_M_finish); } - - /** - * Returns a read/write reverse iterator that points to one before the - * first element in the %deque. Iteration is done in reverse element - * order. - */ - reverse_iterator - rend() { return reverse_iterator(_M_start); } - - /** - * Returns a read-only (constant) reverse iterator that points to one - * before the first element in the %deque. Iteration is done in reverse - * element order. - */ - const_reverse_iterator - rend() const { return const_reverse_iterator(_M_start); } - - // [23.2.1.2] capacity - /** Returns the number of elements in the %deque. */ - size_type - size() const { return _M_finish - _M_start; } - - /** Returns the size() of the largest possible %deque. */ - size_type - max_size() const { return size_type(-1); } - - /** - * @brief Resizes the %deque to the specified number of elements. - * @param new_size Number of elements the %deque should contain. - * @param x Data with which new elements should be populated. - * - * This function will %resize the %deque to the specified number of - * elements. If the number is smaller than the %deque's current size the - * %deque is truncated, otherwise the %deque is extended and new elements - * are populated with given data. - */ - void - resize(size_type __new_size, const value_type& __x) - { - const size_type __len = size(); - if (__new_size < __len) - erase(_M_start + __new_size, _M_finish); - else - insert(_M_finish, __new_size - __len, __x); - } - - /** - * @brief Resizes the %deque to the specified number of elements. - * @param new_size Number of elements the %deque should contain. - * - * This function will resize the %deque to the specified number of - * elements. If the number is smaller than the %deque's current size the - * %deque is truncated, otherwise the %deque is extended and new elements - * are default-constructed. - */ - void - resize(size_type new_size) { resize(new_size, value_type()); } - - /** - * Returns true if the %deque is empty. (Thus begin() would equal end().) - */ - bool empty() const { return _M_finish == _M_start; } - - // element access - /** - * @brief Subscript access to the data contained in the %deque. - * @param n The index of the element for which data should be accessed. - * @return Read/write reference to data. - * - * This operator allows for easy, array-style, data access. - * Note that data access with this operator is unchecked and out_of_range - * lookups are not defined. (For checked lookups see at().) - */ - reference - operator[](size_type __n) { return _M_start[difference_type(__n)]; } - - /** - * @brief Subscript access to the data contained in the %deque. - * @param n The index of the element for which data should be accessed. - * @return Read-only (constant) reference to data. - * - * This operator allows for easy, array-style, data access. - * Note that data access with this operator is unchecked and out_of_range - * lookups are not defined. (For checked lookups see at().) - */ - const_reference - operator[](size_type __n) const { return _M_start[difference_type(__n)]; } - - protected: - /// @if maint Safety check used only from at(). @endif - void - _M_range_check(size_type __n) const - { - if (__n >= this->size()) - __throw_out_of_range("deque [] access out of range"); - } - - public: - /** - * @brief Provides access to the data contained in the %deque. - * @param n The index of the element for which data should be accessed. - * @return Read/write reference to data. - * @throw std::out_of_range If @a n is an invalid index. - * - * This function provides for safer data access. The parameter is first - * checked that it is in the range of the deque. The function throws - * out_of_range if the check fails. - */ - reference - at(size_type __n) { _M_range_check(__n); return (*this)[__n]; } - - /** - * @brief Provides access to the data contained in the %deque. - * @param n The index of the element for which data should be accessed. - * @return Read-only (constant) reference to data. - * @throw std::out_of_range If @a n is an invalid index. - * - * This function provides for safer data access. The parameter is first - * checked that it is in the range of the deque. The function throws - * out_of_range if the check fails. - */ - const_reference - at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; } - - /** - * Returns a read/write reference to the data at the first element of the - * %deque. - */ - reference - front() { return *_M_start; } - - /** - * Returns a read-only (constant) reference to the data at the first - * element of the %deque. - */ - const_reference - front() const { return *_M_start; } - - /** - * Returns a read/write reference to the data at the last element of the - * %deque. - */ - reference - back() - { - iterator __tmp = _M_finish; - --__tmp; - return *__tmp; - } - - /** - * Returns a read-only (constant) reference to the data at the last - * element of the %deque. - */ - const_reference - back() const - { - const_iterator __tmp = _M_finish; - --__tmp; - return *__tmp; - } - - // [23.2.1.2] modifiers - /** - * @brief Add data to the front of the %deque. - * @param x Data to be added. - * - * This is a typical stack operation. The function creates an element at - * the front of the %deque and assigns the given data to it. Due to the - * nature of a %deque this operation can be done in constant time. - */ - void - push_front(const value_type& __x) - { - if (_M_start._M_cur != _M_start._M_first) { - _Construct(_M_start._M_cur - 1, __x); - --_M_start._M_cur; - } - else - _M_push_front_aux(__x); - } - - #ifdef _GLIBCPP_DEPRECATED - /** - * @brief Add data to the front of the %deque. - * - * This is a typical stack operation. The function creates a - * default-constructed element at the front of the %deque. Due to the - * nature of a %deque this operation can be done in constant time. You - * should consider using push_front(value_type()) instead. - * - * @note This was deprecated in 3.2 and will be removed in 3.4. You must - * define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see - * c++config.h. - */ - void - push_front() - { - if (_M_start._M_cur != _M_start._M_first) { - _Construct(_M_start._M_cur - 1); - --_M_start._M_cur; - } - else - _M_push_front_aux(); - } - #endif - - /** - * @brief Add data to the end of the %deque. - * @param x Data to be added. - * - * This is a typical stack operation. The function creates an element at - * the end of the %deque and assigns the given data to it. Due to the - * nature of a %deque this operation can be done in constant time. - */ - void - push_back(const value_type& __x) - { - if (_M_finish._M_cur != _M_finish._M_last - 1) { - _Construct(_M_finish._M_cur, __x); - ++_M_finish._M_cur; - } - else - _M_push_back_aux(__x); - } - - #ifdef _GLIBCPP_DEPRECATED - /** - * @brief Add data to the end of the %deque. - * - * This is a typical stack operation. The function creates a - * default-constructed element at the end of the %deque. Due to the nature - * of a %deque this operation can be done in constant time. You should - * consider using push_back(value_type()) instead. - * - * @note This was deprecated in 3.2 and will be removed in 3.4. You must - * define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see - * c++config.h. - */ - void - push_back() - { - if (_M_finish._M_cur != _M_finish._M_last - 1) { - _Construct(_M_finish._M_cur); - ++_M_finish._M_cur; + + public: + /** + * @brief Provides access to the data contained in the %deque. + * @param n The index of the element for which data should be accessed. + * @return Read/write reference to data. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is first + * checked that it is in the range of the deque. The function throws + * out_of_range if the check fails. + */ + reference + at(size_type __n) + { _M_range_check(__n); return (*this)[__n]; } + + /** + * @brief Provides access to the data contained in the %deque. + * @param n The index of the element for which data should be accessed. + * @return Read-only (constant) reference to data. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is first + * checked that it is in the range of the deque. The function throws + * out_of_range if the check fails. + */ + const_reference + at(size_type __n) const + { + _M_range_check(__n); + return (*this)[__n]; } - else - _M_push_back_aux(); - } - #endif - - /** - * @brief Removes first element. - * - * This is a typical stack operation. It shrinks the %deque by one. - * - * Note that no data is returned, and if the first element's data is - * needed, it should be retrieved before pop_front() is called. - */ - void - pop_front() - { - if (_M_start._M_cur != _M_start._M_last - 1) { - _Destroy(_M_start._M_cur); - ++_M_start._M_cur; + + /** + * Returns a read/write reference to the data at the first element of the + * %deque. + */ + reference + front() + { return *this->_M_impl._M_start; } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %deque. + */ + const_reference + front() const + { return *this->_M_impl._M_start; } + + /** + * Returns a read/write reference to the data at the last element of the + * %deque. + */ + reference + back() + { + iterator __tmp = this->_M_impl._M_finish; + --__tmp; + return *__tmp; } - else - _M_pop_front_aux(); - } - - /** - * @brief Removes last element. - * - * This is a typical stack operation. It shrinks the %deque by one. - * - * Note that no data is returned, and if the last element's data is - * needed, it should be retrieved before pop_back() is called. - */ - void - pop_back() - { - if (_M_finish._M_cur != _M_finish._M_first) { - --_M_finish._M_cur; - _Destroy(_M_finish._M_cur); + + /** + * Returns a read-only (constant) reference to the data at the last + * element of the %deque. + */ + const_reference + back() const + { + const_iterator __tmp = this->_M_impl._M_finish; + --__tmp; + return *__tmp; } - else - _M_pop_back_aux(); - } - - /** - * @brief Inserts given value into %deque before specified iterator. - * @param position An iterator into the %deque. - * @param x Data to be inserted. - * @return An iterator that points to the inserted data. - * - * This function will insert a copy of the given value before the specified - * location. - */ - iterator - insert(iterator position, const value_type& __x); - - #ifdef _GLIBCPP_DEPRECATED - /** - * @brief Inserts an element into the %deque. - * @param position An iterator into the %deque. - * @return An iterator that points to the inserted element. - * - * This function will insert a default-constructed element before the - * specified location. You should consider using - * insert(position,value_type()) instead. - * - * @note This was deprecated in 3.2 and will be removed in 3.4. You must - * define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see - * c++config.h. - */ - iterator - insert(iterator __position) - { return insert(__position, value_type()); } - #endif - - /** - * @brief Inserts a number of copies of given data into the %deque. - * @param position An iterator into the %deque. - * @param n Number of elements to be inserted. - * @param x Data to be inserted. - * - * This function will insert a specified number of copies of the given data - * before the location specified by @a position. - */ - void - insert(iterator __position, size_type __n, const value_type& __x) - { _M_fill_insert(__position, __n, __x); } - - /** - * @brief Inserts a range into the %deque. - * @param pos An iterator into the %deque. - * @param first An input iterator. - * @param last An input iterator. - * - * This function will insert copies of the data in the range [first,last) - * into the %deque before the location specified by @a pos. This is - * known as "range insert." - */ - template<typename _InputIterator> + + // [23.2.1.2] modifiers + /** + * @brief Add data to the front of the %deque. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an element at + * the front of the %deque and assigns the given data to it. Due to the + * nature of a %deque this operation can be done in constant time. + */ void - insert(iterator __pos, _InputIterator __first, _InputIterator __last) + push_front(const value_type& __x) { - // Check whether it's an integral type. If so, it's not an iterator. - typedef typename _Is_integer<_InputIterator>::_Integral _Integral; - _M_insert_dispatch(__pos, __first, __last, _Integral()); + if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first) + { + std::_Construct(this->_M_impl._M_start._M_cur - 1, __x); + --this->_M_impl._M_start._M_cur; + } + else + _M_push_front_aux(__x); } - - /** - * @brief Remove element at given position. - * @param position Iterator pointing to element to be erased. - * @return An iterator pointing to the next element (or end()). - * - * This function will erase the element at the given position and thus - * shorten the %deque by one. - * - * The user is cautioned that - * this function only erases the element, and that if the element is itself - * a pointer, the pointed-to memory is not touched in any way. Managing - * the pointer is the user's responsibilty. - */ - iterator - erase(iterator __position); - - /** - * @brief Remove a range of elements. - * @param first Iterator pointing to the first element to be erased. - * @param last Iterator pointing to one past the last element to be - * erased. - * @return An iterator pointing to the element pointed to by @a last - * prior to erasing (or end()). - * - * This function will erase the elements in the range [first,last) and - * shorten the %deque accordingly. - * - * The user is cautioned that - * this function only erases the elements, and that if the elements - * themselves are pointers, the pointed-to memory is not touched in any - * way. Managing the pointer is the user's responsibilty. - */ - iterator - erase(iterator __first, iterator __last); - - /** - * @brief Swaps data with another %deque. - * @param x A %deque of the same element and allocator types. - * - * This exchanges the elements between two deques in constant time. - * (Four pointers, so it should be quite fast.) - * Note that the global std::swap() function is specialized such that - * std::swap(d1,d2) will feed to this function. - */ - 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); - } - - /** - * Erases all the elements. Note that this function only erases the - * elements, and that if the elements themselves are pointers, the - * pointed-to memory is not touched in any way. Managing the pointer is - * the user's responsibilty. - */ - void clear(); - - protected: - // Internal constructor functions follow. - - // called by the range constructor to implement [23.1.1]/9 - template<typename _Integer> + + /** + * @brief Add data to the end of the %deque. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an element at + * the end of the %deque and assigns the given data to it. Due to the + * nature of a %deque this operation can be done in constant time. + */ void - _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) + push_back(const value_type& __x) { - _M_initialize_map(__n); - _M_fill_initialize(__x); + if (this->_M_impl._M_finish._M_cur != this->_M_impl._M_finish._M_last - 1) + { + std::_Construct(this->_M_impl._M_finish._M_cur, __x); + ++this->_M_impl._M_finish._M_cur; + } + else + _M_push_back_aux(__x); } - - // called by the range constructor to implement [23.1.1]/9 - template<typename _InputIter> + + /** + * @brief Removes first element. + * + * This is a typical stack operation. It shrinks the %deque by one. + * + * Note that no data is returned, and if the first element's data is + * needed, it should be retrieved before pop_front() is called. + */ void - _M_initialize_dispatch(_InputIter __first, _InputIter __last, - __false_type) + pop_front() { - typedef typename iterator_traits<_InputIter>::iterator_category - _IterCategory; - _M_range_initialize(__first, __last, _IterCategory()); + if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_last - 1) + { + std::_Destroy(this->_M_impl._M_start._M_cur); + ++this->_M_impl._M_start._M_cur; + } + else + _M_pop_front_aux(); } - - // called by the second initialize_dispatch above - //@{ - /** - * @if maint - * @brief Fills the deque with whatever is in [first,last). - * @param first An input iterator. - * @param last An input iterator. - * @return Nothing. - * - * If the iterators are actually forward iterators (or better), then the - * memory layout can be done all at once. Else we move forward using - * push_back on each value from the iterator. - * @endif - */ - template <typename _InputIterator> - void - _M_range_initialize(_InputIterator __first, _InputIterator __last, - input_iterator_tag); - - // called by the second initialize_dispatch above - template <typename _ForwardIterator> - void - _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, - forward_iterator_tag); - //@} - - /** - * @if maint - * @brief Fills the %deque with copies of value. - * @param value Initial value. - * @return Nothing. - * @pre _M_start and _M_finish have already been initialized, but none of - * the %deque's elements have yet been constructed. - * - * This function is called only when the user provides an explicit size - * (with or without an explicit exemplar value). - * @endif - */ - void - _M_fill_initialize(const value_type& __value); - - - // Internal assign functions follow. The *_aux functions do the actual - // assignment work for the range versions. - - // called by the range assign to implement [23.1.1]/9 - template<typename _Integer> + + /** + * @brief Removes last element. + * + * This is a typical stack operation. It shrinks the %deque by one. + * + * Note that no data is returned, and if the last element's data is + * needed, it should be retrieved before pop_back() is called. + */ void - _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + pop_back() { - _M_fill_assign(static_cast<size_type>(__n), - static_cast<value_type>(__val)); + if (this->_M_impl._M_finish._M_cur != this->_M_impl._M_finish._M_first) + { + --this->_M_impl._M_finish._M_cur; + std::_Destroy(this->_M_impl._M_finish._M_cur); + } + else + _M_pop_back_aux(); } - - // called by the range assign to implement [23.1.1]/9 - template<typename _InputIter> + + /** + * @brief Inserts given value into %deque before specified iterator. + * @param position An iterator into the %deque. + * @param x Data to be inserted. + * @return An iterator that points to the inserted data. + * + * This function will insert a copy of the given value before the + * specified location. + */ + iterator + insert(iterator position, const value_type& __x); + + /** + * @brief Inserts a number of copies of given data into the %deque. + * @param position An iterator into the %deque. + * @param n Number of elements to be inserted. + * @param x Data to be inserted. + * + * This function will insert a specified number of copies of the given + * data before the location specified by @a position. + */ void - _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type) + insert(iterator __position, size_type __n, const value_type& __x) + { _M_fill_insert(__position, __n, __x); } + + /** + * @brief Inserts a range into the %deque. + * @param position An iterator into the %deque. + * @param first An input iterator. + * @param last An input iterator. + * + * This function will insert copies of the data in the range [first,last) + * into the %deque before the location specified by @a pos. This is + * known as "range insert." + */ + template<typename _InputIterator> + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + /** + * @brief Remove element at given position. + * @param position Iterator pointing to element to be erased. + * @return An iterator pointing to the next element (or end()). + * + * This function will erase the element at the given position and thus + * shorten the %deque by one. + * + * The user is cautioned that + * this function only erases the element, and that if the element is + * itself a pointer, the pointed-to memory is not touched in any way. + * Managing the pointer is the user's responsibilty. + */ + iterator + erase(iterator __position); + + /** + * @brief Remove a range of elements. + * @param first Iterator pointing to the first element to be erased. + * @param last Iterator pointing to one past the last element to be + * erased. + * @return An iterator pointing to the element pointed to by @a last + * prior to erasing (or end()). + * + * This function will erase the elements in the range [first,last) and + * shorten the %deque accordingly. + * + * The user is cautioned that + * this function only erases the elements, and that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + iterator + erase(iterator __first, iterator __last); + + /** + * @brief Swaps data with another %deque. + * @param x A %deque of the same element and allocator types. + * + * This exchanges the elements between two deques in constant time. + * (Four pointers, so it should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(d1,d2) will feed to this function. + */ + void + swap(deque& __x) { - typedef typename iterator_traits<_InputIter>::iterator_category - _IterCategory; - _M_assign_aux(__first, __last, _IterCategory()); + std::swap(this->_M_impl._M_start, __x._M_impl._M_start); + std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); + std::swap(this->_M_impl._M_map, __x._M_impl._M_map); + std::swap(this->_M_impl._M_map_size, __x._M_impl._M_map_size); } - - // called by the second assign_dispatch above - template <typename _InputIterator> + + /** + * Erases all the elements. Note that this function only erases the + * elements, and that if the elements themselves are pointers, the + * pointed-to memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + void clear(); + + protected: + // Internal constructor functions follow. + + // called by the range constructor to implement [23.1.1]/9 + template<typename _Integer> + void + _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) + { + _M_initialize_map(__n); + _M_fill_initialize(__x); + } + + // called by the range constructor to implement [23.1.1]/9 + template<typename _InputIterator> + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_range_initialize(__first, __last, _IterCategory()); + } + + // called by the second initialize_dispatch above + //@{ + /** + * @if maint + * @brief Fills the deque with whatever is in [first,last). + * @param first An input iterator. + * @param last An input iterator. + * @return Nothing. + * + * If the iterators are actually forward iterators (or better), then the + * memory layout can be done all at once. Else we move forward using + * push_back on each value from the iterator. + * @endif + */ + template<typename _InputIterator> + void + _M_range_initialize(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + // called by the second initialize_dispatch above + template<typename _ForwardIterator> + void + _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); + //@} + + /** + * @if maint + * @brief Fills the %deque with copies of value. + * @param value Initial value. + * @return Nothing. + * @pre _M_start and _M_finish have already been initialized, but none of + * the %deque's elements have yet been constructed. + * + * This function is called only when the user provides an explicit size + * (with or without an explicit exemplar value). + * @endif + */ void - _M_assign_aux(_InputIterator __first, _InputIterator __last, - input_iterator_tag); - - // called by the second assign_dispatch above - template <typename _ForwardIterator> + _M_fill_initialize(const value_type& __value); + + // Internal assign functions follow. The *_aux functions do the actual + // assignment work for the range versions. + + // called by the range assign to implement [23.1.1]/9 + template<typename _Integer> + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { + _M_fill_assign(static_cast<size_type>(__n), + static_cast<value_type>(__val)); + } + + // called by the range assign to implement [23.1.1]/9 + template<typename _InputIterator> + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_assign_aux(__first, __last, _IterCategory()); + } + + // called by the second assign_dispatch above + template<typename _InputIterator> + void + _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + // called by the second assign_dispatch above + template<typename _ForwardIterator> + void + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) + { + const size_type __len = std::distance(__first, __last); + if (__len > size()) + { + _ForwardIterator __mid = __first; + std::advance(__mid, size()); + std::copy(__first, __mid, begin()); + insert(end(), __mid, __last); + } + else + erase(std::copy(__first, __last, begin()), end()); + } + + // Called by assign(n,t), and the range assign when it turns out to be the + // same thing. void - _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, - forward_iterator_tag) + _M_fill_assign(size_type __n, const value_type& __val) { - size_type __len = distance(__first, __last); - if (__len > size()) { - _ForwardIterator __mid = __first; - advance(__mid, size()); - copy(__first, __mid, begin()); - insert(end(), __mid, __last); - } - else - erase(copy(__first, __last, begin()), end()); + if (__n > size()) + { + std::fill(begin(), end(), __val); + insert(end(), __n - size(), __val); + } + else + { + erase(begin() + __n, end()); + std::fill(begin(), end(), __val); + } } - - // Called by assign(n,t), and the range assign when it turns out to be the - // same thing. - void - _M_fill_assign(size_type __n, const value_type& __val) - { - if (__n > size()) + + //@{ + /** + * @if maint + * @brief Helper functions for push_* and pop_*. + * @endif + */ + void _M_push_back_aux(const value_type&); + void _M_push_front_aux(const value_type&); + void _M_pop_back_aux(); + void _M_pop_front_aux(); + //@} + + // Internal insert functions follow. The *_aux functions do the actual + // insertion work when all shortcuts fail. + + // called by the range insert to implement [23.1.1]/9 + template<typename _Integer> + void + _M_insert_dispatch(iterator __pos, + _Integer __n, _Integer __x, __true_type) + { + _M_fill_insert(__pos, static_cast<size_type>(__n), + static_cast<value_type>(__x)); + } + + // called by the range insert to implement [23.1.1]/9 + template<typename _InputIterator> + void + _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_range_insert_aux(__pos, __first, __last, _IterCategory()); + } + + // called by the second insert_dispatch above + template<typename _InputIterator> + void + _M_range_insert_aux(iterator __pos, _InputIterator __first, + _InputIterator __last, input_iterator_tag); + + // called by the second insert_dispatch above + template<typename _ForwardIterator> + void + _M_range_insert_aux(iterator __pos, _ForwardIterator __first, + _ForwardIterator __last, forward_iterator_tag); + + // Called by insert(p,n,x), and the range insert when it turns out to be + // the same thing. Can use fill functions in optimal situations, + // otherwise passes off to insert_aux(p,n,x). + void + _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); + + // called by insert(p,x) + iterator + _M_insert_aux(iterator __pos, const value_type& __x); + + // called by insert(p,n,x) via fill_insert + void + _M_insert_aux(iterator __pos, size_type __n, const value_type& __x); + + // called by range_insert_aux for forward iterators + template<typename _ForwardIterator> + void + _M_insert_aux(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + size_type __n); + + //@{ + /** + * @if maint + * @brief Memory-handling helpers for the previous internal insert + * functions. + * @endif + */ + iterator + _M_reserve_elements_at_front(size_type __n) { - fill(begin(), end(), __val); - insert(end(), __n - size(), __val); + const size_type __vacancies = this->_M_impl._M_start._M_cur + - this->_M_impl._M_start._M_first; + if (__n > __vacancies) + _M_new_elements_at_front(__n - __vacancies); + return this->_M_impl._M_start - difference_type(__n); } - else + + iterator + _M_reserve_elements_at_back(size_type __n) { - erase(begin() + __n, end()); - fill(begin(), end(), __val); + const size_type __vacancies = (this->_M_impl._M_finish._M_last + - this->_M_impl._M_finish._M_cur) - 1; + if (__n > __vacancies) + _M_new_elements_at_back(__n - __vacancies); + return this->_M_impl._M_finish + difference_type(__n); } - } - - - //@{ - /** - * @if maint - * @brief Helper functions for push_* and pop_*. - * @endif - */ - void _M_push_back_aux(const value_type&); - void _M_push_front_aux(const value_type&); - #ifdef _GLIBCPP_DEPRECATED - void _M_push_back_aux(); - void _M_push_front_aux(); - #endif - void _M_pop_back_aux(); - void _M_pop_front_aux(); - //@} - - - // Internal insert functions follow. The *_aux functions do the actual - // insertion work when all shortcuts fail. - - // called by the range insert to implement [23.1.1]/9 - template<typename _Integer> + + void + _M_new_elements_at_front(size_type __new_elements); + void - _M_insert_dispatch(iterator __pos, - _Integer __n, _Integer __x, __true_type) + _M_new_elements_at_back(size_type __new_elements); + //@} + + + //@{ + /** + * @if maint + * @brief Memory-handling helpers for the major %map. + * + * 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.) + * @endif + */ + void + _M_reserve_map_at_back (size_type __nodes_to_add = 1) { - _M_fill_insert(__pos, static_cast<size_type>(__n), - static_cast<value_type>(__x)); + if (__nodes_to_add + 1 > this->_M_impl._M_map_size + - (this->_M_impl._M_finish._M_node - this->_M_impl._M_map)) + _M_reallocate_map(__nodes_to_add, false); } - - // called by the range insert to implement [23.1.1]/9 - template<typename _InputIterator> + void - _M_insert_dispatch(iterator __pos, - _InputIterator __first, _InputIterator __last, - __false_type) + _M_reserve_map_at_front (size_type __nodes_to_add = 1) { - typedef typename iterator_traits<_InputIterator>::iterator_category - _IterCategory; - _M_range_insert_aux(__pos, __first, __last, _IterCategory()); + if (__nodes_to_add > size_type(this->_M_impl._M_start._M_node - this->_M_impl._M_map)) + _M_reallocate_map(__nodes_to_add, true); } - - // called by the second insert_dispatch above - template <typename _InputIterator> - void - _M_range_insert_aux(iterator __pos, _InputIterator __first, - _InputIterator __last, input_iterator_tag); - - // called by the second insert_dispatch above - template <typename _ForwardIterator> - void - _M_range_insert_aux(iterator __pos, _ForwardIterator __first, - _ForwardIterator __last, forward_iterator_tag); - - // Called by insert(p,n,x), and the range insert when it turns out to be - // the same thing. Can use fill functions in optimal situations, otherwise - // passes off to insert_aux(p,n,x). - void - _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); - - // called by insert(p,x) - iterator - _M_insert_aux(iterator __pos, const value_type& __x); - - // called by insert(p,n,x) via fill_insert - void - _M_insert_aux(iterator __pos, size_type __n, const value_type& __x); - - // called by range_insert_aux for forward iterators - template <typename _ForwardIterator> + void - _M_insert_aux(iterator __pos, - _ForwardIterator __first, _ForwardIterator __last, - size_type __n); - - #ifdef _GLIBCPP_DEPRECATED - // unused, see comment in implementation - iterator _M_insert_aux(iterator __pos); - #endif - - //@{ - /** - * @if maint - * @brief Memory-handling helpers for the previous internal insert - * functions. - * @endif - */ - iterator - _M_reserve_elements_at_front(size_type __n) - { - size_type __vacancies = _M_start._M_cur - _M_start._M_first; - if (__n > __vacancies) - _M_new_elements_at_front(__n - __vacancies); - return _M_start - difference_type(__n); - } - - iterator - _M_reserve_elements_at_back(size_type __n) - { - size_type __vacancies = (_M_finish._M_last - _M_finish._M_cur) - 1; - if (__n > __vacancies) - _M_new_elements_at_back(__n - __vacancies); - return _M_finish + difference_type(__n); - } - - void - _M_new_elements_at_front(size_type __new_elements); - - void - _M_new_elements_at_back(size_type __new_elements); - //@} - - - //@{ - /** - * @if maint - * @brief Memory-handling helpers for the major %map. - * - * 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.) - * @endif - */ - void - _M_reserve_map_at_back (size_type __nodes_to_add = 1) - { - if (__nodes_to_add + 1 > _M_map_size - (_M_finish._M_node - _M_map)) - _M_reallocate_map(__nodes_to_add, false); - } - - void - _M_reserve_map_at_front (size_type __nodes_to_add = 1) - { - if (__nodes_to_add > size_type(_M_start._M_node - _M_map)) - _M_reallocate_map(__nodes_to_add, true); - } - - void - _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front); - //@} - }; - - + _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front); + //@} + }; + + /** * @brief Deque equality comparison. * @param x A %deque. @@ -1537,67 +1438,64 @@ namespace std * deques. Deques are considered equivalent if their sizes are equal, * and if corresponding elements compare equal. */ - template <typename _Tp, typename _Alloc> - inline bool operator==(const deque<_Tp, _Alloc>& __x, + template<typename _Tp, typename _Alloc> + inline bool + operator==(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) - { - return __x.size() == __y.size() && - equal(__x.begin(), __x.end(), __y.begin()); - } - + { return __x.size() == __y.size() + && std::equal(__x.begin(), __x.end(), __y.begin()); } + /** * @brief Deque ordering relation. * @param x A %deque. * @param y A %deque of the same type as @a x. - * @return True iff @a x is lexographically less than @a y. + * @return True iff @a x is lexicographically less than @a y. * * This is a total ordering relation. It is linear in the size of the * deques. The elements must be comparable with @c <. * - * See std::lexographical_compare() for how the determination is made. + * See std::lexicographical_compare() for how the determination is made. */ - template <typename _Tp, typename _Alloc> - inline bool operator<(const deque<_Tp, _Alloc>& __x, - const deque<_Tp, _Alloc>& __y) - { - return lexicographical_compare(__x.begin(), __x.end(), - __y.begin(), __y.end()); - } - + template<typename _Tp, typename _Alloc> + inline bool + operator<(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } + /// Based on operator== - template <typename _Tp, typename _Alloc> - inline bool operator!=(const deque<_Tp, _Alloc>& __x, - const deque<_Tp, _Alloc>& __y) { - return !(__x == __y); - } - + template<typename _Tp, typename _Alloc> + inline bool + operator!=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return !(__x == __y); } + /// Based on operator< - template <typename _Tp, typename _Alloc> - inline bool operator>(const deque<_Tp, _Alloc>& __x, - const deque<_Tp, _Alloc>& __y) { - return __y < __x; - } - + template<typename _Tp, typename _Alloc> + inline bool + operator>(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return __y < __x; } + /// Based on operator< - template <typename _Tp, typename _Alloc> - inline bool operator<=(const deque<_Tp, _Alloc>& __x, - const deque<_Tp, _Alloc>& __y) { - return !(__y < __x); - } - + template<typename _Tp, typename _Alloc> + inline bool + operator<=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return !(__y < __x); } + /// Based on operator< - template <typename _Tp, typename _Alloc> - inline bool operator>=(const deque<_Tp, _Alloc>& __x, - const deque<_Tp, _Alloc>& __y) { - return !(__x < __y); - } - + template<typename _Tp, typename _Alloc> + inline bool + operator>=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return !(__x < __y); } + /// See std::deque::swap(). - template <typename _Tp, typename _Alloc> - inline void swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) - { - __x.swap(__y); - } -} // namespace std - -#endif /* __GLIBCPP_INTERNAL_DEQUE_H */ + template<typename _Tp, typename _Alloc> + inline void + swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) + { __x.swap(__y); } +} // namespace std + +#endif /* _DEQUE_H */ diff --git a/contrib/libstdc++/include/bits/stl_function.h b/contrib/libstdc++/include/bits/stl_function.h index 9ea975d4a8dc..74ddcce9d8bf 100644 --- a/contrib/libstdc++/include/bits/stl_function.h +++ b/contrib/libstdc++/include/bits/stl_function.h @@ -1,6 +1,6 @@ // Functor implementations -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,678 +58,840 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_FUNCTION_H -#define __GLIBCPP_INTERNAL_FUNCTION_H +#ifndef _FUNCTION_H +#define _FUNCTION_H 1 namespace std { -// 20.3.1 base classes -/** @defgroup s20_3_1_base Functor Base Classes - * Function objects, or @e functors, are objects with an @c operator() - * defined and accessible. They can be passed as arguments to algorithm - * templates and used in place of a function pointer. Not only is the - * resulting expressiveness of the library increased, but the generated - * code can be more efficient than what you might write by hand. When we - * refer to "functors," then, generally we include function pointers in - * the description as well. - * - * Often, functors are only created as temporaries passed to algorithm - * calls, rather than being created as named variables. - * - * Two examples taken from the standard itself follow. To perform a - * by-element addition of two vectors @c a and @c b containing @c double, - * and put the result in @c a, use - * \code - * transform (a.begin(), a.end(), b.begin(), a.begin(), plus<double>()); - * \endcode - * To negate every element in @c a, use - * \code - * transform(a.begin(), a.end(), a.begin(), negate<double>()); - * \endcode - * The addition and negation functions will be inlined directly. - * - * The standard functiors are derived from structs named @c unary_function - * and @c binary_function. These two classes contain nothing but typedefs, - * to aid in generic (template) programming. If you write your own - * functors, you might consider doing the same. - * - * @{ -*/ -/** - * This is one of the @link s20_3_1_base functor base classes@endlink. -*/ -template <class _Arg, class _Result> -struct unary_function { - typedef _Arg argument_type; ///< @c argument_type is the type of the argument (no surprises here) - typedef _Result result_type; ///< @c result_type is the return type -}; - -/** - * This is one of the @link s20_3_1_base functor base classes@endlink. -*/ -template <class _Arg1, class _Arg2, class _Result> -struct binary_function { - typedef _Arg1 first_argument_type; ///< the type of the first argument (no surprises here) - typedef _Arg2 second_argument_type; ///< the type of the second argument - typedef _Result result_type; ///< type of the return type -}; -/** @} */ - -// 20.3.2 arithmetic -/** @defgroup s20_3_2_arithmetic Arithmetic Classes - * Because basic math often needs to be done during an algorithm, the library - * provides functors for those operations. See the documentation for - * @link s20_3_1_base the base classes@endlink for examples of their use. - * - * @{ -*/ -/// One of the @link s20_3_2_arithmetic math functors@endlink. -template <class _Tp> -struct plus : public binary_function<_Tp,_Tp,_Tp> { - _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x + __y; } -}; - -/// One of the @link s20_3_2_arithmetic math functors@endlink. -template <class _Tp> -struct minus : public binary_function<_Tp,_Tp,_Tp> { - _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x - __y; } -}; - -/// One of the @link s20_3_2_arithmetic math functors@endlink. -template <class _Tp> -struct multiplies : public binary_function<_Tp,_Tp,_Tp> { - _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x * __y; } -}; - -/// One of the @link s20_3_2_arithmetic math functors@endlink. -template <class _Tp> -struct divides : public binary_function<_Tp,_Tp,_Tp> { - _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x / __y; } -}; - -/// One of the @link s20_3_2_arithmetic math functors@endlink. -template <class _Tp> -struct modulus : public binary_function<_Tp,_Tp,_Tp> -{ - _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x % __y; } -}; - -/// One of the @link s20_3_2_arithmetic math functors@endlink. -template <class _Tp> -struct negate : public unary_function<_Tp,_Tp> -{ - _Tp operator()(const _Tp& __x) const { return -__x; } -}; -/** @} */ - -// 20.3.3 comparisons -/** @defgroup s20_3_3_comparisons Comparison Classes - * The library provides six wrapper functors for all the basic comparisons - * in C++, like @c <. - * - * @{ -*/ -/// One of the @link s20_3_3_comparisons comparison functors@endlink. -template <class _Tp> -struct equal_to : public binary_function<_Tp,_Tp,bool> -{ - bool operator()(const _Tp& __x, const _Tp& __y) const { return __x == __y; } -}; - -/// One of the @link s20_3_3_comparisons comparison functors@endlink. -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; } -}; - -/// One of the @link s20_3_3_comparisons comparison functors@endlink. -template <class _Tp> -struct greater : public binary_function<_Tp,_Tp,bool> -{ - bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; } -}; - -/// One of the @link s20_3_3_comparisons comparison functors@endlink. -template <class _Tp> -struct less : public binary_function<_Tp,_Tp,bool> -{ - bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; } -}; - -/// One of the @link s20_3_3_comparisons comparison functors@endlink. -template <class _Tp> -struct greater_equal : public binary_function<_Tp,_Tp,bool> -{ - bool operator()(const _Tp& __x, const _Tp& __y) const { return __x >= __y; } -}; + // 20.3.1 base classes + /** @defgroup s20_3_1_base Functor Base Classes + * Function objects, or @e functors, are objects with an @c operator() + * defined and accessible. They can be passed as arguments to algorithm + * templates and used in place of a function pointer. Not only is the + * resulting expressiveness of the library increased, but the generated + * code can be more efficient than what you might write by hand. When we + * refer to "functors," then, generally we include function pointers in + * the description as well. + * + * Often, functors are only created as temporaries passed to algorithm + * calls, rather than being created as named variables. + * + * Two examples taken from the standard itself follow. To perform a + * by-element addition of two vectors @c a and @c b containing @c double, + * and put the result in @c a, use + * \code + * transform (a.begin(), a.end(), b.begin(), a.begin(), plus<double>()); + * \endcode + * To negate every element in @c a, use + * \code + * transform(a.begin(), a.end(), a.begin(), negate<double>()); + * \endcode + * The addition and negation functions will be inlined directly. + * + * The standard functiors are derived from structs named @c unary_function + * and @c binary_function. These two classes contain nothing but typedefs, + * to aid in generic (template) programming. If you write your own + * functors, you might consider doing the same. + * + * @{ + */ + /** + * This is one of the @link s20_3_1_base functor base classes@endlink. + */ + template <class _Arg, class _Result> + struct unary_function + { + typedef _Arg argument_type; ///< @c argument_type is the type of the + /// argument (no surprises here) + + typedef _Result result_type; ///< @c result_type is the return type + }; + + /** + * This is one of the @link s20_3_1_base functor base classes@endlink. + */ + template <class _Arg1, class _Arg2, class _Result> + struct binary_function + { + typedef _Arg1 first_argument_type; ///< the type of the first argument + /// (no surprises here) + + typedef _Arg2 second_argument_type; ///< the type of the second argument + typedef _Result result_type; ///< type of the return type + }; + /** @} */ + + // 20.3.2 arithmetic + /** @defgroup s20_3_2_arithmetic Arithmetic Classes + * Because basic math often needs to be done during an algorithm, the library + * provides functors for those operations. See the documentation for + * @link s20_3_1_base the base classes@endlink for examples of their use. + * + * @{ + */ + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template <class _Tp> + struct plus : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x + __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template <class _Tp> + struct minus : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x - __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template <class _Tp> + struct multiplies : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x * __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template <class _Tp> + struct divides : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x / __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template <class _Tp> + struct modulus : public binary_function<_Tp, _Tp, _Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x % __y; } + }; + + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template <class _Tp> + struct negate : public unary_function<_Tp, _Tp> + { + _Tp + operator()(const _Tp& __x) const + { return -__x; } + }; + /** @} */ + + // 20.3.3 comparisons + /** @defgroup s20_3_3_comparisons Comparison Classes + * The library provides six wrapper functors for all the basic comparisons + * in C++, like @c <. + * + * @{ + */ + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template <class _Tp> + struct equal_to : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x == __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + 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; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template <class _Tp> + struct greater : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x > __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template <class _Tp> + struct less : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x < __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template <class _Tp> + struct greater_equal : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x >= __y; } + }; + + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template <class _Tp> + struct less_equal : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x <= __y; } + }; + /** @} */ + + // 20.3.4 logical operations + /** @defgroup s20_3_4_logical Boolean Operations Classes + * Here are wrapper functors for Boolean operations: @c &&, @c ||, and @c !. + * + * @{ + */ + /// One of the @link s20_3_4_logical Boolean operations functors@endlink. + template <class _Tp> + struct logical_and : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x && __y; } + }; + + /// One of the @link s20_3_4_logical Boolean operations functors@endlink. + template <class _Tp> + struct logical_or : public binary_function<_Tp, _Tp, bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x || __y; } + }; + + /// One of the @link s20_3_4_logical Boolean operations functors@endlink. + template <class _Tp> + struct logical_not : public unary_function<_Tp, bool> + { + bool + operator()(const _Tp& __x) const + { return !__x; } + }; + /** @} */ + + // 20.3.5 negators + /** @defgroup s20_3_5_negators Negators + * The functions @c not1 and @c not2 each take a predicate functor + * and return an instance of @c unary_negate or + * @c binary_negate, respectively. These classes are functors whose + * @c operator() performs the stored predicate function and then returns + * the negation of the result. + * + * For example, given a vector of integers and a trivial predicate, + * \code + * struct IntGreaterThanThree + * : public std::unary_function<int, bool> + * { + * bool operator() (int x) { return x > 3; } + * }; + * + * std::find_if (v.begin(), v.end(), not1(IntGreaterThanThree())); + * \endcode + * The call to @c find_if will locate the first index (i) of @c v for which + * "!(v[i] > 3)" is true. + * + * The not1/unary_negate combination works on predicates taking a single + * argument. The not2/binary_negate combination works on predicates which + * take two arguments. + * + * @{ + */ + /// One of the @link s20_3_5_negators negation functors@endlink. + template <class _Predicate> + class unary_negate + : public unary_function<typename _Predicate::argument_type, bool> + { + protected: + _Predicate _M_pred; + public: + explicit + unary_negate(const _Predicate& __x) : _M_pred(__x) {} + + bool + operator()(const typename _Predicate::argument_type& __x) const + { return !_M_pred(__x); } + }; + + /// One of the @link s20_3_5_negators negation functors@endlink. + template <class _Predicate> + inline unary_negate<_Predicate> + not1(const _Predicate& __pred) + { return unary_negate<_Predicate>(__pred); } + + /// One of the @link s20_3_5_negators negation functors@endlink. + template <class _Predicate> + class binary_negate + : public binary_function<typename _Predicate::first_argument_type, + typename _Predicate::second_argument_type, + bool> + { + protected: + _Predicate _M_pred; + public: + explicit + binary_negate(const _Predicate& __x) + : _M_pred(__x) { } + + bool + operator()(const typename _Predicate::first_argument_type& __x, + const typename _Predicate::second_argument_type& __y) const + { return !_M_pred(__x, __y); } + }; + + /// One of the @link s20_3_5_negators negation functors@endlink. + template <class _Predicate> + inline binary_negate<_Predicate> + not2(const _Predicate& __pred) + { return binary_negate<_Predicate>(__pred); } + /** @} */ + + // 20.3.6 binders + /** @defgroup s20_3_6_binder Binder Classes + * Binders turn functions/functors with two arguments into functors with + * a single argument, storing an argument to be applied later. For + * example, an variable @c B of type @c binder1st is constructed from a + * functor @c f and an argument @c x. Later, B's @c operator() is called + * with a single argument @c y. The return value is the value of @c f(x,y). + * @c B can be "called" with various arguments (y1, y2, ...) and will in + * turn call @c f(x,y1), @c f(x,y2), ... + * + * The function @c bind1st is provided to save some typing. It takes the + * function and an argument as parameters, and returns an instance of + * @c binder1st. + * + * The type @c binder2nd and its creator function @c bind2nd do the same + * thing, but the stored argument is passed as the second parameter instead + * of the first, e.g., @c bind2nd(std::minus<float>,1.3) will create a + * functor whose @c operator() accepts a floating-point number, subtracts + * 1.3 from it, and returns the result. (If @c bind1st had been used, + * the functor would perform "1.3 - x" instead. + * + * Creator-wrapper functions like @c bind1st are intended to be used in + * calling algorithms. Their return values will be temporary objects. + * (The goal is to not require you to type names like + * @c std::binder1st<std::plus<int>> for declaring a variable to hold the + * return value from @c bind1st(std::plus<int>,5). + * + * These become more useful when combined with the composition functions. + * + * @{ + */ + /// One of the @link s20_3_6_binder binder functors@endlink. + template <class _Operation> + class binder1st + : public unary_function<typename _Operation::second_argument_type, + typename _Operation::result_type> + { + protected: + _Operation op; + typename _Operation::first_argument_type value; + public: + binder1st(const _Operation& __x, + const typename _Operation::first_argument_type& __y) + : op(__x), value(__y) {} -/// One of the @link s20_3_3_comparisons comparison functors@endlink. -template <class _Tp> -struct less_equal : public binary_function<_Tp,_Tp,bool> -{ - bool operator()(const _Tp& __x, const _Tp& __y) const { return __x <= __y; } -}; -/** @} */ + typename _Operation::result_type + operator()(const typename _Operation::second_argument_type& __x) const + { return op(value, __x); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 109. Missing binders for non-const sequence elements + typename _Operation::result_type + operator()(typename _Operation::second_argument_type& __x) const + { return op(value, __x); } + }; + + /// One of the @link s20_3_6_binder binder functors@endlink. + template <class _Operation, class _Tp> + inline binder1st<_Operation> + bind1st(const _Operation& __fn, const _Tp& __x) + { + typedef typename _Operation::first_argument_type _Arg1_type; + return binder1st<_Operation>(__fn, _Arg1_type(__x)); + } -// 20.3.4 logical operations -/** @defgroup s20_3_4_logical Boolean Operations Classes - * Here are wrapper functors for Boolean operations: @c &&, @c ||, and @c !. - * - * @{ -*/ -/// One of the @link s20_3_4_logical Boolean operations functors@endlink. -template <class _Tp> -struct logical_and : public binary_function<_Tp,_Tp,bool> -{ - bool operator()(const _Tp& __x, const _Tp& __y) const { return __x && __y; } -}; + /// One of the @link s20_3_6_binder binder functors@endlink. + template <class _Operation> + class binder2nd + : public unary_function<typename _Operation::first_argument_type, + typename _Operation::result_type> + { + protected: + _Operation op; + typename _Operation::second_argument_type value; + public: + binder2nd(const _Operation& __x, + const typename _Operation::second_argument_type& __y) + : op(__x), value(__y) {} -/// One of the @link s20_3_4_logical Boolean operations functors@endlink. -template <class _Tp> -struct logical_or : public binary_function<_Tp,_Tp,bool> -{ - bool operator()(const _Tp& __x, const _Tp& __y) const { return __x || __y; } -}; + typename _Operation::result_type + operator()(const typename _Operation::first_argument_type& __x) const + { return op(__x, value); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 109. Missing binders for non-const sequence elements + typename _Operation::result_type + operator()(typename _Operation::first_argument_type& __x) const + { return op(__x, value); } + }; + + /// One of the @link s20_3_6_binder binder functors@endlink. + template <class _Operation, class _Tp> + inline binder2nd<_Operation> + bind2nd(const _Operation& __fn, const _Tp& __x) + { + typedef typename _Operation::second_argument_type _Arg2_type; + return binder2nd<_Operation>(__fn, _Arg2_type(__x)); + } + /** @} */ + + // 20.3.7 adaptors pointers functions + /** @defgroup s20_3_7_adaptors Adaptors for pointers to functions + * The advantage of function objects over pointers to functions is that + * the objects in the standard library declare nested typedefs describing + * their argument and result types with uniform names (e.g., @c result_type + * from the base classes @c unary_function and @c binary_function). + * Sometimes those typedefs are required, not just optional. + * + * Adaptors are provided to turn pointers to unary (single-argument) and + * binary (double-argument) functions into function objects. The + * long-winded functor @c pointer_to_unary_function is constructed with a + * function pointer @c f, and its @c operator() called with argument @c x + * returns @c f(x). The functor @c pointer_to_binary_function does the same + * thing, but with a double-argument @c f and @c operator(). + * + * The function @c ptr_fun takes a pointer-to-function @c f and constructs + * an instance of the appropriate functor. + * + * @{ + */ + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + template <class _Arg, class _Result> + class pointer_to_unary_function : public unary_function<_Arg, _Result> + { + protected: + _Result (*_M_ptr)(_Arg); + public: + pointer_to_unary_function() {} + + explicit + pointer_to_unary_function(_Result (*__x)(_Arg)) + : _M_ptr(__x) {} -/// One of the @link s20_3_4_logical Boolean operations functors@endlink. -template <class _Tp> -struct logical_not : public unary_function<_Tp,bool> -{ - bool operator()(const _Tp& __x) const { return !__x; } -}; -/** @} */ - -// 20.3.5 negators -/** @defgroup s20_3_5_negators Negators - * The functions @c not1 and @c not2 each take a predicate functor - * and return an instance of @c unary_negate or - * @c binary_negate, respectively. These classes are functors whose - * @c operator() performs the stored predicate function and then returns - * the negation of the result. - * - * For example, given a vector of integers and a trivial predicate, - * \code - * struct IntGreaterThanThree - * : public std::unary_function<int, bool> - * { - * bool operator() (int x) { return x > 3; } - * }; - * - * std::find_if (v.begin(), v.end(), not1(IntGreaterThanThree())); - * \endcode - * The call to @c find_if will locate the first index (i) of @c v for which - * "!(v[i] > 3)" is true. - * - * The not1/unary_negate combination works on predicates taking a single - * argument. The not2/binary_negate combination works on predicates which - * take two arguments. - * - * @{ -*/ -/// One of the @link s20_3_5_negators negation functors@endlink. -template <class _Predicate> -class unary_negate - : public unary_function<typename _Predicate::argument_type, bool> { -protected: - _Predicate _M_pred; -public: - explicit unary_negate(const _Predicate& __x) : _M_pred(__x) {} - bool operator()(const typename _Predicate::argument_type& __x) const { - return !_M_pred(__x); - } -}; - -/// One of the @link s20_3_5_negators negation functors@endlink. -template <class _Predicate> -inline unary_negate<_Predicate> -not1(const _Predicate& __pred) -{ - return unary_negate<_Predicate>(__pred); -} - -/// One of the @link s20_3_5_negators negation functors@endlink. -template <class _Predicate> -class binary_negate - : public binary_function<typename _Predicate::first_argument_type, - typename _Predicate::second_argument_type, - bool> { -protected: - _Predicate _M_pred; -public: - explicit binary_negate(const _Predicate& __x) : _M_pred(__x) {} - bool operator()(const typename _Predicate::first_argument_type& __x, - const typename _Predicate::second_argument_type& __y) const - { - return !_M_pred(__x, __y); - } -}; - -/// One of the @link s20_3_5_negators negation functors@endlink. -template <class _Predicate> -inline binary_negate<_Predicate> -not2(const _Predicate& __pred) -{ - return binary_negate<_Predicate>(__pred); -} -/** @} */ - -// 20.3.6 binders -/** @defgroup s20_3_6_binder Binder Classes - * Binders turn functions/functors with two arguments into functors with - * a single argument, storing an argument to be applied later. For - * example, an variable @c B of type @c binder1st is constructed from a functor - * @c f and an argument @c x. Later, B's @c operator() is called with a - * single argument @c y. The return value is the value of @c f(x,y). - * @c B can be "called" with various arguments (y1, y2, ...) and will in - * turn call @c f(x,y1), @c f(x,y2), ... - * - * The function @c bind1st is provided to save some typing. It takes the - * function and an argument as parameters, and returns an instance of - * @c binder1st. - * - * The type @c binder2nd and its creator function @c bind2nd do the same - * thing, but the stored argument is passed as the second parameter instead - * of the first, e.g., @c bind2nd(std::minus<float>,1.3) will create a - * functor whose @c operator() accepts a floating-point number, subtracts - * 1.3 from it, and returns the result. (If @c bind1st had been used, - * the functor would perform "1.3 - x" instead. - * - * Creator-wrapper functions like @c bind1st are intended to be used in - * calling algorithms. Their return values will be temporary objects. - * (The goal is to not require you to type names like - * @c std::binder1st<std::plus<int>> for declaring a variable to hold the - * return value from @c bind1st(std::plus<int>,5). - * - * These become more useful when combined with the composition functions. - * - * @{ -*/ -/// One of the @link s20_3_6_binder binder functors@endlink. -template <class _Operation> -class binder1st - : public unary_function<typename _Operation::second_argument_type, - typename _Operation::result_type> { -protected: - _Operation op; - typename _Operation::first_argument_type value; -public: - binder1st(const _Operation& __x, - const typename _Operation::first_argument_type& __y) - : op(__x), value(__y) {} - typename _Operation::result_type - operator()(const typename _Operation::second_argument_type& __x) const { - return op(value, __x); - } -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS - //109. Missing binders for non-const sequence elements - typename _Operation::result_type - operator()(typename _Operation::second_argument_type& __x) const { - return op(value, __x); - } -#endif -}; - -/// One of the @link s20_3_6_binder binder functors@endlink. -template <class _Operation, class _Tp> -inline binder1st<_Operation> -bind1st(const _Operation& __fn, const _Tp& __x) -{ - typedef typename _Operation::first_argument_type _Arg1_type; - return binder1st<_Operation>(__fn, _Arg1_type(__x)); -} - -/// One of the @link s20_3_6_binder binder functors@endlink. -template <class _Operation> -class binder2nd - : public unary_function<typename _Operation::first_argument_type, - typename _Operation::result_type> { -protected: - _Operation op; - typename _Operation::second_argument_type value; -public: - binder2nd(const _Operation& __x, - const typename _Operation::second_argument_type& __y) - : op(__x), value(__y) {} - typename _Operation::result_type - operator()(const typename _Operation::first_argument_type& __x) const { - return op(__x, value); - } -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS - //109. Missing binders for non-const sequence elements - typename _Operation::result_type - operator()(typename _Operation::first_argument_type& __x) const { - return op(__x, value); - } -#endif -}; - -/// One of the @link s20_3_6_binder binder functors@endlink. -template <class _Operation, class _Tp> -inline binder2nd<_Operation> -bind2nd(const _Operation& __fn, const _Tp& __x) -{ - typedef typename _Operation::second_argument_type _Arg2_type; - return binder2nd<_Operation>(__fn, _Arg2_type(__x)); -} -/** @} */ - -// 20.3.7 adaptors pointers functions -/** @defgroup s20_3_7_adaptors Adaptors for pointers to functions - * The advantage of function objects over pointers to functions is that - * the objects in the standard library declare nested typedefs describing - * their argument and result types with uniform names (e.g., @c result_type - * from the base classes @c unary_function and @c binary_function). - * Sometimes those typedefs are required, not just optional. - * - * Adaptors are provided to turn pointers to unary (single-argument) and - * binary (double-argument) functions into function objects. The long-winded - * functor @c pointer_to_unary_function is constructed with a function - * pointer @c f, and its @c operator() called with argument @c x returns - * @c f(x). The functor @c pointer_to_binary_function does the same thing, - * but with a double-argument @c f and @c operator(). - * - * The function @c ptr_fun takes a pointer-to-function @c f and constructs - * an instance of the appropriate functor. - * - * @{ -*/ -/// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. -template <class _Arg, class _Result> -class pointer_to_unary_function : public unary_function<_Arg, _Result> { -protected: - _Result (*_M_ptr)(_Arg); -public: - pointer_to_unary_function() {} - explicit pointer_to_unary_function(_Result (*__x)(_Arg)) : _M_ptr(__x) {} - _Result operator()(_Arg __x) const { return _M_ptr(__x); } -}; - -/// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. -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); -} - -/// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. -template <class _Arg1, class _Arg2, class _Result> -class pointer_to_binary_function : - public binary_function<_Arg1,_Arg2,_Result> { -protected: - _Result (*_M_ptr)(_Arg1, _Arg2); -public: - pointer_to_binary_function() {} - explicit pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2)) + _Result + operator()(_Arg __x) const + { return _M_ptr(__x); } + }; + + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + 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); } + + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + template <class _Arg1, class _Arg2, class _Result> + class pointer_to_binary_function + : public binary_function<_Arg1, _Arg2, _Result> + { + protected: + _Result (*_M_ptr)(_Arg1, _Arg2); + public: + pointer_to_binary_function() {} + + explicit + pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2)) : _M_ptr(__x) {} - _Result operator()(_Arg1 __x, _Arg2 __y) const { - return _M_ptr(__x, __y); - } -}; - -/// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. -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 _Tp> -struct _Identity : public unary_function<_Tp,_Tp> { - _Tp& operator()(_Tp& __x) const { return __x; } - const _Tp& operator()(const _Tp& __x) const { return __x; } -}; - -template <class _Pair> -struct _Select1st : public unary_function<_Pair, typename _Pair::first_type> { - typename _Pair::first_type& operator()(_Pair& __x) const { - return __x.first; - } - 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> -{ - typename _Pair::second_type& operator()(_Pair& __x) const { - return __x.second; - } - const typename _Pair::second_type& operator()(const _Pair& __x) const { - return __x.second; - } -}; - -// 20.3.8 adaptors pointers members -/** @defgroup s20_3_8_memadaptors Adaptors for pointers to members - * There are a total of 16 = 2^4 function objects in this family. - * (1) Member functions taking no arguments vs member functions taking - * one argument. - * (2) Call through pointer vs call through reference. - * (3) Member function with void return type vs member function with - * non-void return type. - * (4) Const vs non-const member function. - * - * Note that choice (3) is nothing more than a workaround: according - * to the draft, compilers should handle void and non-void the same way. - * This feature is not yet widely implemented, though. You can only use - * member functions returning void if your compiler supports partial - * specialization. - * - * All of this complexity is in the function objects themselves. You can - * ignore it by using the helper function mem_fun and mem_fun_ref, - * which create whichever type of adaptor is appropriate. - * - * @{ -*/ -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template <class _Ret, class _Tp> -class mem_fun_t : public unary_function<_Tp*,_Ret> { -public: - explicit mem_fun_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {} - _Ret operator()(_Tp* __p) const { return (__p->*_M_f)(); } -private: - _Ret (_Tp::*_M_f)(); -}; - -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template <class _Ret, class _Tp> -class const_mem_fun_t : public unary_function<const _Tp*,_Ret> { -public: - explicit const_mem_fun_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {} - _Ret operator()(const _Tp* __p) const { return (__p->*_M_f)(); } -private: - _Ret (_Tp::*_M_f)() const; -}; - -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template <class _Ret, class _Tp> -class mem_fun_ref_t : public unary_function<_Tp,_Ret> { -public: - explicit mem_fun_ref_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {} - _Ret operator()(_Tp& __r) const { return (__r.*_M_f)(); } -private: - _Ret (_Tp::*_M_f)(); -}; - -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template <class _Ret, class _Tp> -class const_mem_fun_ref_t : public unary_function<_Tp,_Ret> { -public: - explicit const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {} - _Ret operator()(const _Tp& __r) const { return (__r.*_M_f)(); } -private: - _Ret (_Tp::*_M_f)() const; -}; - -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template <class _Ret, class _Tp, class _Arg> -class mem_fun1_t : public binary_function<_Tp*,_Arg,_Ret> { -public: - explicit mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} - _Ret operator()(_Tp* __p, _Arg __x) const { return (__p->*_M_f)(__x); } -private: - _Ret (_Tp::*_M_f)(_Arg); -}; - -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -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(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} - _Ret operator()(const _Tp* __p, _Arg __x) const - { return (__p->*_M_f)(__x); } -private: - _Ret (_Tp::*_M_f)(_Arg) const; -}; - -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template <class _Ret, class _Tp, class _Arg> -class mem_fun1_ref_t : public binary_function<_Tp,_Arg,_Ret> { -public: - explicit mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} - _Ret operator()(_Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } -private: - _Ret (_Tp::*_M_f)(_Arg); -}; - -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -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(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} - _Ret operator()(const _Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } -private: - _Ret (_Tp::*_M_f)(_Arg) const; -}; - -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template <class _Tp> -class mem_fun_t<void, _Tp> : public unary_function<_Tp*,void> { -public: - explicit mem_fun_t(void (_Tp::*__pf)()) : _M_f(__pf) {} - void operator()(_Tp* __p) const { (__p->*_M_f)(); } -private: - void (_Tp::*_M_f)(); -}; - -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template <class _Tp> -class const_mem_fun_t<void, _Tp> : public unary_function<const _Tp*,void> { -public: - explicit const_mem_fun_t(void (_Tp::*__pf)() const) : _M_f(__pf) {} - void operator()(const _Tp* __p) const { (__p->*_M_f)(); } -private: - void (_Tp::*_M_f)() const; -}; - -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template <class _Tp> -class mem_fun_ref_t<void, _Tp> : public unary_function<_Tp,void> { -public: - explicit mem_fun_ref_t(void (_Tp::*__pf)()) : _M_f(__pf) {} - void operator()(_Tp& __r) const { (__r.*_M_f)(); } -private: - void (_Tp::*_M_f)(); -}; - -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template <class _Tp> -class const_mem_fun_ref_t<void, _Tp> : public unary_function<_Tp,void> { -public: - explicit const_mem_fun_ref_t(void (_Tp::*__pf)() const) : _M_f(__pf) {} - void operator()(const _Tp& __r) const { (__r.*_M_f)(); } -private: - void (_Tp::*_M_f)() const; -}; - -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template <class _Tp, class _Arg> -class mem_fun1_t<void, _Tp, _Arg> : public binary_function<_Tp*,_Arg,void> { -public: - explicit mem_fun1_t(void (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} - void operator()(_Tp* __p, _Arg __x) const { (__p->*_M_f)(__x); } -private: - void (_Tp::*_M_f)(_Arg); -}; - -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -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 (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} - void operator()(const _Tp* __p, _Arg __x) const { (__p->*_M_f)(__x); } -private: - void (_Tp::*_M_f)(_Arg) const; -}; - -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -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 (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} - void operator()(_Tp& __r, _Arg __x) const { (__r.*_M_f)(__x); } -private: - void (_Tp::*_M_f)(_Arg); -}; - -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -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 (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} - void operator()(const _Tp& __r, _Arg __x) const { (__r.*_M_f)(__x); } -private: - void (_Tp::*_M_f)(_Arg) const; -}; - - -// Mem_fun adaptor helper functions. There are only two: -// mem_fun and mem_fun_ref. - -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 _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 _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 _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 _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 _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 _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 _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); } - -/** @} */ + + _Result + operator()(_Arg1 __x, _Arg2 __y) const + { return _M_ptr(__x, __y); } + }; + + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + 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 _Tp> + struct _Identity : public unary_function<_Tp,_Tp> + { + _Tp& + operator()(_Tp& __x) const + { return __x; } + + const _Tp& + operator()(const _Tp& __x) const + { return __x; } + }; + + template <class _Pair> + struct _Select1st : public unary_function<_Pair, + typename _Pair::first_type> + { + typename _Pair::first_type& + operator()(_Pair& __x) const + { return __x.first; } + + 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> + { + typename _Pair::second_type& + operator()(_Pair& __x) const + { return __x.second; } + + const typename _Pair::second_type& + operator()(const _Pair& __x) const + { return __x.second; } + }; + + // 20.3.8 adaptors pointers members + /** @defgroup s20_3_8_memadaptors Adaptors for pointers to members + * There are a total of 16 = 2^4 function objects in this family. + * (1) Member functions taking no arguments vs member functions taking + * one argument. + * (2) Call through pointer vs call through reference. + * (3) Member function with void return type vs member function with + * non-void return type. + * (4) Const vs non-const member function. + * + * Note that choice (3) is nothing more than a workaround: according + * to the draft, compilers should handle void and non-void the same way. + * This feature is not yet widely implemented, though. You can only use + * member functions returning void if your compiler supports partial + * specialization. + * + * All of this complexity is in the function objects themselves. You can + * ignore it by using the helper function mem_fun and mem_fun_ref, + * which create whichever type of adaptor is appropriate. + * + * @{ + */ + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Ret, class _Tp> + class mem_fun_t : public unary_function<_Tp*, _Ret> + { + public: + explicit + mem_fun_t(_Ret (_Tp::*__pf)()) + : _M_f(__pf) {} + + _Ret + operator()(_Tp* __p) const + { return (__p->*_M_f)(); } + private: + _Ret (_Tp::*_M_f)(); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Ret, class _Tp> + class const_mem_fun_t : public unary_function<const _Tp*, _Ret> + { + public: + explicit + const_mem_fun_t(_Ret (_Tp::*__pf)() const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp* __p) const + { return (__p->*_M_f)(); } + private: + _Ret (_Tp::*_M_f)() const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Ret, class _Tp> + class mem_fun_ref_t : public unary_function<_Tp, _Ret> + { + public: + explicit + mem_fun_ref_t(_Ret (_Tp::*__pf)()) + : _M_f(__pf) {} + + _Ret + operator()(_Tp& __r) const + { return (__r.*_M_f)(); } + private: + _Ret (_Tp::*_M_f)(); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Ret, class _Tp> + class const_mem_fun_ref_t : public unary_function<_Tp, _Ret> + { + public: + explicit + const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp& __r) const + { return (__r.*_M_f)(); } + private: + _Ret (_Tp::*_M_f)() const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Ret, class _Tp, class _Arg> + class mem_fun1_t : public binary_function<_Tp*, _Arg, _Ret> + { + public: + explicit + mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) + : _M_f(__pf) {} + + _Ret + operator()(_Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + 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(_Ret (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg) const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Ret, class _Tp, class _Arg> + class mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> + { + public: + explicit + mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) + : _M_f(__pf) {} + + _Ret + operator()(_Tp& __r, _Arg __x) const + { return (__r.*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + 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(_Ret (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp& __r, _Arg __x) const + { return (__r.*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg) const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Tp> + class mem_fun_t<void, _Tp> : public unary_function<_Tp*, void> + { + public: + explicit + mem_fun_t(void (_Tp::*__pf)()) + : _M_f(__pf) {} + + void + operator()(_Tp* __p) const + { (__p->*_M_f)(); } + private: + void (_Tp::*_M_f)(); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Tp> + class const_mem_fun_t<void, _Tp> : public unary_function<const _Tp*, void> + { + public: + explicit + const_mem_fun_t(void (_Tp::*__pf)() const) + : _M_f(__pf) {} + + void + operator()(const _Tp* __p) const + { (__p->*_M_f)(); } + private: + void (_Tp::*_M_f)() const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Tp> + class mem_fun_ref_t<void, _Tp> : public unary_function<_Tp, void> + { + public: + explicit + mem_fun_ref_t(void (_Tp::*__pf)()) + : _M_f(__pf) {} + + void + operator()(_Tp& __r) const + { (__r.*_M_f)(); } + private: + void (_Tp::*_M_f)(); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Tp> + class const_mem_fun_ref_t<void, _Tp> : public unary_function<_Tp, void> + { + public: + explicit + const_mem_fun_ref_t(void (_Tp::*__pf)() const) + : _M_f(__pf) {} + + void + operator()(const _Tp& __r) const + { (__r.*_M_f)(); } + private: + void (_Tp::*_M_f)() const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template <class _Tp, class _Arg> + class mem_fun1_t<void, _Tp, _Arg> : public binary_function<_Tp*, _Arg, void> + { + public: + explicit + mem_fun1_t(void (_Tp::*__pf)(_Arg)) + : _M_f(__pf) {} + + void + operator()(_Tp* __p, _Arg __x) const + { (__p->*_M_f)(__x); } + private: + void (_Tp::*_M_f)(_Arg); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + 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 (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} + + void + operator()(const _Tp* __p, _Arg __x) const + { (__p->*_M_f)(__x); } + private: + void (_Tp::*_M_f)(_Arg) const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + 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 (_Tp::*__pf)(_Arg)) + : _M_f(__pf) {} + + void + operator()(_Tp& __r, _Arg __x) const + { (__r.*_M_f)(__x); } + private: + void (_Tp::*_M_f)(_Arg); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + 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 (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} + + void + operator()(const _Tp& __r, _Arg __x) const + { (__r.*_M_f)(__x); } + private: + void (_Tp::*_M_f)(_Arg) const; + }; + + // Mem_fun adaptor helper functions. There are only two: + // mem_fun and mem_fun_ref. + 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 _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 _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 _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 _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 _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 _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 _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); } + + /** @} */ } // namespace std -#endif /* __GLIBCPP_INTERNAL_FUNCTION_H */ +#endif /* _FUNCTION_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/bits/stl_heap.h b/contrib/libstdc++/include/bits/stl_heap.h index c19195aad39a..eff7fd351d7a 100644 --- a/contrib/libstdc++/include/bits/stl_heap.h +++ b/contrib/libstdc++/include/bits/stl_heap.h @@ -1,6 +1,6 @@ // Heap implementation -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -57,30 +57,87 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_STL_HEAP_H -#define _CPP_BITS_STL_HEAP_H 1 +#ifndef _STL_HEAP_H +#define _STL_HEAP_H 1 + +#include <debug/debug.h> namespace std { + // is_heap, a predicate testing whether or not a range is + // a heap. This function is an extension, not part of the C++ + // standard. + template<typename _RandomAccessIterator, typename _Distance> + bool + __is_heap(_RandomAccessIterator __first, _Distance __n) + { + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) + { + if (__first[__parent] < __first[__child]) + return false; + if ((__child & 1) == 0) + ++__parent; + } + return true; + } + + template<typename _RandomAccessIterator, typename _Distance, + typename _StrictWeakOrdering> + bool + __is_heap(_RandomAccessIterator __first, _StrictWeakOrdering __comp, + _Distance __n) + { + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) + { + if (__comp(__first[__parent], __first[__child])) + return false; + if ((__child & 1) == 0) + ++__parent; + } + return true; + } + + template<typename _RandomAccessIterator> + bool + __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { return std::__is_heap(__first, std::distance(__first, __last)); } + + template<typename _RandomAccessIterator, typename _StrictWeakOrdering> + bool + __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _StrictWeakOrdering __comp) + { return std::__is_heap(__first, __comp, std::distance(__first, __last)); } // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap. template<typename _RandomAccessIterator, typename _Distance, typename _Tp> - void + 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; - } + while (__holeIndex > __topIndex && *(__first + __parent) < __value) + { + *(__first + __holeIndex) = *(__first + __parent); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } *(__first + __holeIndex) = __value; } + /** + * @brief Push an element onto a heap. + * @param first Start of heap. + * @param last End of heap + element. + * @ingroup heap + * + * This operation pushes the element at last-1 onto the valid heap over the + * range [first,last-1). After completion, [first,last) is a valid heap. + */ template<typename _RandomAccessIterator> - inline void + inline void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { typedef typename iterator_traits<_RandomAccessIterator>::value_type @@ -89,31 +146,46 @@ namespace std _DistanceType; // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) - __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + // __glibcxx_requires_heap(__first, __last - 1); - __push_heap(__first, _DistanceType((__last - __first) - 1), _DistanceType(0), - _ValueType(*(__last - 1))); + std::__push_heap(__first, _DistanceType((__last - __first) - 1), + _DistanceType(0), _ValueType(*(__last - 1))); } - template<typename _RandomAccessIterator, typename _Distance, typename _Tp, + template<typename _RandomAccessIterator, typename _Distance, typename _Tp, typename _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; - } + while (__holeIndex > __topIndex + && __comp(*(__first + __parent), __value)) + { + *(__first + __holeIndex) = *(__first + __parent); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } *(__first + __holeIndex) = __value; } + /** + * @brief Push an element onto a heap using comparison functor. + * @param first Start of heap. + * @param last End of heap + element. + * @param comp Comparison functor. + * @ingroup heap + * + * This operation pushes the element at last-1 onto the valid heap over the + * range [first,last-1). After completion, [first,last) is a valid heap. + * Compare operations are performed using comp. + */ template<typename _RandomAccessIterator, typename _Compare> - inline void + inline void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { @@ -123,56 +195,75 @@ namespace std _DistanceType; // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap_pred(__first, __last - 1, __comp); - __push_heap(__first, _DistanceType((__last - __first) - 1), _DistanceType(0), - _ValueType(*(__last - 1)), __comp); + std::__push_heap(__first, _DistanceType((__last - __first) - 1), + _DistanceType(0), _ValueType(*(__last - 1)), __comp); } template<typename _RandomAccessIterator, typename _Distance, typename _Tp> - void + void __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, _Distance __len, _Tp __value) { - _Distance __topIndex = __holeIndex; + const _Distance __topIndex = __holeIndex; _Distance __secondChild = 2 * __holeIndex + 2; - while (__secondChild < __len) { - if (*(__first + __secondChild) < *(__first + (__secondChild - 1))) - __secondChild--; - *(__first + __holeIndex) = *(__first + __secondChild); - __holeIndex = __secondChild; - __secondChild = 2 * (__secondChild + 1); - } - if (__secondChild == __len) { - *(__first + __holeIndex) = *(__first + (__secondChild - 1)); - __holeIndex = __secondChild - 1; - } - __push_heap(__first, __holeIndex, __topIndex, __value); + 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; + } + std::__push_heap(__first, __holeIndex, __topIndex, __value); } template<typename _RandomAccessIterator, typename _Tp> - inline void + inline void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _RandomAccessIterator __result, _Tp __value) { - typedef typename iterator_traits<_RandomAccessIterator>::difference_type _Distance; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; *__result = *__first; - __adjust_heap(__first, _Distance(0), _Distance(__last - __first), __value); + std::__adjust_heap(__first, _Distance(0), _Distance(__last - __first), + __value); } + /** + * @brief Pop an element off a heap. + * @param first Start of heap. + * @param last End of heap. + * @ingroup heap + * + * This operation pops the top of the heap. The elements first and last-1 + * are swapped and [first,last-1) is made into a heap. + */ template<typename _RandomAccessIterator> inline void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { - typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) - __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap(__first, __last); - __pop_heap(__first, __last - 1, __last - 1, _ValueType(*(__last - 1))); + std::__pop_heap(__first, __last - 1, __last - 1, + _ValueType(*(__last - 1))); } template<typename _RandomAccessIterator, typename _Distance, @@ -181,48 +272,75 @@ namespace std __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, _Distance __len, _Tp __value, _Compare __comp) { - _Distance __topIndex = __holeIndex; + const _Distance __topIndex = __holeIndex; _Distance __secondChild = 2 * __holeIndex + 2; - while (__secondChild < __len) { - if (__comp(*(__first + __secondChild), *(__first + (__secondChild - 1)))) - __secondChild--; - *(__first + __holeIndex) = *(__first + __secondChild); - __holeIndex = __secondChild; - __secondChild = 2 * (__secondChild + 1); - } - if (__secondChild == __len) { - *(__first + __holeIndex) = *(__first + (__secondChild - 1)); - __holeIndex = __secondChild - 1; - } - __push_heap(__first, __holeIndex, __topIndex, __value, __comp); + 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; + } + std::__push_heap(__first, __holeIndex, __topIndex, __value, __comp); } template<typename _RandomAccessIterator, typename _Tp, typename _Compare> - inline void + inline void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _RandomAccessIterator __result, _Tp __value, _Compare __comp) { - typedef typename iterator_traits<_RandomAccessIterator>::difference_type _Distance; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _Distance; *__result = *__first; - __adjust_heap(__first, _Distance(0), _Distance(__last - __first), - __value, __comp); + std::__adjust_heap(__first, _Distance(0), _Distance(__last - __first), + __value, __comp); } + /** + * @brief Pop an element off a heap using comparison functor. + * @param first Start of heap. + * @param last End of heap. + * @param comp Comparison functor to use. + * @ingroup heap + * + * This operation pops the top of the heap. The elements first and last-1 + * are swapped and [first,last-1) is made into a heap. Comparisons are + * made using comp. + */ template<typename _RandomAccessIterator, typename _Compare> - inline void + inline void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap_pred(__first, __last, __comp); - typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType; - __pop_heap(__first, __last - 1, __last - 1, _ValueType(*(__last - 1)), __comp); + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + std::__pop_heap(__first, __last - 1, __last - 1, + _ValueType(*(__last - 1)), __comp); } + /** + * @brief Construct a heap over a range. + * @param first Start of heap. + * @param last End of heap. + * @ingroup heap + * + * This operation makes the elements in [first,last) into a heap. + */ template<typename _RandomAccessIterator> - void + void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { typedef typename iterator_traits<_RandomAccessIterator>::value_type @@ -231,23 +349,38 @@ namespace std _DistanceType; // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) - __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>) - - if (__last - __first < 2) return; - _DistanceType __len = __last - __first; - _DistanceType __parent = (__len - 2)/2; - - while (true) { - __adjust_heap(__first, __parent, __len, _ValueType(*(__first + __parent))); - if (__parent == 0) return; - __parent--; - } + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__last - __first < 2) + return; + + const _DistanceType __len = __last - __first; + _DistanceType __parent = (__len - 2) / 2; + while (true) + { + std::__adjust_heap(__first, __parent, __len, + _ValueType(*(__first + __parent))); + if (__parent == 0) + return; + __parent--; + } } + /** + * @brief Construct a heap over a range using comparison functor. + * @param first Start of heap. + * @param last End of heap. + * @param comp Comparison functor to use. + * @ingroup heap + * + * This operation makes the elements in [first,last) into a heap. + * Comparisons are made using comp. + */ template<typename _RandomAccessIterator, typename _Compare> - inline void + inline void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { @@ -257,51 +390,77 @@ namespace std _DistanceType; // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) - - if (__last - __first < 2) return; - _DistanceType __len = __last - __first; - _DistanceType __parent = (__len - 2)/2; - - while (true) { - __adjust_heap(__first, __parent, __len, - _ValueType(*(__first + __parent)), __comp); - if (__parent == 0) return; - __parent--; - } + __glibcxx_requires_valid_range(__first, __last); + + if (__last - __first < 2) + return; + + const _DistanceType __len = __last - __first; + _DistanceType __parent = (__len - 2) / 2; + while (true) + { + std::__adjust_heap(__first, __parent, __len, + _ValueType(*(__first + __parent)), __comp); + if (__parent == 0) + return; + __parent--; + } } + /** + * @brief Sort a heap. + * @param first Start of heap. + * @param last End of heap. + * @ingroup heap + * + * This operation sorts the valid heap in the range [first,last). + */ template<typename _RandomAccessIterator> void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) - __glibcpp_function_requires(_LessThanComparableConcept< + __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + // __glibcxx_requires_heap(__first, __last); while (__last - __first > 1) - pop_heap(__first, __last--); + std::pop_heap(__first, __last--); } + /** + * @brief Sort a heap using comparison functor. + * @param first Start of heap. + * @param last End of heap. + * @param comp Comparison functor to use. + * @ingroup heap + * + * This operation sorts the valid heap in the range [first,last). + * Comparisons are made using comp. + */ template<typename _RandomAccessIterator, typename _Compare> - void + void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap_pred(__first, __last, __comp); while (__last - __first > 1) - pop_heap(__first, __last--, __comp); + std::pop_heap(__first, __last--, __comp); } } // namespace std -#endif /* _CPP_BITS_STL_HEAP_H */ +#endif /* _STL_HEAP_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/bits/stl_iterator.h b/contrib/libstdc++/include/bits/stl_iterator.h index 529ad7741756..cc564314bc8b 100644 --- a/contrib/libstdc++/include/bits/stl_iterator.h +++ b/contrib/libstdc++/include/bits/stl_iterator.h @@ -1,6 +1,6 @@ // Iterators -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -62,8 +62,8 @@ * supporting functions and overloaded operators. */ -#ifndef __GLIBCPP_INTERNAL_ITERATOR_H -#define __GLIBCPP_INTERNAL_ITERATOR_H +#ifndef _ITERATOR_H +#define _ITERATOR_H 1 namespace std { @@ -87,7 +87,7 @@ namespace std * the requirement that the iterators must be safe. */ template<typename _Iterator> - class reverse_iterator + class reverse_iterator : public iterator<typename iterator_traits<_Iterator>::iterator_category, typename iterator_traits<_Iterator>::value_type, typename iterator_traits<_Iterator>::difference_type, @@ -98,9 +98,9 @@ namespace std _Iterator current; public: - typedef _Iterator iterator_type; - typedef typename iterator_traits<_Iterator>::difference_type - difference_type; + typedef _Iterator iterator_type; + typedef typename iterator_traits<_Iterator>::difference_type + difference_type; typedef typename iterator_traits<_Iterator>::reference reference; typedef typename iterator_traits<_Iterator>::pointer pointer; @@ -109,20 +109,20 @@ namespace std * The default constructor default-initializes member @p current. * If it is a pointer, that means it is zero-initialized. */ - // _GLIBCPP_RESOLVE_LIB_DEFECTS + // _GLIBCXX_RESOLVE_LIB_DEFECTS // 235 No specification of default ctor for reverse_iterator reverse_iterator() : current() { } /** * This %iterator will move in the opposite direction that @p x does. */ - explicit + explicit reverse_iterator(iterator_type __x) : current(__x) { } /** * The copy constructor is normal. */ - reverse_iterator(const reverse_iterator& __x) + reverse_iterator(const reverse_iterator& __x) : current(__x.current) { } /** @@ -132,20 +132,21 @@ namespace std template<typename _Iter> reverse_iterator(const reverse_iterator<_Iter>& __x) : current(__x.base()) { } - + /** * @return @c current, the %iterator used for underlying work. */ - iterator_type - base() const { return current; } + iterator_type + base() const + { return current; } /** * @return TODO * * @doctodo */ - reference - operator*() const + reference + operator*() const { _Iterator __tmp = current; return *--__tmp; @@ -156,16 +157,17 @@ namespace std * * @doctodo */ - pointer - operator->() const { return &(operator*()); } + pointer + operator->() const + { return &(operator*()); } /** * @return TODO * * @doctodo */ - reverse_iterator& - operator++() + reverse_iterator& + operator++() { --current; return *this; @@ -176,8 +178,8 @@ namespace std * * @doctodo */ - reverse_iterator - operator++(int) + reverse_iterator + operator++(int) { reverse_iterator __tmp = *this; --current; @@ -189,8 +191,8 @@ namespace std * * @doctodo */ - reverse_iterator& - operator--() + reverse_iterator& + operator--() { ++current; return *this; @@ -201,20 +203,20 @@ namespace std * * @doctodo */ - reverse_iterator operator--(int) + reverse_iterator operator--(int) { reverse_iterator __tmp = *this; ++current; return __tmp; } - + /** * @return TODO * * @doctodo */ - reverse_iterator - operator+(difference_type __n) const + reverse_iterator + operator+(difference_type __n) const { return reverse_iterator(current - __n); } /** @@ -222,8 +224,8 @@ namespace std * * @doctodo */ - reverse_iterator& - operator+=(difference_type __n) + reverse_iterator& + operator+=(difference_type __n) { current -= __n; return *this; @@ -234,8 +236,8 @@ namespace std * * @doctodo */ - reverse_iterator - operator-(difference_type __n) const + reverse_iterator + operator-(difference_type __n) const { return reverse_iterator(current + __n); } /** @@ -243,8 +245,8 @@ namespace std * * @doctodo */ - reverse_iterator& - operator-=(difference_type __n) + reverse_iterator& + operator-=(difference_type __n) { current += __n; return *this; @@ -255,10 +257,11 @@ namespace std * * @doctodo */ - reference - operator[](difference_type __n) const { return *(*this + __n); } - }; - + reference + operator[](difference_type __n) const + { return *(*this + __n); } + }; + //@{ /** * @param x A %reverse_iterator. @@ -270,51 +273,51 @@ namespace std * */ template<typename _Iterator> - inline bool - operator==(const reverse_iterator<_Iterator>& __x, - const reverse_iterator<_Iterator>& __y) + inline bool + operator==(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { return __x.base() == __y.base(); } template<typename _Iterator> - inline bool - operator<(const reverse_iterator<_Iterator>& __x, - const reverse_iterator<_Iterator>& __y) + inline bool + operator<(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { return __y.base() < __x.base(); } template<typename _Iterator> - inline bool - operator!=(const reverse_iterator<_Iterator>& __x, - const reverse_iterator<_Iterator>& __y) + inline bool + operator!=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { return !(__x == __y); } template<typename _Iterator> - inline bool - operator>(const reverse_iterator<_Iterator>& __x, - const reverse_iterator<_Iterator>& __y) + inline bool + operator>(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { return __y < __x; } template<typename _Iterator> - inline bool - operator<=(const reverse_iterator<_Iterator>& __x, - const reverse_iterator<_Iterator>& __y) + inline bool + operator<=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { return !(__y < __x); } template<typename _Iterator> - inline bool - operator>=(const reverse_iterator<_Iterator>& __x, - const reverse_iterator<_Iterator>& __y) + inline bool + operator>=(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { return !(__x < __y); } template<typename _Iterator> inline typename reverse_iterator<_Iterator>::difference_type - operator-(const reverse_iterator<_Iterator>& __x, - const reverse_iterator<_Iterator>& __y) + operator-(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { return __y.base() - __x.base(); } template<typename _Iterator> - inline reverse_iterator<_Iterator> + inline reverse_iterator<_Iterator> operator+(typename reverse_iterator<_Iterator>::difference_type __n, - const reverse_iterator<_Iterator>& __x) + const reverse_iterator<_Iterator>& __x) { return reverse_iterator<_Iterator>(__x.base() - __n); } //@} @@ -330,7 +333,7 @@ namespace std * save typing. */ template<typename _Container> - class back_insert_iterator + class back_insert_iterator : public iterator<output_iterator_tag, void, void, void, void> { protected: @@ -339,9 +342,9 @@ namespace std public: /// A nested typedef for the type of whatever container you used. typedef _Container container_type; - + /// The only way to create this %iterator is with a container. - explicit + explicit back_insert_iterator(_Container& __x) : container(&__x) { } /** @@ -356,23 +359,26 @@ namespace std * always append the value to the end of the container. */ back_insert_iterator& - operator=(typename _Container::const_reference __value) - { + operator=(typename _Container::const_reference __value) + { container->push_back(__value); return *this; } /// Simply returns *this. - back_insert_iterator& - operator*() { return *this; } + back_insert_iterator& + operator*() + { return *this; } /// Simply returns *this. (This %iterator does not "move".) - back_insert_iterator& - operator++() { return *this; } + back_insert_iterator& + operator++() + { return *this; } /// Simply returns *this. (This %iterator does not "move".) back_insert_iterator - operator++(int) { return *this; } + operator++(int) + { return *this; } }; /** @@ -387,8 +393,8 @@ namespace std * types for you. */ template<typename _Container> - inline back_insert_iterator<_Container> - back_inserter(_Container& __x) + inline back_insert_iterator<_Container> + back_inserter(_Container& __x) { return back_insert_iterator<_Container>(__x); } /** @@ -402,7 +408,7 @@ namespace std * save typing. */ template<typename _Container> - class front_insert_iterator + class front_insert_iterator : public iterator<output_iterator_tag, void, void, void, void> { protected: @@ -427,23 +433,26 @@ namespace std * always prepend the value to the front of the container. */ front_insert_iterator& - operator=(typename _Container::const_reference __value) - { + operator=(typename _Container::const_reference __value) + { container->push_front(__value); return *this; } /// Simply returns *this. - front_insert_iterator& - operator*() { return *this; } + front_insert_iterator& + operator*() + { return *this; } /// Simply returns *this. (This %iterator does not "move".) - front_insert_iterator& - operator++() { return *this; } + front_insert_iterator& + operator++() + { return *this; } /// Simply returns *this. (This %iterator does not "move".) - front_insert_iterator - operator++(int) { return *this; } + front_insert_iterator + operator++(int) + { return *this; } }; /** @@ -458,8 +467,8 @@ namespace std * types for you. */ template<typename _Container> - inline front_insert_iterator<_Container> - front_inserter(_Container& __x) + inline front_insert_iterator<_Container> + front_inserter(_Container& __x) { return front_insert_iterator<_Container>(__x); } /** @@ -477,7 +486,7 @@ namespace std * save typing. */ template<typename _Container> - class insert_iterator + class insert_iterator : public iterator<output_iterator_tag, void, void, void, void> { protected: @@ -487,14 +496,14 @@ namespace std public: /// A nested typedef for the type of whatever container you used. typedef _Container container_type; - + /** * The only way to create this %iterator is with a container and an * initial position (a normal %iterator into the container). */ - insert_iterator(_Container& __x, typename _Container::iterator __i) + insert_iterator(_Container& __x, typename _Container::iterator __i) : container(&__x), iter(__i) {} - + /** * @param value An instance of whatever type * container_type::const_reference is; presumably a @@ -519,26 +528,29 @@ namespace std * @endcode */ insert_iterator& - operator=(const typename _Container::const_reference __value) - { + operator=(const typename _Container::const_reference __value) + { iter = container->insert(iter, __value); ++iter; return *this; } /// Simply returns *this. - insert_iterator& - operator*() { return *this; } + insert_iterator& + operator*() + { return *this; } /// Simply returns *this. (This %iterator does not "move".) - insert_iterator& - operator++() { return *this; } + insert_iterator& + operator++() + { return *this; } /// Simply returns *this. (This %iterator does not "move".) - insert_iterator& - operator++(int) { return *this; } + insert_iterator& + operator++(int) + { return *this; } }; - + /** * @param x A container of arbitrary type. * @return An instance of insert_iterator working on @p x. @@ -551,16 +563,16 @@ namespace std * types for you. */ template<typename _Container, typename _Iterator> - inline insert_iterator<_Container> + inline insert_iterator<_Container> inserter(_Container& __x, _Iterator __i) { - return insert_iterator<_Container>(__x, + return insert_iterator<_Container>(__x, typename _Container::iterator(__i)); } } // namespace std namespace __gnu_cxx -{ +{ // This iterator adapter is 'normal' in the sense that it does not // change the semantics of any of the operators of its iterator // parameter. Its primary purpose is to convert an iterator that is @@ -572,56 +584,67 @@ namespace __gnu_cxx using std::iterator; template<typename _Iterator, typename _Container> class __normal_iterator - : public iterator<typename iterator_traits<_Iterator>::iterator_category, - typename iterator_traits<_Iterator>::value_type, - typename iterator_traits<_Iterator>::difference_type, - typename iterator_traits<_Iterator>::pointer, - typename iterator_traits<_Iterator>::reference> { protected: _Iterator _M_current; - + public: - typedef typename iterator_traits<_Iterator>::difference_type - difference_type; - typedef typename iterator_traits<_Iterator>::reference reference; - typedef typename iterator_traits<_Iterator>::pointer pointer; + typedef typename iterator_traits<_Iterator>::iterator_category + iterator_category; + typedef typename iterator_traits<_Iterator>::value_type value_type; + typedef typename iterator_traits<_Iterator>::difference_type + difference_type; + typedef typename iterator_traits<_Iterator>::reference reference; + typedef typename iterator_traits<_Iterator>::pointer pointer; __normal_iterator() : _M_current(_Iterator()) { } - explicit + explicit __normal_iterator(const _Iterator& __i) : _M_current(__i) { } // Allow iterator to const_iterator conversion template<typename _Iter> - inline __normal_iterator(const __normal_iterator<_Iter, _Container>& __i) + inline __normal_iterator(const __normal_iterator<_Iter, + _Container>& __i) : _M_current(__i.base()) { } // Forward iterator requirements reference - operator*() const { return *_M_current; } - + operator*() const + { return *_M_current; } + pointer - operator->() const { return _M_current; } - + operator->() const + { return _M_current; } + __normal_iterator& - operator++() { ++_M_current; return *this; } - + operator++() + { + ++_M_current; + return *this; + } + __normal_iterator - operator++(int) { return __normal_iterator(_M_current++); } - + operator++(int) + { return __normal_iterator(_M_current++); } + // Bidirectional iterator requirements __normal_iterator& - operator--() { --_M_current; return *this; } - + operator--() + { + --_M_current; + return *this; + } + __normal_iterator - operator--(int) { return __normal_iterator(_M_current--); } - + operator--(int) + { return __normal_iterator(_M_current--); } + // Random access iterator requirements reference operator[](const difference_type& __n) const { return _M_current[__n]; } - + __normal_iterator& operator+=(const difference_type& __n) { _M_current += __n; return *this; } @@ -629,17 +652,18 @@ namespace __gnu_cxx __normal_iterator operator+(const difference_type& __n) const { return __normal_iterator(_M_current + __n); } - + __normal_iterator& operator-=(const difference_type& __n) { _M_current -= __n; return *this; } - + __normal_iterator operator-(const difference_type& __n) const { return __normal_iterator(_M_current - __n); } - - const _Iterator& - base() const { return _M_current; } + + const _Iterator& + base() const + { return _M_current; } }; // Note: In what follows, the left- and right-hand-side iterators are @@ -649,99 +673,99 @@ namespace __gnu_cxx // will make overload resolution ambiguous (when in scope) if we don't // provide overloads whose operands are of the same type. Can someone // remind me what generic programming is about? -- Gaby - + // Forward iterator requirements template<typename _IteratorL, typename _IteratorR, typename _Container> - inline bool - operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - { return __lhs.base() == __rhs.base(); } + inline bool + operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() == __rhs.base(); } template<typename _Iterator, typename _Container> - inline bool - operator==(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - { return __lhs.base() == __rhs.base(); } + inline bool + operator==(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() == __rhs.base(); } template<typename _IteratorL, typename _IteratorR, typename _Container> - inline bool - operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - { return __lhs.base() != __rhs.base(); } + inline bool + operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() != __rhs.base(); } template<typename _Iterator, typename _Container> - inline bool - operator!=(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - { return __lhs.base() != __rhs.base(); } + inline bool + operator!=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() != __rhs.base(); } // Random access iterator requirements template<typename _IteratorL, typename _IteratorR, typename _Container> - inline bool - operator<(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - { return __lhs.base() < __rhs.base(); } + inline bool + operator<(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() < __rhs.base(); } template<typename _Iterator, typename _Container> - inline bool - operator<(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - { return __lhs.base() < __rhs.base(); } + inline bool + operator<(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() < __rhs.base(); } template<typename _IteratorL, typename _IteratorR, typename _Container> - inline bool - operator>(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - { return __lhs.base() > __rhs.base(); } + inline bool + operator>(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() > __rhs.base(); } template<typename _Iterator, typename _Container> - inline bool - operator>(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - { return __lhs.base() > __rhs.base(); } + inline bool + operator>(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() > __rhs.base(); } template<typename _IteratorL, typename _IteratorR, typename _Container> - inline bool - operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - { return __lhs.base() <= __rhs.base(); } + inline bool + operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() <= __rhs.base(); } template<typename _Iterator, typename _Container> - inline bool - operator<=(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - { return __lhs.base() <= __rhs.base(); } + inline bool + operator<=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() <= __rhs.base(); } template<typename _IteratorL, typename _IteratorR, typename _Container> - inline bool - operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - { return __lhs.base() >= __rhs.base(); } + inline bool + operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() >= __rhs.base(); } template<typename _Iterator, typename _Container> - inline bool - operator>=(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - { return __lhs.base() >= __rhs.base(); } + inline bool + operator>=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() >= __rhs.base(); } - // _GLIBCPP_RESOLVE_LIB_DEFECTS + // _GLIBCXX_RESOLVE_LIB_DEFECTS // According to the resolution of DR179 not only the various comparison // operators but also operator- must accept mixed iterator/const_iterator // parameters. template<typename _IteratorL, typename _IteratorR, typename _Container> - inline typename __normal_iterator<_IteratorL, _Container>::difference_type - operator-(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - { return __lhs.base() - __rhs.base(); } + inline typename __normal_iterator<_IteratorL, _Container>::difference_type + operator-(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() - __rhs.base(); } template<typename _Iterator, typename _Container> - inline __normal_iterator<_Iterator, _Container> - operator+(typename __normal_iterator<_Iterator, _Container>::difference_type __n, - const __normal_iterator<_Iterator, _Container>& __i) - { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); } + inline __normal_iterator<_Iterator, _Container> + operator+(typename __normal_iterator<_Iterator, _Container>::difference_type + __n, const __normal_iterator<_Iterator, _Container>& __i) + { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); } } // namespace __gnu_cxx -#endif +#endif // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/bits/stl_iterator_base_funcs.h b/contrib/libstdc++/include/bits/stl_iterator_base_funcs.h index 7c245d056c6d..c514e81a0893 100644 --- a/contrib/libstdc++/include/bits/stl_iterator_base_funcs.h +++ b/contrib/libstdc++/include/bits/stl_iterator_base_funcs.h @@ -1,6 +1,6 @@ // Functions used by iterators -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -61,8 +61,8 @@ * functions, such as distance() and advance(). */ -#ifndef __GLIBCPP_INTERNAL_ITERATOR_BASE_FUNCS_H -#define __GLIBCPP_INTERNAL_ITERATOR_BASE_FUNCS_H +#ifndef _ITERATOR_BASE_FUNCS_H +#define _ITERATOR_BASE_FUNCS_H 1 #pragma GCC system_header #include <bits/concept_check.h> @@ -75,25 +75,28 @@ namespace std input_iterator_tag) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>) - + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + typename iterator_traits<_InputIterator>::difference_type __n = 0; - while (__first != __last) { - ++__first; ++__n; - } + while (__first != __last) + { + ++__first; + ++__n; + } return __n; } - + template<typename _RandomAccessIterator> inline typename iterator_traits<_RandomAccessIterator>::difference_type __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) { // concept requirements - __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) + __glibcxx_function_requires(_RandomAccessIteratorConcept< + _RandomAccessIterator>) return __last - __first; } - + /** * @brief A generalization of pointer arithmetic. * @param first An input iterator. @@ -111,42 +114,47 @@ namespace std distance(_InputIterator __first, _InputIterator __last) { // concept requirements -- taken care of in __distance - return __distance(__first, __last, __iterator_category(__first)); + return std::__distance(__first, __last, + std::__iterator_category(__first)); } - - template<typename _InputIter, typename _Distance> + + template<typename _InputIterator, typename _Distance> inline void - __advance(_InputIter& __i, _Distance __n, input_iterator_tag) + __advance(_InputIterator& __i, _Distance __n, input_iterator_tag) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - while (__n--) ++__i; + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + while (__n--) + ++__i; } - + template<typename _BidirectionalIterator, typename _Distance> inline void __advance(_BidirectionalIterator& __i, _Distance __n, bidirectional_iterator_tag) { // concept requirements - __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIterator>) - + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) if (__n > 0) - while (__n--) ++__i; + while (__n--) + ++__i; else - while (__n++) --__i; + while (__n++) + --__i; } - + template<typename _RandomAccessIterator, typename _Distance> inline void __advance(_RandomAccessIterator& __i, _Distance __n, random_access_iterator_tag) { // concept requirements - __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) + __glibcxx_function_requires(_RandomAccessIteratorConcept< + _RandomAccessIterator>) __i += __n; } - + /** * @brief A generalization of pointer arithmetic. * @param i An input iterator. @@ -164,8 +172,8 @@ namespace std advance(_InputIterator& __i, _Distance __n) { // concept requirements -- taken care of in __advance - __advance(__i, __n, __iterator_category(__i)); + std::__advance(__i, __n, std::__iterator_category(__i)); } } // namespace std -#endif /* __GLIBCPP_INTERNAL_ITERATOR_BASE_FUNCS_H */ +#endif /* _ITERATOR_BASE_FUNCS_H */ diff --git a/contrib/libstdc++/include/bits/stl_iterator_base_types.h b/contrib/libstdc++/include/bits/stl_iterator_base_types.h index 8b040e496023..c3bb1c55727d 100644 --- a/contrib/libstdc++/include/bits/stl_iterator_base_types.h +++ b/contrib/libstdc++/include/bits/stl_iterator_base_types.h @@ -1,6 +1,6 @@ // Types used in iterator implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -61,8 +61,8 @@ * such as iterator_traits and struct iterator. */ -#ifndef __GLIBCPP_INTERNAL_ITERATOR_BASE_TYPES_H -#define __GLIBCPP_INTERNAL_ITERATOR_BASE_TYPES_H +#ifndef _ITERATOR_BASE_TYPES_H +#define _ITERATOR_BASE_TYPES_H 1 #pragma GCC system_header @@ -82,9 +82,11 @@ namespace std struct output_iterator_tag {}; /// Forward iterators support a superset of input iterator operations. struct forward_iterator_tag : public input_iterator_tag {}; - /// Bidirectional iterators support a superset of forward iterator operations. + /// Bidirectional iterators support a superset of forward iterator + /// operations. struct bidirectional_iterator_tag : public forward_iterator_tag {}; - /// Random-access iterators support a superset of bidirectional iterator operations. + /// Random-access iterators support a superset of bidirectional iterator + /// operations. struct random_access_iterator_tag : public bidirectional_iterator_tag {}; //@} @@ -122,7 +124,8 @@ namespace std * provide tighter, more correct semantics. */ template<typename _Iterator> - struct iterator_traits { + struct iterator_traits + { typedef typename _Iterator::iterator_category iterator_category; typedef typename _Iterator::value_type value_type; typedef typename _Iterator::difference_type difference_type; @@ -131,7 +134,8 @@ namespace std }; template<typename _Tp> - struct iterator_traits<_Tp*> { + struct iterator_traits<_Tp*> + { typedef random_access_iterator_tag iterator_category; typedef _Tp value_type; typedef ptrdiff_t difference_type; @@ -140,7 +144,8 @@ namespace std }; template<typename _Tp> - struct iterator_traits<const _Tp*> { + struct iterator_traits<const _Tp*> + { typedef random_access_iterator_tag iterator_category; typedef _Tp value_type; typedef ptrdiff_t difference_type; @@ -161,5 +166,5 @@ namespace std } // namespace std -#endif /* __GLIBCPP_INTERNAL_ITERATOR_BASE_TYPES_H */ +#endif /* _ITERATOR_BASE_TYPES_H */ diff --git a/contrib/libstdc++/include/bits/stl_list.h b/contrib/libstdc++/include/bits/stl_list.h index fcba3598df24..060755a213c8 100644 --- a/contrib/libstdc++/include/bits/stl_list.h +++ b/contrib/libstdc++/include/bits/stl_list.h @@ -1,6 +1,6 @@ // List implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,269 +58,289 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_LIST_H -#define __GLIBCPP_INTERNAL_LIST_H +#ifndef _LIST_H +#define _LIST_H 1 #include <bits/concept_check.h> -namespace std +namespace _GLIBCXX_STD { // Supporting structures are split into common and templated types; the // latter publicly inherits from the former in an effort to reduce code // duplication. This results in some "needless" static_cast'ing later on, // but it's all safe downcasting. - + /// @if maint Common part of a node in the %list. @endif struct _List_node_base { _List_node_base* _M_next; ///< Self-explanatory _List_node_base* _M_prev; ///< Self-explanatory + + static void + swap(_List_node_base& __x, _List_node_base& __y); + + void + transfer(_List_node_base * const __first, + _List_node_base * const __last); + + void + reverse(); + + void + hook(_List_node_base * const __position); + + void + unhook(); }; - + /// @if maint An actual node in the %list. @endif template<typename _Tp> struct _List_node : public _List_node_base - { - _Tp _M_data; ///< User's data. - }; - - - /** - * @if maint - * @brief Common part of a list::iterator. - * - * A simple type to walk a doubly-linked list. All operations here should - * be self-explanatory after taking any decent introductory data structures - * course. - * @endif - */ - struct _List_iterator_base - { - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef bidirectional_iterator_tag iterator_category; - - /// The only member points to the %list element. - _List_node_base* _M_node; - - _List_iterator_base(_List_node_base* __x) - : _M_node(__x) - { } - - _List_iterator_base() - { } - - /// Walk the %list forward. - void - _M_incr() - { _M_node = _M_node->_M_next; } - - /// Walk the %list backward. - void - _M_decr() - { _M_node = _M_node->_M_prev; } - - bool - operator==(const _List_iterator_base& __x) const - { return _M_node == __x._M_node; } - - bool - operator!=(const _List_iterator_base& __x) const - { return _M_node != __x._M_node; } - }; - + { + _Tp _M_data; ///< User's data. + }; + /** * @brief A list::iterator. * - * In addition to being used externally, a list holds one of these - * internally, pointing to the sequence of data. - * * @if maint * All the functions are op overloads. * @endif */ - template<typename _Tp, typename _Ref, typename _Ptr> - struct _List_iterator : public _List_iterator_base - { - 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 _Tp value_type; - typedef _Ptr pointer; - typedef _Ref reference; - typedef _List_node<_Tp> _Node; - - _List_iterator(_Node* __x) - : _List_iterator_base(__x) - { } - - _List_iterator() - { } - - _List_iterator(const iterator& __x) - : _List_iterator_base(__x._M_node) - { } - - reference - operator*() const - { return static_cast<_Node*>(_M_node)->_M_data; } - // Must downcast from List_node_base to _List_node to get to _M_data. - - pointer - operator->() const - { return &(operator*()); } - - _Self& - operator++() - { - this->_M_incr(); - return *this; - } - - _Self - operator++(int) - { - _Self __tmp = *this; - this->_M_incr(); - return __tmp; - } - - _Self& - operator--() - { - this->_M_decr(); - return *this; - } - - _Self - operator--(int) + template<typename _Tp> + struct _List_iterator { - _Self __tmp = *this; - this->_M_decr(); - return __tmp; - } - }; - - - /// @if maint Primary default version. @endif + typedef _List_iterator<_Tp> _Self; + typedef _List_node<_Tp> _Node; + + typedef ptrdiff_t difference_type; + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Tp* pointer; + typedef _Tp& reference; + + _List_iterator() { } + + _List_iterator(_List_node_base* __x) + : _M_node(__x) { } + + // Must downcast from List_node_base to _List_node to get to _M_data. + reference + operator*() const + { return static_cast<_Node*>(_M_node)->_M_data; } + + pointer + operator->() const + { return &static_cast<_Node*>(_M_node)->_M_data; } + + _Self& + operator++() + { + _M_node = _M_node->_M_next; + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_next; + return __tmp; + } + + _Self& + operator--() + { + _M_node = _M_node->_M_prev; + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_prev; + return __tmp; + } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + // The only member points to the %list element. + _List_node_base* _M_node; + }; + /** + * @brief A list::const_iterator. + * * @if maint - * See bits/stl_deque.h's _Deque_alloc_base for an explanation. + * All the functions are op overloads. * @endif */ - template<typename _Tp, typename _Allocator, bool _IsStatic> - class _List_alloc_base - { - public: - typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type - allocator_type; - - allocator_type - get_allocator() const { return _M_node_allocator; } - - _List_alloc_base(const allocator_type& __a) - : _M_node_allocator(__a) - { } - - protected: - _List_node<_Tp>* - _M_get_node() - { return _M_node_allocator.allocate(1); } - - void - _M_put_node(_List_node<_Tp>* __p) - { _M_node_allocator.deallocate(__p, 1); } - - // NOTA BENE - // The stored instance is not actually of "allocator_type"'s type. Instead - // we rebind the type to Allocator<List_node<Tp>>, which according to - // [20.1.5]/4 should probably be the same. List_node<Tp> is not the same - // size as Tp (it's two pointers larger), and specializations on Tp may go - // unused because List_node<Tp> is being bound instead. - // - // We put this to the test in get_allocator above; if the two types are - // actually different, there had better be a conversion between them. - // - // None of the predefined allocators shipped with the library (as of 3.1) - // use this instantiation anyhow; they're all instanceless. - typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type - _M_node_allocator; - - _List_node<_Tp>* _M_node; - }; - - /// @if maint Specialization for instanceless allocators. @endif - template<typename _Tp, typename _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: - // See comment in primary template class about why this is safe for the - // standard predefined classes. - 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); } - - _List_node<_Tp>* _M_node; - }; - - + template<typename _Tp> + struct _List_const_iterator + { + typedef _List_const_iterator<_Tp> _Self; + typedef const _List_node<_Tp> _Node; + typedef _List_iterator<_Tp> iterator; + + typedef ptrdiff_t difference_type; + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + + _List_const_iterator() { } + + _List_const_iterator(const _List_node_base* __x) + : _M_node(__x) { } + + _List_const_iterator(const iterator& __x) + : _M_node(__x._M_node) { } + + // Must downcast from List_node_base to _List_node to get to + // _M_data. + reference + operator*() const + { return static_cast<_Node*>(_M_node)->_M_data; } + + pointer + operator->() const + { return &static_cast<_Node*>(_M_node)->_M_data; } + + _Self& + operator++() + { + _M_node = _M_node->_M_next; + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_next; + return __tmp; + } + + _Self& + operator--() + { + _M_node = _M_node->_M_prev; + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_prev; + return __tmp; + } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + // The only member points to the %list element. + const _List_node_base* _M_node; + }; + + template<typename _Val> + inline bool + operator==(const _List_iterator<_Val>& __x, + const _List_const_iterator<_Val>& __y) + { return __x._M_node == __y._M_node; } + + template<typename _Val> + inline bool + operator!=(const _List_iterator<_Val>& __x, + const _List_const_iterator<_Val>& __y) + { return __x._M_node != __y._M_node; } + + /** * @if maint * See bits/stl_deque.h's _Deque_base for an explanation. * @endif */ - template <typename _Tp, typename _Alloc> + template<typename _Tp, typename _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; - } - - // This is what actually destroys the list. - ~_List_base() - { - __clear(); - _M_put_node(_M_node); - } - - void - __clear(); - }; - - + protected: + // NOTA BENE + // The stored instance is not actually of "allocator_type"'s + // type. Instead we rebind the type to + // Allocator<List_node<Tp>>, which according to [20.1.5]/4 + // should probably be the same. List_node<Tp> is not the same + // size as Tp (it's two pointers larger), and specializations on + // Tp may go unused because List_node<Tp> is being bound + // instead. + // + // We put this to the test in the constructors and in + // get_allocator, where we use conversions between + // allocator_type and _Node_Alloc_type. The conversion is + // required by table 32 in [20.1.5]. + typedef typename _Alloc::template rebind<_List_node<_Tp> >::other + + _Node_Alloc_type; + + struct _List_impl + : public _Node_Alloc_type { + _List_node_base _M_node; + _List_impl (const _Node_Alloc_type& __a) + : _Node_Alloc_type(__a) + { } + }; + + _List_impl _M_impl; + + _List_node<_Tp>* + _M_get_node() + { return _M_impl._Node_Alloc_type::allocate(1); } + + void + _M_put_node(_List_node<_Tp>* __p) + { _M_impl._Node_Alloc_type::deallocate(__p, 1); } + + public: + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return allocator_type(*static_cast<const _Node_Alloc_type*>(&this->_M_impl)); } + + _List_base(const allocator_type& __a) + : _M_impl(__a) + { _M_init(); } + + // This is what actually destroys the list. + ~_List_base() + { _M_clear(); } + + void + _M_clear(); + + void + _M_init() + { + this->_M_impl._M_node._M_next = &this->_M_impl._M_node; + this->_M_impl._M_node._M_prev = &this->_M_impl._M_node; + } + }; + /** - * @brief A standard container with linear time access to elements, and - * fixed time insertion/deletion at any point in the sequence. + * @brief A standard container with linear time access to elements, + * and fixed time insertion/deletion at any point in the sequence. * * @ingroup Containers * @ingroup Sequences @@ -331,830 +351,897 @@ namespace std * <a href="tables.html#68">optional sequence requirements</a> with the * %exception of @c at and @c operator[]. * - * This is a @e doubly @e linked %list. Traversal up and down the %list - * requires linear time, but adding and removing elements (or @e nodes) is - * done in constant time, regardless of where the change takes place. - * Unlike std::vector and std::deque, random-access iterators are not - * provided, so subscripting ( @c [] ) access is not allowed. For algorithms - * which only need sequential access, this lack makes no difference. + * This is a @e doubly @e linked %list. Traversal up and down the + * %list requires linear time, but adding and removing elements (or + * @e nodes) is done in constant time, regardless of where the + * change takes place. Unlike std::vector and std::deque, + * random-access iterators are not provided, so subscripting ( @c + * [] ) access is not allowed. For algorithms which only need + * sequential access, this lack makes no difference. * - * Also unlike the other standard containers, std::list provides specialized - * algorithms %unique to linked lists, such as splicing, sorting, and - * in-place reversal. + * Also unlike the other standard containers, std::list provides + * specialized algorithms %unique to linked lists, such as + * splicing, sorting, and in-place reversal. * * @if maint * A couple points on memory allocation for list<Tp>: * - * First, we never actually allocate a Tp, we allocate List_node<Tp>'s - * and trust [20.1.5]/4 to DTRT. This is to ensure that after elements from - * %list<X,Alloc1> are spliced into %list<X,Alloc2>, destroying the memory of - * the second %list is a valid operation, i.e., Alloc1 giveth and Alloc2 - * taketh away. + * First, we never actually allocate a Tp, we allocate + * List_node<Tp>'s and trust [20.1.5]/4 to DTRT. This is to ensure + * that after elements from %list<X,Alloc1> are spliced into + * %list<X,Alloc2>, destroying the memory of the second %list is a + * valid operation, i.e., Alloc1 giveth and Alloc2 taketh away. * * Second, a %list conceptually represented as * @code * A <---> B <---> C <---> D * @endcode - * is actually circular; a link exists between A and D. The %list class - * holds (as its only data member) a private list::iterator pointing to - * @e D, not to @e A! To get to the head of the %list, we start at the tail - * and move forward by one. When this member iterator's next/previous - * pointers refer to itself, the %list is %empty. - * @endif + * is actually circular; a link exists between A and D. The %list + * class holds (as its only data member) a private list::iterator + * pointing to @e D, not to @e A! To get to the head of the %list, + * we start at the tail and move forward by one. When this member + * iterator's next/previous pointers refer to itself, the %list is + * %empty. @endif */ template<typename _Tp, typename _Alloc = allocator<_Tp> > class list : protected _List_base<_Tp, _Alloc> - { - // concept requirements - __glibcpp_class_requires(_Tp, _SGIAssignableConcept) - - typedef _List_base<_Tp, _Alloc> _Base; - - public: - typedef _Tp value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator; - typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; - typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - typedef std::reverse_iterator<iterator> reverse_iterator; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef typename _Base::allocator_type allocator_type; - - protected: - // Note that pointers-to-_Node's can be ctor-converted to iterator types. - typedef _List_node<_Tp> _Node; - - /** @if maint - * One data member plus two memory-handling functions. If the _Alloc - * type requires separate instances, then one of those will also be - * included, accumulated from the topmost parent. - * @endif - */ - using _Base::_M_node; - using _Base::_M_put_node; - using _Base::_M_get_node; - - /** - * @if maint - * @param x An instance of user data. - * - * Allocates space for a new node and constructs a copy of @a x in it. - * @endif - */ - _Node* - _M_create_node(const value_type& __x) { - _Node* __p = _M_get_node(); - try { - _Construct(&__p->_M_data, __x); - } - catch(...) + // concept requirements + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + + typedef _List_base<_Tp, _Alloc> _Base; + + public: + typedef _Tp value_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef _List_iterator<_Tp> iterator; + typedef _List_const_iterator<_Tp> const_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef typename _Base::allocator_type allocator_type; + + protected: + // Note that pointers-to-_Node's can be ctor-converted to + // iterator types. + typedef _List_node<_Tp> _Node; + + /** @if maint + * One data member plus two memory-handling functions. If the + * _Alloc type requires separate instances, then one of those + * will also be included, accumulated from the topmost parent. + * @endif + */ + using _Base::_M_impl; + using _Base::_M_put_node; + using _Base::_M_get_node; + + /** + * @if maint + * @param x An instance of user data. + * + * Allocates space for a new node and constructs a copy of @a x in it. + * @endif + */ + _Node* + _M_create_node(const value_type& __x) { - _M_put_node(__p); - __throw_exception_again; - } - return __p; - } - - /** - * @if maint - * Allocates space for a new node and default-constructs a new instance - * of @c value_type in it. - * @endif - */ - _Node* - _M_create_node() - { - _Node* __p = _M_get_node(); - try { - _Construct(&__p->_M_data); + _Node* __p = this->_M_get_node(); + try + { + std::_Construct(&__p->_M_data, __x); + } + catch(...) + { + _M_put_node(__p); + __throw_exception_again; + } + return __p; } - catch(...) + + /** + * @if maint + * Allocates space for a new node and default-constructs a new + * instance of @c value_type in it. + * @endif + */ + _Node* + _M_create_node() { - _M_put_node(__p); - __throw_exception_again; + _Node* __p = this->_M_get_node(); + try + { + std::_Construct(&__p->_M_data); + } + catch(...) + { + _M_put_node(__p); + __throw_exception_again; + } + return __p; } - return __p; - } - - public: - // [23.2.2.1] construct/copy/destroy - // (assign() and get_allocator() are also listed in this section) - /** - * @brief Default constructor creates no elements. - */ - explicit - list(const allocator_type& __a = allocator_type()) - : _Base(__a) { } - - /** - * @brief Create a %list with copies of an exemplar element. - * @param n The number of elements to initially create. - * @param value An element to copy. - * - * This constructor fills the %list with @a n copies of @a value. - */ - list(size_type __n, const value_type& __value, - const allocator_type& __a = allocator_type()) + + public: + // [23.2.2.1] construct/copy/destroy + // (assign() and get_allocator() are also listed in this section) + /** + * @brief Default constructor creates no elements. + */ + explicit + list(const allocator_type& __a = allocator_type()) + : _Base(__a) { } + + /** + * @brief Create a %list with copies of an exemplar element. + * @param n The number of elements to initially create. + * @param value An element to copy. + * + * This constructor fills the %list with @a n copies of @a value. + */ + list(size_type __n, const value_type& __value, + const allocator_type& __a = allocator_type()) : _Base(__a) { this->insert(begin(), __n, __value); } - - /** - * @brief Create a %list with default elements. - * @param n The number of elements to initially create. - * - * This constructor fills the %list with @a n copies of a - * default-constructed element. - */ - explicit - list(size_type __n) + + /** + * @brief Create a %list with default elements. + * @param n The number of elements to initially create. + * + * This constructor fills the %list with @a n copies of a + * default-constructed element. + */ + explicit + list(size_type __n) : _Base(allocator_type()) { this->insert(begin(), __n, value_type()); } - - /** - * @brief %List copy constructor. - * @param x A %list of identical element and allocator types. - * - * The newly-created %list uses a copy of the allocation object used - * by @a x. - */ - list(const list& __x) + + /** + * @brief %List copy constructor. + * @param x A %list of identical element and allocator types. + * + * The newly-created %list uses a copy of the allocation object used + * by @a x. + */ + list(const list& __x) : _Base(__x.get_allocator()) { this->insert(begin(), __x.begin(), __x.end()); } - - /** - * @brief Builds a %list from a range. - * @param first An input iterator. - * @param last An input iterator. - * - * Create a %list consisting of copies of the elements from [first,last). - * This is linear in N (where N is distance(first,last)). - * - * @if maint - * We don't need any dispatching tricks here, because insert does all of - * that anyway. - * @endif - */ - template<typename _InputIterator> - list(_InputIterator __first, _InputIterator __last, - const allocator_type& __a = allocator_type()) - : _Base(__a) - { this->insert(begin(), __first, __last); } - - /** - * The dtor only erases the elements, and note that if the elements - * themselves are pointers, the pointed-to memory is not touched in any - * way. Managing the pointer is the user's responsibilty. - */ - ~list() { } - - /** - * @brief %List assignment operator. - * @param x A %list of identical element and allocator types. - * - * All the elements of @a x are copied, but unlike the copy constructor, - * the allocator object is not copied. - */ - list& - operator=(const list& __x); - - /** - * @brief Assigns a given value to a %list. - * @param n Number of elements to be assigned. - * @param val Value to be assigned. - * - * This function fills a %list with @a n copies of the given value. - * Note that the assignment completely changes the %list and that the - * resulting %list's size is the same as the number of elements assigned. - * Old data may be lost. - */ - void - assign(size_type __n, const value_type& __val) { _M_fill_assign(__n, __val); } - - /** - * @brief Assigns a range to a %list. - * @param first An input iterator. - * @param last An input iterator. - * - * This function fills a %list with copies of the elements in the - * range [first,last). - * - * Note that the assignment completely changes the %list and that the - * resulting %list's size is the same as the number of elements assigned. - * Old data may be lost. - */ - template<typename _InputIterator> + + /** + * @brief Builds a %list from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %list consisting of copies of the elements from + * [@a first,@a last). This is linear in N (where N is + * distance(@a first,@a last)). + * + * @if maint + * We don't need any dispatching tricks here, because insert does all of + * that anyway. + * @endif + */ + template<typename _InputIterator> + list(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { this->insert(begin(), __first, __last); } + + /** + * No explicit dtor needed as the _Base dtor takes care of + * things. The _Base dtor only erases the elements, and note + * that if the elements themselves are pointers, the pointed-to + * memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + + /** + * @brief %List assignment operator. + * @param x A %list of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy + * constructor, the allocator object is not copied. + */ + list& + operator=(const list& __x); + + /** + * @brief Assigns a given value to a %list. + * @param n Number of elements to be assigned. + * @param val Value to be assigned. + * + * This function fills a %list with @a n copies of the given + * value. Note that the assignment completely changes the %list + * and that the resulting %list's size is the same as the number + * of elements assigned. Old data may be lost. + */ + void + assign(size_type __n, const value_type& __val) + { _M_fill_assign(__n, __val); } + + /** + * @brief Assigns a range to a %list. + * @param first An input iterator. + * @param last An input iterator. + * + * This function fills a %list with copies of the elements in the + * range [@a first,@a last). + * + * Note that the assignment completely changes the %list and + * that the resulting %list's size is the same as the number of + * elements assigned. Old data may be lost. + */ + template<typename _InputIterator> + void + assign(_InputIterator __first, _InputIterator __last) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _Base::get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first element in the + * %list. Iteration is done in ordinary element order. + */ + iterator + begin() + { return this->_M_impl._M_node._M_next; } + + /** + * Returns a read-only (constant) iterator that points to the + * first element in the %list. Iteration is done in ordinary + * element order. + */ + const_iterator + begin() const + { return this->_M_impl._M_node._M_next; } + + /** + * Returns a read/write iterator that points one past the last + * element in the %list. Iteration is done in ordinary element + * order. + */ + iterator + end() { return &this->_M_impl._M_node; } + + /** + * Returns a read-only (constant) iterator that points one past + * the last element in the %list. Iteration is done in ordinary + * element order. + */ + const_iterator + end() const + { return &this->_M_impl._M_node; } + + /** + * Returns a read/write reverse iterator that points to the last + * element in the %list. Iteration is done in reverse element + * order. + */ + reverse_iterator + rbegin() + { return reverse_iterator(end()); } + + /** + * Returns a read-only (constant) reverse iterator that points to + * the last element in the %list. Iteration is done in reverse + * element order. + */ + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } + + /** + * Returns a read/write reverse iterator that points to one + * before the first element in the %list. Iteration is done in + * reverse element order. + */ + reverse_iterator + rend() + { return reverse_iterator(begin()); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first element in the %list. Iteration is done in reverse + * element order. + */ + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // [23.2.2.2] capacity + /** + * Returns true if the %list is empty. (Thus begin() would equal + * end().) + */ + bool + empty() const + { return this->_M_impl._M_node._M_next == &this->_M_impl._M_node; } + + /** Returns the number of elements in the %list. */ + size_type + size() const + { return std::distance(begin(), end()); } + + /** Returns the size() of the largest possible %list. */ + size_type + max_size() const + { return size_type(-1); } + + /** + * @brief Resizes the %list to the specified number of elements. + * @param new_size Number of elements the %list should contain. + * @param x Data with which new elements should be populated. + * + * This function will %resize the %list to the specified number + * of elements. If the number is smaller than the %list's + * current size the %list is truncated, otherwise the %list is + * extended and new elements are populated with given data. + */ + void + resize(size_type __new_size, const value_type& __x); + + /** + * @brief Resizes the %list to the specified number of elements. + * @param new_size Number of elements the %list should contain. + * + * This function will resize the %list to the specified number of + * elements. If the number is smaller than the %list's current + * size the %list is truncated, otherwise the %list is extended + * and new elements are default-constructed. + */ + void + resize(size_type __new_size) + { this->resize(__new_size, value_type()); } + + // element access + /** + * Returns a read/write reference to the data at the first + * element of the %list. + */ + reference + front() + { return *begin(); } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %list. + */ + const_reference + front() const + { return *begin(); } + + /** + * Returns a read/write reference to the data at the last element + * of the %list. + */ + reference + back() + { return *(--end()); } + + /** + * Returns a read-only (constant) reference to the data at the last + * element of the %list. + */ + const_reference + back() const + { return *(--end()); } + + // [23.2.2.3] modifiers + /** + * @brief Add data to the front of the %list. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an + * element at the front of the %list and assigns the given data + * to it. Due to the nature of a %list this operation can be + * done in constant time, and does not invalidate iterators and + * references. + */ + void + push_front(const value_type& __x) + { this->_M_insert(begin(), __x); } + + /** + * @brief Removes first element. + * + * This is a typical stack operation. It shrinks the %list by + * one. Due to the nature of a %list this operation can be done + * in constant time, and only invalidates iterators/references to + * the element being removed. + * + * Note that no data is returned, and if the first element's data + * is needed, it should be retrieved before pop_front() is + * called. + */ void - assign(_InputIterator __first, _InputIterator __last) + pop_front() + { this->_M_erase(begin()); } + + /** + * @brief Add data to the end of the %list. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an + * element at the end of the %list and assigns the given data to + * it. Due to the nature of a %list this operation can be done + * in constant time, and does not invalidate iterators and + * references. + */ + void + push_back(const value_type& __x) + { this->_M_insert(end(), __x); } + + /** + * @brief Removes last element. + * + * This is a typical stack operation. It shrinks the %list by + * one. Due to the nature of a %list this operation can be done + * in constant time, and only invalidates iterators/references to + * the element being removed. + * + * Note that no data is returned, and if the last element's data + * is needed, it should be retrieved before pop_back() is called. + */ + void + pop_back() + { this->_M_erase(this->_M_impl._M_node._M_prev); } + + /** + * @brief Inserts given value into %list before specified iterator. + * @param position An iterator into the %list. + * @param x Data to be inserted. + * @return An iterator that points to the inserted data. + * + * This function will insert a copy of the given value before + * the specified location. Due to the nature of a %list this + * operation can be done in constant time, and does not + * invalidate iterators and references. + */ + iterator + insert(iterator __position, const value_type& __x); + + /** + * @brief Inserts a number of copies of given data into the %list. + * @param position An iterator into the %list. + * @param n Number of elements to be inserted. + * @param x Data to be inserted. + * + * This function will insert a specified number of copies of the + * given data before the location specified by @a position. + * + * Due to the nature of a %list this operation can be done in + * constant time, and does not invalidate iterators and + * references. + */ + void + insert(iterator __position, size_type __n, const value_type& __x) + { _M_fill_insert(__position, __n, __x); } + + /** + * @brief Inserts a range into the %list. + * @param position An iterator into the %list. + * @param first An input iterator. + * @param last An input iterator. + * + * This function will insert copies of the data in the range [@a + * first,@a last) into the %list before the location specified by + * @a position. + * + * Due to the nature of a %list this operation can be done in + * constant time, and does not invalidate iterators and + * references. + */ + template<typename _InputIterator> + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + /** + * @brief Remove element at given position. + * @param position Iterator pointing to element to be erased. + * @return An iterator pointing to the next element (or end()). + * + * This function will erase the element at the given position and thus + * shorten the %list by one. + * + * Due to the nature of a %list this operation can be done in + * constant time, and only invalidates iterators/references to + * the element being removed. The user is also cautioned that + * this function only erases the element, and that if the element + * is itself a pointer, the pointed-to memory is not touched in + * any way. Managing the pointer is the user's responsibilty. + */ + iterator + erase(iterator __position); + + /** + * @brief Remove a range of elements. + * @param first Iterator pointing to the first element to be erased. + * @param last Iterator pointing to one past the last element to be + * erased. + * @return An iterator pointing to the element pointed to by @a last + * prior to erasing (or end()). + * + * This function will erase the elements in the range @a + * [first,last) and shorten the %list accordingly. + * + * Due to the nature of a %list this operation can be done in + * constant time, and only invalidates iterators/references to + * the element being removed. The user is also cautioned that + * this function only erases the elements, and that if the + * elements themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's + * responsibilty. + */ + iterator + erase(iterator __first, iterator __last) { - // Check whether it's an integral type. If so, it's not an iterator. - typedef typename _Is_integer<_InputIterator>::_Integral _Integral; - _M_assign_dispatch(__first, __last, _Integral()); + while (__first != __last) + __first = erase(__first); + return __last; } - - /// Get a copy of the memory allocation object. - allocator_type - get_allocator() const { return _Base::get_allocator(); } - - // iterators - /** - * Returns a read/write iterator that points to the first element in the - * %list. Iteration is done in ordinary element order. - */ - iterator - begin() { return static_cast<_Node*>(_M_node->_M_next); } - - /** - * Returns a read-only (constant) iterator that points to the first element - * in the %list. Iteration is done in ordinary element order. - */ - const_iterator - begin() const { return static_cast<_Node*>(_M_node->_M_next); } - - /** - * Returns a read/write iterator that points one past the last element in - * the %list. Iteration is done in ordinary element order. - */ - iterator - end() { return _M_node; } - - /** - * Returns a read-only (constant) iterator that points one past the last - * element in the %list. Iteration is done in ordinary element order. - */ - const_iterator - end() const { return _M_node; } - - /** - * Returns a read/write reverse iterator that points to the last element in - * the %list. Iteration is done in reverse element order. - */ - reverse_iterator - rbegin() { return reverse_iterator(end()); } - - /** - * Returns a read-only (constant) reverse iterator that points to the last - * element in the %list. Iteration is done in reverse element order. - */ - const_reverse_iterator - rbegin() const { return const_reverse_iterator(end()); } - - /** - * Returns a read/write reverse iterator that points to one before the - * first element in the %list. Iteration is done in reverse element - * order. - */ - reverse_iterator - rend() { return reverse_iterator(begin()); } - - /** - * Returns a read-only (constant) reverse iterator that points to one - * before the first element in the %list. Iteration is done in reverse - * element order. - */ - const_reverse_iterator - rend() const - { return const_reverse_iterator(begin()); } - - // [23.2.2.2] capacity - /** - * Returns true if the %list is empty. (Thus begin() would equal end().) - */ - bool - empty() const { return _M_node->_M_next == _M_node; } - - /** Returns the number of elements in the %list. */ - size_type - size() const { return distance(begin(), end()); } - - /** Returns the size() of the largest possible %list. */ - size_type - max_size() const { return size_type(-1); } - - /** - * @brief Resizes the %list to the specified number of elements. - * @param new_size Number of elements the %list should contain. - * @param x Data with which new elements should be populated. - * - * This function will %resize the %list to the specified number of - * elements. If the number is smaller than the %list's current size the - * %list is truncated, otherwise the %list is extended and new elements - * are populated with given data. - */ - void - resize(size_type __new_size, const value_type& __x); - - /** - * @brief Resizes the %list to the specified number of elements. - * @param new_size Number of elements the %list should contain. - * - * This function will resize the %list to the specified number of - * elements. If the number is smaller than the %list's current size the - * %list is truncated, otherwise the %list is extended and new elements - * are default-constructed. - */ - void - resize(size_type __new_size) { this->resize(__new_size, value_type()); } - - // element access - /** - * Returns a read/write reference to the data at the first element of the - * %list. - */ - reference - front() { return *begin(); } - - /** - * Returns a read-only (constant) reference to the data at the first - * element of the %list. - */ - const_reference - front() const { return *begin(); } - - /** - * Returns a read/write reference to the data at the last element of the - * %list. - */ - reference - back() { return *(--end()); } - - /** - * Returns a read-only (constant) reference to the data at the last - * element of the %list. - */ - const_reference - back() const { return *(--end()); } - - // [23.2.2.3] modifiers - /** - * @brief Add data to the front of the %list. - * @param x Data to be added. - * - * This is a typical stack operation. The function creates an element at - * the front of the %list and assigns the given data to it. Due to the - * nature of a %list this operation can be done in constant time, and - * does not invalidate iterators and references. - */ - void - push_front(const value_type& __x) { this->insert(begin(), __x); } - - #ifdef _GLIBCPP_DEPRECATED - /** - * @brief Add data to the front of the %list. - * - * This is a typical stack operation. The function creates a - * default-constructed element at the front of the %list. Due to the - * nature of a %list this operation can be done in constant time. You - * should consider using push_front(value_type()) instead. - * - * @note This was deprecated in 3.2 and will be removed in 3.4. You must - * define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see - * c++config.h. - */ - void - push_front() { this->insert(begin(), value_type()); } - #endif - - /** - * @brief Removes first element. - * - * This is a typical stack operation. It shrinks the %list by one. - * Due to the nature of a %list this operation can be done in constant - * time, and only invalidates iterators/references to the element being - * removed. - * - * Note that no data is returned, and if the first element's data is - * needed, it should be retrieved before pop_front() is called. - */ - void - pop_front() { this->erase(begin()); } - - /** - * @brief Add data to the end of the %list. - * @param x Data to be added. - * - * This is a typical stack operation. The function creates an element at - * the end of the %list and assigns the given data to it. Due to the - * nature of a %list this operation can be done in constant time, and - * does not invalidate iterators and references. - */ - void - push_back(const value_type& __x) { this->insert(end(), __x); } - - #ifdef _GLIBCPP_DEPRECATED - /** - * @brief Add data to the end of the %list. - * - * This is a typical stack operation. The function creates a - * default-constructed element at the end of the %list. Due to the nature - * of a %list this operation can be done in constant time. You should - * consider using push_back(value_type()) instead. - * - * @note This was deprecated in 3.2 and will be removed in 3.4. You must - * define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see - * c++config.h. - */ - void - push_back() { this->insert(end(), value_type()); } - #endif - - /** - * @brief Removes last element. - * - * This is a typical stack operation. It shrinks the %list by one. - * Due to the nature of a %list this operation can be done in constant - * time, and only invalidates iterators/references to the element being - * removed. - * - * Note that no data is returned, and if the last element's data is - * needed, it should be retrieved before pop_back() is called. - */ - void - pop_back() - { - iterator __tmp = end(); - this->erase(--__tmp); - } - - /** - * @brief Inserts given value into %list before specified iterator. - * @param position An iterator into the %list. - * @param x Data to be inserted. - * @return An iterator that points to the inserted data. - * - * This function will insert a copy of the given value before the specified - * location. - * Due to the nature of a %list this operation can be done in constant - * time, and does not invalidate iterators and references. - */ - iterator - insert(iterator __position, const value_type& __x); - - #ifdef _GLIBCPP_DEPRECATED - /** - * @brief Inserts an element into the %list. - * @param position An iterator into the %list. - * @return An iterator that points to the inserted element. - * - * This function will insert a default-constructed element before the - * specified location. You should consider using - * insert(position,value_type()) instead. - * Due to the nature of a %list this operation can be done in constant - * time, and does not invalidate iterators and references. - * - * @note This was deprecated in 3.2 and will be removed in 3.4. You must - * define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see - * c++config.h. - */ - iterator - insert(iterator __position) { return insert(__position, value_type()); } - #endif - - /** - * @brief Inserts a number of copies of given data into the %list. - * @param position An iterator into the %list. - * @param n Number of elements to be inserted. - * @param x Data to be inserted. - * - * This function will insert a specified number of copies of the given data - * before the location specified by @a position. - * - * Due to the nature of a %list this operation can be done in constant - * time, and does not invalidate iterators and references. - */ - void - insert(iterator __pos, size_type __n, const value_type& __x) - { _M_fill_insert(__pos, __n, __x); } - - /** - * @brief Inserts a range into the %list. - * @param pos An iterator into the %list. - * @param first An input iterator. - * @param last An input iterator. - * - * This function will insert copies of the data in the range [first,last) - * into the %list before the location specified by @a pos. - * - * Due to the nature of a %list this operation can be done in constant - * time, and does not invalidate iterators and references. - */ - template<typename _InputIterator> + + /** + * @brief Swaps data with another %list. + * @param x A %list of the same element and allocator types. + * + * This exchanges the elements between two lists in constant + * time. Note that the global std::swap() function is + * specialized such that std::swap(l1,l2) will feed to this + * function. + */ void - insert(iterator __pos, _InputIterator __first, _InputIterator __last) + swap(list& __x) + { _List_node_base::swap(this->_M_impl._M_node,__x._M_impl._M_node); } + + /** + * Erases all the elements. Note that this function only erases + * the elements, and that if the elements themselves are + * pointers, the pointed-to memory is not touched in any way. + * Managing the pointer is the user's responsibilty. + */ + void + clear() { - // Check whether it's an integral type. If so, it's not an iterator. - typedef typename _Is_integer<_InputIterator>::_Integral _Integral; - _M_insert_dispatch(__pos, __first, __last, _Integral()); + _Base::_M_clear(); + _Base::_M_init(); } - - /** - * @brief Remove element at given position. - * @param position Iterator pointing to element to be erased. - * @return An iterator pointing to the next element (or end()). - * - * This function will erase the element at the given position and thus - * shorten the %list by one. - * - * Due to the nature of a %list this operation can be done in constant - * time, and only invalidates iterators/references to the element being - * removed. - * The user is also cautioned that - * this function only erases the element, and that if the element is itself - * a pointer, the pointed-to memory is not touched in any way. Managing - * the pointer is the user's responsibilty. - */ - iterator - erase(iterator __position); - - /** - * @brief Remove a range of elements. - * @param first Iterator pointing to the first element to be erased. - * @param last Iterator pointing to one past the last element to be - * erased. - * @return An iterator pointing to the element pointed to by @a last - * prior to erasing (or end()). - * - * This function will erase the elements in the range [first,last) and - * shorten the %list accordingly. - * - * Due to the nature of a %list this operation can be done in constant - * time, and only invalidates iterators/references to the element being - * removed. - * The user is also cautioned that - * this function only erases the elements, and that if the elements - * themselves are pointers, the pointed-to memory is not touched in any - * way. Managing the pointer is the user's responsibilty. - */ - iterator - erase(iterator __first, iterator __last) - { - while (__first != __last) - erase(__first++); - return __last; - } - - /** - * @brief Swaps data with another %list. - * @param x A %list of the same element and allocator types. - * - * This exchanges the elements between two lists in constant time. - * (It is only swapping a single pointer, so it should be quite fast.) - * Note that the global std::swap() function is specialized such that - * std::swap(l1,l2) will feed to this function. - */ - void - swap(list& __x) { std::swap(_M_node, __x._M_node); } - - /** - * Erases all the elements. Note that this function only erases the - * elements, and that if the elements themselves are pointers, the - * pointed-to memory is not touched in any way. Managing the pointer is - * the user's responsibilty. - */ - void - clear() { _Base::__clear(); } - - // [23.2.2.4] list operations - /** - * @doctodo - */ - void - splice(iterator __position, list& __x) - { - if (!__x.empty()) - this->_M_transfer(__position, __x.begin(), __x.end()); - } - - /** - * @doctodo - */ - void - splice(iterator __position, list&, iterator __i) - { - iterator __j = __i; - ++__j; - if (__position == __i || __position == __j) return; - this->_M_transfer(__position, __i, __j); - } - - /** - * @doctodo - */ - void - splice(iterator __position, list&, iterator __first, iterator __last) - { - if (__first != __last) - this->_M_transfer(__position, __first, __last); - } - - /** - * @doctodo - */ - void - remove(const _Tp& __value); - - /** - * @doctodo - */ - template<typename _Predicate> + + // [23.2.2.4] list operations + /** + * @brief Insert contents of another %list. + * @param position Iterator referencing the element to insert before. + * @param x Source list. + * + * The elements of @a x are inserted in constant time in front of + * the element referenced by @a position. @a x becomes an empty + * list. + */ + void + splice(iterator __position, list& __x) + { + if (!__x.empty()) + this->_M_transfer(__position, __x.begin(), __x.end()); + } + + /** + * @brief Insert element from another %list. + * @param position Iterator referencing the element to insert before. + * @param x Source list. + * @param i Iterator referencing the element to move. + * + * Removes the element in list @a x referenced by @a i and + * inserts it into the current list before @a position. + */ + void + splice(iterator __position, list&, iterator __i) + { + iterator __j = __i; + ++__j; + if (__position == __i || __position == __j) + return; + this->_M_transfer(__position, __i, __j); + } + + /** + * @brief Insert range from another %list. + * @param position Iterator referencing the element to insert before. + * @param x Source list. + * @param first Iterator referencing the start of range in x. + * @param last Iterator referencing the end of range in x. + * + * Removes elements in the range [first,last) and inserts them + * before @a position in constant time. + * + * Undefined if @a position is in [first,last). + */ + void + splice(iterator __position, list&, iterator __first, iterator __last) + { + if (__first != __last) + this->_M_transfer(__position, __first, __last); + } + + /** + * @brief Remove all elements equal to value. + * @param value The value to remove. + * + * Removes every element in the list equal to @a value. + * Remaining elements stay in list order. Note that this + * function only erases the elements, and that if the elements + * themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's + * responsibilty. + */ + void + remove(const _Tp& __value); + + /** + * @brief Remove all elements satisfying a predicate. + * @param Predicate Unary predicate function or object. + * + * Removes every element in the list for which the predicate + * returns true. Remaining elements stay in list order. Note + * that this function only erases the elements, and that if the + * elements themselves are pointers, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. + */ + template<typename _Predicate> void remove_if(_Predicate); - - /** - * @doctodo - */ - void - unique(); - - /** - * @doctodo - */ - template<typename _BinaryPredicate> + + /** + * @brief Remove consecutive duplicate elements. + * + * For each consecutive set of elements with the same value, + * remove all but the first one. Remaining elements stay in + * list order. Note that this function only erases the + * elements, and that if the elements themselves are pointers, + * the pointed-to memory is not touched in any way. Managing + * the pointer is the user's responsibilty. + */ void - unique(_BinaryPredicate); - - /** - * @doctodo - */ - void - merge(list& __x); - - /** - * @doctodo - */ - template<typename _StrictWeakOrdering> + unique(); + + /** + * @brief Remove consecutive elements satisfying a predicate. + * @param BinaryPredicate Binary predicate function or object. + * + * For each consecutive set of elements [first,last) that + * satisfy predicate(first,i) where i is an iterator in + * [first,last), remove all but the first one. Remaining + * elements stay in list order. Note that this function only + * erases the elements, and that if the elements themselves are + * pointers, the pointed-to memory is not touched in any way. + * Managing the pointer is the user's responsibilty. + */ + template<typename _BinaryPredicate> + void + unique(_BinaryPredicate); + + /** + * @brief Merge sorted lists. + * @param x Sorted list to merge. + * + * Assumes that both @a x and this list are sorted according to + * operator<(). Merges elements of @a x into this list in + * sorted order, leaving @a x empty when complete. Elements in + * this list precede elements in @a x that are equal. + */ void - merge(list&, _StrictWeakOrdering); - - /** - * @doctodo - */ - void - reverse() { __List_base_reverse(this->_M_node); } - - /** - * @doctodo - */ - void - sort(); - - /** - * @doctodo - */ - template<typename _StrictWeakOrdering> + merge(list& __x); + + /** + * @brief Merge sorted lists according to comparison function. + * @param x Sorted list to merge. + * @param StrictWeakOrdering Comparison function definining + * sort order. + * + * Assumes that both @a x and this list are sorted according to + * StrictWeakOrdering. Merges elements of @a x into this list + * in sorted order, leaving @a x empty when complete. Elements + * in this list precede elements in @a x that are equivalent + * according to StrictWeakOrdering(). + */ + template<typename _StrictWeakOrdering> + void + merge(list&, _StrictWeakOrdering); + + /** + * @brief Reverse the elements in list. + * + * Reverse the order of elements in the list in linear time. + */ void - sort(_StrictWeakOrdering); - - protected: - // Internal assign functions follow. - - // called by the range assign to implement [23.1.1]/9 - template<typename _Integer> + reverse() + { this->_M_impl._M_node.reverse(); } + + /** + * @brief Sort the elements. + * + * Sorts the elements of this list in NlogN time. Equivalent + * elements remain in list order. + */ void - _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + sort(); + + /** + * @brief Sort the elements according to comparison function. + * + * Sorts the elements of this list in NlogN time. Equivalent + * elements remain in list order. + */ + template<typename _StrictWeakOrdering> + void + sort(_StrictWeakOrdering); + + protected: + // Internal assign functions follow. + + // Called by the range assign to implement [23.1.1]/9 + template<typename _Integer> + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { + _M_fill_assign(static_cast<size_type>(__n), + static_cast<value_type>(__val)); + } + + // Called by the range assign to implement [23.1.1]/9 + template<typename _InputIterator> + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); + + // Called by assign(n,t), and the range assign when it turns out + // to be the same thing. + void + _M_fill_assign(size_type __n, const value_type& __val); + + + // Internal insert functions follow. + + // Called by the range insert to implement [23.1.1]/9 + template<typename _Integer> + void + _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) + { + _M_fill_insert(__pos, static_cast<size_type>(__n), + static_cast<value_type>(__x)); + } + + // Called by the range insert to implement [23.1.1]/9 + template<typename _InputIterator> + void + _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) + { + for ( ; __first != __last; ++__first) + _M_insert(__pos, *__first); + } + + // Called by insert(p,n,x), and the range insert when it turns out + // to be the same thing. + void + _M_fill_insert(iterator __pos, size_type __n, const value_type& __x) { - _M_fill_assign(static_cast<size_type>(__n), - static_cast<value_type>(__val)); + for ( ; __n > 0; --__n) + _M_insert(__pos, __x); } - - // called by the range assign to implement [23.1.1]/9 - template<typename _InputIter> + + + // Moves the elements from [first,last) before position. void - _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type); - - // Called by assign(n,t), and the range assign when it turns out to be the - // same thing. - void - _M_fill_assign(size_type __n, const value_type& __val); - - - // Internal insert functions follow. - - // called by the range insert to implement [23.1.1]/9 - template<typename _Integer> + _M_transfer(iterator __position, iterator __first, iterator __last) + { __position._M_node->transfer(__first._M_node,__last._M_node); } + + // Inserts new element at position given and with value given. void - _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, - __true_type) + _M_insert(iterator __position, const value_type& __x) { - _M_fill_insert(__pos, static_cast<size_type>(__n), - static_cast<value_type>(__x)); + _Node* __tmp = _M_create_node(__x); + __tmp->hook(__position._M_node); } - - // called by the range insert to implement [23.1.1]/9 - template<typename _InputIterator> + + // Erases element at position given. void - _M_insert_dispatch(iterator __pos, - _InputIterator __first, _InputIterator __last, - __false_type) + _M_erase(iterator __position) { - for ( ; __first != __last; ++__first) - insert(__pos, *__first); + __position._M_node->unhook(); + _Node* __n = static_cast<_Node*>(__position._M_node); + std::_Destroy(&__n->_M_data); + _M_put_node(__n); } - - // Called by insert(p,n,x), and the range insert when it turns out to be - // the same thing. - void - _M_fill_insert(iterator __pos, size_type __n, const value_type& __x) - { - for ( ; __n > 0; --__n) - insert(__pos, __x); - } - - - // Moves the elements from [first,last) before position. - void - _M_transfer(iterator __position, iterator __first, iterator __last) - { - if (__position != __last) { - // Remove [first, last) from its old position. - __last._M_node->_M_prev->_M_next = __position._M_node; - __first._M_node->_M_prev->_M_next = __last._M_node; - __position._M_node->_M_prev->_M_next = __first._M_node; - - // Splice [first, last) into its new position. - _List_node_base* __tmp = __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; - } - } - }; - - + }; + /** * @brief List equality comparison. * @param x A %list. * @param y A %list of the same type as @a x. * @return True iff the size and elements of the lists are equal. * - * This is an equivalence relation. It is linear in the size of the - * lists. Lists are considered equivalent if their sizes are equal, - * and if corresponding elements compare equal. + * This is an equivalence relation. It is linear in the size of + * the lists. Lists are considered equivalent if their sizes are + * equal, and if corresponding elements compare equal. */ template<typename _Tp, typename _Alloc> - inline bool + inline bool operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) { typedef typename list<_Tp,_Alloc>::const_iterator const_iterator; const_iterator __end1 = __x.end(); const_iterator __end2 = __y.end(); - + const_iterator __i1 = __x.begin(); const_iterator __i2 = __y.begin(); - while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) { - ++__i1; - ++__i2; - } + while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) + { + ++__i1; + ++__i2; + } return __i1 == __end1 && __i2 == __end2; } - + /** * @brief List ordering relation. * @param x A %list. * @param y A %list of the same type as @a x. - * @return True iff @a x is lexographically less than @a y. + * @return True iff @a x is lexicographically less than @a y. * * This is a total ordering relation. It is linear in the size of the * lists. The elements must be comparable with @c <. * - * See std::lexographical_compare() for how the determination is made. + * See std::lexicographical_compare() for how the determination is made. */ template<typename _Tp, typename _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()); - } - + { return std::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } + /// Based on operator== template<typename _Tp, typename _Alloc> inline bool operator!=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) { return !(__x == __y); } - + /// Based on operator< template<typename _Tp, typename _Alloc> inline bool operator>(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) { return __y < __x; } - + /// Based on operator< template<typename _Tp, typename _Alloc> inline bool operator<=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) { return !(__y < __x); } - + /// Based on operator< template<typename _Tp, typename _Alloc> inline bool operator>=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) { return !(__x < __y); } - + /// See std::list::swap(). template<typename _Tp, typename _Alloc> inline void @@ -1162,4 +1249,5 @@ namespace std { __x.swap(__y); } } // namespace std -#endif /* __GLIBCPP_INTERNAL_LIST_H */ +#endif /* _LIST_H */ + diff --git a/contrib/libstdc++/include/bits/stl_map.h b/contrib/libstdc++/include/bits/stl_map.h index ed47bbb44e73..8535ae5f2680 100644 --- a/contrib/libstdc++/include/bits/stl_map.h +++ b/contrib/libstdc++/include/bits/stl_map.h @@ -1,6 +1,6 @@ // Map implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,12 +58,12 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_MAP_H -#define __GLIBCPP_INTERNAL_MAP_H +#ifndef _MAP_H +#define _MAP_H 1 #include <bits/concept_check.h> -namespace std +namespace _GLIBCXX_STD { /** * @brief A standard container made up of (key,value) pairs, which can be @@ -89,507 +89,540 @@ namespace std template <typename _Key, typename _Tp, typename _Compare = less<_Key>, typename _Alloc = allocator<pair<const _Key, _Tp> > > class map - { - // concept requirements - __glibcpp_class_requires(_Tp, _SGIAssignableConcept) - __glibcpp_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept) - - public: - typedef _Key key_type; - typedef _Tp mapped_type; - typedef pair<const _Key, _Tp> value_type; - typedef _Compare key_compare; - - class value_compare + { + // concept requirements + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) + + public: + typedef _Key key_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,_Tp,_Compare,_Alloc>; + friend class map<_Key,_Tp,_Compare,_Alloc>; protected: - _Compare comp; - value_compare(_Compare __c) : comp(__c) {} + _Compare comp; + + value_compare(_Compare __c) + : comp(__c) { } + public: - bool operator()(const value_type& __x, const value_type& __y) const - { return comp(__x.first, __y.first); } + bool operator()(const value_type& __x, const value_type& __y) const + { return comp(__x.first, __y.first); } }; - - private: - /// @if maint This turns a red-black tree into a [multi]map. @endif - typedef _Rb_tree<key_type, value_type, - _Select1st<value_type>, key_compare, _Alloc> _Rep_type; - /// @if maint The actual tree structure. @endif - _Rep_type _M_t; - - public: - // many of these are specified differently in ISO, but the following are - // "functionally equivalent" - typedef typename _Rep_type::allocator_type allocator_type; - 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::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::reverse_iterator reverse_iterator; - typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; - - - // [23.3.1.1] construct/copy/destroy - // (get_allocator() is normally listed in this section, but seems to have - // been accidentally omitted in the printed standard) - /** - * @brief Default constructor creates no elements. - */ - map() : _M_t(_Compare(), allocator_type()) { } - - // for some reason this was made a separate function - /** - * @brief Default constructor creates no elements. - */ - explicit - map(const _Compare& __comp, const allocator_type& __a = allocator_type()) + + private: + /// @if maint This turns a red-black tree into a [multi]map. @endif + typedef _Rb_tree<key_type, value_type, + _Select1st<value_type>, key_compare, _Alloc> _Rep_type; + /// @if maint The actual tree structure. @endif + _Rep_type _M_t; + + public: + // many of these are specified differently in ISO, but the following are + // "functionally equivalent" + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Rep_type::allocator_type allocator_type; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + + // [23.3.1.1] construct/copy/destroy + // (get_allocator() is normally listed in this section, but seems to have + // been accidentally omitted in the printed standard) + /** + * @brief Default constructor creates no elements. + */ + map() + : _M_t(_Compare(), allocator_type()) { } + + // for some reason this was made a separate function + /** + * @brief Default constructor creates no elements. + */ + explicit + map(const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { } - - /** - * @brief Map copy constructor. - * @param x A %map of identical element and allocator types. - * - * The newly-created %map uses a copy of the allocation object used - * by @a x. - */ - map(const map& __x) + + /** + * @brief Map copy constructor. + * @param x A %map of identical element and allocator types. + * + * The newly-created %map uses a copy of the allocation object used + * by @a x. + */ + map(const map& __x) : _M_t(__x._M_t) { } - - /** - * @brief Builds a %map from a range. - * @param first An input iterator. - * @param last An input iterator. - * - * Create a %map consisting of copies of the elements from [first,last). - * This is linear in N if the range is already sorted, and NlogN - * otherwise (where N is distance(first,last)). - */ - template <typename _InputIterator> - map(_InputIterator __first, _InputIterator __last) - : _M_t(_Compare(), allocator_type()) - { _M_t.insert_unique(__first, __last); } - - /** - * @brief Builds a %map from a range. - * @param first An input iterator. - * @param last An input iterator. - * @param comp A comparison functor. - * @param a An allocator object. - * - * Create a %map consisting of copies of the elements from [first,last). - * This is linear in N if the range is already sorted, and NlogN - * otherwise (where N is distance(first,last)). - */ - template <typename _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); } - - // FIXME There is no dtor declared, but we should have something generated - // by Doxygen. I don't know what tags to add to this paragraph to make - // that happen: - /** - * The dtor only erases the elements, and note that if the elements - * themselves are pointers, the pointed-to memory is not touched in any - * way. Managing the pointer is the user's responsibilty. - */ - - /** - * @brief Map assignment operator. - * @param x A %map of identical element and allocator types. - * - * All the elements of @a x are copied, but unlike the copy constructor, - * the allocator object is not copied. - */ - map& - operator=(const map& __x) - { - _M_t = __x._M_t; - return *this; - } - - /// Get a copy of the memory allocation object. - allocator_type - get_allocator() const { return _M_t.get_allocator(); } - - // iterators - /** - * Returns a read/write iterator that points to the first pair in the %map. - * Iteration is done in ascending order according to the keys. - */ - iterator - begin() { return _M_t.begin(); } - - /** - * Returns a read-only (constant) iterator that points to the first pair - * in the %map. Iteration is done in ascending order according to the - * keys. - */ - const_iterator - begin() const { return _M_t.begin(); } - - /** - * Returns a read/write iterator that points one past the last pair in the - * %map. Iteration is done in ascending order according to the keys. - */ - iterator - end() { return _M_t.end(); } - - /** - * Returns a read-only (constant) iterator that points one past the last - * pair in the %map. Iteration is done in ascending order according to the - * keys. - */ - const_iterator - end() const { return _M_t.end(); } - - /** - * Returns a read/write reverse iterator that points to the last pair in - * the %map. Iteration is done in descending order according to the keys. - */ - reverse_iterator - rbegin() { return _M_t.rbegin(); } - - /** - * Returns a read-only (constant) reverse iterator that points to the last - * pair in the %map. Iteration is done in descending order according to - * the keys. - */ - const_reverse_iterator - rbegin() const { return _M_t.rbegin(); } - - /** - * Returns a read/write reverse iterator that points to one before the - * first pair in the %map. Iteration is done in descending order according - * to the keys. - */ - reverse_iterator - rend() { return _M_t.rend(); } - - /** - * Returns a read-only (constant) reverse iterator that points to one - * before the first pair in the %map. Iteration is done in descending - * order according to the keys. - */ - const_reverse_iterator - rend() const { return _M_t.rend(); } - - // capacity - /** Returns true if the %map is empty. (Thus begin() would equal end().) */ - bool - empty() const { return _M_t.empty(); } - - /** Returns the size of the %map. */ - size_type - size() const { return _M_t.size(); } - - /** Returns the maximum size of the %map. */ - size_type - max_size() const { return _M_t.max_size(); } - - // [23.3.1.2] element access - /** - * @brief Subscript ( @c [] ) access to %map data. - * @param k The key for which data should be retrieved. - * @return A reference to the data of the (key,data) %pair. - * - * Allows for easy lookup with the subscript ( @c [] ) operator. Returns - * data associated with the key specified in subscript. If the key does - * not exist, a pair with that key is created using default values, which - * is then returned. - * - * Lookup requires logarithmic time. - */ - mapped_type& - operator[](const key_type& __k) - { - // concept requirements - __glibcpp_function_requires(_DefaultConstructibleConcept<mapped_type>) - - 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, mapped_type())); - return (*__i).second; - } - - // modifiers - /** - * @brief Attempts to insert a std::pair into the %map. - * @param x Pair to be inserted (see std::make_pair for easy creation of - * pairs). - * @return A pair, of which the first element is an iterator that points - * to the possibly inserted pair, and the second is a bool that - * is true if the pair was actually inserted. - * - * This function attempts to insert a (key, value) %pair into the %map. - * A %map relies on unique keys and thus a %pair is only inserted if its - * first element (the key) is not already present in the %map. - * - * Insertion requires logarithmic time. - */ - pair<iterator,bool> - insert(const value_type& __x) - { return _M_t.insert_unique(__x); } - - /** - * @brief Attempts to insert a std::pair into the %map. - * @param position An iterator that serves as a hint as to where the - * pair should be inserted. - * @param x Pair to be inserted (see std::make_pair for easy creation of - * pairs). - * @return An iterator that points to the element with key of @a x (may - * or may not be the %pair passed in). - * - * This function is not concerned about whether the insertion took place, - * and thus does not return a boolean like the single-argument - * insert() does. Note that the first parameter is only a hint and can - * potentially improve the performance of the insertion process. A bad - * hint would cause no gains in efficiency. - * - * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 - * for more on "hinting". - * - * Insertion requires logarithmic time (if the hint is not taken). - */ - iterator - insert(iterator position, const value_type& __x) - { return _M_t.insert_unique(position, __x); } - - /** - * @brief A template function that attemps to insert a range of elements. - * @param first Iterator pointing to the start of the range to be - * inserted. - * @param last Iterator pointing to the end of the range. - * - * Complexity similar to that of the range constructor. - */ - template <typename _InputIterator> + + /** + * @brief Builds a %map from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %map consisting of copies of the elements from [first,last). + * This is linear in N if the range is already sorted, and NlogN + * otherwise (where N is distance(first,last)). + */ + template <typename _InputIterator> + map(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + /** + * @brief Builds a %map from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %map consisting of copies of the elements from [first,last). + * This is linear in N if the range is already sorted, and NlogN + * otherwise (where N is distance(first,last)). + */ + template <typename _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); } + + // FIXME There is no dtor declared, but we should have something generated + // by Doxygen. I don't know what tags to add to this paragraph to make + // that happen: + /** + * The dtor only erases the elements, and note that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + + /** + * @brief Map assignment operator. + * @param x A %map of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + map& + operator=(const map& __x) + { + _M_t = __x._M_t; + return *this; + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first pair in the + * %map. + * Iteration is done in ascending order according to the keys. + */ + iterator + begin() + { return _M_t.begin(); } + + /** + * Returns a read-only (constant) iterator that points to the first pair + * in the %map. Iteration is done in ascending order according to the + * keys. + */ + const_iterator + begin() const + { return _M_t.begin(); } + + /** + * Returns a read/write iterator that points one past the last pair in + * the %map. Iteration is done in ascending order according to the keys. + */ + iterator + end() + { return _M_t.end(); } + + /** + * Returns a read-only (constant) iterator that points one past the last + * pair in the %map. Iteration is done in ascending order according to + * the keys. + */ + const_iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last pair in + * the %map. Iteration is done in descending order according to the + * keys. + */ + reverse_iterator + rbegin() + { return _M_t.rbegin(); } + + /** + * Returns a read-only (constant) reverse iterator that points to the + * last pair in the %map. Iteration is done in descending order + * according to the keys. + */ + const_reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first pair in the %map. Iteration is done in descending order + * according to the keys. + */ + reverse_iterator + rend() + { return _M_t.rend(); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first pair in the %map. Iteration is done in descending + * order according to the keys. + */ + const_reverse_iterator + rend() const + { return _M_t.rend(); } + + // capacity + /** Returns true if the %map is empty. (Thus begin() would equal + * end().) + */ + bool + empty() const + { return _M_t.empty(); } + + /** Returns the size of the %map. */ + size_type + size() const + { return _M_t.size(); } + + /** Returns the maximum size of the %map. */ + size_type + max_size() const + { return _M_t.max_size(); } + + // [23.3.1.2] element access + /** + * @brief Subscript ( @c [] ) access to %map data. + * @param k The key for which data should be retrieved. + * @return A reference to the data of the (key,data) %pair. + * + * Allows for easy lookup with the subscript ( @c [] ) operator. Returns + * data associated with the key specified in subscript. If the key does + * not exist, a pair with that key is created using default values, which + * is then returned. + * + * Lookup requires logarithmic time. + */ + mapped_type& + operator[](const key_type& __k) + { + // concept requirements + __glibcxx_function_requires(_DefaultConstructibleConcept<mapped_type>) + + 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, mapped_type())); + return (*__i).second; + } + + // modifiers + /** + * @brief Attempts to insert a std::pair into the %map. + * @param x Pair to be inserted (see std::make_pair for easy creation of + * pairs). + * @return A pair, of which the first element is an iterator that points + * to the possibly inserted pair, and the second is a bool that + * is true if the pair was actually inserted. + * + * This function attempts to insert a (key, value) %pair into the %map. + * A %map relies on unique keys and thus a %pair is only inserted if its + * first element (the key) is not already present in the %map. + * + * Insertion requires logarithmic time. + */ + pair<iterator,bool> + insert(const value_type& __x) + { return _M_t.insert_unique(__x); } + + /** + * @brief Attempts to insert a std::pair into the %map. + * @param position An iterator that serves as a hint as to where the + * pair should be inserted. + * @param x Pair to be inserted (see std::make_pair for easy creation of + * pairs). + * @return An iterator that points to the element with key of @a x (may + * or may not be the %pair passed in). + * + * This function is not concerned about whether the insertion took place, + * and thus does not return a boolean like the single-argument + * insert() does. Note that the first parameter is only a hint and can + * potentially improve the performance of the insertion process. A bad + * hint would cause no gains in efficiency. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator position, const value_type& __x) + { return _M_t.insert_unique(position, __x); } + + /** + * @brief A template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template <typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t.insert_unique(__first, __last); } + + /** + * @brief Erases an element from a %map. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given iterator, + * from a %map. Note that this function only erases the element, and + * that if the element is itself a pointer, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __position) + { _M_t.erase(__position); } + + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all the elements located by the given key from + * a %map. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } + + /** + * @brief Erases a [first,last) range of elements from a %map. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %map. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ void - insert(_InputIterator __first, _InputIterator __last) - { _M_t.insert_unique(__first, __last); } - - /** - * @brief Erases an element from a %map. - * @param position An iterator pointing to the element to be erased. - * - * This function erases an element, pointed to by the given iterator, from - * a %map. Note that this function only erases the element, and that if - * the element is itself a pointer, the pointed-to memory is not touched - * in any way. Managing the pointer is the user's responsibilty. - */ - void - erase(iterator __position) { _M_t.erase(__position); } - - /** - * @brief Erases elements according to the provided key. - * @param x Key of element to be erased. - * @return The number of elements erased. - * - * This function erases all the elements located by the given key from - * a %map. - * Note that this function only erases the element, and that if - * the element is itself a pointer, the pointed-to memory is not touched - * in any way. Managing the pointer is the user's responsibilty. - */ - size_type - erase(const key_type& __x) { return _M_t.erase(__x); } - - /** - * @brief Erases a [first,last) range of elements from a %map. - * @param first Iterator pointing to the start of the range to be erased. - * @param last Iterator pointing to the end of the range to be erased. - * - * This function erases a sequence of elements from a %map. - * Note that this function only erases the element, and that if - * the element is itself a pointer, the pointed-to memory is not touched - * in any way. Managing the pointer is the user's responsibilty. - */ - void - erase(iterator __first, iterator __last) { _M_t.erase(__first, __last); } - - /** - * @brief Swaps data with another %map. - * @param x A %map of the same element and allocator types. - * - * This exchanges the elements between two maps in constant time. - * (It is only swapping a pointer, an integer, and an instance of - * the @c Compare type (which itself is often stateless and empty), so it - * should be quite fast.) - * Note that the global std::swap() function is specialized such that - * std::swap(m1,m2) will feed to this function. - */ - void - swap(map& __x) { _M_t.swap(__x._M_t); } - - /** - * Erases all elements in a %map. Note that this function only erases - * the elements, and that if the elements themselves are pointers, the - * pointed-to memory is not touched in any way. Managing the pointer is - * the user's responsibilty. - */ - void - clear() { _M_t.clear(); } - - // observers - /** - * Returns the key comparison object out of which the %map was constructed. - */ - key_compare - key_comp() const { return _M_t.key_comp(); } - - /** - * Returns a value comparison object, built from the key comparison - * object out of which the %map was constructed. - */ - value_compare - value_comp() const { return value_compare(_M_t.key_comp()); } - - // [23.3.1.3] map operations - /** - * @brief Tries to locate an element in a %map. - * @param x Key of (key, value) %pair to be located. - * @return Iterator pointing to sought-after element, or end() if not - * found. - * - * This function takes a key and tries to locate the element with which - * the key matches. If successful the function returns an iterator - * pointing to the sought after %pair. If unsuccessful it returns the - * past-the-end ( @c end() ) iterator. - */ - iterator - find(const key_type& __x) { return _M_t.find(__x); } - - /** - * @brief Tries to locate an element in a %map. - * @param x Key of (key, value) %pair to be located. - * @return Read-only (constant) iterator pointing to sought-after - * element, or end() if not found. - * - * This function takes a key and tries to locate the element with which - * the key matches. If successful the function returns a constant iterator - * pointing to the sought after %pair. If unsuccessful it returns the - * past-the-end ( @c end() ) iterator. - */ - const_iterator - find(const key_type& __x) const { return _M_t.find(__x); } - - /** - * @brief Finds the number of elements with given key. - * @param x Key of (key, value) pairs to be located. - * @return Number of elements with specified key. - * - * This function only makes sense for multimaps; for map the result will - * either be 0 (not present) or 1 (present). - */ - size_type - count(const key_type& __x) const - { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } - - /** - * @brief Finds the beginning of a subsequence matching given key. - * @param x Key of (key, value) pair to be located. - * @return Iterator pointing to first element matching given key, or - * end() if not found. - * - * This function is useful only with multimaps. It returns the first - * element of a subsequence of elements that matches the given key. If - * unsuccessful it returns an iterator pointing to the first element that - * has a greater value than given key or end() if no such element exists. - */ - iterator - lower_bound(const key_type& __x) { return _M_t.lower_bound(__x); } - - /** - * @brief Finds the beginning of a subsequence matching given key. - * @param x Key of (key, value) pair to be located. - * @return Read-only (constant) iterator pointing to first element - * matching given key, or end() if not found. - * - * This function is useful only with multimaps. It returns the first - * element of a subsequence of elements that matches the given key. If - * unsuccessful the iterator will point to the next greatest element or, - * if no such greater element exists, to end(). - */ - const_iterator - lower_bound(const key_type& __x) const { return _M_t.lower_bound(__x); } - - /** - * @brief Finds the end of a subsequence matching given key. - * @param x Key of (key, value) pair to be located. - * @return Iterator pointing to last element matching given key. - * - * This function only makes sense with multimaps. - */ - iterator - upper_bound(const key_type& __x) { return _M_t.upper_bound(__x); } - - /** - * @brief Finds the end of a subsequence matching given key. - * @param x Key of (key, value) pair to be located. - * @return Read-only (constant) iterator pointing to last element matching - * given key. - * - * This function only makes sense with multimaps. - */ - const_iterator - upper_bound(const key_type& __x) const - { return _M_t.upper_bound(__x); } - - /** - * @brief Finds a subsequence matching given key. - * @param x Key of (key, value) pairs to be located. - * @return Pair of iterators that possibly points to the subsequence - * matching given key. - * - * This function returns a pair of which the first - * element possibly points to the first element matching the given key - * and the second element possibly points to the last element matching the - * given key. If unsuccessful the first element of the returned pair will - * contain an iterator pointing to the next greatest element or, if no such - * greater element exists, to end(). - * - * This function only makes sense for multimaps. - */ - pair<iterator,iterator> - equal_range(const key_type& __x) - { return _M_t.equal_range(__x); } - - /** - * @brief Finds a subsequence matching given key. - * @param x Key of (key, value) pairs to be located. - * @return Pair of read-only (constant) iterators that possibly points to - * the subsequence matching given key. - * - * This function returns a pair of which the first - * element possibly points to the first element matching the given key - * and the second element possibly points to the last element matching the - * given key. If unsuccessful the first element of the returned pair will - * contain an iterator pointing to the next greatest element or, if no such - * a greater element exists, to end(). - * - * This function only makes sense for multimaps. - */ - pair<const_iterator,const_iterator> - equal_range(const key_type& __x) const - { return _M_t.equal_range(__x); } - - template <typename _K1, typename _T1, typename _C1, typename _A1> - friend bool operator== (const map<_K1,_T1,_C1,_A1>&, - const map<_K1,_T1,_C1,_A1>&); - template <typename _K1, typename _T1, typename _C1, typename _A1> - friend bool operator< (const map<_K1,_T1,_C1,_A1>&, - const map<_K1,_T1,_C1,_A1>&); - }; - - + erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + + /** + * @brief Swaps data with another %map. + * @param x A %map of the same element and allocator types. + * + * This exchanges the elements between two maps in constant time. + * (It is only swapping a pointer, an integer, and an instance of + * the @c Compare type (which itself is often stateless and empty), so it + * should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(m1,m2) will feed to this function. + */ + void + swap(map& __x) + { _M_t.swap(__x._M_t); } + + /** + * Erases all elements in a %map. Note that this function only erases + * the elements, and that if the elements themselves are pointers, the + * pointed-to memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } + + // observers + /** + * Returns the key comparison object out of which the %map was + * constructed. + */ + key_compare + key_comp() const + { return _M_t.key_comp(); } + + /** + * Returns a value comparison object, built from the key comparison + * object out of which the %map was constructed. + */ + value_compare + value_comp() const + { return value_compare(_M_t.key_comp()); } + + // [23.3.1.3] map operations + /** + * @brief Tries to locate an element in a %map. + * @param x Key of (key, value) %pair to be located. + * @return Iterator pointing to sought-after element, or end() if not + * found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after %pair. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + /** + * @brief Tries to locate an element in a %map. + * @param x Key of (key, value) %pair to be located. + * @return Read-only (constant) iterator pointing to sought-after + * element, or end() if not found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns a constant + * iterator pointing to the sought after %pair. If unsuccessful it + * returns the past-the-end ( @c end() ) iterator. + */ + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + + /** + * @brief Finds the number of elements with given key. + * @param x Key of (key, value) pairs to be located. + * @return Number of elements with specified key. + * + * This function only makes sense for multimaps; for map the result will + * either be 0 (not present) or 1 (present). + */ + size_type + count(const key_type& __x) const + { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } + + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first element + * equal to or greater than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first iterator + * greater than key, or end(). + */ + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multimaps. + */ + pair<iterator,iterator> + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } + + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of read-only (constant) iterators that possibly points + * to the subsequence matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multimaps. + */ + pair<const_iterator,const_iterator> + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + + template <typename _K1, typename _T1, typename _C1, typename _A1> + friend bool + operator== (const map<_K1,_T1,_C1,_A1>&, + const map<_K1,_T1,_C1,_A1>&); + + template <typename _K1, typename _T1, typename _C1, typename _A1> + friend bool + operator< (const map<_K1,_T1,_C1,_A1>&, + const map<_K1,_T1,_C1,_A1>&); + }; + /** * @brief Map equality comparison. * @param x A %map. @@ -605,52 +638,52 @@ namespace std operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y) { return __x._M_t == __y._M_t; } - + /** * @brief Map ordering relation. * @param x A %map. * @param y A %map of the same type as @a x. - * @return True iff @a x is lexographically less than @a y. + * @return True iff @a x is lexicographically less than @a y. * * This is a total ordering relation. It is linear in the size of the * maps. The elements must be comparable with @c <. * - * See std::lexographical_compare() for how the determination is made. + * See std::lexicographical_compare() for how the determination is made. */ template <typename _Key, typename _Tp, typename _Compare, typename _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; } - + /// Based on operator== template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator!=(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y) { return !(__x == __y); } - + /// Based on operator< template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator>(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y) { return __y < __x; } - + /// Based on operator< template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator<=(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y) { return !(__y < __x); } - + /// Based on operator< template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator>=(const map<_Key,_Tp,_Compare,_Alloc>& __x, const map<_Key,_Tp,_Compare,_Alloc>& __y) { return !(__x < __y); } - + /// See std::map::swap(). template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline void @@ -658,4 +691,4 @@ namespace std { __x.swap(__y); } } // namespace std -#endif /* __GLIBCPP_INTERNAL_MAP_H */ +#endif /* _MAP_H */ diff --git a/contrib/libstdc++/include/bits/stl_multimap.h b/contrib/libstdc++/include/bits/stl_multimap.h index 0fa79a8d139e..e080f9aaba7e 100644 --- a/contrib/libstdc++/include/bits/stl_multimap.h +++ b/contrib/libstdc++/include/bits/stl_multimap.h @@ -1,6 +1,6 @@ // Multimap implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,28 +58,30 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_MULTIMAP_H -#define __GLIBCPP_INTERNAL_MULTIMAP_H +#ifndef _MULTIMAP_H +#define _MULTIMAP_H 1 #include <bits/concept_check.h> -namespace std +namespace _GLIBCXX_STD { // Forward declaration of operators < and ==, needed for friend declaration. - + template <typename _Key, typename _Tp, typename _Compare = less<_Key>, typename _Alloc = allocator<pair<const _Key, _Tp> > > - class multimap; - + class multimap; + template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> - inline bool operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, - const multimap<_Key,_Tp,_Compare,_Alloc>& __y); - + inline bool + operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y); + template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> - inline bool operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, - const multimap<_Key,_Tp,_Compare,_Alloc>& __y); - + inline bool + operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y); + /** * @brief A standard container made up of (key,value) pairs, which can be * retrieved based on a key, in logarithmic time. @@ -103,465 +105,506 @@ namespace std */ template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> class multimap - { - // concept requirements - __glibcpp_class_requires(_Tp, _SGIAssignableConcept) - __glibcpp_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept) - - public: - typedef _Key key_type; - typedef _Tp mapped_type; - typedef pair<const _Key, _Tp> value_type; - typedef _Compare key_compare; - - class value_compare + { + // concept requirements + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) + + public: + typedef _Key key_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,_Tp,_Compare,_Alloc>; + friend class multimap<_Key,_Tp,_Compare,_Alloc>; protected: - _Compare comp; - value_compare(_Compare __c) : comp(__c) {} + _Compare comp; + + value_compare(_Compare __c) + : comp(__c) { } + public: - bool operator()(const value_type& __x, const value_type& __y) const - { return comp(__x.first, __y.first); } - }; - - private: - /// @if maint This turns a red-black tree into a [multi]map. @endif - typedef _Rb_tree<key_type, value_type, - _Select1st<value_type>, key_compare, _Alloc> _Rep_type; - /// @if maint The actual tree structure. @endif - _Rep_type _M_t; - - public: - // many of these are specified differently in ISO, but the following are - // "functionally equivalent" - typedef typename _Rep_type::allocator_type allocator_type; - 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::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::reverse_iterator reverse_iterator; - typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; - - - // [23.3.2] construct/copy/destroy - // (get_allocator() is also listed in this section) - /** - * @brief Default constructor creates no elements. - */ - multimap() : _M_t(_Compare(), allocator_type()) { } - - // for some reason this was made a separate function - /** - * @brief Default constructor creates no elements. - */ - explicit - multimap(const _Compare& __comp, const allocator_type& __a = allocator_type()) + bool operator()(const value_type& __x, const value_type& __y) const + { return comp(__x.first, __y.first); } + }; + + private: + /// @if maint This turns a red-black tree into a [multi]map. @endif + typedef _Rb_tree<key_type, value_type, + _Select1st<value_type>, key_compare, _Alloc> _Rep_type; + /// @if maint The actual tree structure. @endif + _Rep_type _M_t; + + public: + // many of these are specified differently in ISO, but the following are + // "functionally equivalent" + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Rep_type::allocator_type allocator_type; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + + // [23.3.2] construct/copy/destroy + // (get_allocator() is also listed in this section) + /** + * @brief Default constructor creates no elements. + */ + multimap() + : _M_t(_Compare(), allocator_type()) { } + + // for some reason this was made a separate function + /** + * @brief Default constructor creates no elements. + */ + explicit + multimap(const _Compare& __comp, + const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { } - - /** - * @brief %Multimap copy constructor. - * @param x A %multimap of identical element and allocator types. - * - * The newly-created %multimap uses a copy of the allocation object used - * by @a x. - */ - multimap(const multimap& __x) + + /** + * @brief %Multimap copy constructor. + * @param x A %multimap of identical element and allocator types. + * + * The newly-created %multimap uses a copy of the allocation object used + * by @a x. + */ + multimap(const multimap& __x) : _M_t(__x._M_t) { } - - /** - * @brief Builds a %multimap from a range. - * @param first An input iterator. - * @param last An input iterator. - * - * Create a %multimap consisting of copies of the elements from - * [first,last). This is linear in N if the range is already sorted, - * and NlogN otherwise (where N is distance(first,last)). - */ - template <typename _InputIterator> - multimap(_InputIterator __first, _InputIterator __last) - : _M_t(_Compare(), allocator_type()) + + /** + * @brief Builds a %multimap from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %multimap consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template <typename _InputIterator> + multimap(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) { _M_t.insert_equal(__first, __last); } - - /** - * @brief Builds a %multimap from a range. - * @param first An input iterator. - * @param last An input iterator. - * @param comp A comparison functor. - * @param a An allocator object. - * - * Create a %multimap consisting of copies of the elements from - * [first,last). This is linear in N if the range is already sorted, - * and NlogN otherwise (where N is distance(first,last)). - */ - template <typename _InputIterator> - multimap(_InputIterator __first, _InputIterator __last, - const _Compare& __comp, - const allocator_type& __a = allocator_type()) + + /** + * @brief Builds a %multimap from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %multimap consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template <typename _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); } - - // FIXME There is no dtor declared, but we should have something generated - // by Doxygen. I don't know what tags to add to this paragraph to make - // that happen: - /** - * The dtor only erases the elements, and note that if the elements - * themselves are pointers, the pointed-to memory is not touched in any - * way. Managing the pointer is the user's responsibilty. - */ - - /** - * @brief %Multimap assignment operator. - * @param x A %multimap of identical element and allocator types. - * - * All the elements of @a x are copied, but unlike the copy constructor, - * the allocator object is not copied. - */ - multimap& - operator=(const multimap& __x) - { - _M_t = __x._M_t; - return *this; - } - - /// Get a copy of the memory allocation object. - allocator_type - get_allocator() const { return _M_t.get_allocator(); } - - // iterators - /** - * Returns a read/write iterator that points to the first pair in the - * %multimap. Iteration is done in ascending order according to the keys. - */ - iterator - begin() { return _M_t.begin(); } - - /** - * Returns a read-only (constant) iterator that points to the first pair - * in the %multimap. Iteration is done in ascending order according to the - * keys. - */ - const_iterator - begin() const { return _M_t.begin(); } - - /** - * Returns a read/write iterator that points one past the last pair in the - * %multimap. Iteration is done in ascending order according to the keys. - */ - iterator - end() { return _M_t.end(); } - - /** - * Returns a read-only (constant) iterator that points one past the last - * pair in the %multimap. Iteration is done in ascending order according - * to the keys. - */ - const_iterator - end() const { return _M_t.end(); } - - /** - * Returns a read/write reverse iterator that points to the last pair in - * the %multimap. Iteration is done in descending order according to the - * keys. - */ - reverse_iterator - rbegin() { return _M_t.rbegin(); } - - /** - * Returns a read-only (constant) reverse iterator that points to the last - * pair in the %multimap. Iteration is done in descending order according - * to the keys. - */ - const_reverse_iterator - rbegin() const { return _M_t.rbegin(); } - - /** - * Returns a read/write reverse iterator that points to one before the - * first pair in the %multimap. Iteration is done in descending order - * according to the keys. - */ - reverse_iterator - rend() { return _M_t.rend(); } - - /** - * Returns a read-only (constant) reverse iterator that points to one - * before the first pair in the %multimap. Iteration is done in descending - * order according to the keys. - */ - const_reverse_iterator - rend() const { return _M_t.rend(); } - - // capacity - /** Returns true if the %multimap is empty. */ - bool - empty() const { return _M_t.empty(); } - - /** Returns the size of the %multimap. */ - size_type - size() const { return _M_t.size(); } - - /** Returns the maximum size of the %multimap. */ - size_type - max_size() const { return _M_t.max_size(); } - - // modifiers - /** - * @brief Inserts a std::pair into the %multimap. - * @param x Pair to be inserted (see std::make_pair for easy creation of - * pairs). - * @return An iterator that points to the inserted (key,value) pair. - * - * This function inserts a (key, value) pair into the %multimap. Contrary - * to a std::map the %multimap does not rely on unique keys and thus - * multiple pairs with the same key can be inserted. - * - * Insertion requires logarithmic time. - */ - iterator - insert(const value_type& __x) { return _M_t.insert_equal(__x); } - - /** - * @brief Inserts a std::pair into the %multimap. - * @param position An iterator that serves as a hint as to where the - * pair should be inserted. - * @param x Pair to be inserted (see std::make_pair for easy creation of - * pairs). - * @return An iterator that points to the inserted (key,value) pair. - * - * This function inserts a (key, value) pair into the %multimap. Contrary - * to a std::map the %multimap does not rely on unique keys and thus - * multiple pairs with the same key can be inserted. - * Note that the first parameter is only a hint and can potentially - * improve the performance of the insertion process. A bad hint would - * cause no gains in efficiency. - * - * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 - * for more on "hinting". - * - * Insertion requires logarithmic time (if the hint is not taken). - */ - iterator - insert(iterator __position, const value_type& __x) - { return _M_t.insert_equal(__position, __x); } - - /** - * @brief A template function that attemps to insert a range of elements. - * @param first Iterator pointing to the start of the range to be - * inserted. - * @param last Iterator pointing to the end of the range. - * - * Complexity similar to that of the range constructor. - */ - template <typename _InputIterator> + + // FIXME There is no dtor declared, but we should have something generated + // by Doxygen. I don't know what tags to add to this paragraph to make + // that happen: + /** + * The dtor only erases the elements, and note that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + + /** + * @brief %Multimap assignment operator. + * @param x A %multimap of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + multimap& + operator=(const multimap& __x) + { + _M_t = __x._M_t; + return *this; + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first pair in the + * %multimap. Iteration is done in ascending order according to the + * keys. + */ + iterator + begin() + { return _M_t.begin(); } + + /** + * Returns a read-only (constant) iterator that points to the first pair + * in the %multimap. Iteration is done in ascending order according to + * the keys. + */ + const_iterator + begin() const + { return _M_t.begin(); } + + /** + * Returns a read/write iterator that points one past the last pair in + * the %multimap. Iteration is done in ascending order according to the + * keys. + */ + iterator + end() + { return _M_t.end(); } + + /** + * Returns a read-only (constant) iterator that points one past the last + * pair in the %multimap. Iteration is done in ascending order according + * to the keys. + */ + const_iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last pair in + * the %multimap. Iteration is done in descending order according to the + * keys. + */ + reverse_iterator + rbegin() + { return _M_t.rbegin(); } + + /** + * Returns a read-only (constant) reverse iterator that points to the + * last pair in the %multimap. Iteration is done in descending order + * according to the keys. + */ + const_reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first pair in the %multimap. Iteration is done in descending order + * according to the keys. + */ + reverse_iterator + rend() + { return _M_t.rend(); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first pair in the %multimap. Iteration is done in + * descending order according to the keys. + */ + const_reverse_iterator + rend() const + { return _M_t.rend(); } + + // capacity + /** Returns true if the %multimap is empty. */ + bool + empty() const + { return _M_t.empty(); } + + /** Returns the size of the %multimap. */ + size_type + size() const + { return _M_t.size(); } + + /** Returns the maximum size of the %multimap. */ + size_type + max_size() const + { return _M_t.max_size(); } + + // modifiers + /** + * @brief Inserts a std::pair into the %multimap. + * @param x Pair to be inserted (see std::make_pair for easy creation + * of pairs). + * @return An iterator that points to the inserted (key,value) pair. + * + * This function inserts a (key, value) pair into the %multimap. + * Contrary to a std::map the %multimap does not rely on unique keys and + * thus multiple pairs with the same key can be inserted. + * + * Insertion requires logarithmic time. + */ + iterator + insert(const value_type& __x) + { return _M_t.insert_equal(__x); } + + /** + * @brief Inserts a std::pair into the %multimap. + * @param position An iterator that serves as a hint as to where the + * pair should be inserted. + * @param x Pair to be inserted (see std::make_pair for easy creation + * of pairs). + * @return An iterator that points to the inserted (key,value) pair. + * + * This function inserts a (key, value) pair into the %multimap. + * Contrary to a std::map the %multimap does not rely on unique keys and + * thus multiple pairs with the same key can be inserted. + * Note that the first parameter is only a hint and can potentially + * improve the performance of the insertion process. A bad hint would + * cause no gains in efficiency. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator __position, const value_type& __x) + { return _M_t.insert_equal(__position, __x); } + + /** + * @brief A template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template <typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t.insert_equal(__first, __last); } + + /** + * @brief Erases an element from a %multimap. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given iterator, + * from a %multimap. Note that this function only erases the element, + * and that if the element is itself a pointer, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. + */ + void + erase(iterator __position) + { _M_t.erase(__position); } + + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all elements located by the given key from a + * %multimap. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } + + /** + * @brief Erases a [first,last) range of elements from a %multimap. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %multimap. + * Note that this function only erases the elements, and that if + * the elements themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's responsibilty. + */ void - insert(_InputIterator __first, _InputIterator __last) - { _M_t.insert_equal(__first, __last); } - - /** - * @brief Erases an element from a %multimap. - * @param position An iterator pointing to the element to be erased. - * - * This function erases an element, pointed to by the given iterator, from - * a %multimap. Note that this function only erases the element, and that - * if the element is itself a pointer, the pointed-to memory is not - * touched in any way. Managing the pointer is the user's responsibilty. - */ - void - erase(iterator __position) { _M_t.erase(__position); } - - /** - * @brief Erases elements according to the provided key. - * @param x Key of element to be erased. - * @return The number of elements erased. - * - * This function erases all elements located by the given key from a - * %multimap. - * Note that this function only erases the element, and that if - * the element is itself a pointer, the pointed-to memory is not touched - * in any way. Managing the pointer is the user's responsibilty. - */ - size_type - erase(const key_type& __x) { return _M_t.erase(__x); } - - /** - * @brief Erases a [first,last) range of elements from a %multimap. - * @param first Iterator pointing to the start of the range to be erased. - * @param last Iterator pointing to the end of the range to be erased. - * - * This function erases a sequence of elements from a %multimap. - * Note that this function only erases the elements, and that if - * the elements themselves are pointers, the pointed-to memory is not - * touched in any way. Managing the pointer is the user's responsibilty. - */ - void - erase(iterator __first, iterator __last) { _M_t.erase(__first, __last); } - - /** - * @brief Swaps data with another %multimap. - * @param x A %multimap of the same element and allocator types. - * - * This exchanges the elements between two multimaps in constant time. - * (It is only swapping a pointer, an integer, and an instance of - * the @c Compare type (which itself is often stateless and empty), so it - * should be quite fast.) - * Note that the global std::swap() function is specialized such that - * std::swap(m1,m2) will feed to this function. - */ - void - swap(multimap& __x) { _M_t.swap(__x._M_t); } - - /** - * Erases all elements in a %multimap. Note that this function only erases - * the elements, and that if the elements themselves are pointers, the - * pointed-to memory is not touched in any way. Managing the pointer is - * the user's responsibilty. - */ - void - clear() { _M_t.clear(); } - - // observers - /** - * Returns the key comparison object out of which the %multimap - * was constructed. - */ - key_compare - key_comp() const { return _M_t.key_comp(); } - - /** - * Returns a value comparison object, built from the key comparison - * object out of which the %multimap was constructed. - */ - value_compare - value_comp() const { return value_compare(_M_t.key_comp()); } - - // multimap operations - /** - * @brief Tries to locate an element in a %multimap. - * @param x Key of (key, value) pair to be located. - * @return Iterator pointing to sought-after element, - * or end() if not found. - * - * This function takes a key and tries to locate the element with which - * the key matches. If successful the function returns an iterator - * pointing to the sought after %pair. If unsuccessful it returns the - * past-the-end ( @c end() ) iterator. - */ - iterator - find(const key_type& __x) { return _M_t.find(__x); } - - /** - * @brief Tries to locate an element in a %multimap. - * @param x Key of (key, value) pair to be located. - * @return Read-only (constant) iterator pointing to sought-after - * element, or end() if not found. - * - * This function takes a key and tries to locate the element with which - * the key matches. If successful the function returns a constant iterator - * pointing to the sought after %pair. If unsuccessful it returns the - * past-the-end ( @c end() ) iterator. - */ - const_iterator - find(const key_type& __x) const { return _M_t.find(__x); } - - /** - * @brief Finds the number of elements with given key. - * @param x Key of (key, value) pairs to be located. - * @return Number of elements with specified key. - */ - size_type - count(const key_type& __x) const { return _M_t.count(__x); } - - /** - * @brief Finds the beginning of a subsequence matching given key. - * @param x Key of (key, value) pair to be located. - * @return Iterator pointing to first element matching given key, or - * end() if not found. - * - * This function returns the first element of a subsequence of elements - * that matches the given key. If unsuccessful it returns an iterator - * pointing to the first element that has a greater value than given key - * or end() if no such element exists. - */ - iterator - lower_bound(const key_type& __x) { return _M_t.lower_bound(__x); } - - /** - * @brief Finds the beginning of a subsequence matching given key. - * @param x Key of (key, value) pair to be located. - * @return Read-only (constant) iterator pointing to first element - * matching given key, or end() if not found. - * - * This function returns the first element of a subsequence of elements - * that matches the given key. If unsuccessful the iterator will point - * to the next greatest element or, if no such greater element exists, to - * end(). - */ - const_iterator - lower_bound(const key_type& __x) const { return _M_t.lower_bound(__x); } - - /** - * @brief Finds the end of a subsequence matching given key. - * @param x Key of (key, value) pair to be located. - * @return Iterator pointing to last element matching given key. - */ - iterator - upper_bound(const key_type& __x) { return _M_t.upper_bound(__x); } - - /** - * @brief Finds the end of a subsequence matching given key. - * @param x Key of (key, value) pair to be located. - * @return Read-only (constant) iterator pointing to last element matching - * given key. - */ - const_iterator - upper_bound(const key_type& __x) const { return _M_t.upper_bound(__x); } - - /** - * @brief Finds a subsequence matching given key. - * @param x Key of (key, value) pairs to be located. - * @return Pair of iterators that possibly points to the subsequence - * matching given key. - * - * This function returns a pair of which the first - * element possibly points to the first element matching the given key - * and the second element possibly points to the last element matching the - * given key. If unsuccessful the first element of the returned pair will - * contain an iterator pointing to the next greatest element or, if no such - * greater element exists, to end(). - */ - pair<iterator,iterator> - equal_range(const key_type& __x) { return _M_t.equal_range(__x); } - - /** - * @brief Finds a subsequence matching given key. - * @param x Key of (key, value) pairs to be located. - * @return Pair of read-only (constant) iterators that possibly points to - * the subsequence matching given key. - * - * This function returns a pair of which the first - * element possibly points to the first element matching the given key - * and the second element possibly points to the last element matching the - * given key. If unsuccessful the first element of the returned pair will - * contain an iterator pointing to the next greatest element or, if no such - * a greater element exists, to end(). - */ - pair<const_iterator,const_iterator> - equal_range(const key_type& __x) const { return _M_t.equal_range(__x); } - - template <typename _K1, typename _T1, typename _C1, typename _A1> - friend bool operator== (const multimap<_K1,_T1,_C1,_A1>&, - const multimap<_K1,_T1,_C1,_A1>&); - template <typename _K1, typename _T1, typename _C1, typename _A1> - friend bool operator< (const multimap<_K1,_T1,_C1,_A1>&, - const multimap<_K1,_T1,_C1,_A1>&); + erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + + /** + * @brief Swaps data with another %multimap. + * @param x A %multimap of the same element and allocator types. + * + * This exchanges the elements between two multimaps in constant time. + * (It is only swapping a pointer, an integer, and an instance of + * the @c Compare type (which itself is often stateless and empty), so it + * should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(m1,m2) will feed to this function. + */ + void + swap(multimap& __x) + { _M_t.swap(__x._M_t); } + + /** + * Erases all elements in a %multimap. Note that this function only + * erases the elements, and that if the elements themselves are pointers, + * the pointed-to memory is not touched in any way. Managing the pointer + * is the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } + + // observers + /** + * Returns the key comparison object out of which the %multimap + * was constructed. + */ + key_compare + key_comp() const + { return _M_t.key_comp(); } + + /** + * Returns a value comparison object, built from the key comparison + * object out of which the %multimap was constructed. + */ + value_compare + value_comp() const + { return value_compare(_M_t.key_comp()); } + + // multimap operations + /** + * @brief Tries to locate an element in a %multimap. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to sought-after element, + * or end() if not found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after %pair. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + /** + * @brief Tries to locate an element in a %multimap. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to sought-after + * element, or end() if not found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns a constant + * iterator pointing to the sought after %pair. If unsuccessful it + * returns the past-the-end ( @c end() ) iterator. + */ + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + + /** + * @brief Finds the number of elements with given key. + * @param x Key of (key, value) pairs to be located. + * @return Number of elements with specified key. + */ + size_type + count(const key_type& __x) const + { return _M_t.count(__x); } + + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first element + * equal to or greater than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful the iterator will point + * to the next greatest element or, if no such greater element exists, to + * end(). + */ + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first iterator + * greater than key, or end(). + */ + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + */ + pair<iterator,iterator> + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } + + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of read-only (constant) iterators that possibly points + * to the subsequence matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + */ + pair<const_iterator,const_iterator> + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + + template <typename _K1, typename _T1, typename _C1, typename _A1> + friend bool + operator== (const multimap<_K1,_T1,_C1,_A1>&, + const multimap<_K1,_T1,_C1,_A1>&); + + template <typename _K1, typename _T1, typename _C1, typename _A1> + friend bool + operator< (const multimap<_K1,_T1,_C1,_A1>&, + const multimap<_K1,_T1,_C1,_A1>&); }; - - + /** * @brief Multimap equality comparison. * @param x A %multimap. @@ -576,55 +619,53 @@ namespace std inline bool operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y) - { - return __x._M_t == __y._M_t; - } - + { return __x._M_t == __y._M_t; } + /** * @brief Multimap ordering relation. * @param x A %multimap. * @param y A %multimap of the same type as @a x. - * @return True iff @a x is lexographically less than @a y. + * @return True iff @a x is lexicographically less than @a y. * * This is a total ordering relation. It is linear in the size of the * multimaps. The elements must be comparable with @c <. * - * See std::lexographical_compare() for how the determination is made. + * See std::lexicographical_compare() for how the determination is made. */ template <typename _Key, typename _Tp, typename _Compare, typename _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; } - + /// Based on operator== template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator!=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { return !(__x == __y); } - + /// Based on operator< template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator>(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { return __y < __x; } - + /// Based on operator< template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator<=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { return !(__y < __x); } - + /// Based on operator< template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator>=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { return !(__x < __y); } - + /// See std::multimap::swap(). template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline void @@ -633,4 +674,4 @@ namespace std { __x.swap(__y); } } // namespace std -#endif /* __GLIBCPP_INTERNAL_MULTIMAP_H */ +#endif /* _MULTIMAP_H */ diff --git a/contrib/libstdc++/include/bits/stl_multiset.h b/contrib/libstdc++/include/bits/stl_multiset.h index 2bfc8f10c32b..c82dee68e4ef 100644 --- a/contrib/libstdc++/include/bits/stl_multiset.h +++ b/contrib/libstdc++/include/bits/stl_multiset.h @@ -1,6 +1,6 @@ // Multiset implementation -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,220 +58,528 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_MULTISET_H -#define __GLIBCPP_INTERNAL_MULTISET_H +#ifndef _MULTISET_H +#define _MULTISET_H 1 #include <bits/concept_check.h> -namespace std +namespace _GLIBCXX_STD { -// Forward declaration of operators < and ==, needed for friend declaration. - -template <class _Key, class _Compare = less<_Key>, - class _Alloc = allocator<_Key> > -class multiset; - -template <class _Key, class _Compare, class _Alloc> -inline bool operator==(const multiset<_Key,_Compare,_Alloc>& __x, - const multiset<_Key,_Compare,_Alloc>& __y); - -template <class _Key, class _Compare, class _Alloc> -inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, - const multiset<_Key,_Compare,_Alloc>& __y); - -template <class _Key, class _Compare, class _Alloc> -class multiset -{ - // concept requirements - __glibcpp_class_requires(_Key, _SGIAssignableConcept) - __glibcpp_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept); - -public: - - // typedefs: - - typedef _Key key_type; - typedef _Key value_type; - typedef _Compare key_compare; - typedef _Compare value_compare; -private: - typedef _Rb_tree<key_type, value_type, - _Identity<value_type>, key_compare, _Alloc> _Rep_type; - _Rep_type _M_t; // red-black tree representing multiset -public: - typedef typename _Rep_type::const_pointer pointer; - typedef typename _Rep_type::const_pointer const_pointer; - typedef typename _Rep_type::const_reference reference; - typedef typename _Rep_type::const_reference const_reference; - typedef typename _Rep_type::const_iterator iterator; - typedef typename _Rep_type::const_iterator const_iterator; - typedef typename _Rep_type::const_reverse_iterator reverse_iterator; - typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; - typedef typename _Rep_type::size_type size_type; - typedef typename _Rep_type::difference_type difference_type; - typedef typename _Rep_type::allocator_type allocator_type; - - // allocation/deallocation - - multiset() : _M_t(_Compare(), allocator_type()) {} - explicit multiset(const _Compare& __comp, - const allocator_type& __a = allocator_type()) - : _M_t(__comp, __a) {} - - 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); } - - multiset(const multiset<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} - - multiset<_Key,_Compare,_Alloc>& - operator=(const multiset<_Key,_Compare,_Alloc>& __x) { - _M_t = __x._M_t; - return *this; - } - - // accessors: - - key_compare key_comp() const { return _M_t.key_comp(); } - value_compare value_comp() const { return _M_t.key_comp(); } - allocator_type get_allocator() const { return _M_t.get_allocator(); } - - iterator begin() const { return _M_t.begin(); } - iterator end() const { return _M_t.end(); } - reverse_iterator rbegin() const { return _M_t.rbegin(); } - reverse_iterator rend() const { return _M_t.rend(); } - bool empty() const { return _M_t.empty(); } - size_type size() const { return _M_t.size(); } - size_type max_size() const { return _M_t.max_size(); } - void swap(multiset<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } - - // insert/erase - iterator insert(const value_type& __x) { - return _M_t.insert_equal(__x); - } - iterator insert(iterator __position, const value_type& __x) { - typedef typename _Rep_type::iterator _Rep_iterator; - return _M_t.insert_equal((_Rep_iterator&)__position, __x); - } - - template <class _InputIterator> - void insert(_InputIterator __first, _InputIterator __last) { - _M_t.insert_equal(__first, __last); - } - void erase(iterator __position) { - typedef typename _Rep_type::iterator _Rep_iterator; - _M_t.erase((_Rep_iterator&)__position); - } - size_type erase(const key_type& __x) { - return _M_t.erase(__x); - } - void erase(iterator __first, iterator __last) { - typedef typename _Rep_type::iterator _Rep_iterator; - _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); - } - void clear() { _M_t.clear(); } - - // multiset operations: - - size_type count(const key_type& __x) const { return _M_t.count(__x); } - -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -//214. set::find() missing const overload - iterator find(const key_type& __x) { return _M_t.find(__x); } - const_iterator find(const key_type& __x) const { return _M_t.find(__x); } - iterator lower_bound(const key_type& __x) { - return _M_t.lower_bound(__x); - } - const_iterator lower_bound(const key_type& __x) const { - return _M_t.lower_bound(__x); - } - iterator upper_bound(const key_type& __x) { - return _M_t.upper_bound(__x); - } - const_iterator upper_bound(const key_type& __x) const { - return _M_t.upper_bound(__x); - } - pair<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 _M_t.equal_range(__x); - } -#else - iterator find(const key_type& __x) const { return _M_t.find(__x); } - iterator lower_bound(const key_type& __x) const { - return _M_t.lower_bound(__x); - } - iterator upper_bound(const key_type& __x) const { - return _M_t.upper_bound(__x); - } - pair<iterator,iterator> equal_range(const key_type& __x) const { - return _M_t.equal_range(__x); - } -#endif - - template <class _K1, class _C1, class _A1> - friend bool operator== (const multiset<_K1,_C1,_A1>&, - const multiset<_K1,_C1,_A1>&); - template <class _K1, class _C1, class _A1> - friend bool operator< (const multiset<_K1,_C1,_A1>&, - const multiset<_K1,_C1,_A1>&); -}; - -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._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 == __y); -} - -template <class _Key, class _Compare, class _Alloc> -inline bool operator>(const multiset<_Key,_Compare,_Alloc>& __x, - const multiset<_Key,_Compare,_Alloc>& __y) { - return __y < __x; -} - -template <class _Key, class _Compare, class _Alloc> -inline bool operator<=(const multiset<_Key,_Compare,_Alloc>& __x, - const multiset<_Key,_Compare,_Alloc>& __y) { - return !(__y < __x); -} - -template <class _Key, class _Compare, class _Alloc> -inline bool operator>=(const multiset<_Key,_Compare,_Alloc>& __x, - const multiset<_Key,_Compare,_Alloc>& __y) { - return !(__x < __y); -} - -template <class _Key, class _Compare, class _Alloc> -inline void swap(multiset<_Key,_Compare,_Alloc>& __x, - multiset<_Key,_Compare,_Alloc>& __y) { - __x.swap(__y); -} + // Forward declaration of operators < and ==, needed for friend declaration. + template <class _Key, class _Compare = less<_Key>, + class _Alloc = allocator<_Key> > + class multiset; + + template <class _Key, class _Compare, class _Alloc> + inline bool + operator==(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y); + + template <class _Key, class _Compare, class _Alloc> + inline bool + operator<(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y); + + /** + * @brief A standard container made up of elements, which can be retrieved + * in logarithmic time. + * + * @ingroup Containers + * @ingroup Assoc_containers + * + * Meets the requirements of a <a href="tables.html#65">container</a>, a + * <a href="tables.html#66">reversible container</a>, and an + * <a href="tables.html#69">associative container</a> (using equivalent + * keys). For a @c multiset<Key> the key_type and value_type are Key. + * + * Multisets support bidirectional iterators. + * + * @if maint + * The private tree data is declared exactly the same way for set and + * multiset; the distinction is made entirely in how the tree functions are + * called (*_unique versus *_equal, same as the standard). + * @endif + */ + template <class _Key, class _Compare, class _Alloc> + class multiset + { + // concept requirements + __glibcxx_class_requires(_Key, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) + + public: + // typedefs: + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + + private: + /// @if maint This turns a red-black tree into a [multi]set. @endif + typedef _Rb_tree<key_type, value_type, + _Identity<value_type>, key_compare, _Alloc> _Rep_type; + /// @if maint The actual tree structure. @endif + _Rep_type _M_t; + + public: + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 103. set::iterator is required to be modifiable, + // but this allows modification of keys. + 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 + + /** + * @brief Default constructor creates no elements. + */ + multiset() + : _M_t(_Compare(), allocator_type()) { } + + explicit + multiset(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { } + + /** + * @brief Builds a %multiset from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %multiset consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template <class _InputIterator> + multiset(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + /** + * @brief Builds a %multiset from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %multiset consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(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); } + + /** + * @brief %Multiset copy constructor. + * @param x A %multiset of identical element and allocator types. + * + * The newly-created %multiset uses a copy of the allocation object used + * by @a x. + */ + multiset(const multiset<_Key,_Compare,_Alloc>& __x) + : _M_t(__x._M_t) { } + + /** + * @brief %Multiset assignment operator. + * @param x A %multiset of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + multiset<_Key,_Compare,_Alloc>& + operator=(const multiset<_Key,_Compare,_Alloc>& __x) + { + _M_t = __x._M_t; + return *this; + } + + // accessors: + + /// Returns the comparison object. + key_compare + key_comp() const + { return _M_t.key_comp(); } + /// Returns the comparison object. + value_compare + value_comp() const + { return _M_t.key_comp(); } + /// Returns the memory allocation object. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + /** + * Returns a read/write iterator that points to the first element in the + * %multiset. Iteration is done in ascending order according to the + * keys. + */ + iterator + begin() const + { return _M_t.begin(); } + + /** + * Returns a read/write iterator that points one past the last element in + * the %multiset. Iteration is done in ascending order according to the + * keys. + */ + iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last element + * in the %multiset. Iteration is done in descending order according to + * the keys. + */ + reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read/write reverse iterator that points to the last element + * in the %multiset. Iteration is done in descending order according to + * the keys. + */ + reverse_iterator + rend() const + { return _M_t.rend(); } + + /// Returns true if the %set is empty. + bool + empty() const + { return _M_t.empty(); } + + /// Returns the size of the %set. + size_type + size() const + { return _M_t.size(); } + + /// Returns the maximum size of the %set. + size_type + max_size() const + { return _M_t.max_size(); } + + /** + * @brief Swaps data with another %multiset. + * @param x A %multiset of the same element and allocator types. + * + * This exchanges the elements between two multisets in constant time. + * (It is only swapping a pointer, an integer, and an instance of the @c + * Compare type (which itself is often stateless and empty), so it should + * be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(s1,s2) will feed to this function. + */ + void + swap(multiset<_Key,_Compare,_Alloc>& __x) + { _M_t.swap(__x._M_t); } + + // insert/erase + /** + * @brief Inserts an element into the %multiset. + * @param x Element to be inserted. + * @return An iterator that points to the inserted element. + * + * This function inserts an element into the %multiset. Contrary + * to a std::set the %multiset does not rely on unique keys and thus + * multiple copies of the same element can be inserted. + * + * Insertion requires logarithmic time. + */ + iterator + insert(const value_type& __x) + { return _M_t.insert_equal(__x); } + + /** + * @brief Inserts an element into the %multiset. + * @param position An iterator that serves as a hint as to where the + * element should be inserted. + * @param x Element to be inserted. + * @return An iterator that points to the inserted element. + * + * This function inserts an element into the %multiset. Contrary + * to a std::set the %multiset does not rely on unique keys and thus + * multiple copies of the same element can be inserted. + * + * Note that the first parameter is only a hint and can potentially + * improve the performance of the insertion process. A bad hint would + * cause no gains in efficiency. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator __position, const value_type& __x) + { + typedef typename _Rep_type::iterator _Rep_iterator; + return _M_t.insert_equal((_Rep_iterator&)__position, __x); + } + + /** + * @brief A template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template <class _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t.insert_equal(__first, __last); } + + /** + * @brief Erases an element from a %multiset. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given iterator, + * from a %multiset. Note that this function only erases the element, + * and that if the element is itself a pointer, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. + */ + void + erase(iterator __position) + { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__position); + } + + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all elements located by the given key from a + * %multiset. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } + + /** + * @brief Erases a [first,last) range of elements from a %multiset. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %multiset. + * Note that this function only erases the elements, and that if + * the elements themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __first, iterator __last) + { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); + } + + /** + * Erases all elements in a %multiset. Note that this function only + * erases the elements, and that if the elements themselves are pointers, + * the pointed-to memory is not touched in any way. Managing the pointer + * is the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } + + // multiset operations: + + /** + * @brief Finds the number of elements with given key. + * @param x Key of elements to be located. + * @return Number of elements with specified key. + */ + size_type + count(const key_type& __x) const + { return _M_t.count(__x); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + //@{ + /** + * @brief Tries to locate an element in a %set. + * @param x Element to be located. + * @return Iterator pointing to sought-after element, or end() if not + * found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after element. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + //@} + + //@{ + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + 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); } + //@} + + //@{ + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + 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); } + //@} + + //@{ + /** + * @brief Finds a subsequence matching given key. + * @param x Key to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multisets. + */ + 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 _M_t.equal_range(__x); } + + template <class _K1, class _C1, class _A1> + friend bool + operator== (const multiset<_K1,_C1,_A1>&, + const multiset<_K1,_C1,_A1>&); + + template <class _K1, class _C1, class _A1> + friend bool + operator< (const multiset<_K1,_C1,_A1>&, + const multiset<_K1,_C1,_A1>&); + }; + + /** + * @brief Multiset equality comparison. + * @param x A %multiset. + * @param y A %multiset of the same type as @a x. + * @return True iff the size and elements of the multisets are equal. + * + * This is an equivalence relation. It is linear in the size of the + * multisets. + * Multisets are considered equivalent if their sizes are equal, and if + * corresponding elements compare equal. + */ + 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; } + + /** + * @brief Multiset ordering relation. + * @param x A %multiset. + * @param y A %multiset of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * maps. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + 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; } + + /// Returns !(x == y). + template <class _Key, class _Compare, class _Alloc> + inline bool + operator!=(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) + { return !(__x == __y); } + + /// Returns y < x. + template <class _Key, class _Compare, class _Alloc> + inline bool + operator>(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) + { return __y < __x; } + + /// Returns !(y < x) + template <class _Key, class _Compare, class _Alloc> + inline bool + operator<=(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) + { return !(__y < __x); } + + /// Returns !(x < y) + template <class _Key, class _Compare, class _Alloc> + inline bool + operator>=(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) + { return !(__x < __y); } + + /// See std::multiset::swap(). + template <class _Key, class _Compare, class _Alloc> + inline void + swap(multiset<_Key,_Compare,_Alloc>& __x, + multiset<_Key,_Compare,_Alloc>& __y) + { __x.swap(__y); } } // namespace std -#endif /* __GLIBCPP_INTERNAL_MULTISET_H */ - -// Local Variables: -// mode:C++ -// End: +#endif /* _MULTISET_H */ diff --git a/contrib/libstdc++/include/bits/stl_numeric.h b/contrib/libstdc++/include/bits/stl_numeric.h index 23f2bcc4512c..58762a40a7d2 100644 --- a/contrib/libstdc++/include/bits/stl_numeric.h +++ b/contrib/libstdc++/include/bits/stl_numeric.h @@ -1,6 +1,6 @@ // Numeric functions implementation -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,78 +58,153 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_STL_NUMERIC_H -#define _CPP_BITS_STL_NUMERIC_H 1 +#ifndef _STL_NUMERIC_H +#define _STL_NUMERIC_H 1 + +#include <debug/debug.h> namespace std { + /** + * @brief Accumulate values in a range. + * + * Accumulates the values in the range [first,last) using operator+(). The + * initial value is @a init. The values are processed in order. + * + * @param first Start of range. + * @param last End of range. + * @param init Starting value to add other values to. + * @return The final sum. + */ template<typename _InputIterator, typename _Tp> _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) __init = __init + *__first; return __init; } + /** + * @brief Accumulate values in a range with operation. + * + * Accumulates the values in the range [first,last) using the function + * object @a binary_op. The initial value is @a init. The values are + * processed in order. + * + * @param first Start of range. + * @param last End of range. + * @param init Starting value to add other values to. + * @param binary_op Function object to accumulate with. + * @return The final sum. + */ template<typename _InputIterator, typename _Tp, typename _BinaryOperation> _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) __init = __binary_op(__init, *__first); return __init; } + /** + * @brief Compute inner product of two ranges. + * + * Starting with an initial value of @a init, multiplies successive + * elements from the two ranges and adds each product into the accumulated + * value using operator+(). The values in the ranges are processed in + * order. + * + * @param first1 Start of range 1. + * @param last1 End of range 1. + * @param first2 Start of range 2. + * @param init Starting value to add other values to. + * @return The final inner product. + */ template<typename _InputIterator1, typename _InputIterator2, typename _Tp> _Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIterator1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); for ( ; __first1 != __last1; ++__first1, ++__first2) __init = __init + (*__first1 * *__first2); return __init; } + /** + * @brief Compute inner product of two ranges. + * + * Starting with an initial value of @a init, applies @a binary_op2 to + * successive elements from the two ranges and accumulates each result into + * the accumulated value using @a binary_op1. The values in the ranges are + * processed in order. + * + * @param first1 Start of range 1. + * @param last1 End of range 1. + * @param first2 Start of range 2. + * @param init Starting value to add other values to. + * @param binary_op1 Function object to accumulate with. + * @param binary_op2 Function object to apply to pairs of input values. + * @return The final inner product. + */ template<typename _InputIterator1, typename _InputIterator2, typename _Tp, typename _BinaryOperation1, typename _BinaryOperation2> _Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _Tp __init, + _InputIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIterator1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_requires_valid_range(__first1, __last1); for ( ; __first1 != __last1; ++__first1, ++__first2) __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); return __init; } + /** + * @brief Return list of partial sums + * + * Accumulates the values in the range [first,last) using operator+(). + * As each successive input value is added into the total, that partial sum + * is written to @a result. Therefore, the first value in result is the + * first value of the input, the second value in result is the sum of the + * first and second input values, and so on. + * + * @param first Start of input range. + * @param last End of input range. + * @param result Output to write sums to. + * @return Iterator pointing just beyond the values written to result. + */ template<typename _InputIterator, typename _OutputIterator> - _OutputIterator + _OutputIterator partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { typedef typename iterator_traits<_InputIterator>::value_type _ValueType; // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __result; *__result = *__first; @@ -141,16 +216,31 @@ namespace std return ++__result; } + /** + * @brief Return list of partial sums + * + * Accumulates the values in the range [first,last) using operator+(). + * As each successive input value is added into the total, that partial sum + * is written to @a result. Therefore, the first value in result is the + * first value of the input, the second value in result is the sum of the + * first and second input values, and so on. + * + * @param first Start of input range. + * @param last End of input range. + * @param result Output to write sums to. + * @return Iterator pointing just beyond the values written to result. + */ template<typename _InputIterator, typename _OutputIterator, typename _BinaryOperation> - _OutputIterator + _OutputIterator partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryOperation __binary_op) { typedef typename iterator_traits<_InputIterator>::value_type _ValueType; // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __result; *__result = *__first; @@ -162,6 +252,17 @@ namespace std return ++__result; } + /** + * @brief Return differences between adjacent values. + * + * Computes the difference between adjacent values in the range + * [first,last) using operator-() and writes the result to @a result. + * + * @param first Start of input range. + * @param last End of input range. + * @param result Output to write sums to. + * @return Iterator pointing just beyond the values written to result. + */ template<typename _InputIterator, typename _OutputIterator> _OutputIterator adjacent_difference(_InputIterator __first, @@ -170,8 +271,9 @@ namespace std typedef typename iterator_traits<_InputIterator>::value_type _ValueType; // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __result; *__result = *__first; @@ -184,16 +286,29 @@ namespace std return ++__result; } + /** + * @brief Return differences between adjacent values. + * + * Computes the difference between adjacent values in the range + * [first,last) using the function object @a binary_op and writes the + * result to @a result. + * + * @param first Start of input range. + * @param last End of input range. + * @param result Output to write sums to. + * @return Iterator pointing just beyond the values written to result. + */ template<typename _InputIterator, typename _OutputIterator, typename _BinaryOperation> - _OutputIterator + _OutputIterator adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryOperation __binary_op) { typedef typename iterator_traits<_InputIterator>::value_type _ValueType; // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __result; *__result = *__first; @@ -208,8 +323,4 @@ namespace std } // namespace std -#endif /* _CPP_BITS_STL_NUMERIC_H */ - -// Local Variables: -// mode:C++ -// End: +#endif /* _STL_NUMERIC_H */ diff --git a/contrib/libstdc++/include/bits/stl_pair.h b/contrib/libstdc++/include/bits/stl_pair.h index b0411b2becc9..d5146bb5943f 100644 --- a/contrib/libstdc++/include/bits/stl_pair.h +++ b/contrib/libstdc++/include/bits/stl_pair.h @@ -1,6 +1,6 @@ // Pair implementation -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,100 +58,90 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_PAIR_H -#define __GLIBCPP_INTERNAL_PAIR_H +#ifndef _PAIR_H +#define _PAIR_H 1 namespace std { - -/// pair holds two objects of arbitrary type. -template <class _T1, class _T2> -struct pair { - typedef _T1 first_type; ///< @c first_type is the first bound type - typedef _T2 second_type; ///< @c second_type is the second bound type - - _T1 first; ///< @c first is a copy of the first object - _T2 second; ///< @c second is a copy of the second object -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -//265. std::pair::pair() effects overly restrictive - /** The default constructor creates @c first and @c second using their - * respective default constructors. */ - pair() : first(), second() {} -#else - pair() : first(_T1()), second(_T2()) {} -#endif - /** Two objects may be passed to a @c pair constructor to be copied. */ - pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) {} - - /** There is also a templated copy ctor for the @c pair class itself. */ - template <class _U1, class _U2> - pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {} -}; - -/// Two pairs of the same type are equal iff their members are equal. -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; -} - -/// <http://gcc.gnu.org/onlinedocs/libstdc++/20_util/howto.html#pairlt> -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); -} - -/// Uses @c operator== to find the result. -template <class _T1, class _T2> -inline bool operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { - return !(__x == __y); -} - -/// Uses @c operator< to find the result. -template <class _T1, class _T2> -inline bool operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { - return __y < __x; -} - -/// Uses @c operator< to find the result. -template <class _T1, class _T2> -inline bool operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { - return !(__y < __x); -} - -/// Uses @c operator< to find the result. -template <class _T1, class _T2> -inline bool operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { - return !(__x < __y); -} - -/** - * @brief A convenience wrapper for creating a pair from two objects. - * @param x The first object. - * @param y The second object. - * @return A newly-constructed pair<> object of the appropriate type. - * - * The standard requires that the objects be passed by reference-to-const, - * but LWG issue #181 says they should be passed by const value. We follow - * the LWG by default. -*/ -template <class _T1, class _T2> -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -//181. make_pair() unintended behavior -inline pair<_T1, _T2> make_pair(_T1 __x, _T2 __y) -#else -inline pair<_T1, _T2> make_pair(const _T1& __x, const _T2& __y) -#endif -{ - return pair<_T1, _T2>(__x, __y); -} - + /// pair holds two objects of arbitrary type. + template<class _T1, class _T2> + struct pair + { + typedef _T1 first_type; ///< @c first_type is the first bound type + typedef _T2 second_type; ///< @c second_type is the second bound type + + _T1 first; ///< @c first is a copy of the first object + _T2 second; ///< @c second is a copy of the second object + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 265. std::pair::pair() effects overly restrictive + /** The default constructor creates @c first and @c second using their + * respective default constructors. */ + pair() + : first(), second() { } + + /** Two objects may be passed to a @c pair constructor to be copied. */ + pair(const _T1& __a, const _T2& __b) + : first(__a), second(__b) { } + + /** There is also a templated copy ctor for the @c pair class itself. */ + template<class _U1, class _U2> + pair(const pair<_U1, _U2>& __p) + : first(__p.first), second(__p.second) { } + }; + + /// Two pairs of the same type are equal iff their members are equal. + 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; } + + /// <http://gcc.gnu.org/onlinedocs/libstdc++/20_util/howto.html#pairlt> + 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); } + + /// Uses @c operator== to find the result. + template<class _T1, class _T2> + inline bool + operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return !(__x == __y); } + + /// Uses @c operator< to find the result. + template<class _T1, class _T2> + inline bool + operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return __y < __x; } + + /// Uses @c operator< to find the result. + template<class _T1, class _T2> + inline bool + operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return !(__y < __x); } + + /// Uses @c operator< to find the result. + template<class _T1, class _T2> + inline bool + operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) + { return !(__x < __y); } + + /** + * @brief A convenience wrapper for creating a pair from two objects. + * @param x The first object. + * @param y The second object. + * @return A newly-constructed pair<> object of the appropriate type. + * + * The standard requires that the objects be passed by reference-to-const, + * but LWG issue #181 says they should be passed by const value. We follow + * the LWG by default. + */ + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 181. make_pair() unintended behavior + template<class _T1, class _T2> + inline pair<_T1, _T2> + make_pair(_T1 __x, _T2 __y) { return pair<_T1, _T2>(__x, __y); } } // namespace std -#endif /* __GLIBCPP_INTERNAL_PAIR_H */ - -// Local Variables: -// mode:C++ -// End: +#endif /* _PAIR_H */ diff --git a/contrib/libstdc++/include/bits/stl_queue.h b/contrib/libstdc++/include/bits/stl_queue.h index ff2ba266aab7..3583547dbb4d 100644 --- a/contrib/libstdc++/include/bits/stl_queue.h +++ b/contrib/libstdc++/include/bits/stl_queue.h @@ -1,6 +1,6 @@ // Queue implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,25 +58,26 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_QUEUE_H -#define __GLIBCPP_INTERNAL_QUEUE_H +#ifndef _QUEUE_H +#define _QUEUE_H 1 #include <bits/concept_check.h> +#include <debug/debug.h> namespace std { // Forward declarations of operators < and ==, needed for friend declaration. - - template <typename _Tp, typename _Sequence = deque<_Tp> > - class queue; - - template <typename _Tp, typename _Seq> - inline bool operator==(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&); - - template <typename _Tp, typename _Seq> - inline bool operator<(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&); - - + template<typename _Tp, typename _Sequence = deque<_Tp> > + class queue; + + template<typename _Tp, typename _Seq> + inline bool + operator==(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&); + + template<typename _Tp, typename _Seq> + inline bool + operator<(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&); + /** * @brief A standard container giving FIFO behavior. * @@ -101,113 +102,138 @@ namespace std * which is a typedef for the second Sequence parameter, and @c push and * @c pop, which are standard %queue/FIFO operations. */ - template <typename _Tp, typename _Sequence> + template<typename _Tp, typename _Sequence> class queue - { - // concept requirements - typedef typename _Sequence::value_type _Sequence_value_type; - __glibcpp_class_requires(_Tp, _SGIAssignableConcept) - __glibcpp_class_requires(_Sequence, _FrontInsertionSequenceConcept) - __glibcpp_class_requires(_Sequence, _BackInsertionSequenceConcept) - __glibcpp_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) - - template <typename _Tp1, typename _Seq1> - friend bool operator== (const queue<_Tp1, _Seq1>&, - const queue<_Tp1, _Seq1>&); - template <typename _Tp1, typename _Seq1> - friend bool operator< (const queue<_Tp1, _Seq1>&, - const queue<_Tp1, _Seq1>&); - - public: - typedef typename _Sequence::value_type value_type; - typedef typename _Sequence::reference reference; - typedef typename _Sequence::const_reference const_reference; - typedef typename _Sequence::size_type size_type; - typedef _Sequence container_type; - - protected: - /** - * 'c' is the underlying container. Maintainers wondering why this isn't - * uglified as per style guidelines should note that this name is - * specified in the standard, [23.2.3.1]. (Why? Presumably for the same - * reason that it's protected instead of private: to allow derivation. - * But none of the other containers allow for derivation. Odd.) - */ - _Sequence c; - - public: - /** - * @brief Default constructor creates no elements. - */ - explicit - queue(const _Sequence& __c = _Sequence()) - : c(__c) {} - - /** - * Returns true if the %queue is empty. - */ - bool - empty() const { return c.empty(); } - - /** Returns the number of elements in the %queue. */ - size_type - size() const { return c.size(); } - - /** - * Returns a read/write reference to the data at the first element of the - * %queue. - */ - reference - front() { return c.front(); } - - /** - * Returns a read-only (constant) reference to the data at the first - * element of the %queue. - */ - const_reference - front() const { return c.front(); } - - /** - * Returns a read/write reference to the data at the last element of the - * %queue. - */ - reference - back() { return c.back(); } - - /** - * Returns a read-only (constant) reference to the data at the last - * element of the %queue. - */ - const_reference - back() const { return c.back(); } - - /** - * @brief Add data to the end of the %queue. - * @param x Data to be added. - * - * This is a typical %queue operation. The function creates an element at - * the end of the %queue and assigns the given data to it. - * The time complexity of the operation depends on the underlying - * sequence. - */ - void - push(const value_type& __x) { c.push_back(__x); } - - /** - * @brief Removes first element. - * - * This is a typical %queue operation. It shrinks the %queue by one. - * The time complexity of the operation depends on the underlying - * sequence. - * - * Note that no data is returned, and if the first element's data is - * needed, it should be retrieved before pop() is called. - */ - void - pop() { c.pop_front(); } - }; - - + { + // concept requirements + typedef typename _Sequence::value_type _Sequence_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires(_Sequence, _FrontInsertionSequenceConcept) + __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept) + __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) + + template<typename _Tp1, typename _Seq1> + friend bool + operator==(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&); + + template<typename _Tp1, typename _Seq1> + friend bool + operator<(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&); + + public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + protected: + /** + * 'c' is the underlying container. Maintainers wondering why + * this isn't uglified as per style guidelines should note that + * this name is specified in the standard, [23.2.3.1]. (Why? + * Presumably for the same reason that it's protected instead + * of private: to allow derivation. But none of the other + * containers allow for derivation. Odd.) + */ + _Sequence c; + + public: + /** + * @brief Default constructor creates no elements. + */ + explicit + queue(const _Sequence& __c = _Sequence()) : c(__c) {} + + /** + * Returns true if the %queue is empty. + */ + bool + empty() const + { return c.empty(); } + + /** Returns the number of elements in the %queue. */ + size_type + size() const + { return c.size(); } + + /** + * Returns a read/write reference to the data at the first + * element of the %queue. + */ + reference + front() + { + __glibcxx_requires_nonempty(); + return c.front(); + } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %queue. + */ + const_reference + front() const + { + __glibcxx_requires_nonempty(); + return c.front(); + } + + /** + * Returns a read/write reference to the data at the last + * element of the %queue. + */ + reference + back() + { + __glibcxx_requires_nonempty(); + return c.back(); + } + + /** + * Returns a read-only (constant) reference to the data at the last + * element of the %queue. + */ + const_reference + back() const + { + __glibcxx_requires_nonempty(); + return c.back(); + } + + /** + * @brief Add data to the end of the %queue. + * @param x Data to be added. + * + * This is a typical %queue operation. The function creates an + * element at the end of the %queue and assigns the given data + * to it. The time complexity of the operation depends on the + * underlying sequence. + */ + void + push(const value_type& __x) + { c.push_back(__x); } + + /** + * @brief Removes first element. + * + * This is a typical %queue operation. It shrinks the %queue by one. + * The time complexity of the operation depends on the underlying + * sequence. + * + * Note that no data is returned, and if the first element's + * data is needed, it should be retrieved before pop() is + * called. + */ + void + pop() + { + __glibcxx_requires_nonempty(); + c.pop_front(); + } + }; + + /** * @brief Queue equality comparison. * @param x A %queue. @@ -219,212 +245,228 @@ namespace std * linear in the size of the sequences, and queues are considered equivalent * if their sequences compare equal. */ - template <typename _Tp, typename _Sequence> - inline bool - operator==(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y) + template<typename _Tp, typename _Sequence> + inline bool + operator==(const queue<_Tp,_Sequence>& __x, + const queue<_Tp,_Sequence>& __y) { return __x.c == __y.c; } - + /** * @brief Queue ordering relation. * @param x A %queue. * @param y A %queue of the same type as @a x. - * @return True iff @a x is lexographically less than @a y. + * @return True iff @a x is lexicographically less than @a y. * - * This is an total ordering relation. Complexity and semantics depend on - * the underlying sequence type, but the expected rules are: this relation - * is linear in the size of the sequences, the elements must be comparable - * with @c <, and std::lexographical_compare() is usually used to make the + * This is an total ordering relation. Complexity and semantics + * depend on the underlying sequence type, but the expected rules + * are: this relation is linear in the size of the sequences, the + * elements must be comparable with @c <, and + * std::lexicographical_compare() is usually used to make the * determination. */ - template <typename _Tp, typename _Sequence> + template<typename _Tp, typename _Sequence> inline bool operator<(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y) { return __x.c < __y.c; } - + /// Based on operator== - template <typename _Tp, typename _Sequence> + template<typename _Tp, typename _Sequence> inline bool - operator!=(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y) + operator!=(const queue<_Tp,_Sequence>& __x, + const queue<_Tp,_Sequence>& __y) { return !(__x == __y); } - + /// Based on operator< - template <typename _Tp, typename _Sequence> - inline bool + template<typename _Tp, typename _Sequence> + inline bool operator>(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y) { return __y < __x; } - + /// Based on operator< - template <typename _Tp, typename _Sequence> - inline bool - operator<=(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y) + template<typename _Tp, typename _Sequence> + inline bool + operator<=(const queue<_Tp,_Sequence>& __x, + const queue<_Tp,_Sequence>& __y) { return !(__y < __x); } - + /// Based on operator< - template <typename _Tp, typename _Sequence> - inline bool - operator>=(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y) + template<typename _Tp, typename _Sequence> + inline bool + operator>=(const queue<_Tp,_Sequence>& __x, + const queue<_Tp,_Sequence>& __y) { return !(__x < __y); } - - + /** * @brief A standard container automatically sorting its contents. * * @ingroup Containers * @ingroup Sequences * - * This is not a true container, but an @e adaptor. It holds another - * container, and provides a wrapper interface to that container. The - * wrapper is what enforces sorting and first-in-first-out %queue behavior. - * Very few of the standard container/sequence interface requirements are - * met (e.g., iterators). + * This is not a true container, but an @e adaptor. It holds + * another container, and provides a wrapper interface to that + * container. The wrapper is what enforces sorting and + * first-in-first-out %queue behavior. Very few of the standard + * container/sequence interface requirements are met (e.g., + * iterators). * * The second template parameter defines the type of the underlying - * sequence/container. It defaults to std::vector, but it can be any type - * that supports @c front(), @c push_back, @c pop_back, and random-access - * iterators, such as std::deque or an appropriate user-defined type. + * sequence/container. It defaults to std::vector, but it can be + * any type that supports @c front(), @c push_back, @c pop_back, + * and random-access iterators, such as std::deque or an + * appropriate user-defined type. * - * The third template parameter supplies the means of making priority - * comparisons. It defaults to @c less<value_type> but can be anything - * defining a strict weak ordering. + * The third template parameter supplies the means of making + * priority comparisons. It defaults to @c less<value_type> but + * can be anything defining a strict weak ordering. * * Members not found in "normal" containers are @c container_type, - * which is a typedef for the second Sequence parameter, and @c push, - * @c pop, and @c top, which are standard %queue/FIFO operations. + * which is a typedef for the second Sequence parameter, and @c + * push, @c pop, and @c top, which are standard %queue/FIFO + * operations. * - * @note No equality/comparison operators are provided for %priority_queue. + * @note No equality/comparison operators are provided for + * %priority_queue. * - * @note Sorting of the elements takes place as they are added to, and - * removed from, the %priority_queue using the %priority_queue's - * member functions. If you access the elements by other means, and - * change their data such that the sorting order would be different, - * the %priority_queue will not re-sort the elements for you. (How - * could it know to do so?) + * @note Sorting of the elements takes place as they are added to, + * and removed from, the %priority_queue using the + * %priority_queue's member functions. If you access the elements + * by other means, and change their data such that the sorting + * order would be different, the %priority_queue will not re-sort + * the elements for you. (How could it know to do so?) */ - template <typename _Tp, typename _Sequence = vector<_Tp>, - typename _Compare = less<typename _Sequence::value_type> > + template<typename _Tp, typename _Sequence = vector<_Tp>, + typename _Compare = less<typename _Sequence::value_type> > class priority_queue - { - // concept requirements - typedef typename _Sequence::value_type _Sequence_value_type; - __glibcpp_class_requires(_Tp, _SGIAssignableConcept) - __glibcpp_class_requires(_Sequence, _SequenceConcept) - __glibcpp_class_requires(_Sequence, _RandomAccessContainerConcept) - __glibcpp_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) - __glibcpp_class_requires4(_Compare, bool, _Tp, _Tp, _BinaryFunctionConcept) - - public: - typedef typename _Sequence::value_type value_type; - typedef typename _Sequence::reference reference; - typedef typename _Sequence::const_reference const_reference; - typedef typename _Sequence::size_type size_type; - typedef _Sequence container_type; - - protected: - // See queue::c for notes on these names. - _Sequence c; - _Compare comp; - - public: - /** - * @brief Default constructor creates no elements. - */ - explicit - priority_queue(const _Compare& __x = _Compare(), - const _Sequence& __s = _Sequence()) - : c(__s), comp(__x) - { make_heap(c.begin(), c.end(), comp); } - - /** - * @brief Builds a %queue from a range. - * @param first An input iterator. - * @param last An input iterator. - * @param x A comparison functor describing a strict weak ordering. - * @param s An initial sequence with which to start. - * - * Begins by copying @a s, inserting a copy of the elements from - * @a [first,last) into the copy of @a s, then ordering the copy - * according to @a x. - * - * For more information on function objects, see the documentation on - * @link s20_3_1_base functor base classes@endlink. - */ - template <typename _InputIterator> - priority_queue(_InputIterator __first, _InputIterator __last, - const _Compare& __x = _Compare(), - const _Sequence& __s = _Sequence()) + { + // concept requirements + typedef typename _Sequence::value_type _Sequence_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires(_Sequence, _SequenceConcept) + __glibcxx_class_requires(_Sequence, _RandomAccessContainerConcept) + __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) + __glibcxx_class_requires4(_Compare, bool, _Tp,_Tp,_BinaryFunctionConcept) + + public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + protected: + // See queue::c for notes on these names. + _Sequence c; + _Compare comp; + + public: + /** + * @brief Default constructor creates no elements. + */ + explicit + priority_queue(const _Compare& __x = _Compare(), + const _Sequence& __s = _Sequence()) : c(__s), comp(__x) - { - c.insert(c.end(), __first, __last); - make_heap(c.begin(), c.end(), comp); + { std::make_heap(c.begin(), c.end(), comp); } + + /** + * @brief Builds a %queue from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param x A comparison functor describing a strict weak ordering. + * @param s An initial sequence with which to start. + * + * Begins by copying @a s, inserting a copy of the elements + * from @a [first,last) into the copy of @a s, then ordering + * the copy according to @a x. + * + * For more information on function objects, see the + * documentation on @link s20_3_1_base functor base + * classes@endlink. + */ + template<typename _InputIterator> + priority_queue(_InputIterator __first, _InputIterator __last, + const _Compare& __x = _Compare(), + const _Sequence& __s = _Sequence()) + : c(__s), comp(__x) + { + __glibcxx_requires_valid_range(__first, __last); + c.insert(c.end(), __first, __last); + std::make_heap(c.begin(), c.end(), comp); + } + + /** + * Returns true if the %queue is empty. + */ + bool + empty() const { return c.empty(); } + + /** Returns the number of elements in the %queue. */ + size_type + size() const { return c.size(); } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %queue. + */ + const_reference + top() const + { + __glibcxx_requires_nonempty(); + return c.front(); } - - /** - * Returns true if the %queue is empty. - */ - bool - empty() const { return c.empty(); } - - /** Returns the number of elements in the %queue. */ - size_type - size() const { return c.size(); } - - /** - * Returns a read-only (constant) reference to the data at the first - * element of the %queue. - */ - const_reference - top() const { return c.front(); } - - /** - * @brief Add data to the %queue. - * @param x Data to be added. - * - * This is a typical %queue operation. - * The time complexity of the operation depends on the underlying - * sequence. - */ - void - push(const value_type& __x) - { - try + + /** + * @brief Add data to the %queue. + * @param x Data to be added. + * + * This is a typical %queue operation. + * The time complexity of the operation depends on the underlying + * sequence. + */ + void + push(const value_type& __x) + { + try { - c.push_back(__x); - push_heap(c.begin(), c.end(), comp); + c.push_back(__x); + std::push_heap(c.begin(), c.end(), comp); } - catch(...) + catch(...) { c.clear(); - __throw_exception_again; + __throw_exception_again; } - } - - /** - * @brief Removes first element. - * - * This is a typical %queue operation. It shrinks the %queue by one. - * The time complexity of the operation depends on the underlying - * sequence. - * - * Note that no data is returned, and if the first element's data is - * needed, it should be retrieved before pop() is called. - */ - void - pop() - { - try + } + + /** + * @brief Removes first element. + * + * This is a typical %queue operation. It shrinks the %queue + * by one. The time complexity of the operation depends on the + * underlying sequence. + * + * Note that no data is returned, and if the first element's + * data is needed, it should be retrieved before pop() is + * called. + */ + void + pop() + { + __glibcxx_requires_nonempty(); + try { - pop_heap(c.begin(), c.end(), comp); + std::pop_heap(c.begin(), c.end(), comp); c.pop_back(); } - catch(...) + catch(...) { c.clear(); - __throw_exception_again; + __throw_exception_again; } - } - }; - + } + }; + // No equality/comparison operators are provided for priority_queue. } // namespace std -#endif /* __GLIBCPP_INTERNAL_QUEUE_H */ +#endif /* _QUEUE_H */ diff --git a/contrib/libstdc++/include/bits/stl_raw_storage_iter.h b/contrib/libstdc++/include/bits/stl_raw_storage_iter.h index 59aa004296e8..732142e1e6b9 100644 --- a/contrib/libstdc++/include/bits/stl_raw_storage_iter.h +++ b/contrib/libstdc++/include/bits/stl_raw_storage_iter.h @@ -1,6 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,8 +58,8 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_STL_RAW_STORAGE_ITERATOR_H -#define _CPP_BITS_STL_RAW_STORAGE_ITERATOR_H 1 +#ifndef _STL_RAW_STORAGE_ITERATOR_H +#define _STL_RAW_STORAGE_ITERATOR_H 1 namespace std { @@ -68,35 +68,36 @@ namespace std * uninitialized memory. */ template <class _ForwardIterator, class _Tp> - class raw_storage_iterator + class raw_storage_iterator : public iterator<output_iterator_tag, void, void, void, void> { protected: _ForwardIterator _M_iter; public: - explicit - raw_storage_iterator(_ForwardIterator __x) : _M_iter(__x) {} + explicit + raw_storage_iterator(_ForwardIterator __x) + : _M_iter(__x) {} - raw_storage_iterator& + raw_storage_iterator& operator*() { return *this; } - raw_storage_iterator& - operator=(const _Tp& __element) + raw_storage_iterator& + operator=(const _Tp& __element) { - _Construct(&*_M_iter, __element); + std::_Construct(&*_M_iter, __element); return *this; - } + } - raw_storage_iterator<_ForwardIterator, _Tp>& - operator++() + raw_storage_iterator<_ForwardIterator, _Tp>& + operator++() { ++_M_iter; return *this; } - raw_storage_iterator<_ForwardIterator, _Tp> - operator++(int) + raw_storage_iterator<_ForwardIterator, _Tp> + operator++(int) { raw_storage_iterator<_ForwardIterator, _Tp> __tmp = *this; ++_M_iter; diff --git a/contrib/libstdc++/include/bits/stl_relops.h b/contrib/libstdc++/include/bits/stl_relops.h index ce3dc0b9b393..3e9f060f2877 100644 --- a/contrib/libstdc++/include/bits/stl_relops.h +++ b/contrib/libstdc++/include/bits/stl_relops.h @@ -1,6 +1,6 @@ // std::rel_ops implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -68,74 +68,70 @@ * @endif */ -#ifndef _CPP_BITS_STL_RELOPS_H -#define _CPP_BITS_STL_RELOPS_H 1 +#ifndef _STL_RELOPS_H +#define _STL_RELOPS_H 1 namespace std { namespace rel_ops { - /** @namespace std::rel_ops - * @brief The generated relational operators are sequestered here. - */ + /** @namespace std::rel_ops + * @brief The generated relational operators are sequestered here. + */ -/** - * @brief Defines @c != for arbitrary types, in terms of @c ==. - * @param x A thing. - * @param y Another thing. - * @return x != y - * - * This function uses @c == to determine its result. -*/ -template <class _Tp> -inline bool operator!=(const _Tp& __x, const _Tp& __y) { - return !(__x == __y); -} + /** + * @brief Defines @c != for arbitrary types, in terms of @c ==. + * @param x A thing. + * @param y Another thing. + * @return x != y + * + * This function uses @c == to determine its result. + */ + template <class _Tp> + inline bool + operator!=(const _Tp& __x, const _Tp& __y) + { return !(__x == __y); } -/** - * @brief Defines @c > for arbitrary types, in terms of @c <. - * @param x A thing. - * @param y Another thing. - * @return x > y - * - * This function uses @c < to determine its result. -*/ -template <class _Tp> -inline bool operator>(const _Tp& __x, const _Tp& __y) { - return __y < __x; -} + /** + * @brief Defines @c > for arbitrary types, in terms of @c <. + * @param x A thing. + * @param y Another thing. + * @return x > y + * + * This function uses @c < to determine its result. + */ + template <class _Tp> + inline bool + operator>(const _Tp& __x, const _Tp& __y) + { return __y < __x; } -/** - * @brief Defines @c <= for arbitrary types, in terms of @c <. - * @param x A thing. - * @param y Another thing. - * @return x <= y - * - * This function uses @c < to determine its result. -*/ -template <class _Tp> -inline bool operator<=(const _Tp& __x, const _Tp& __y) { - return !(__y < __x); -} + /** + * @brief Defines @c <= for arbitrary types, in terms of @c <. + * @param x A thing. + * @param y Another thing. + * @return x <= y + * + * This function uses @c < to determine its result. + */ + template <class _Tp> + inline bool + operator<=(const _Tp& __x, const _Tp& __y) + { return !(__y < __x); } -/** - * @brief Defines @c >= for arbitrary types, in terms of @c <. - * @param x A thing. - * @param y Another thing. - * @return x >= y - * - * This function uses @c < to determine its result. -*/ -template <class _Tp> -inline bool operator>=(const _Tp& __x, const _Tp& __y) { - return !(__x < __y); -} + /** + * @brief Defines @c >= for arbitrary types, in terms of @c <. + * @param x A thing. + * @param y Another thing. + * @return x >= y + * + * This function uses @c < to determine its result. + */ + template <class _Tp> + inline bool + operator>=(const _Tp& __x, const _Tp& __y) + { return !(__x < __y); } } // namespace rel_ops } // namespace std -#endif /* _CPP_BITS_STL_RELOPS_H */ - -// Local Variables: -// mode:C++ -// End: +#endif /* _STL_RELOPS_H */ diff --git a/contrib/libstdc++/include/bits/stl_set.h b/contrib/libstdc++/include/bits/stl_set.h index ee708c292179..bb28bddc7af9 100644 --- a/contrib/libstdc++/include/bits/stl_set.h +++ b/contrib/libstdc++/include/bits/stl_set.h @@ -1,6 +1,6 @@ // Set implementation -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,217 +58,536 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_SET_H -#define __GLIBCPP_INTERNAL_SET_H +#ifndef _SET_H +#define _SET_H 1 #include <bits/concept_check.h> -namespace std +namespace _GLIBCXX_STD { - -// Forward declarations of operators < and ==, needed for friend declaration. - -template <class _Key, class _Compare = less<_Key>, - class _Alloc = allocator<_Key> > -class set; - -template <class _Key, class _Compare, class _Alloc> -inline bool operator==(const set<_Key,_Compare,_Alloc>& __x, - const set<_Key,_Compare,_Alloc>& __y); - -template <class _Key, class _Compare, class _Alloc> -inline bool operator<(const set<_Key,_Compare,_Alloc>& __x, - const set<_Key,_Compare,_Alloc>& __y); - - -template <class _Key, class _Compare, class _Alloc> -class set -{ - // concept requirements - __glibcpp_class_requires(_Key, _SGIAssignableConcept) - __glibcpp_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept); - -public: - // typedefs: - typedef _Key key_type; - typedef _Key value_type; - typedef _Compare key_compare; - typedef _Compare value_compare; -private: - typedef _Rb_tree<key_type, value_type, - _Identity<value_type>, key_compare, _Alloc> _Rep_type; - _Rep_type _M_t; // red-black tree representing set -public: - typedef typename _Rep_type::const_pointer pointer; - typedef typename _Rep_type::const_pointer const_pointer; - typedef typename _Rep_type::const_reference reference; - typedef typename _Rep_type::const_reference const_reference; - typedef typename _Rep_type::const_iterator iterator; - typedef typename _Rep_type::const_iterator const_iterator; - typedef typename _Rep_type::const_reverse_iterator reverse_iterator; - typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; - typedef typename _Rep_type::size_type size_type; - typedef typename _Rep_type::difference_type difference_type; - typedef typename _Rep_type::allocator_type allocator_type; - - // allocation/deallocation - - set() : _M_t(_Compare(), allocator_type()) {} - explicit set(const _Compare& __comp, - const allocator_type& __a = allocator_type()) - : _M_t(__comp, __a) {} - - 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); } - - set(const set<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} - set<_Key,_Compare,_Alloc>& operator=(const set<_Key, _Compare, _Alloc>& __x) - { - _M_t = __x._M_t; - return *this; - } - - // accessors: - - key_compare key_comp() const { return _M_t.key_comp(); } - value_compare value_comp() const { return _M_t.key_comp(); } - allocator_type get_allocator() const { return _M_t.get_allocator(); } - - iterator begin() const { return _M_t.begin(); } - iterator end() const { return _M_t.end(); } - reverse_iterator rbegin() const { return _M_t.rbegin(); } - reverse_iterator rend() const { return _M_t.rend(); } - bool empty() const { return _M_t.empty(); } - size_type size() const { return _M_t.size(); } - size_type max_size() const { return _M_t.max_size(); } - void swap(set<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } - - // insert/erase - pair<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 _M_t.insert_unique((_Rep_iterator&)__position, __x); - } - template <class _InputIterator> - void insert(_InputIterator __first, _InputIterator __last) { - _M_t.insert_unique(__first, __last); - } - void erase(iterator __position) { - typedef typename _Rep_type::iterator _Rep_iterator; - _M_t.erase((_Rep_iterator&)__position); - } - size_type erase(const key_type& __x) { - return _M_t.erase(__x); - } - void erase(iterator __first, iterator __last) { - typedef typename _Rep_type::iterator _Rep_iterator; - _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); - } - void clear() { _M_t.clear(); } - - // set operations: - - size_type count(const key_type& __x) const { - return _M_t.find(__x) == _M_t.end() ? 0 : 1; - } - -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -//214. set::find() missing const overload - iterator find(const key_type& __x) { return _M_t.find(__x); } - const_iterator find(const key_type& __x) const { return _M_t.find(__x); } - iterator lower_bound(const key_type& __x) { - return _M_t.lower_bound(__x); - } - const_iterator lower_bound(const key_type& __x) const { - return _M_t.lower_bound(__x); - } - iterator upper_bound(const key_type& __x) { - return _M_t.upper_bound(__x); - } - const_iterator upper_bound(const key_type& __x) const { - return _M_t.upper_bound(__x); - } - pair<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 _M_t.equal_range(__x); - } -#else - iterator find(const key_type& __x) const { return _M_t.find(__x); } - iterator lower_bound(const key_type& __x) const { - return _M_t.lower_bound(__x); - } - iterator upper_bound(const key_type& __x) const { - return _M_t.upper_bound(__x); - } - pair<iterator,iterator> equal_range(const key_type& __x) const { - return _M_t.equal_range(__x); - } -#endif - - template <class _K1, class _C1, class _A1> - friend bool operator== (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); - template <class _K1, class _C1, class _A1> - friend bool operator< (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); -}; - -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._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 == __y); -} - -template <class _Key, class _Compare, class _Alloc> -inline bool operator>(const set<_Key,_Compare,_Alloc>& __x, - const set<_Key,_Compare,_Alloc>& __y) { - return __y < __x; -} - -template <class _Key, class _Compare, class _Alloc> -inline bool operator<=(const set<_Key,_Compare,_Alloc>& __x, - const set<_Key,_Compare,_Alloc>& __y) { - return !(__y < __x); -} - -template <class _Key, class _Compare, class _Alloc> -inline bool operator>=(const set<_Key,_Compare,_Alloc>& __x, - const set<_Key,_Compare,_Alloc>& __y) { - return !(__x < __y); -} - -template <class _Key, class _Compare, class _Alloc> -inline void swap(set<_Key,_Compare,_Alloc>& __x, - set<_Key,_Compare,_Alloc>& __y) { - __x.swap(__y); -} + // Forward declarations of operators < and ==, needed for friend declaration. + template<class _Key, class _Compare = less<_Key>, + class _Alloc = allocator<_Key> > + class set; + + template<class _Key, class _Compare, class _Alloc> + inline bool + operator==(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y); + + template<class _Key, class _Compare, class _Alloc> + inline bool + operator<(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y); + + /** + * @brief A standard container made up of unique keys, which can be + * retrieved in logarithmic time. + * + * @ingroup Containers + * @ingroup Assoc_containers + * + * Meets the requirements of a <a href="tables.html#65">container</a>, a + * <a href="tables.html#66">reversible container</a>, and an + * <a href="tables.html#69">associative container</a> (using unique keys). + * + * Sets support bidirectional iterators. + * + * @param Key Type of key objects. + * @param Compare Comparison function object type, defaults to less<Key>. + * @param Alloc Allocator type, defaults to allocator<Key>. + * + * @if maint + * The private tree data is declared exactly the same way for set and + * multiset; the distinction is made entirely in how the tree functions are + * called (*_unique versus *_equal, same as the standard). + * @endif + */ + template<class _Key, class _Compare, class _Alloc> + class set + { + // concept requirements + __glibcxx_class_requires(_Key, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) + + public: + // typedefs: + //@{ + /// Public typedefs. + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + //@} + + private: + typedef _Rb_tree<key_type, value_type, + _Identity<value_type>, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing set + public: + //@{ + /// Iterator-related typedefs. + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 103. set::iterator is required to be modifiable, + // but this allows modification of keys. + 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 + /// Default constructor creates no elements. + set() + : _M_t(_Compare(), allocator_type()) {} + + /** + * @brief Default constructor creates no elements. + * + * @param comp Comparator to use. + * @param a Allocator to use. + */ + explicit set(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) {} + + /** + * @brief Builds a %set from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %set consisting of copies of the elements from [first,last). + * This is linear in N if the range is already sorted, and NlogN + * otherwise (where N is distance(first,last)). + */ + template<class _InputIterator> + set(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + /** + * @brief Builds a %set from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %set consisting of copies of the elements from [first,last). + * This is linear in N if the range is already sorted, and NlogN + * otherwise (where N is distance(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); } + + /** + * @brief Set copy constructor. + * @param x A %set of identical element and allocator types. + * + * The newly-created %set uses a copy of the allocation object used + * by @a x. + */ + set(const set<_Key,_Compare,_Alloc>& __x) + : _M_t(__x._M_t) { } + + /** + * @brief Set assignment operator. + * @param x A %set of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + set<_Key,_Compare,_Alloc>& + operator=(const set<_Key, _Compare, _Alloc>& __x) + { + _M_t = __x._M_t; + return *this; + } + + // accessors: + + /// Returns the comparison object with which the %set was constructed. + key_compare + key_comp() const + { return _M_t.key_comp(); } + /// Returns the comparison object with which the %set was constructed. + value_compare + value_comp() const + { return _M_t.key_comp(); } + /// Returns the allocator object with which the %set was constructed. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + /** + * Returns a read/write iterator that points to the first element in the + * %set. Iteration is done in ascending order according to the keys. + */ + iterator + begin() const + { return _M_t.begin(); } + + /** + * Returns a read/write iterator that points one past the last element in + * the %set. Iteration is done in ascending order according to the keys. + */ + iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last element + * in the %set. Iteration is done in descending order according to the + * keys. + */ + reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read-only (constant) reverse iterator that points to the + * last pair in the %map. Iteration is done in descending order + * according to the keys. + */ + reverse_iterator + rend() const + { return _M_t.rend(); } + + /// Returns true if the %set is empty. + bool + empty() const + { return _M_t.empty(); } + + /// Returns the size of the %set. + size_type + size() const + { return _M_t.size(); } + + /// Returns the maximum size of the %set. + size_type + max_size() const + { return _M_t.max_size(); } + + /** + * @brief Swaps data with another %set. + * @param x A %set of the same element and allocator types. + * + * This exchanges the elements between two sets in constant time. + * (It is only swapping a pointer, an integer, and an instance of + * the @c Compare type (which itself is often stateless and empty), so it + * should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(s1,s2) will feed to this function. + */ + void + swap(set<_Key,_Compare,_Alloc>& __x) + { _M_t.swap(__x._M_t); } + + // insert/erase + /** + * @brief Attempts to insert an element into the %set. + * @param x Element to be inserted. + * @return A pair, of which the first element is an iterator that points + * to the possibly inserted element, and the second is a bool + * that is true if the element was actually inserted. + * + * This function attempts to insert an element into the %set. A %set + * relies on unique keys and thus an element is only inserted if it is + * not already present in the %set. + * + * Insertion requires logarithmic time. + */ + 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); + } + + /** + * @brief Attempts to insert an element into the %set. + * @param position An iterator that serves as a hint as to where the + * element should be inserted. + * @param x Element to be inserted. + * @return An iterator that points to the element with key of @a x (may + * or may not be the element passed in). + * + * This function is not concerned about whether the insertion took place, + * and thus does not return a boolean like the single-argument insert() + * does. Note that the first parameter is only a hint and can + * potentially improve the performance of the insertion process. A bad + * hint would cause no gains in efficiency. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator __position, const value_type& __x) + { + typedef typename _Rep_type::iterator _Rep_iterator; + return _M_t.insert_unique((_Rep_iterator&)__position, __x); + } + + /** + * @brief A template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template<class _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t.insert_unique(__first, __last); } + + /** + * @brief Erases an element from a %set. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given iterator, + * from a %set. Note that this function only erases the element, and + * that if the element is itself a pointer, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __position) + { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__position); + } + + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all the elements located by the given key from + * a %set. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) { return _M_t.erase(__x); } + + /** + * @brief Erases a [first,last) range of elements from a %set. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %set. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __first, iterator __last) + { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); + } + + /** + * Erases all elements in a %set. Note that this function only erases + * the elements, and that if the elements themselves are pointers, the + * pointed-to memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } + + // set operations: + + /** + * @brief Finds the number of elements. + * @param x Element to located. + * @return Number of elements with specified key. + * + * This function only makes sense for multisets; for set the result will + * either be 0 (not present) or 1 (present). + */ + size_type + count(const key_type& __x) const + { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + //@{ + /** + * @brief Tries to locate an element in a %set. + * @param x Element to be located. + * @return Iterator pointing to sought-after element, or end() if not + * found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after element. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + //@} + + //@{ + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + 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); } + //@} + + //@{ + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + 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); } + //@} + + //@{ + /** + * @brief Finds a subsequence matching given key. + * @param x Key to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multisets. + */ + 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 _M_t.equal_range(__x); } + //@} + + template<class _K1, class _C1, class _A1> + friend bool + operator== (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); + + template<class _K1, class _C1, class _A1> + friend bool + operator< (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); + }; + + + /** + * @brief Set equality comparison. + * @param x A %set. + * @param y A %set of the same type as @a x. + * @return True iff the size and elements of the sets are equal. + * + * This is an equivalence relation. It is linear in the size of the sets. + * Sets are considered equivalent if their sizes are equal, and if + * corresponding elements compare equal. + */ + 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; } + + /** + * @brief Set ordering relation. + * @param x A %set. + * @param y A %set of the same type as @a x. + * @return True iff @a x is lexicographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * maps. The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + */ + 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; } + + /// Returns !(x == y). + template<class _Key, class _Compare, class _Alloc> + inline bool + operator!=(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) + { return !(__x == __y); } + + /// Returns y < x. + template<class _Key, class _Compare, class _Alloc> + inline bool + operator>(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) + { return __y < __x; } + + /// Returns !(y < x) + template<class _Key, class _Compare, class _Alloc> + inline bool + operator<=(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) + { return !(__y < __x); } + + /// Returns !(x < y) + template<class _Key, class _Compare, class _Alloc> + inline bool + operator>=(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) + { return !(__x < __y); } + + /// See std::set::swap(). + template<class _Key, class _Compare, class _Alloc> + inline void + swap(set<_Key,_Compare,_Alloc>& __x, set<_Key,_Compare,_Alloc>& __y) + { __x.swap(__y); } } // namespace std -#endif /* __GLIBCPP_INTERNAL_SET_H */ - -// Local Variables: -// mode:C++ -// End: +#endif /* _SET_H */ diff --git a/contrib/libstdc++/include/bits/stl_stack.h b/contrib/libstdc++/include/bits/stl_stack.h index 7f2496c383eb..ada50ee350ea 100644 --- a/contrib/libstdc++/include/bits/stl_stack.h +++ b/contrib/libstdc++/include/bits/stl_stack.h @@ -1,6 +1,6 @@ // Stack implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,26 +58,27 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_STACK_H -#define __GLIBCPP_INTERNAL_STACK_H +#ifndef _STACK_H +#define _STACK_H 1 #include <bits/concept_check.h> +#include <debug/debug.h> namespace std { - // Forward declarations of operators == and <, needed for friend declaration. - - template <typename _Tp, typename _Sequence = deque<_Tp> > - class stack; - - template <typename _Tp, typename _Seq> - inline bool operator==(const stack<_Tp,_Seq>& __x, - const stack<_Tp,_Seq>& __y); - - template <typename _Tp, typename _Seq> - inline bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y); - - + // Forward declarations of operators == and <, needed for friend + // declaration. + template<typename _Tp, typename _Sequence = deque<_Tp> > + class stack; + + template<typename _Tp, typename _Seq> + inline bool + operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y); + + template<typename _Tp, typename _Seq> + inline bool + operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y); + /** * @brief A standard container giving FILO behavior. * @@ -89,162 +90,183 @@ namespace std * but does not define anything to do with iterators. Very few of the * other standard container interfaces are defined. * - * This is not a true container, but an @e adaptor. It holds another - * container, and provides a wrapper interface to that container. The - * wrapper is what enforces strict first-in-last-out %stack behavior. + * This is not a true container, but an @e adaptor. It holds + * another container, and provides a wrapper interface to that + * container. The wrapper is what enforces strict + * first-in-last-out %stack behavior. * * The second template parameter defines the type of the underlying - * sequence/container. It defaults to std::deque, but it can be any type - * that supports @c back, @c push_back, and @c pop_front, such as - * std::list, std::vector, or an appropriate user-defined type. + * sequence/container. It defaults to std::deque, but it can be + * any type that supports @c back, @c push_back, and @c pop_front, + * such as std::list, std::vector, or an appropriate user-defined + * type. * * Members not found in "normal" containers are @c container_type, - * which is a typedef for the second Sequence parameter, and @c push, - * @c pop, and @c top, which are standard %stack/FILO operations. + * which is a typedef for the second Sequence parameter, and @c + * push, @c pop, and @c top, which are standard %stack/FILO + * operations. */ - template <typename _Tp, typename _Sequence> + template<typename _Tp, typename _Sequence> class stack - { - // concept requirements - typedef typename _Sequence::value_type _Sequence_value_type; - __glibcpp_class_requires(_Tp, _SGIAssignableConcept) - __glibcpp_class_requires(_Sequence, _BackInsertionSequenceConcept) - __glibcpp_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) - - template <typename _Tp1, typename _Seq1> - friend bool operator== (const stack<_Tp1, _Seq1>&, - const stack<_Tp1, _Seq1>&); - template <typename _Tp1, typename _Seq1> - friend bool operator< (const stack<_Tp1, _Seq1>&, - const stack<_Tp1, _Seq1>&); - - public: - typedef typename _Sequence::value_type value_type; - typedef typename _Sequence::reference reference; - typedef typename _Sequence::const_reference const_reference; - typedef typename _Sequence::size_type size_type; - typedef _Sequence container_type; - - protected: - // See queue::c for notes on this name. - _Sequence c; - - public: - // XXX removed old def ctor, added def arg to this one to match 14882 - /** - * @brief Default constructor creates no elements. - */ - explicit - stack(const _Sequence& __c = _Sequence()) - : c(__c) {} - - /** - * Returns true if the %stack is empty. - */ - bool - empty() const { return c.empty(); } - - /** Returns the number of elements in the %stack. */ - size_type - size() const { return c.size(); } - - /** - * Returns a read/write reference to the data at the first element of the - * %stack. - */ - reference - top() { return c.back(); } - - /** - * Returns a read-only (constant) reference to the data at the first - * element of the %stack. - */ - const_reference - top() const { return c.back(); } - - /** - * @brief Add data to the top of the %stack. - * @param x Data to be added. - * - * This is a typical %stack operation. The function creates an element at - * the top of the %stack and assigns the given data to it. - * The time complexity of the operation depends on the underlying - * sequence. - */ - void - push(const value_type& __x) { c.push_back(__x); } - - /** - * @brief Removes first element. - * - * This is a typical %stack operation. It shrinks the %stack by one. - * The time complexity of the operation depends on the underlying - * sequence. - * - * Note that no data is returned, and if the first element's data is - * needed, it should be retrieved before pop() is called. - */ - void - pop() { c.pop_back(); } - }; - - + { + // concept requirements + typedef typename _Sequence::value_type _Sequence_value_type; + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept) + __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) + + template<typename _Tp1, typename _Seq1> + friend bool + operator==(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&); + + template<typename _Tp1, typename _Seq1> + friend bool + operator<(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&); + + public: + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + protected: + // See queue::c for notes on this name. + _Sequence c; + + public: + // XXX removed old def ctor, added def arg to this one to match 14882 + /** + * @brief Default constructor creates no elements. + */ + explicit + stack(const _Sequence& __c = _Sequence()) + : c(__c) {} + + /** + * Returns true if the %stack is empty. + */ + bool + empty() const + { return c.empty(); } + + /** Returns the number of elements in the %stack. */ + size_type + size() const + { return c.size(); } + + /** + * Returns a read/write reference to the data at the first + * element of the %stack. + */ + reference + top() + { + __glibcxx_requires_nonempty(); + return c.back(); + } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %stack. + */ + const_reference + top() const + { + __glibcxx_requires_nonempty(); + return c.back(); + } + + /** + * @brief Add data to the top of the %stack. + * @param x Data to be added. + * + * This is a typical %stack operation. The function creates an + * element at the top of the %stack and assigns the given data + * to it. The time complexity of the operation depends on the + * underlying sequence. + */ + void + push(const value_type& __x) + { c.push_back(__x); } + + /** + * @brief Removes first element. + * + * This is a typical %stack operation. It shrinks the %stack + * by one. The time complexity of the operation depends on the + * underlying sequence. + * + * Note that no data is returned, and if the first element's + * data is needed, it should be retrieved before pop() is + * called. + */ + void + pop() + { + __glibcxx_requires_nonempty(); + c.pop_back(); + } + }; + /** * @brief Stack equality comparison. * @param x A %stack. * @param y A %stack of the same type as @a x. * @return True iff the size and elements of the stacks are equal. * - * This is an equivalence relation. Complexity and semantics depend on the - * underlying sequence type, but the expected rules are: this relation is - * linear in the size of the sequences, and stacks are considered equivalent - * if their sequences compare equal. + * This is an equivalence relation. Complexity and semantics + * depend on the underlying sequence type, but the expected rules + * are: this relation is linear in the size of the sequences, and + * stacks are considered equivalent if their sequences compare + * equal. */ - template <typename _Tp, typename _Seq> + template<typename _Tp, typename _Seq> inline bool - operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) + operator==(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) { return __x.c == __y.c; } - + /** * @brief Stack ordering relation. * @param x A %stack. * @param y A %stack of the same type as @a x. - * @return True iff @a x is lexographically less than @a y. + * @return True iff @a x is lexicographically less than @a y. * - * This is an total ordering relation. Complexity and semantics depend on - * the underlying sequence type, but the expected rules are: this relation - * is linear in the size of the sequences, the elements must be comparable - * with @c <, and std::lexographical_compare() is usually used to make the + * This is an total ordering relation. Complexity and semantics + * depend on the underlying sequence type, but the expected rules + * are: this relation is linear in the size of the sequences, the + * elements must be comparable with @c <, and + * std::lexicographical_compare() is usually used to make the * determination. */ - template <typename _Tp, typename _Seq> + template<typename _Tp, typename _Seq> inline bool - operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) + operator<(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) { return __x.c < __y.c; } - + /// Based on operator== - template <typename _Tp, typename _Seq> + template<typename _Tp, typename _Seq> inline bool - operator!=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) + operator!=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) { return !(__x == __y); } - + /// Based on operator< - template <typename _Tp, typename _Seq> + template<typename _Tp, typename _Seq> inline bool - operator>(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) + operator>(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) { return __y < __x; } - + /// Based on operator< - template <typename _Tp, typename _Seq> + template<typename _Tp, typename _Seq> inline bool - operator<=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) + operator<=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) { return !(__y < __x); } - + /// Based on operator< - template <typename _Tp, typename _Seq> + template<typename _Tp, typename _Seq> inline bool - operator>=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) + operator>=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) { return !(__x < __y); } } // namespace std -#endif /* __GLIBCPP_INTERNAL_STACK_H */ +#endif /* _STACK_H */ diff --git a/contrib/libstdc++/include/bits/stl_tempbuf.h b/contrib/libstdc++/include/bits/stl_tempbuf.h index 7b88f9333ec7..399cffb3311c 100644 --- a/contrib/libstdc++/include/bits/stl_tempbuf.h +++ b/contrib/libstdc++/include/bits/stl_tempbuf.h @@ -1,6 +1,6 @@ // Temporary buffer implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,92 +58,114 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_TEMPBUF_H -#define __GLIBCPP_INTERNAL_TEMPBUF_H +#ifndef _TEMPBUF_H +#define _TEMPBUF_H 1 + +#include <memory> namespace std { + /** + * @if maint + * This class is used in two places: stl_algo.h and ext/memory, + * where it is wrapped as the temporary_buffer class. See + * temporary_buffer docs for more notes. + * @endif + */ + template<typename _ForwardIterator, typename _Tp> + class _Temporary_buffer + { + // concept requirements + __glibcxx_class_requires(_ForwardIterator, _ForwardIteratorConcept) + + public: + typedef _Tp value_type; + typedef value_type* pointer; + typedef pointer iterator; + typedef ptrdiff_t size_type; + + protected: + size_type _M_original_len; + size_type _M_len; + pointer _M_buffer; + + void + _M_initialize_buffer(const _Tp&, __true_type) { } + + void + _M_initialize_buffer(const _Tp& val, __false_type) + { std::uninitialized_fill_n(_M_buffer, _M_len, val); } + + public: + /// As per Table mumble. + size_type + size() const + { return _M_len; } + + /// Returns the size requested by the constructor; may be >size(). + size_type + requested_size() const + { return _M_original_len; } + + /// As per Table mumble. + iterator + begin() + { return _M_buffer; } + + /// As per Table mumble. + iterator + end() + { return _M_buffer + _M_len; } + + /** + * Constructs a temporary buffer of a size somewhere between + * zero and the size of the given range. + */ + _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last); + + ~_Temporary_buffer() + { + std::_Destroy(_M_buffer, _M_buffer + _M_len); + std::return_temporary_buffer(_M_buffer); + } -/** - * @if maint - * This class is used in two places: stl_algo.h and ext/memory, where it - * is wrapped as the temporary_buffer class. See temporary_buffer docs for - * more notes. - * @endif -*/ -template <class _ForwardIterator, class _Tp> - class _Temporary_buffer -{ - // concept requirements - __glibcpp_class_requires(_ForwardIterator, _ForwardIteratorConcept) - - ptrdiff_t _M_original_len; - ptrdiff_t _M_len; - _Tp* _M_buffer; - - // this is basically get_temporary_buffer() all over again - void _M_allocate_buffer() { - _M_original_len = _M_len; - _M_buffer = 0; - - if (_M_len > (ptrdiff_t)(INT_MAX / sizeof(_Tp))) - _M_len = INT_MAX / sizeof(_Tp); - - while (_M_len > 0) { - _M_buffer = (_Tp*) malloc(_M_len * sizeof(_Tp)); - if (_M_buffer) - break; - _M_len /= 2; + private: + // Disable copy constructor and assignment operator. + _Temporary_buffer(const _Temporary_buffer&); + + void + operator=(const _Temporary_buffer&); + }; + + + template<typename _ForwardIterator, typename _Tp> + _Temporary_buffer<_ForwardIterator, _Tp>:: + _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) + : _M_original_len(std::distance(__first, __last)), + _M_len(0), _M_buffer(0) + { + // Workaround for a __type_traits bug in the pre-7.3 compiler. + typedef typename __type_traits<_Tp>::has_trivial_default_constructor + _Trivial; + + try + { + pair<pointer, size_type> __p(get_temporary_buffer< + value_type>(_M_original_len)); + _M_buffer = __p.first; + _M_len = __p.second; + if (_M_len > 0) + _M_initialize_buffer(*__first, _Trivial()); + } + catch(...) + { + std::return_temporary_buffer(_M_buffer); + _M_buffer = 0; + _M_len = 0; + __throw_exception_again; + } } - } - - 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: - /// As per Table mumble. - ptrdiff_t size() const { return _M_len; } - /// Returns the size requested by the constructor; may be >size(). - ptrdiff_t requested_size() const { return _M_original_len; } - /// As per Table mumble. - _Tp* begin() { return _M_buffer; } - /// As per Table mumble. - _Tp* end() { return _M_buffer + _M_len; } - - _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) { - // Workaround for a __type_traits bug in the pre-7.3 compiler. - typedef typename __type_traits<_Tp>::has_trivial_default_constructor - _Trivial; - - try { - _M_len = distance(__first, __last); - _M_allocate_buffer(); - if (_M_len > 0) - _M_initialize_buffer(*__first, _Trivial()); - } - catch(...) - { - free(_M_buffer); - _M_buffer = 0; - _M_len = 0; - __throw_exception_again; - } - } - - ~_Temporary_buffer() { - _Destroy(_M_buffer, _M_buffer + _M_len); - free(_M_buffer); - } - -private: - // Disable copy constructor and assignment operator. - _Temporary_buffer(const _Temporary_buffer&) {} - void operator=(const _Temporary_buffer&) {} -}; - } // namespace std -#endif /* __GLIBCPP_INTERNAL_TEMPBUF_H */ +#endif /* _TEMPBUF_H */ diff --git a/contrib/libstdc++/include/bits/stl_threads.h b/contrib/libstdc++/include/bits/stl_threads.h index b21ebdd36d64..04baf0a08f91 100644 --- a/contrib/libstdc++/include/bits/stl_threads.h +++ b/contrib/libstdc++/include/bits/stl_threads.h @@ -1,6 +1,6 @@ // Threading support -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -45,89 +45,28 @@ * You should not attempt to use it directly. */ -#ifndef __SGI_STL_INTERNAL_THREADS_H -#define __SGI_STL_INTERNAL_THREADS_H +#ifndef _STL_THREADS_H +#define _STL_THREADS_H 1 -// The only supported threading model is GCC's own gthr.h abstraction layer. +#include <cstddef> + +// The only supported threading model is GCC's own gthr.h abstraction +// layer. #include "bits/gthr.h" -namespace std +namespace __gnu_internal { - // Class _Refcount_Base provides a type, _RC_t, a data member, - // _M_ref_count, and member functions _M_incr and _M_decr, which perform - // atomic preincrement/predecrement. The constructor initializes - // _M_ref_count. - struct _Refcount_Base - { - // The type _RC_t - typedef size_t _RC_t; - - // The data member _M_ref_count - volatile _RC_t _M_ref_count; - - // Constructor - __gthread_mutex_t _M_ref_count_lock; - - _Refcount_Base(_RC_t __n) : _M_ref_count(__n) - { -#ifdef __GTHREAD_MUTEX_INIT - __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; - _M_ref_count_lock = __tmp; -#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION) - __GTHREAD_MUTEX_INIT_FUNCTION (&_M_ref_count_lock); -#else -#error __GTHREAD_MUTEX_INIT or __GTHREAD_MUTEX_INIT_FUNCTION should be defined by gthr.h abstraction layer, report problem to libstdc++@gcc.gnu.org. -#endif - } - - void - _M_incr() - { - __gthread_mutex_lock(&_M_ref_count_lock); - ++_M_ref_count; - __gthread_mutex_unlock(&_M_ref_count_lock); - } - - _RC_t - _M_decr() - { - __gthread_mutex_lock(&_M_ref_count_lock); - volatile _RC_t __tmp = --_M_ref_count; - __gthread_mutex_unlock(&_M_ref_count_lock); - return __tmp; - } - }; - - // Atomic swap on unsigned long - // This is guaranteed to behave as though it were atomic only if all - // possibly concurrent updates use _Atomic_swap. - // In some cases the operation is emulated with a lock. -#if defined (__GTHREAD_MUTEX_INIT) - // This could be optimized to use the atomicity.h abstraction layer. - // vyzo: simple _Atomic_swap implementation following the guidelines above - // We use a template here only to get a unique initialized instance. - template<int __dummy> - struct _Swap_lock_struct - { static __gthread_mutex_t _S_swap_lock; }; - - template<int __dummy> - __gthread_mutex_t - _Swap_lock_struct<__dummy>::_S_swap_lock = __GTHREAD_MUTEX_INIT; - - // This should be portable, but performance is expected to be quite - // awful. This really needs platform specific code. - inline unsigned long - _Atomic_swap(unsigned long * __p, unsigned long __q) - { - __gthread_mutex_lock(&_Swap_lock_struct<0>::_S_swap_lock); - unsigned long __result = *__p; - *__p = __q; - __gthread_mutex_unlock(&_Swap_lock_struct<0>::_S_swap_lock); - return __result; - } +#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION) + extern __gthread_mutex_t _GLIBCXX_mutex; + extern __gthread_mutex_t *_GLIBCXX_mutex_address; + extern __gthread_once_t _GLIBCXX_once; + extern void _GLIBCXX_mutex_init(void); + extern void _GLIBCXX_mutex_address_init(void); #endif -} //namespace std +} // namespace __gnu_internal +namespace __gnu_cxx +{ // Locking class. Note that this class *does not have a // constructor*. It must be initialized either statically, with // __STL_MUTEX_INITIALIZER, or dynamically, by explicitly calling @@ -140,20 +79,6 @@ namespace std // 8.5.1 of the C++ standard) can be initialized that way. That // means we must have no constructors, no base classes, no virtual // functions, and no private or protected members. - -#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION) -namespace __gnu_cxx -{ - extern __gthread_mutex_t _GLIBCPP_mutex; - extern __gthread_mutex_t *_GLIBCPP_mutex_address; - extern __gthread_once_t _GLIBCPP_once; - extern void _GLIBCPP_mutex_init (void); - extern void _GLIBCPP_mutex_address_init (void); -} -#endif - -namespace std -{ struct _STL_mutex_lock { // The class must be statically initialized with __STL_MUTEX_INITIALIZER. @@ -163,36 +88,36 @@ namespace std #endif __gthread_mutex_t _M_lock; - void - _M_initialize() + void + _M_initialize() { #ifdef __GTHREAD_MUTEX_INIT // There should be no code in this path given the usage rules above. #elif defined(__GTHREAD_MUTEX_INIT_FUNCTION) if (_M_init_flag) return; - if (__gthread_once (&__gnu_cxx::_GLIBCPP_once, - __gnu_cxx::_GLIBCPP_mutex_init) != 0 - && __gthread_active_p ()) + if (__gthread_once(&__gnu_internal::_GLIBCXX_once, + __gnu_internal::_GLIBCXX_mutex_init) != 0 + && __gthread_active_p()) abort (); - __gthread_mutex_lock (&__gnu_cxx::_GLIBCPP_mutex); - if (!_M_init_flag) + __gthread_mutex_lock(&__gnu_internal::_GLIBCXX_mutex); + if (!_M_init_flag) { // Even though we have a global lock, we use __gthread_once to be // absolutely certain the _M_lock mutex is only initialized once on // multiprocessor systems. - __gnu_cxx::_GLIBCPP_mutex_address = &_M_lock; - if (__gthread_once (&_M_once, - __gnu_cxx::_GLIBCPP_mutex_address_init) != 0 - && __gthread_active_p ()) - abort (); + __gnu_internal::_GLIBCXX_mutex_address = &_M_lock; + if (__gthread_once(&_M_once, + __gnu_internal::_GLIBCXX_mutex_address_init) != 0 + && __gthread_active_p()) + abort(); _M_init_flag = 1; } - __gthread_mutex_unlock (&__gnu_cxx::_GLIBCPP_mutex); + __gthread_mutex_unlock(&__gnu_internal::_GLIBCXX_mutex); #endif } - void - _M_acquire_lock() + void + _M_acquire_lock() { #if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION) if (!_M_init_flag) _M_initialize(); @@ -200,8 +125,8 @@ namespace std __gthread_mutex_lock(&_M_lock); } - void - _M_release_lock() + void + _M_release_lock() { #if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION) if (!_M_init_flag) _M_initialize(); @@ -209,7 +134,7 @@ namespace std __gthread_mutex_unlock(&_M_lock); } }; - + #ifdef __GTHREAD_MUTEX_INIT #define __STL_MUTEX_INITIALIZER = { __GTHREAD_MUTEX_INIT } #elif defined(__GTHREAD_MUTEX_INIT_FUNCTION) @@ -220,25 +145,6 @@ namespace std #define __STL_MUTEX_INITIALIZER = { 0, __GTHREAD_ONCE_INIT } #endif #endif +} // namespace __gnu_cxx - // A locking class that uses _STL_mutex_lock. The constructor takes a - // reference to an _STL_mutex_lock, and acquires a lock. The - // destructor releases the lock. It's not clear that this is exactly - // the right functionality. It will probably change in the future. - struct _STL_auto_lock - { - _STL_mutex_lock& _M_lock; - - _STL_auto_lock(_STL_mutex_lock& __lock) : _M_lock(__lock) - { _M_lock._M_acquire_lock(); } - - ~_STL_auto_lock() { _M_lock._M_release_lock(); } - - private: - void operator=(const _STL_auto_lock&); - _STL_auto_lock(const _STL_auto_lock&); - }; - -} // namespace std - -#endif +#endif diff --git a/contrib/libstdc++/include/bits/stl_tree.h b/contrib/libstdc++/include/bits/stl_tree.h index 1e7fdf5db2da..ac9add899b92 100644 --- a/contrib/libstdc++/include/bits/stl_tree.h +++ b/contrib/libstdc++/include/bits/stl_tree.h @@ -1,6 +1,6 @@ // RB tree implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -60,60 +60,72 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_TREE_H -#define __GLIBCPP_INTERNAL_TREE_H - -/* - -Red-black tree class, designed for use in implementing STL -associative containers (set, multiset, map, and multimap). The -insertion and deletion algorithms are based on those in Cormen, -Leiserson, and Rivest, Introduction to Algorithms (MIT Press, 1990), -except that - -(1) the header cell is maintained with links not only to the root -but also to the leftmost node of the tree, to enable constant time -begin(), and to the rightmost node of the tree, to enable linear time -performance when used with the generic set algorithms (set_union, -etc.); - -(2) when a node being deleted has two children its successor node is -relinked into its place, rather than copied, so that the only -iterators invalidated are those referring to the deleted node. - -*/ +#ifndef _TREE_H +#define _TREE_H 1 #include <bits/stl_algobase.h> -#include <bits/stl_alloc.h> +#include <bits/allocator.h> #include <bits/stl_construct.h> #include <bits/stl_function.h> +#include <bits/cpp_type_traits.h> namespace std -{ - enum _Rb_tree_color { _M_red = false, _M_black = true }; +{ + // Red-black tree class, designed for use in implementing STL + // associative containers (set, multiset, map, and multimap). The + // insertion and deletion algorithms are based on those in Cormen, + // Leiserson, and Rivest, Introduction to Algorithms (MIT Press, + // 1990), except that + // + // (1) the header cell is maintained with links not only to the root + // but also to the leftmost node of the tree, to enable constant + // time begin(), and to the rightmost node of the tree, to enable + // linear time performance when used with the generic set algorithms + // (set_union, etc.) + // + // (2) when a node being deleted has two children its successor node + // is relinked into its place, rather than copied, so that the only + // iterators invalidated are those referring to the deleted node. + + enum _Rb_tree_color { _S_red = false, _S_black = true }; struct _Rb_tree_node_base { typedef _Rb_tree_node_base* _Base_ptr; - - _Rb_tree_color _M_color; - _Base_ptr _M_parent; - _Base_ptr _M_left; - _Base_ptr _M_right; - - static _Base_ptr + typedef const _Rb_tree_node_base* _Const_Base_ptr; + + _Rb_tree_color _M_color; + _Base_ptr _M_parent; + _Base_ptr _M_left; + _Base_ptr _M_right; + + static _Base_ptr _S_minimum(_Base_ptr __x) { while (__x->_M_left != 0) __x = __x->_M_left; return __x; } - static _Base_ptr + static _Const_Base_ptr + _S_minimum(_Const_Base_ptr __x) + { + while (__x->_M_left != 0) __x = __x->_M_left; + return __x; + } + + static _Base_ptr _S_maximum(_Base_ptr __x) { while (__x->_M_right != 0) __x = __x->_M_right; return __x; } + + static _Const_Base_ptr + _S_maximum(_Const_Base_ptr __x) + { + while (__x->_M_right != 0) __x = __x->_M_right; + return __x; + } }; template<typename _Val> @@ -122,475 +134,203 @@ namespace std typedef _Rb_tree_node<_Val>* _Link_type; _Val _M_value_field; }; - - struct _Rb_tree_base_iterator - { - typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; - typedef bidirectional_iterator_tag iterator_category; - typedef ptrdiff_t difference_type; - _Base_ptr _M_node; + _Rb_tree_node_base* + _Rb_tree_increment(_Rb_tree_node_base* __x); - void - _M_increment() - { - if (_M_node->_M_right != 0) - { - _M_node = _M_node->_M_right; - while (_M_node->_M_left != 0) - _M_node = _M_node->_M_left; - } - else - { - _Base_ptr __y = _M_node->_M_parent; - while (_M_node == __y->_M_right) - { - _M_node = __y; - __y = __y->_M_parent; - } - if (_M_node->_M_right != __y) - _M_node = __y; - } - } + const _Rb_tree_node_base* + _Rb_tree_increment(const _Rb_tree_node_base* __x); - void - _M_decrement() - { - if (_M_node->_M_color == _M_red - && _M_node->_M_parent->_M_parent == _M_node) - _M_node = _M_node->_M_right; - else if (_M_node->_M_left != 0) - { - _Base_ptr __y = _M_node->_M_left; - while (__y->_M_right != 0) - __y = __y->_M_right; - _M_node = __y; - } - else - { - _Base_ptr __y = _M_node->_M_parent; - while (_M_node == __y->_M_left) - { - _M_node = __y; - __y = __y->_M_parent; - } - _M_node = __y; - } - } - }; + _Rb_tree_node_base* + _Rb_tree_decrement(_Rb_tree_node_base* __x); - template<typename _Val, typename _Ref, typename _Ptr> - struct _Rb_tree_iterator : public _Rb_tree_base_iterator + const _Rb_tree_node_base* + _Rb_tree_decrement(const _Rb_tree_node_base* __x); + + template<typename _Tp> + struct _Rb_tree_iterator { - typedef _Val value_type; - typedef _Ref reference; - typedef _Ptr pointer; - typedef _Rb_tree_iterator<_Val, _Val&, _Val*> iterator; - typedef _Rb_tree_iterator<_Val, const _Val&, const _Val*> - const_iterator; - typedef _Rb_tree_iterator<_Val, _Ref, _Ptr> _Self; - typedef _Rb_tree_node<_Val>* _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; } - - pointer - operator->() const { return &(operator*()); } - - _Self& - operator++() - { - _M_increment(); - return *this; + typedef _Tp value_type; + typedef _Tp& reference; + typedef _Tp* pointer; + + typedef bidirectional_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; + + typedef _Rb_tree_iterator<_Tp> _Self; + typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; + typedef _Rb_tree_node<_Tp>* _Link_type; + + _Rb_tree_iterator() { } + + _Rb_tree_iterator(_Link_type __x) + : _M_node(__x) { } + + reference + operator*() const + { return static_cast<_Link_type>(_M_node)->_M_value_field; } + + pointer + operator->() const + { return &static_cast<_Link_type>(_M_node)->_M_value_field; } + + _Self& + operator++() + { + _M_node = _Rb_tree_increment(_M_node); + return *this; } - _Self - operator++(int) + _Self + operator++(int) { _Self __tmp = *this; - _M_increment(); + _M_node = _Rb_tree_increment(_M_node); return __tmp; } - - _Self& - operator--() { _M_decrement(); return *this; } - _Self - operator--(int) + _Self& + operator--() + { + _M_node = _Rb_tree_decrement(_M_node); + return *this; + } + + _Self + operator--(int) { _Self __tmp = *this; - _M_decrement(); + _M_node = _Rb_tree_decrement(_M_node); return __tmp; } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + _Base_ptr _M_node; }; - template<typename _Val, typename _Ref, typename _Ptr> - inline bool - operator==(const _Rb_tree_iterator<_Val, _Ref, _Ptr>& __x, - const _Rb_tree_iterator<_Val, _Ref, _Ptr>& __y) - { return __x._M_node == __y._M_node; } + template<typename _Tp> + struct _Rb_tree_const_iterator + { + typedef _Tp value_type; + typedef const _Tp& reference; + typedef const _Tp* pointer; - template<typename _Val> - inline bool - operator==(const _Rb_tree_iterator<_Val, const _Val&, const _Val*>& __x, - const _Rb_tree_iterator<_Val, _Val&, _Val*>& __y) - { return __x._M_node == __y._M_node; } + typedef _Rb_tree_iterator<_Tp> iterator; - template<typename _Val> - inline bool - operator==(const _Rb_tree_iterator<_Val, _Val&, _Val*>& __x, - const _Rb_tree_iterator<_Val, const _Val&, const _Val*>& __y) - { return __x._M_node == __y._M_node; } + typedef bidirectional_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; - template<typename _Val, typename _Ref, typename _Ptr> - inline bool - operator!=(const _Rb_tree_iterator<_Val, _Ref, _Ptr>& __x, - const _Rb_tree_iterator<_Val, _Ref, _Ptr>& __y) - { return __x._M_node != __y._M_node; } + typedef _Rb_tree_const_iterator<_Tp> _Self; + typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr; + typedef const _Rb_tree_node<_Tp>* _Link_type; - template<typename _Val> - inline bool - operator!=(const _Rb_tree_iterator<_Val, const _Val&, const _Val*>& __x, - const _Rb_tree_iterator<_Val, _Val&, _Val*>& __y) - { return __x._M_node != __y._M_node; } + _Rb_tree_const_iterator() { } - template<typename _Val> - inline bool - operator!=(const _Rb_tree_iterator<_Val, _Val&, _Val*>& __x, - const _Rb_tree_iterator<_Val, const _Val&, const _Val*>& __y) - { return __x._M_node != __y._M_node; } + _Rb_tree_const_iterator(_Link_type __x) + : _M_node(__x) { } - inline void - _Rb_tree_rotate_left(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) - { - _Rb_tree_node_base* __y = __x->_M_right; - __x->_M_right = __y->_M_left; - if (__y->_M_left !=0) - __y->_M_left->_M_parent = __x; - __y->_M_parent = __x->_M_parent; - - if (__x == __root) - __root = __y; - else if (__x == __x->_M_parent->_M_left) - __x->_M_parent->_M_left = __y; - else - __x->_M_parent->_M_right = __y; - __y->_M_left = __x; - __x->_M_parent = __y; - } - - inline void - _Rb_tree_rotate_right(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) - { - _Rb_tree_node_base* __y = __x->_M_left; - __x->_M_left = __y->_M_right; - if (__y->_M_right != 0) - __y->_M_right->_M_parent = __x; - __y->_M_parent = __x->_M_parent; - - if (__x == __root) - __root = __y; - else if (__x == __x->_M_parent->_M_right) - __x->_M_parent->_M_right = __y; - else - __x->_M_parent->_M_left = __y; - __y->_M_right = __x; - __x->_M_parent = __y; - } - - inline void - _Rb_tree_rebalance(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) - { - __x->_M_color = _M_red; - while (__x != __root - && __x->_M_parent->_M_color == _M_red) + _Rb_tree_const_iterator(const iterator& __it) + : _M_node(__it._M_node) { } + + reference + operator*() const + { return static_cast<_Link_type>(_M_node)->_M_value_field; } + + pointer + operator->() const + { return &static_cast<_Link_type>(_M_node)->_M_value_field; } + + _Self& + operator++() { - 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 == _M_red) - { - __x->_M_parent->_M_color = _M_black; - __y->_M_color = _M_black; - __x->_M_parent->_M_parent->_M_color = _M_red; - __x = __x->_M_parent->_M_parent; - } - else - { - if (__x == __x->_M_parent->_M_right) - { - __x = __x->_M_parent; - _Rb_tree_rotate_left(__x, __root); - } - __x->_M_parent->_M_color = _M_black; - __x->_M_parent->_M_parent->_M_color = _M_red; - _Rb_tree_rotate_right(__x->_M_parent->_M_parent, __root); - } - } - else - { - _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_left; - if (__y && __y->_M_color == _M_red) - { - __x->_M_parent->_M_color = _M_black; - __y->_M_color = _M_black; - __x->_M_parent->_M_parent->_M_color = _M_red; - __x = __x->_M_parent->_M_parent; - } - else - { - if (__x == __x->_M_parent->_M_left) - { - __x = __x->_M_parent; - _Rb_tree_rotate_right(__x, __root); - } - __x->_M_parent->_M_color = _M_black; - __x->_M_parent->_M_parent->_M_color = _M_red; - _Rb_tree_rotate_left(__x->_M_parent->_M_parent, __root); - } - } + _M_node = _Rb_tree_increment(_M_node); + return *this; } - __root->_M_color = _M_black; - } - - inline _Rb_tree_node_base* - _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* __z, - _Rb_tree_node_base*& __root, - _Rb_tree_node_base*& __leftmost, - _Rb_tree_node_base*& __rightmost) - { - _Rb_tree_node_base* __y = __z; - _Rb_tree_node_base* __x = 0; - _Rb_tree_node_base* __x_parent = 0; - if (__y->_M_left == 0) // __z has at most one non-null child. y == z. - __x = __y->_M_right; // __x might be null. - else - if (__y->_M_right == 0) // __z has exactly one non-null child. y == z. - __x = __y->_M_left; // __x is not null. - else - { - // __z has two non-null children. Set __y to - __y = __y->_M_right; // __z's successor. __x might be null. - while (__y->_M_left != 0) - __y = __y->_M_left; - __x = __y->_M_right; - } - if (__y != __z) + + _Self + operator++(int) { - // relink y in place of z. y is z's successor - __z->_M_left->_M_parent = __y; - __y->_M_left = __z->_M_left; - if (__y != __z->_M_right) - { - __x_parent = __y->_M_parent; - if (__x) __x->_M_parent = __y->_M_parent; - __y->_M_parent->_M_left = __x; // __y must be a child of _M_left - __y->_M_right = __z->_M_right; - __z->_M_right->_M_parent = __y; - } - else - __x_parent = __y; - if (__root == __z) - __root = __y; - else if (__z->_M_parent->_M_left == __z) - __z->_M_parent->_M_left = __y; - else - __z->_M_parent->_M_right = __y; - __y->_M_parent = __z->_M_parent; - std::swap(__y->_M_color, __z->_M_color); - __y = __z; - // __y now points to node to be actually deleted - } - else - { // __y == __z - __x_parent = __y->_M_parent; - if (__x) - __x->_M_parent = __y->_M_parent; - if (__root == __z) - __root = __x; - else - if (__z->_M_parent->_M_left == __z) - __z->_M_parent->_M_left = __x; - else - __z->_M_parent->_M_right = __x; - if (__leftmost == __z) - if (__z->_M_right == 0) // __z->_M_left must be null also - __leftmost = __z->_M_parent; - // makes __leftmost == _M_header if __z == __root - else - __leftmost = _Rb_tree_node_base::_S_minimum(__x); - if (__rightmost == __z) - if (__z->_M_left == 0) // __z->_M_right must be null also - __rightmost = __z->_M_parent; - // makes __rightmost == _M_header if __z == __root - else // __x == __z->_M_left - __rightmost = _Rb_tree_node_base::_S_maximum(__x); - } - if (__y->_M_color != _M_red) - { - while (__x != __root && (__x == 0 || __x->_M_color == _M_black)) - if (__x == __x_parent->_M_left) - { - _Rb_tree_node_base* __w = __x_parent->_M_right; - if (__w->_M_color == _M_red) - { - __w->_M_color = _M_black; - __x_parent->_M_color = _M_red; - _Rb_tree_rotate_left(__x_parent, __root); - __w = __x_parent->_M_right; - } - if ((__w->_M_left == 0 || - __w->_M_left->_M_color == _M_black) && - (__w->_M_right == 0 || - __w->_M_right->_M_color == _M_black)) - { - __w->_M_color = _M_red; - __x = __x_parent; - __x_parent = __x_parent->_M_parent; - } - else - { - if (__w->_M_right == 0 - || __w->_M_right->_M_color == _M_black) - { - __w->_M_left->_M_color = _M_black; - __w->_M_color = _M_red; - _Rb_tree_rotate_right(__w, __root); - __w = __x_parent->_M_right; - } - __w->_M_color = __x_parent->_M_color; - __x_parent->_M_color = _M_black; - if (__w->_M_right) - __w->_M_right->_M_color = _M_black; - _Rb_tree_rotate_left(__x_parent, __root); - break; - } - } - else - { - // same as above, with _M_right <-> _M_left. - _Rb_tree_node_base* __w = __x_parent->_M_left; - if (__w->_M_color == _M_red) - { - __w->_M_color = _M_black; - __x_parent->_M_color = _M_red; - _Rb_tree_rotate_right(__x_parent, __root); - __w = __x_parent->_M_left; - } - if ((__w->_M_right == 0 || - __w->_M_right->_M_color == _M_black) && - (__w->_M_left == 0 || - __w->_M_left->_M_color == _M_black)) - { - __w->_M_color = _M_red; - __x = __x_parent; - __x_parent = __x_parent->_M_parent; - } - else - { - if (__w->_M_left == 0 || __w->_M_left->_M_color == _M_black) - { - __w->_M_right->_M_color = _M_black; - __w->_M_color = _M_red; - _Rb_tree_rotate_left(__w, __root); - __w = __x_parent->_M_left; - } - __w->_M_color = __x_parent->_M_color; - __x_parent->_M_color = _M_black; - if (__w->_M_left) - __w->_M_left->_M_color = _M_black; - _Rb_tree_rotate_right(__x_parent, __root); - break; - } - } - if (__x) __x->_M_color = _M_black; + _Self __tmp = *this; + _M_node = _Rb_tree_increment(_M_node); + return __tmp; } - return __y; - } - // Base class to encapsulate the differences between old SGI-style - // allocators and standard-conforming allocators. In order to avoid - // having an empty base class, we arbitrarily move one of rb_tree's - // data members into the base class. + _Self& + operator--() + { + _M_node = _Rb_tree_decrement(_M_node); + return *this; + } - // _Base for general standard-conforming allocators. - template<typename _Tp, typename _Alloc, bool _S_instanceless> - class _Rb_tree_alloc_base - { - public: - typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_decrement(_M_node); + return __tmp; + } - allocator_type - get_allocator() const { return _M_node_allocator; } + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } - _Rb_tree_alloc_base(const allocator_type& __a) - : _M_node_allocator(__a), _M_header(0) {} + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } - protected: - typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::allocator_type - _M_node_allocator; + _Base_ptr _M_node; + }; - _Rb_tree_node<_Tp>* _M_header; - - _Rb_tree_node<_Tp>* - _M_get_node() { return _M_node_allocator.allocate(1); } + template<typename _Val> + inline bool + operator==(const _Rb_tree_iterator<_Val>& __x, + const _Rb_tree_const_iterator<_Val>& __y) + { return __x._M_node == __y._M_node; } - void - _M_put_node(_Rb_tree_node<_Tp>* __p) - { _M_node_allocator.deallocate(__p, 1); } - }; + template<typename _Val> + inline bool + operator!=(const _Rb_tree_iterator<_Val>& __x, + const _Rb_tree_const_iterator<_Val>& __y) + { return __x._M_node != __y._M_node; } - // Specialization for instanceless allocators. - template<typename _Tp, typename _Alloc> - class _Rb_tree_alloc_base<_Tp, _Alloc, true> - { - public: - typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; - allocator_type get_allocator() const { return allocator_type(); } + void + _Rb_tree_rotate_left(_Rb_tree_node_base* const __x, + _Rb_tree_node_base*& __root); - _Rb_tree_alloc_base(const allocator_type&) : _M_header(0) {} + void + _Rb_tree_rotate_right(_Rb_tree_node_base* const __x, + _Rb_tree_node_base*& __root); - 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<typename _Tp, typename _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; + void + _Rb_tree_insert_and_rebalance(const bool __insert_left, + _Rb_tree_node_base* __x, + _Rb_tree_node_base* __p, + _Rb_tree_node_base& __header); - _Rb_tree_base(const allocator_type& __a) - : _Base(__a) { _M_header = _M_get_node(); } - ~_Rb_tree_base() { _M_put_node(_M_header); } - }; + _Rb_tree_node_base* + _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z, + _Rb_tree_node_base& __header); - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc = allocator<_Val> > - class _Rb_tree : protected _Rb_tree_base<_Val, _Alloc> + class _Rb_tree { - typedef _Rb_tree_base<_Val, _Alloc> _Base; - + typedef typename _Alloc::template rebind<_Rb_tree_node<_Val> >::other + _Node_allocator; + protected: typedef _Rb_tree_node_base* _Base_ptr; + typedef const _Rb_tree_node_base* _Const_Base_ptr; typedef _Rb_tree_node<_Val> _Rb_tree_node; - + public: typedef _Key key_type; typedef _Val value_type; @@ -599,33 +339,40 @@ namespace std typedef value_type& reference; typedef const value_type& const_reference; typedef _Rb_tree_node* _Link_type; + typedef const _Rb_tree_node* _Const_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(); } - + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const + { return *static_cast<const _Node_allocator*>(&this->_M_impl); } + protected: - using _Base::_M_get_node; - using _Base::_M_put_node; - using _Base::_M_header; - + _Rb_tree_node* + _M_get_node() + { return _M_impl._Node_allocator::allocate(1); } + + void + _M_put_node(_Rb_tree_node* __p) + { _M_impl._Node_allocator::deallocate(__p, 1); } + _Link_type _M_create_node(const value_type& __x) { _Link_type __tmp = _M_get_node(); - try - { _Construct(&__tmp->_M_value_field, __x); } + try + { std::_Construct(&__tmp->_M_value_field, __x); } catch(...) { - _M_put_node(__tmp); - __throw_exception_again; + _M_put_node(__tmp); + __throw_exception_again; } return __tmp; } - - _Link_type - _M_clone_node(_Link_type __x) + + _Link_type + _M_clone_node(_Const_Link_type __x) { _Link_type __tmp = _M_create_node(__x->_M_value_field); __tmp->_M_color = __x->_M_color; @@ -637,512 +384,598 @@ namespace std void destroy_node(_Link_type __p) { - _Destroy(&__p->_M_value_field); + std::_Destroy(&__p->_M_value_field); _M_put_node(__p); } - size_type _M_node_count; // keeps track of size of tree - _Compare _M_key_compare; + protected: + template<typename _Key_compare, + bool _Is_pod_comparator = std::__is_pod<_Key_compare>::_M_type> + struct _Rb_tree_impl : public _Node_allocator + { + _Key_compare _M_key_compare; + _Rb_tree_node_base _M_header; + size_type _M_node_count; // Keeps track of size of tree. + + _Rb_tree_impl(const _Node_allocator& __a = _Node_allocator(), + const _Key_compare& __comp = _Key_compare()) + : _Node_allocator(__a), _M_key_compare(__comp), _M_node_count(0) + { + this->_M_header._M_color = _S_red; + this->_M_header._M_parent = 0; + this->_M_header._M_left = &this->_M_header; + this->_M_header._M_right = &this->_M_header; + } + }; + + // Specialization for _Comparison types that are not capable of + // being base classes / super classes. + template<typename _Key_compare> + struct _Rb_tree_impl<_Key_compare, true> : public _Node_allocator + { + _Key_compare _M_key_compare; + _Rb_tree_node_base _M_header; + size_type _M_node_count; // Keeps track of size of tree. + + _Rb_tree_impl(const _Node_allocator& __a = _Node_allocator(), + const _Key_compare& __comp = _Key_compare()) + : _Node_allocator(__a), _M_key_compare(__comp), _M_node_count(0) + { + this->_M_header._M_color = _S_red; + this->_M_header._M_parent = 0; + this->_M_header._M_left = &this->_M_header; + this->_M_header._M_right = &this->_M_header; + } + }; - _Link_type& - _M_root() const { return (_Link_type&) _M_header->_M_parent; } + _Rb_tree_impl<_Compare> _M_impl; - _Link_type& - _M_leftmost() const { return (_Link_type&) _M_header->_M_left; } + protected: + _Base_ptr& + _M_root() + { return this->_M_impl._M_header._M_parent; } + + _Const_Base_ptr + _M_root() const + { return this->_M_impl._M_header._M_parent; } + + _Base_ptr& + _M_leftmost() + { return this->_M_impl._M_header._M_left; } + + _Const_Base_ptr + _M_leftmost() const + { return this->_M_impl._M_header._M_left; } + + _Base_ptr& + _M_rightmost() + { return this->_M_impl._M_header._M_right; } + + _Const_Base_ptr + _M_rightmost() const + { return this->_M_impl._M_header._M_right; } + + _Link_type + _M_begin() + { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); } - _Link_type& - _M_rightmost() const { return (_Link_type&) _M_header->_M_right; } + _Const_Link_type + _M_begin() const + { return static_cast<_Const_Link_type>(this->_M_impl._M_header._M_parent); } - static _Link_type& - _S_left(_Link_type __x) { return (_Link_type&)(__x->_M_left); } + _Link_type + _M_end() + { return static_cast<_Link_type>(&this->_M_impl._M_header); } - static _Link_type& - _S_right(_Link_type __x) { return (_Link_type&)(__x->_M_right); } + _Const_Link_type + _M_end() const + { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); } - static _Link_type& - _S_parent(_Link_type __x) { return (_Link_type&)(__x->_M_parent); } + static const_reference + _S_value(_Const_Link_type __x) + { return __x->_M_value_field; } - static reference - _S_value(_Link_type __x) { return __x->_M_value_field; } + static const _Key& + _S_key(_Const_Link_type __x) + { return _KeyOfValue()(_S_value(__x)); } - static const _Key& - _S_key(_Link_type __x) { return _KeyOfValue()(_S_value(__x)); } + static _Link_type + _S_left(_Base_ptr __x) + { return static_cast<_Link_type>(__x->_M_left); } - static _Rb_tree_color& - _S_color(_Link_type __x) { return __x->_M_color; } + static _Const_Link_type + _S_left(_Const_Base_ptr __x) + { return static_cast<_Const_Link_type>(__x->_M_left); } - static _Link_type& - _S_left(_Base_ptr __x) { return (_Link_type&)(__x->_M_left); } + static _Link_type + _S_right(_Base_ptr __x) + { return static_cast<_Link_type>(__x->_M_right); } - static _Link_type& - _S_right(_Base_ptr __x) { return (_Link_type&)(__x->_M_right); } + static _Const_Link_type + _S_right(_Const_Base_ptr __x) + { return static_cast<_Const_Link_type>(__x->_M_right); } - static _Link_type& - _S_parent(_Base_ptr __x) { return (_Link_type&)(__x->_M_parent); } + static const_reference + _S_value(_Const_Base_ptr __x) + { return static_cast<_Const_Link_type>(__x)->_M_value_field; } - static reference - _S_value(_Base_ptr __x) { return ((_Link_type)__x)->_M_value_field; } + static const _Key& + _S_key(_Const_Base_ptr __x) + { return _KeyOfValue()(_S_value(__x)); } - static const _Key& - _S_key(_Base_ptr __x) { return _KeyOfValue()(_S_value(_Link_type(__x)));} + static _Base_ptr + _S_minimum(_Base_ptr __x) + { return _Rb_tree_node_base::_S_minimum(__x); } - static _Rb_tree_color& - _S_color(_Base_ptr __x) { return (_Link_type(__x)->_M_color); } + static _Const_Base_ptr + _S_minimum(_Const_Base_ptr __x) + { return _Rb_tree_node_base::_S_minimum(__x); } - static _Link_type - _S_minimum(_Link_type __x) - { return (_Link_type) _Rb_tree_node_base::_S_minimum(__x); } + static _Base_ptr + _S_maximum(_Base_ptr __x) + { return _Rb_tree_node_base::_S_maximum(__x); } - static _Link_type - _S_maximum(_Link_type __x) - { return (_Link_type) _Rb_tree_node_base::_S_maximum(__x); } + static _Const_Base_ptr + _S_maximum(_Const_Base_ptr __x) + { return _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> - const_iterator; + typedef _Rb_tree_iterator<value_type> iterator; + typedef _Rb_tree_const_iterator<value_type> const_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - typedef std::reverse_iterator<iterator> reverse_iterator; private: - iterator + iterator _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v); - _Link_type - _M_copy(_Link_type __x, _Link_type __p); + _Link_type + _M_copy(_Const_Link_type __x, _Link_type __p); - void + void _M_erase(_Link_type __x); public: // allocation/deallocation _Rb_tree() - : _Base(allocator_type()), _M_node_count(0), _M_key_compare() - { _M_empty_initialize(); } + { } _Rb_tree(const _Compare& __comp) - : _Base(allocator_type()), _M_node_count(0), _M_key_compare(__comp) - { _M_empty_initialize(); } + : _M_impl(allocator_type(), __comp) + { } _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,_Val,_KeyOfValue,_Compare,_Alloc>& __x) - : _Base(__x.get_allocator()), _M_node_count(0), - _M_key_compare(__x._M_key_compare) - { - if (__x._M_root() == 0) - _M_empty_initialize(); - else + : _M_impl(__a, __comp) + { } + + _Rb_tree(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x) + : _M_impl(__x.get_allocator(), __x._M_impl._M_key_compare) + { + if (__x._M_root() != 0) { - _S_color(_M_header) = _M_red; - _M_root() = _M_copy(__x._M_root(), _M_header); + _M_root() = _M_copy(__x._M_begin(), _M_end()); _M_leftmost() = _S_minimum(_M_root()); _M_rightmost() = _S_maximum(_M_root()); + _M_impl._M_node_count = __x._M_impl._M_node_count; } - _M_node_count = __x._M_node_count; } - ~_Rb_tree() { clear(); } + ~_Rb_tree() + { _M_erase(_M_begin()); } - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& operator=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x); - private: - void _M_empty_initialize() - { - _S_color(_M_header) = _M_red; // used to distinguish header from - // __root, in iterator.operator++ - _M_root() = 0; - _M_leftmost() = _M_header; - _M_rightmost() = _M_header; - } - - public: // Accessors. - _Compare - key_comp() const { return _M_key_compare; } + _Compare + key_comp() const + { return _M_impl._M_key_compare; } - iterator - begin() { return _M_leftmost(); } + iterator + begin() + { return static_cast<_Link_type>(this->_M_impl._M_header._M_left); } - const_iterator - begin() const { return _M_leftmost(); } + const_iterator + begin() const + { return static_cast<_Const_Link_type>(this->_M_impl._M_header._M_left); } - iterator - end() { return _M_header; } + iterator + end() + { return static_cast<_Link_type>(&this->_M_impl._M_header); } - const_iterator - end() const { return _M_header; } + const_iterator + end() const + { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); } - reverse_iterator - rbegin() { return reverse_iterator(end()); } + reverse_iterator + rbegin() + { return reverse_iterator(end()); } - const_reverse_iterator - rbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } - reverse_iterator - rend() { return reverse_iterator(begin()); } + reverse_iterator + rend() + { return reverse_iterator(begin()); } - const_reverse_iterator - rend() const { return const_reverse_iterator(begin()); } - - bool - empty() const { return _M_node_count == 0; } + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } - size_type - size() const { return _M_node_count; } + bool + empty() const + { return _M_impl._M_node_count == 0; } - size_type - max_size() const { return size_type(-1); } + size_type + size() const + { return _M_impl._M_node_count; } + + size_type + max_size() const + { return size_type(-1); } + + void + swap(_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __t); - void - swap(_Rb_tree<_Key,_Val,_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); - } - // Insert/erase. - pair<iterator,bool> + pair<iterator,bool> insert_unique(const value_type& __x); - iterator + iterator insert_equal(const value_type& __x); - iterator + iterator insert_unique(iterator __position, const value_type& __x); - iterator + iterator insert_equal(iterator __position, const value_type& __x); template<typename _InputIterator> - void + void insert_unique(_InputIterator __first, _InputIterator __last); template<typename _InputIterator> - void + void insert_equal(_InputIterator __first, _InputIterator __last); - void + void erase(iterator __position); - size_type + size_type erase(const key_type& __x); - void + void erase(iterator __first, iterator __last); - void + void erase(const key_type* __first, const key_type* __last); - void - clear() + void + clear() { - if (_M_node_count != 0) - { - _M_erase(_M_root()); - _M_leftmost() = _M_header; - _M_root() = 0; - _M_rightmost() = _M_header; - _M_node_count = 0; - } - } + _M_erase(_M_begin()); + _M_leftmost() = _M_end(); + _M_root() = 0; + _M_rightmost() = _M_end(); + _M_impl._M_node_count = 0; + } // Set operations. - iterator + iterator find(const key_type& __x); - const_iterator + const_iterator find(const key_type& __x) const; - size_type + size_type count(const key_type& __x) const; - iterator + iterator lower_bound(const key_type& __x); - const_iterator + const_iterator lower_bound(const key_type& __x) const; - iterator + iterator upper_bound(const key_type& __x); - const_iterator + const_iterator upper_bound(const key_type& __x) const; - pair<iterator,iterator> + pair<iterator,iterator> equal_range(const key_type& __x); - pair<const_iterator, const_iterator> + pair<const_iterator, const_iterator> equal_range(const key_type& __x) const; // Debugging. - bool + bool __rb_verify() const; }; - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - inline bool - operator==(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + inline bool + operator==(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) { - return __x.size() == __y.size() && - equal(__x.begin(), __x.end(), __y.begin()); + return __x.size() == __y.size() + && equal(__x.begin(), __x.end(), __y.begin()); } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - inline bool - operator<(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + inline bool + operator<(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) { - return lexicographical_compare(__x.begin(), __x.end(), + return lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - inline bool - operator!=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, - const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + inline bool + operator!=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) { return !(__x == __y); } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - inline bool - operator>(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, - const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + inline bool + operator>(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) { return __y < __x; } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - inline bool - operator<=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, - const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) - { return !(__y < __x); } + inline bool + operator<=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { return !(__y < __x); } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - inline bool - operator>=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, - const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) - { return !(__x < __y); } + inline bool + operator>=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + { return !(__x < __y); } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - inline void - swap(_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, + inline void + swap(_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) { __x.swap(__y); } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: operator=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x) { - if (this != &__x) + if (this != &__x) { // Note that _Key may be a constant type. clear(); - _M_node_count = 0; - _M_key_compare = __x._M_key_compare; - if (__x._M_root() == 0) - { - _M_root() = 0; - _M_leftmost() = _M_header; - _M_rightmost() = _M_header; - } - else + _M_impl._M_key_compare = __x._M_impl._M_key_compare; + if (__x._M_root() != 0) { - _M_root() = _M_copy(__x._M_root(), _M_header); + _M_root() = _M_copy(__x._M_begin(), _M_end()); _M_leftmost() = _S_minimum(_M_root()); _M_rightmost() = _S_maximum(_M_root()); - _M_node_count = __x._M_node_count; + _M_impl._M_node_count = __x._M_impl._M_node_count; } } return *this; } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: - _M_insert(_Base_ptr __x_, _Base_ptr __y_, const _Val& __v) + _M_insert(_Base_ptr __x, _Base_ptr __p, const _Val& __v) { - _Link_type __x = (_Link_type) __x_; - _Link_type __y = (_Link_type) __y_; - _Link_type __z; - - if (__y == _M_header || __x != 0 || - _M_key_compare(_KeyOfValue()(__v), _S_key(__y))) - { - __z = _M_create_node(__v); - _S_left(__y) = __z; // also makes _M_leftmost() = __z - // when __y == _M_header - if (__y == _M_header) - { - _M_root() = __z; - _M_rightmost() = __z; - } - else if (__y == _M_leftmost()) - _M_leftmost() = __z; // maintain _M_leftmost() pointing to min node - } - else - { - __z = _M_create_node(__v); - _S_right(__y) = __z; - // Maintain _M_rightmost() pointing to max node. - if (__y == _M_rightmost()) - _M_rightmost() = __z; - } - _S_parent(__z) = __y; - _S_left(__z) = 0; - _S_right(__z) = 0; - _Rb_tree_rebalance(__z, _M_header->_M_parent); - ++_M_node_count; + _Link_type __z = _M_create_node(__v); + bool __insert_left; + + __insert_left = __x != 0 || __p == _M_end() + || _M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__p)); + + _Rb_tree_insert_and_rebalance(__insert_left, __z, __p, + this->_M_impl._M_header); + ++_M_impl._M_node_count; return iterator(__z); } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: insert_equal(const _Val& __v) { - _Link_type __y = _M_header; - _Link_type __x = _M_root(); - while (__x != 0) + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); + while (__x != 0) { __y = __x; - __x = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ? - _S_left(__x) : _S_right(__x); + __x = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ? + _S_left(__x) : _S_right(__x); } return _M_insert(__x, __y, __v); } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, typename _Alloc> + void + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + swap(_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __t) + { + if (_M_root() == 0) + { + if (__t._M_root() != 0) + { + _M_root() = __t._M_root(); + _M_leftmost() = __t._M_leftmost(); + _M_rightmost() = __t._M_rightmost(); + _M_root()->_M_parent = _M_end(); + + __t._M_root() = 0; + __t._M_leftmost() = __t._M_end(); + __t._M_rightmost() = __t._M_end(); + } + } + else if (__t._M_root() == 0) + { + __t._M_root() = _M_root(); + __t._M_leftmost() = _M_leftmost(); + __t._M_rightmost() = _M_rightmost(); + __t._M_root()->_M_parent = __t._M_end(); + + _M_root() = 0; + _M_leftmost() = _M_end(); + _M_rightmost() = _M_end(); + } + else + { + std::swap(_M_root(),__t._M_root()); + std::swap(_M_leftmost(),__t._M_leftmost()); + std::swap(_M_rightmost(),__t._M_rightmost()); + + _M_root()->_M_parent = _M_end(); + __t._M_root()->_M_parent = __t._M_end(); + } + // No need to swap header's color as it does not change. + std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count); + std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare); + } + + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - pair<typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator, + pair<typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator, bool> _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: insert_unique(const _Val& __v) { - _Link_type __y = _M_header; - _Link_type __x = _M_root(); + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); bool __comp = true; - while (__x != 0) + while (__x != 0) { __y = __x; - __comp = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)); + __comp = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x)); __x = __comp ? _S_left(__x) : _S_right(__x); } - iterator __j = iterator(__y); + iterator __j = iterator(__y); if (__comp) - if (__j == begin()) + if (__j == begin()) return pair<iterator,bool>(_M_insert(__x, __y, __v), true); else --__j; - if (_M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v))) + if (_M_impl._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<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + 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) - { + if (__position._M_node == _M_leftmost()) + { // begin() - if (size() > 0 && - _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) + if (size() > 0 + && _M_impl._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 + // First argument just needs to be non-null. else return insert_unique(__v).first; - } - else if (__position._M_node == _M_header) - { + } + else if (__position._M_node == _M_end()) + { // end() - if (_M_key_compare(_S_key(_M_rightmost()), _KeyOfValue()(__v))) + if (_M_impl._M_key_compare(_S_key(_M_rightmost()), + _KeyOfValue()(__v))) return _M_insert(0, _M_rightmost(), __v); else return insert_unique(__v).first; - } - else + } + 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 (_M_impl._M_key_compare(_S_key(__before._M_node), + _KeyOfValue()(__v)) + && _M_impl._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); + return _M_insert(0, __before._M_node, __v); else return _M_insert(__position._M_node, __position._M_node, __v); - // first argument just needs to be non-null - } + // First argument just needs to be non-null. + } else return insert_unique(__v).first; } } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + 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) - { + if (__position._M_node == _M_leftmost()) + { // begin() - if (size() > 0 && - !_M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__v))) + if (size() > 0 + && !_M_impl._M_key_compare(_S_key(__position._M_node), + _KeyOfValue()(__v))) return _M_insert(__position._M_node, __position._M_node, __v); - // first argument just needs to be non-null + // first argument just needs to be non-null else return insert_equal(__v); - } - else if (__position._M_node == _M_header) + } + else if (__position._M_node == _M_end()) { // end() - if (!_M_key_compare(_KeyOfValue()(__v), _S_key(_M_rightmost()))) + if (!_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(_M_rightmost()))) return _M_insert(0, _M_rightmost(), __v); else return insert_equal(__v); - } - else + } + 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 (!_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__before._M_node)) + && !_M_impl._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); + return _M_insert(0, __before._M_node, __v); else return _M_insert(__position._M_node, __position._M_node, __v); - // first argument just needs to be non-null - } + // First argument just needs to be non-null. + } else return insert_equal(__v); } } - template<typename _Key, typename _Val, typename _KoV, + template<typename _Key, typename _Val, typename _KoV, typename _Cmp, typename _Alloc> template<class _II> - void + void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>:: insert_equal(_II __first, _II __last) { @@ -1150,60 +983,58 @@ namespace std insert_equal(*__first); } - template<typename _Key, typename _Val, typename _KoV, - typename _Cmp, typename _Alloc> + template<typename _Key, typename _Val, typename _KoV, + typename _Cmp, typename _Alloc> template<class _II> - void + void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>:: - insert_unique(_II __first, _II __last) + insert_unique(_II __first, _II __last) { for ( ; __first != __last; ++__first) insert_unique(*__first); } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - inline void + inline void _Rb_tree<_Key,_Val,_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); + _Link_type __y = + static_cast<_Link_type>(_Rb_tree_rebalance_for_erase(__position._M_node, + this->_M_impl._M_header)); destroy_node(__y); - --_M_node_count; + --_M_impl._M_node_count; } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::erase(const _Key& __x) { pair<iterator,iterator> __p = equal_range(__x); - size_type __n = distance(__p.first, __p.second); + size_type __n = std::distance(__p.first, __p.second); erase(__p.first, __p.second); return __n; } - template<typename _Key, typename _Val, typename _KoV, + template<typename _Key, typename _Val, typename _KoV, typename _Compare, typename _Alloc> - typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type + 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) + _M_copy(_Const_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; - - try + + try { if (__x->_M_right) __top->_M_right = _M_copy(_S_right(__x), __top); __p = __top; __x = _S_left(__x); - - while (__x != 0) + + while (__x != 0) { _Link_type __y = _M_clone_node(__x); __p->_M_left = __y; @@ -1217,18 +1048,18 @@ namespace std catch(...) { _M_erase(__top); - __throw_exception_again; + __throw_exception_again; } return __top; } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - void + void _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::_M_erase(_Link_type __x) { // Erase without rebalancing. - while (__x != 0) + while (__x != 0) { _M_erase(_S_right(__x)); _Link_type __y = _S_left(__x); @@ -1237,9 +1068,9 @@ namespace std } } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - void + void _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: erase(iterator __first, iterator __last) { @@ -1249,214 +1080,202 @@ namespace std while (__first != __last) erase(__first++); } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - void + void _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: - erase(const _Key* __first, const _Key* __last) - { - while (__first != __last) - erase(*__first++); + erase(const _Key* __first, const _Key* __last) + { + while (__first != __last) + erase(*__first++); } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k) { - _Link_type __y = _M_header; // Last node which is not less than __k. - _Link_type __x = _M_root(); // Current node. - - while (__x != 0) - if (!_M_key_compare(_S_key(__x), __k)) + _Link_type __x = _M_begin(); // Current node. + _Link_type __y = _M_end(); // Last node which is not less than __k. + + while (__x != 0) + if (!_M_impl._M_key_compare(_S_key(__x), __k)) __y = __x, __x = _S_left(__x); else __x = _S_right(__x); - - iterator __j = iterator(__y); - return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ? - end() : __j; + + iterator __j = iterator(__y); + return (__j == end() + || _M_impl._M_key_compare(__k, _S_key(__j._M_node))) ? end() : __j; } - - template<typename _Key, typename _Val, typename _KeyOfValue, + + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator _Rb_tree<_Key,_Val,_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) + _Const_Link_type __x = _M_begin(); // Current node. + _Const_Link_type __y = _M_end(); // Last node which is not less than __k. + + while (__x != 0) { - if (!_M_key_compare(_S_key(__x), __k)) + if (!_M_impl._M_key_compare(_S_key(__x), __k)) __y = __x, __x = _S_left(__x); else __x = _S_right(__x); - } - const_iterator __j = const_iterator(__y); - return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ? - end() : __j; + } + const_iterator __j = const_iterator(__y); + return (__j == end() + || _M_impl._M_key_compare(__k, _S_key(__j._M_node))) ? end() : __j; } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: count(const _Key& __k) const { pair<const_iterator, const_iterator> __p = equal_range(__k); - size_type __n = distance(__p.first, __p.second); + const size_type __n = std::distance(__p.first, __p.second); return __n; } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: lower_bound(const _Key& __k) { - _Link_type __y = _M_header; /* Last node which is not less than __k. */ - _Link_type __x = _M_root(); /* Current node. */ - - while (__x != 0) - if (!_M_key_compare(_S_key(__x), __k)) + _Link_type __x = _M_begin(); // Current node. + _Link_type __y = _M_end(); // Last node which is not less than __k. + + while (__x != 0) + if (!_M_impl._M_key_compare(_S_key(__x), __k)) __y = __x, __x = _S_left(__x); else __x = _S_right(__x); - + return iterator(__y); } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: lower_bound(const _Key& __k) const { - _Link_type __y = _M_header; /* Last node which is not less than __k. */ - _Link_type __x = _M_root(); /* Current node. */ - - while (__x != 0) - if (!_M_key_compare(_S_key(__x), __k)) + _Const_Link_type __x = _M_begin(); // Current node. + _Const_Link_type __y = _M_end(); // Last node which is not less than __k. + + while (__x != 0) + if (!_M_impl._M_key_compare(_S_key(__x), __k)) __y = __x, __x = _S_left(__x); else __x = _S_right(__x); - + return const_iterator(__y); } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: upper_bound(const _Key& __k) { - _Link_type __y = _M_header; /* Last node which is greater than __k. */ - _Link_type __x = _M_root(); /* Current node. */ - - while (__x != 0) - if (_M_key_compare(__k, _S_key(__x))) + _Link_type __x = _M_begin(); // Current node. + _Link_type __y = _M_end(); // Last node which is greater than __k. + + while (__x != 0) + if (_M_impl._M_key_compare(__k, _S_key(__x))) __y = __x, __x = _S_left(__x); else __x = _S_right(__x); - + return iterator(__y); } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: upper_bound(const _Key& __k) const { - _Link_type __y = _M_header; /* Last node which is greater than __k. */ - _Link_type __x = _M_root(); /* Current node. */ - - while (__x != 0) - if (_M_key_compare(__k, _S_key(__x))) + _Const_Link_type __x = _M_begin(); // Current node. + _Const_Link_type __y = _M_end(); // Last node which is greater than __k. + + while (__x != 0) + if (_M_impl._M_key_compare(__k, _S_key(__x))) __y = __x, __x = _S_left(__x); else __x = _S_right(__x); - + return const_iterator(__y); } - template<typename _Key, typename _Val, typename _KeyOfValue, + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - inline - pair<typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator, - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator> + inline + pair<typename _Rb_tree<_Key,_Val,_KeyOfValue, + _Compare,_Alloc>::iterator, + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator> _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: equal_range(const _Key& __k) { return pair<iterator, iterator>(lower_bound(__k), upper_bound(__k)); } - template<typename _Key, typename _Val, typename _KoV, + template<typename _Key, typename _Val, typename _KoV, typename _Compare, typename _Alloc> - inline - pair<typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::const_iterator, - typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::const_iterator> - _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc> - ::equal_range(const _Key& __k) const - { - return pair<const_iterator,const_iterator>(lower_bound(__k), - upper_bound(__k)); - } - - inline int - __black_count(_Rb_tree_node_base* __node, _Rb_tree_node_base* __root) - { - if (__node == 0) - return 0; - int __sum = 0; - do - { - if (__node->_M_color == _M_black) - ++__sum; - if (__node == __root) - break; - __node = __node->_M_parent; - } - while (1); - return __sum; - } - - template<typename _Key, typename _Val, typename _KeyOfValue, + inline + pair<typename _Rb_tree<_Key, _Val, _KoV, + _Compare, _Alloc>::const_iterator, + typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::const_iterator> + _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>:: + equal_range(const _Key& __k) const + { return pair<const_iterator, const_iterator>(lower_bound(__k), + upper_bound(__k)); } + + unsigned int + _Rb_tree_black_count(const _Rb_tree_node_base* __node, + const _Rb_tree_node_base* __root); + + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> - bool + bool _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const { - if (_M_node_count == 0 || begin() == end()) - return _M_node_count == 0 && begin() == end() && - _M_header->_M_left == _M_header && _M_header->_M_right == _M_header; - - int __len = __black_count(_M_leftmost(), _M_root()); - for (const_iterator __it = begin(); __it != end(); ++__it) - { - _Link_type __x = (_Link_type) __it._M_node; - _Link_type __L = _S_left(__x); - _Link_type __R = _S_right(__x); - - if (__x->_M_color == _M_red) - if ((__L && __L->_M_color == _M_red) - || (__R && __R->_M_color == _M_red)) + if (_M_impl._M_node_count == 0 || begin() == end()) + return _M_impl._M_node_count == 0 && begin() == end() + && this->_M_impl._M_header._M_left == _M_end() + && this->_M_impl._M_header._M_right == _M_end(); + + unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root()); + for (const_iterator __it = begin(); __it != end(); ++__it) + { + _Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node); + _Const_Link_type __L = _S_left(__x); + _Const_Link_type __R = _S_right(__x); + + if (__x->_M_color == _S_red) + if ((__L && __L->_M_color == _S_red) + || (__R && __R->_M_color == _S_red)) + return false; + + if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L))) return false; - - if (__L && _M_key_compare(_S_key(__x), _S_key(__L))) - return false; - if (__R && _M_key_compare(_S_key(__R), _S_key(__x))) - return false; - - if (!__L && !__R && __black_count(__x, _M_root()) != __len) - return false; - } - - if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root())) - return false; - if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root())) - return false; - return true; + if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x))) + return false; + + if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len) + return false; + } + + if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root())) + return false; + if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root())) + return false; + return true; } -} // namespace std +} // namespace std + +#endif -#endif diff --git a/contrib/libstdc++/include/bits/stl_uninitialized.h b/contrib/libstdc++/include/bits/stl_uninitialized.h index b5f7b8c40b69..f4f8d187f646 100644 --- a/contrib/libstdc++/include/bits/stl_uninitialized.h +++ b/contrib/libstdc++/include/bits/stl_uninitialized.h @@ -1,6 +1,6 @@ // Raw memory manipulators -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,39 +58,38 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_STL_UNINITIALIZED_H -#define _CPP_BITS_STL_UNINITIALIZED_H 1 +#ifndef _STL_UNINITIALIZED_H +#define _STL_UNINITIALIZED_H 1 #include <cstring> namespace std { - // uninitialized_copy - - template<typename _InputIter, typename _ForwardIter> - inline _ForwardIter - __uninitialized_copy_aux(_InputIter __first, _InputIter __last, - _ForwardIter __result, + template<typename _InputIterator, typename _ForwardIterator> + inline _ForwardIterator + __uninitialized_copy_aux(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, __true_type) - { return copy(__first, __last, __result); } + { return std::copy(__first, __last, __result); } - template<typename _InputIter, typename _ForwardIter> - _ForwardIter - __uninitialized_copy_aux(_InputIter __first, _InputIter __last, - _ForwardIter __result, + template<typename _InputIterator, typename _ForwardIterator> + inline _ForwardIterator + __uninitialized_copy_aux(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result, __false_type) { - _ForwardIter __cur = __result; - try { - for ( ; __first != __last; ++__first, ++__cur) - _Construct(&*__cur, *__first); - return __cur; - } + _ForwardIterator __cur = __result; + try + { + for ( ; __first != __last; ++__first, ++__cur) + std::_Construct(&*__cur, *__first); + return __cur; + } catch(...) { - _Destroy(__result, __cur); - __throw_exception_again; + std::_Destroy(__result, __cur); + __throw_exception_again; } } @@ -103,52 +102,56 @@ namespace std * * Like copy(), but does not require an initialized output range. */ - template<typename _InputIter, typename _ForwardIter> - inline _ForwardIter - uninitialized_copy(_InputIter __first, _InputIter __last, _ForwardIter __result) + template<typename _InputIterator, typename _ForwardIterator> + inline _ForwardIterator + uninitialized_copy(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result) { - typedef typename iterator_traits<_ForwardIter>::value_type _ValueType; + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; typedef typename __type_traits<_ValueType>::is_POD_type _Is_POD; - return __uninitialized_copy_aux(__first, __last, __result, _Is_POD()); + return std::__uninitialized_copy_aux(__first, __last, __result, + _Is_POD()); } inline char* uninitialized_copy(const char* __first, const char* __last, char* __result) { - memmove(__result, __first, __last - __first); + std::memmove(__result, __first, __last - __first); return __result + (__last - __first); } - inline wchar_t* + inline wchar_t* uninitialized_copy(const wchar_t* __first, const wchar_t* __last, wchar_t* __result) { - memmove(__result, __first, sizeof(wchar_t) * (__last - __first)); + std::memmove(__result, __first, sizeof(wchar_t) * (__last - __first)); return __result + (__last - __first); } // Valid if copy construction is equivalent to assignment, and if the // destructor is trivial. - template<typename _ForwardIter, typename _Tp> + template<typename _ForwardIterator, typename _Tp> inline void - __uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last, + __uninitialized_fill_aux(_ForwardIterator __first, + _ForwardIterator __last, const _Tp& __x, __true_type) - { fill(__first, __last, __x); } + { std::fill(__first, __last, __x); } - template<typename _ForwardIter, typename _Tp> + template<typename _ForwardIterator, typename _Tp> void - __uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last, + __uninitialized_fill_aux(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __x, __false_type) { - _ForwardIter __cur = __first; - try { - for ( ; __cur != __last; ++__cur) - _Construct(&*__cur, __x); - } + _ForwardIterator __cur = __first; + try + { + for ( ; __cur != __last; ++__cur) + std::_Construct(&*__cur, __x); + } catch(...) { - _Destroy(__first, __cur); - __throw_exception_again; + std::_Destroy(__first, __cur); + __throw_exception_again; } } @@ -161,40 +164,40 @@ namespace std * * Like fill(), but does not require an initialized output range. */ - template<typename _ForwardIter, typename _Tp> + template<typename _ForwardIterator, typename _Tp> inline void - uninitialized_fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __x) + uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __x) { - typedef typename iterator_traits<_ForwardIter>::value_type _ValueType; + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; typedef typename __type_traits<_ValueType>::is_POD_type _Is_POD; - __uninitialized_fill_aux(__first, __last, __x, _Is_POD()); + std::__uninitialized_fill_aux(__first, __last, __x, _Is_POD()); } // Valid if copy construction is equivalent to assignment, and if the // destructor is trivial. - template<typename _ForwardIter, typename _Size, typename _Tp> - inline _ForwardIter - __uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, + template<typename _ForwardIterator, typename _Size, typename _Tp> + inline _ForwardIterator + __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n, const _Tp& __x, __true_type) - { - return fill_n(__first, __n, __x); - } + { return std::fill_n(__first, __n, __x); } - template<typename _ForwardIter, typename _Size, typename _Tp> - _ForwardIter - __uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, + template<typename _ForwardIterator, typename _Size, typename _Tp> + _ForwardIterator + __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n, const _Tp& __x, __false_type) { - _ForwardIter __cur = __first; - try { - for ( ; __n > 0; --__n, ++__cur) - _Construct(&*__cur, __x); - return __cur; - } + _ForwardIterator __cur = __first; + try + { + for ( ; __n > 0; --__n, ++__cur) + std::_Construct(&*__cur, __x); + return __cur; + } catch(...) - { - _Destroy(__first, __cur); - __throw_exception_again; + { + std::_Destroy(__first, __cur); + __throw_exception_again; } } @@ -207,16 +210,16 @@ namespace std * * Like fill_n(), but does not require an initialized output range. */ - template<typename _ForwardIter, typename _Size, typename _Tp> - inline _ForwardIter - uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x) + template<typename _ForwardIterator, typename _Size, typename _Tp> + inline _ForwardIterator + uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) { - typedef typename iterator_traits<_ForwardIter>::value_type _ValueType; + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; typedef typename __type_traits<_ValueType>::is_POD_type _Is_POD; - return __uninitialized_fill_n_aux(__first, __n, __x, _Is_POD()); + return std::__uninitialized_fill_n_aux(__first, __n, __x, _Is_POD()); } - // Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill, + // Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill, // __uninitialized_fill_copy. // __uninitialized_copy_copy @@ -224,67 +227,71 @@ namespace std // copies [first2, last2) into // [result, result + (last1 - first1) + (last2 - first2)). - template<typename _InputIter1, typename _InputIter2, typename _ForwardIter> - inline _ForwardIter - __uninitialized_copy_copy(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, _InputIter2 __last2, - _ForwardIter __result) + template<typename _InputIterator1, typename _InputIterator2, + typename _ForwardIterator> + inline _ForwardIterator + __uninitialized_copy_copy(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _ForwardIterator __result) { - _ForwardIter __mid = uninitialized_copy(__first1, __last1, __result); - try { - return uninitialized_copy(__first2, __last2, __mid); - } + _ForwardIterator __mid = std::uninitialized_copy(__first1, __last1, + __result); + try + { + return std::uninitialized_copy(__first2, __last2, __mid); + } catch(...) - { - _Destroy(__result, __mid); - __throw_exception_again; + { + std::_Destroy(__result, __mid); + __throw_exception_again; } } // __uninitialized_fill_copy // Fills [result, mid) with x, and copies [first, last) into // [mid, mid + (last - first)). - template<typename _ForwardIter, typename _Tp, typename _InputIter> - inline _ForwardIter - __uninitialized_fill_copy(_ForwardIter __result, _ForwardIter __mid, - const _Tp& __x, - _InputIter __first, _InputIter __last) + template<typename _ForwardIterator, typename _Tp, typename _InputIterator> + inline _ForwardIterator + __uninitialized_fill_copy(_ForwardIterator __result, _ForwardIterator __mid, + const _Tp& __x, _InputIterator __first, + _InputIterator __last) { - uninitialized_fill(__result, __mid, __x); - try { - return uninitialized_copy(__first, __last, __mid); - } + std::uninitialized_fill(__result, __mid, __x); + try + { + return std::uninitialized_copy(__first, __last, __mid); + } catch(...) { - _Destroy(__result, __mid); - __throw_exception_again; + std::_Destroy(__result, __mid); + __throw_exception_again; } } // __uninitialized_copy_fill // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and // fills [first2 + (last1 - first1), last2) with x. - template<typename _InputIter, typename _ForwardIter, typename _Tp> + template<typename _InputIterator, typename _ForwardIterator, typename _Tp> inline void - __uninitialized_copy_fill(_InputIter __first1, _InputIter __last1, - _ForwardIter __first2, _ForwardIter __last2, - const _Tp& __x) + __uninitialized_copy_fill(_InputIterator __first1, _InputIterator __last1, + _ForwardIterator __first2, + _ForwardIterator __last2, const _Tp& __x) { - _ForwardIter __mid2 = uninitialized_copy(__first1, __last1, __first2); - try { - uninitialized_fill(__mid2, __last2, __x); - } + _ForwardIterator __mid2 = std::uninitialized_copy(__first1, __last1, + __first2); + try + { + std::uninitialized_fill(__mid2, __last2, __x); + } catch(...) { - _Destroy(__first2, __mid2); - __throw_exception_again; + std::_Destroy(__first2, __mid2); + __throw_exception_again; } } } // namespace std -#endif /* _CPP_BITS_STL_UNINITIALIZED_H */ - -// Local Variables: -// mode:C++ -// End: +#endif /* _STL_UNINITIALIZED_H */ diff --git a/contrib/libstdc++/include/bits/stl_vector.h b/contrib/libstdc++/include/bits/stl_vector.h index 53547322d651..fee413dc6f0e 100644 --- a/contrib/libstdc++/include/bits/stl_vector.h +++ b/contrib/libstdc++/include/bits/stl_vector.h @@ -1,6 +1,6 @@ // Vector implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,79 +58,15 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_VECTOR_H -#define __GLIBCPP_INTERNAL_VECTOR_H +#ifndef _VECTOR_H +#define _VECTOR_H 1 #include <bits/stl_iterator_base_funcs.h> #include <bits/functexcept.h> #include <bits/concept_check.h> -namespace std +namespace _GLIBCXX_STD { - /// @if maint Primary default version. @endif - /** - * @if maint - * See bits/stl_deque.h's _Deque_alloc_base for an explanation. - * @endif - */ - template<typename _Tp, typename _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); } - }; - - /// @if maint Specialization for instanceless allocators. @endif - template<typename _Tp, typename _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);} - }; - - /** * @if maint * See bits/stl_deque.h's _Deque_base for an explanation. @@ -138,34 +74,53 @@ namespace std */ template<typename _Tp, typename _Alloc> struct _Vector_base - : public _Vector_alloc_base<_Tp, _Alloc, - _Alloc_traits<_Tp, _Alloc>::_S_instanceless> { + struct _Vector_impl + : public _Alloc { + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; + _Vector_impl (_Alloc const& __a) + : _Alloc(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) + { } + }; + public: - typedef _Vector_alloc_base<_Tp, _Alloc, - _Alloc_traits<_Tp, _Alloc>::_S_instanceless> - _Base; - typedef typename _Base::allocator_type allocator_type; + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const { return *static_cast<const _Alloc*>(&this->_M_impl); } + + _Vector_base(const allocator_type& __a) : _M_impl(__a) + { } - _Vector_base(const allocator_type& __a) - : _Base(__a) { } - _Vector_base(size_t __n, const allocator_type& __a) - : _Base(__a) + : _M_impl(__a) { - _M_start = _M_allocate(__n); - _M_finish = _M_start; - _M_end_of_storage = _M_start + __n; + this->_M_impl._M_start = this->_M_allocate(__n); + this->_M_impl._M_finish = this->_M_impl._M_start; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; } - - ~_Vector_base() - { _M_deallocate(_M_start, _M_end_of_storage - _M_start); } + + ~_Vector_base() + { _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); } + + public: + _Vector_impl _M_impl; + + _Tp* + _M_allocate(size_t __n) { return _M_impl.allocate(__n); } + + void + _M_deallocate(_Tp* __p, size_t __n) + { if (__p) _M_impl.deallocate(__p, __n); } }; - - + + /** - * @brief A standard container which offers fixed time access to individual - * elements in any order. + * @brief A standard container which offers fixed time access to + * individual elements in any order. * * @ingroup Containers * @ingroup Sequences @@ -176,48 +131,46 @@ namespace std * <a href="tables.html#68">optional sequence requirements</a> with the * %exception of @c push_front and @c pop_front. * - * In some terminology a %vector can be described as a dynamic C-style array, - * it offers fast and efficient access to individual elements in any order - * and saves the user from worrying about memory and size allocation. - * Subscripting ( @c [] ) access is also provided as with C-style arrays. + * In some terminology a %vector can be described as a dynamic + * C-style array, it offers fast and efficient access to individual + * elements in any order and saves the user from worrying about + * memory and size allocation. Subscripting ( @c [] ) access is + * also provided as with C-style arrays. */ template<typename _Tp, typename _Alloc = allocator<_Tp> > class vector : protected _Vector_base<_Tp, _Alloc> { // Concept requirements. - __glibcpp_class_requires(_Tp, _SGIAssignableConcept) - - typedef _Vector_base<_Tp, _Alloc> _Base; - typedef vector<_Tp, _Alloc> vector_type; - + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + + typedef _Vector_base<_Tp, _Alloc> _Base; + typedef vector<_Tp, _Alloc> vector_type; + public: - typedef _Tp value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; + typedef _Tp value_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; typedef __gnu_cxx::__normal_iterator<pointer, vector_type> iterator; typedef __gnu_cxx::__normal_iterator<const_pointer, vector_type> const_iterator; - typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - typedef std::reverse_iterator<iterator> reverse_iterator; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef typename _Base::allocator_type allocator_type; - + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef typename _Base::allocator_type allocator_type; + protected: /** @if maint * These two functions and three data members are all from the - * top-most base class, which varies depending on the type of - * %allocator. They should be pretty self-explanatory, as + * base class. They should be pretty self-explanatory, as * %vector uses a simple contiguous allocation scheme. @endif */ using _Base::_M_allocate; using _Base::_M_deallocate; - using _Base::_M_start; - using _Base::_M_finish; - using _Base::_M_end_of_storage; - + using _Base::_M_impl; + public: // [23.2.4.1] construct/copy/destroy // (assign() and get_allocator() are also listed in this section) @@ -227,35 +180,37 @@ namespace std explicit vector(const allocator_type& __a = allocator_type()) : _Base(__a) { } - + /** * @brief Create a %vector with copies of an exemplar element. * @param n The number of elements to initially create. * @param value An element to copy. - * + * * This constructor fills the %vector with @a n copies of @a value. */ vector(size_type __n, const value_type& __value, const allocator_type& __a = allocator_type()) : _Base(__n, __a) - { _M_finish = uninitialized_fill_n(_M_start, __n, __value); } - + { this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start, + __n, __value); } + /** * @brief Create a %vector with default elements. * @param n The number of elements to initially create. - * + * * This constructor fills the %vector with @a n copies of a * default-constructed element. */ explicit vector(size_type __n) : _Base(__n, allocator_type()) - { _M_finish = uninitialized_fill_n(_M_start, __n, value_type()); } - + { this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start, + __n, value_type()); } + /** * @brief %Vector copy constructor. * @param x A %vector of identical element and allocator types. - * + * * The newly-created %vector uses a copy of the allocation * object used by @a x. All the elements of @a x are copied, * but any extra memory in @@ -263,21 +218,24 @@ namespace std */ vector(const vector& __x) : _Base(__x.size(), __x.get_allocator()) - { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); } - + { this->_M_impl._M_finish = std::uninitialized_copy(__x.begin(), __x.end(), + this->_M_impl._M_start); + } + /** * @brief Builds a %vector from a range. * @param first An input iterator. * @param last An input iterator. - * + * * Create a %vector consisting of copies of the elements from * [first,last). * - * If the iterators are forward, bidirectional, or random-access, then - * this will call the elements' copy constructor N times (where N is - * distance(first,last)) and do no memory reallocation. But if only - * input iterators are used, then this will do at most 2N calls to the - * copy constructor, and logN memory reallocations. + * If the iterators are forward, bidirectional, or + * random-access, then this will call the elements' copy + * constructor N times (where N is distance(first,last)) and do + * no memory reallocation. But if only input iterators are + * used, then this will do at most 2N calls to the copy + * constructor, and logN memory reallocations. */ template<typename _InputIterator> vector(_InputIterator __first, _InputIterator __last, @@ -288,25 +246,26 @@ namespace std typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_initialize_dispatch(__first, __last, _Integral()); } - + /** - * The dtor only erases the elements, and note that if the elements - * themselves are pointers, the pointed-to memory is not touched in any - * way. Managing the pointer is the user's responsibilty. + * The dtor only erases the elements, and note that if the + * elements themselves are pointers, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. */ - ~vector() { _Destroy(_M_start, _M_finish); } - + ~vector() { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); } + /** * @brief %Vector assignment operator. * @param x A %vector of identical element and allocator types. - * + * * All the elements of @a x are copied, but any extra memory in * @a x (for fast expansion) will not be copied. Unlike the * copy constructor, the allocator object is not copied. */ vector& operator=(const vector& __x); - + /** * @brief Assigns a given value to a %vector. * @param n Number of elements to be assigned. @@ -318,9 +277,9 @@ namespace std * the number of elements assigned. Old data may be lost. */ void - assign(size_type __n, const value_type& __val) + assign(size_type __n, const value_type& __val) { _M_fill_assign(__n, __val); } - + /** * @brief Assigns a range to a %vector. * @param first An input iterator. @@ -341,42 +300,43 @@ namespace std typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_assign_dispatch(__first, __last, _Integral()); } - + /// Get a copy of the memory allocation object. - allocator_type - get_allocator() const { return _Base::get_allocator(); } - + using _Base::get_allocator; + // iterators /** - * Returns a read/write iterator that points to the first element in the - * %vector. Iteration is done in ordinary element order. + * Returns a read/write iterator that points to the first + * element in the %vector. Iteration is done in ordinary + * element order. */ iterator - begin() { return iterator (_M_start); } - + begin() { return iterator (this->_M_impl._M_start); } + /** * Returns a read-only (constant) iterator that points to the * first element in the %vector. Iteration is done in ordinary * element order. */ const_iterator - begin() const { return const_iterator (_M_start); } - + begin() const { return const_iterator (this->_M_impl._M_start); } + /** * Returns a read/write iterator that points one past the last * element in the %vector. Iteration is done in ordinary * element order. */ iterator - end() { return iterator (_M_finish); } - + end() { return iterator (this->_M_impl._M_finish); } + /** - * Returns a read-only (constant) iterator that points one past the last - * element in the %vector. Iteration is done in ordinary element order. + * Returns a read-only (constant) iterator that points one past + * the last element in the %vector. Iteration is done in + * ordinary element order. */ const_iterator - end() const { return const_iterator (_M_finish); } - + end() const { return const_iterator (this->_M_impl._M_finish); } + /** * Returns a read/write reverse iterator that points to the * last element in the %vector. Iteration is done in reverse @@ -384,7 +344,7 @@ namespace std */ reverse_iterator rbegin() { return reverse_iterator(end()); } - + /** * Returns a read-only (constant) reverse iterator that points * to the last element in the %vector. Iteration is done in @@ -392,15 +352,15 @@ namespace std */ const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } - + /** - * Returns a read/write reverse iterator that points to one before the - * first element in the %vector. Iteration is done in reverse element - * order. + * Returns a read/write reverse iterator that points to one + * before the first element in the %vector. Iteration is done + * in reverse element order. */ reverse_iterator rend() { return reverse_iterator(begin()); } - + /** * Returns a read-only (constant) reverse iterator that points * to one before the first element in the %vector. Iteration @@ -408,16 +368,16 @@ namespace std */ const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } - + // [23.2.4.2] capacity /** Returns the number of elements in the %vector. */ size_type size() const { return size_type(end() - begin()); } - + /** Returns the size() of the largest possible %vector. */ size_type max_size() const { return size_type(-1) / sizeof(value_type); } - + /** * @brief Resizes the %vector to the specified number of elements. * @param new_size Number of elements the %vector should contain. @@ -437,7 +397,7 @@ namespace std else insert(end(), __new_size - size(), __x); } - + /** * @brief Resizes the %vector to the specified number of elements. * @param new_size Number of elements the %vector should contain. @@ -450,22 +410,22 @@ namespace std */ void resize(size_type __new_size) { resize(__new_size, value_type()); } - + /** - * Returns the total number of elements that the %vector can hold before - * needing to allocate more memory. + * Returns the total number of elements that the %vector can + * hold before needing to allocate more memory. */ size_type capacity() const - { return size_type(const_iterator(_M_end_of_storage) - begin()); } - + { return size_type(const_iterator(this->_M_impl._M_end_of_storage) - begin()); } + /** * Returns true if the %vector is empty. (Thus begin() would * equal end().) */ bool empty() const { return begin() == end(); } - + /** * @brief Attempt to preallocate enough memory for specified number of * elements. @@ -485,11 +445,12 @@ namespace std */ void reserve(size_type __n); - + // element access /** * @brief Subscript access to the data contained in the %vector. - * @param n The index of the element for which data should be accessed. + * @param n The index of the element for which data should be + * accessed. * @return Read/write reference to data. * * This operator allows for easy, array-style, data access. @@ -499,7 +460,7 @@ namespace std */ reference operator[](size_type __n) { return *(begin() + __n); } - + /** * @brief Subscript access to the data contained in the %vector. * @param n The index of the element for which data should be @@ -513,16 +474,16 @@ namespace std */ const_reference operator[](size_type __n) const { return *(begin() + __n); } - + protected: /// @if maint Safety check used only from at(). @endif void _M_range_check(size_type __n) const { if (__n >= this->size()) - __throw_out_of_range("vector [] access out of range"); + __throw_out_of_range(__N("vector::_M_range_check")); } - + public: /** * @brief Provides access to the data contained in the %vector. @@ -531,13 +492,13 @@ namespace std * @return Read/write reference to data. * @throw std::out_of_range If @a n is an invalid index. * - * This function provides for safer data access. The parameter is first - * checked that it is in the range of the vector. The function throws - * out_of_range if the check fails. + * This function provides for safer data access. The parameter + * is first checked that it is in the range of the vector. The + * function throws out_of_range if the check fails. */ reference at(size_type __n) { _M_range_check(__n); return (*this)[__n]; } - + /** * @brief Provides access to the data contained in the %vector. * @param n The index of the element for which data should be @@ -551,35 +512,35 @@ namespace std */ const_reference at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; } - + /** * Returns a read/write reference to the data at the first * element of the %vector. */ reference front() { return *begin(); } - + /** * Returns a read-only (constant) reference to the data at the first * element of the %vector. */ const_reference front() const { return *begin(); } - + /** - * Returns a read/write reference to the data at the last element of the - * %vector. + * Returns a read/write reference to the data at the last + * element of the %vector. */ reference back() { return *(end() - 1); } - + /** - * Returns a read-only (constant) reference to the data at the last - * element of the %vector. + * Returns a read-only (constant) reference to the data at the + * last element of the %vector. */ const_reference back() const { return *(end() - 1); } - + // [23.2.4.3] modifiers /** * @brief Add data to the end of the %vector. @@ -594,30 +555,31 @@ namespace std void push_back(const value_type& __x) { - if (_M_finish != _M_end_of_storage) + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) { - _Construct(_M_finish, __x); - ++_M_finish; + std::_Construct(this->_M_impl._M_finish, __x); + ++this->_M_impl._M_finish; } else _M_insert_aux(end(), __x); } - + /** * @brief Removes last element. * * This is a typical stack operation. It shrinks the %vector by one. * - * Note that no data is returned, and if the last element's data is - * needed, it should be retrieved before pop_back() is called. + * Note that no data is returned, and if the last element's + * data is needed, it should be retrieved before pop_back() is + * called. */ void pop_back() { - --_M_finish; - _Destroy(_M_finish); + --this->_M_impl._M_finish; + std::_Destroy(this->_M_impl._M_finish); } - + /** * @brief Inserts given value into %vector before specified iterator. * @param position An iterator into the %vector. @@ -631,28 +593,7 @@ namespace std */ iterator insert(iterator __position, const value_type& __x); - -#ifdef _GLIBCPP_DEPRECATED - /** - * @brief Inserts an element into the %vector. - * @param position An iterator into the %vector. - * @return An iterator that points to the inserted element. - * - * This function will insert a default-constructed element - * before the specified location. You should consider using - * insert(position,value_type()) instead. Note that this kind - * of operation could be expensive for a vector and if it is - * frequently used the user should consider using std::list. - * - * @note This was deprecated in 3.2 and will be removed in 3.4. - * You must define @c _GLIBCPP_DEPRECATED to make this visible - * in 3.2; see c++config.h. - */ - iterator - insert(iterator __position) - { return insert(__position, value_type()); } -#endif - + /** * @brief Inserts a number of copies of given data into the %vector. * @param position An iterator into the %vector. @@ -667,12 +608,12 @@ namespace std * consider using std::list. */ void - insert(iterator __pos, size_type __n, const value_type& __x) - { _M_fill_insert(__pos, __n, __x); } - + insert(iterator __position, size_type __n, const value_type& __x) + { _M_fill_insert(__position, __n, __x); } + /** * @brief Inserts a range into the %vector. - * @param pos An iterator into the %vector. + * @param position An iterator into the %vector. * @param first An input iterator. * @param last An input iterator. * @@ -686,13 +627,14 @@ namespace std */ template<typename _InputIterator> void - insert(iterator __pos, _InputIterator __first, _InputIterator __last) + insert(iterator __position, _InputIterator __first, + _InputIterator __last) { // Check whether it's an integral type. If so, it's not an iterator. typedef typename _Is_integer<_InputIterator>::_Integral _Integral; - _M_insert_dispatch(__pos, __first, __last, _Integral()); + _M_insert_dispatch(__position, __first, __last, _Integral()); } - + /** * @brief Remove element at given position. * @param position Iterator pointing to element to be erased. @@ -710,7 +652,7 @@ namespace std */ iterator erase(iterator __position); - + /** * @brief Remove a range of elements. * @param first Iterator pointing to the first element to be erased. @@ -731,7 +673,7 @@ namespace std */ iterator erase(iterator __first, iterator __last); - + /** * @brief Swaps data with another %vector. * @param x A %vector of the same element and allocator types. @@ -744,11 +686,11 @@ namespace std void swap(vector& __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); + std::swap(this->_M_impl._M_start, __x._M_impl._M_start); + std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); + std::swap(this->_M_impl._M_end_of_storage, __x._M_impl._M_end_of_storage); } - + /** * Erases all the elements. Note that this function only erases the * elements, and that if the elements themselves are pointers, the @@ -757,7 +699,7 @@ namespace std */ void clear() { erase(begin(), end()); } - + protected: /** * @if maint @@ -770,10 +712,10 @@ namespace std _M_allocate_and_copy(size_type __n, _ForwardIterator __first, _ForwardIterator __last) { - pointer __result = _M_allocate(__n); + pointer __result = this->_M_allocate(__n); try { - uninitialized_copy(__first, __last, __result); + std::uninitialized_copy(__first, __last, __result); return __result; } catch(...) @@ -782,31 +724,32 @@ namespace std __throw_exception_again; } } - - + + // Internal constructor functions follow. - + // Called by the range constructor to implement [23.1.1]/9 template<typename _Integer> void _M_initialize_dispatch(_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); + this->_M_impl._M_start = _M_allocate(__n); + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start, + __n, __value); } - + // Called by the range constructor to implement [23.1.1]/9 - template<typename _InputIter> + template<typename _InputIterator> void - _M_initialize_dispatch(_InputIter __first, _InputIter __last, + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, __false_type) { - typedef typename iterator_traits<_InputIter>::iterator_category + typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory; _M_range_initialize(__first, __last, _IterCategory()); } - + // Called by the second initialize_dispatch above template<typename _InputIterator> void @@ -816,23 +759,24 @@ namespace std for ( ; __first != __last; ++__first) push_back(*__first); } - + // Called by the second initialize_dispatch above template<typename _ForwardIterator> - void + void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag) { - size_type __n = distance(__first, __last); - _M_start = _M_allocate(__n); - _M_end_of_storage = _M_start + __n; - _M_finish = uninitialized_copy(__first, __last, _M_start); + size_type __n = std::distance(__first, __last); + this->_M_impl._M_start = this->_M_allocate(__n); + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + this->_M_impl._M_finish = std::uninitialized_copy(__first, __last, + this->_M_impl._M_start); } - - + + // Internal assign functions follow. The *_aux functions do the actual // assignment work for the range versions. - + // Called by the range assign to implement [23.1.1]/9 template<typename _Integer> void @@ -841,37 +785,38 @@ namespace std _M_fill_assign(static_cast<size_type>(__n), static_cast<value_type>(__val)); } - + // Called by the range assign to implement [23.1.1]/9 - template<typename _InputIter> + template<typename _InputIterator> void - _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type) + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) { - typedef typename iterator_traits<_InputIter>::iterator_category + typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory; _M_assign_aux(__first, __last, _IterCategory()); } - + // Called by the second assign_dispatch above template<typename _InputIterator> - void + void _M_assign_aux(_InputIterator __first, _InputIterator __last, input_iterator_tag); - + // Called by the second assign_dispatch above template<typename _ForwardIterator> - void + void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag); - + // Called by assign(n,t), and the range assign when it turns out // to be the same thing. void _M_fill_assign(size_type __n, const value_type& __val); - - + + // Internal insert functions follow. - + // Called by the range insert to implement [23.1.1]/9 template<typename _Integer> void @@ -881,7 +826,7 @@ namespace std _M_fill_insert(__pos, static_cast<size_type>(__n), static_cast<value_type>(__val)); } - + // Called by the range insert to implement [23.1.1]/9 template<typename _InputIterator> void @@ -892,35 +837,30 @@ namespace std _IterCategory; _M_range_insert(__pos, __first, __last, _IterCategory()); } - + // Called by the second insert_dispatch above template<typename _InputIterator> void - _M_range_insert(iterator __pos, _InputIterator __first, + _M_range_insert(iterator __pos, _InputIterator __first, _InputIterator __last, input_iterator_tag); - + // Called by the second insert_dispatch above template<typename _ForwardIterator> void - _M_range_insert(iterator __pos, _ForwardIterator __first, + _M_range_insert(iterator __pos, _ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag); - + // Called by insert(p,n,x), and the range insert when it turns out to be // the same thing. void _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); - + // Called by insert(p,x) void _M_insert_aux(iterator __position, const value_type& __x); - -#ifdef _GLIBCPP_DEPRECATED - // Unused now (same situation as in deque) - void _M_insert_aux(iterator __position); -#endif }; - - + + /** * @brief Vector equality comparison. * @param x A %vector. @@ -936,52 +876,52 @@ namespace std operator==(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y) { return __x.size() == __y.size() && - equal(__x.begin(), __x.end(), __y.begin()); + std::equal(__x.begin(), __x.end(), __y.begin()); } - + /** * @brief Vector ordering relation. * @param x A %vector. * @param y A %vector of the same type as @a x. - * @return True iff @a x is lexographically less than @a y. + * @return True iff @a x is lexicographically less than @a y. * * This is a total ordering relation. It is linear in the size of the * vectors. The elements must be comparable with @c <. * - * See std::lexographical_compare() for how the determination is made. + * See std::lexicographical_compare() for how the determination is made. */ template<typename _Tp, typename _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()); + return std::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } - + /// Based on operator== template<typename _Tp, typename _Alloc> inline bool operator!=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y) { return !(__x == __y); } - + /// Based on operator< template<typename _Tp, typename _Alloc> inline bool operator>(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y) { return __y < __x; } - + /// Based on operator< template<typename _Tp, typename _Alloc> inline bool operator<=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y) { return !(__y < __x); } - + /// Based on operator< template<typename _Tp, typename _Alloc> inline bool operator>=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y) { return !(__x < __y); } - + /// See std::vector::swap(). template<typename _Tp, typename _Alloc> inline void @@ -989,4 +929,4 @@ namespace std { __x.swap(__y); } } // namespace std -#endif /* __GLIBCPP_INTERNAL_VECTOR_H */ +#endif /* _VECTOR_H */ diff --git a/contrib/libstdc++/include/bits/stream_iterator.h b/contrib/libstdc++/include/bits/stream_iterator.h index 4897fc36fefb..fa11bd6b28fb 100644 --- a/contrib/libstdc++/include/bits/stream_iterator.h +++ b/contrib/libstdc++/include/bits/stream_iterator.h @@ -1,6 +1,6 @@ // Stream iterators -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -32,17 +32,20 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_STREAM_ITERATOR_H -#define _CPP_BITS_STREAM_ITERATOR_H 1 +#ifndef _STREAM_ITERATOR_H +#define _STREAM_ITERATOR_H 1 #pragma GCC system_header +#include <debug/debug.h> + namespace std { - template<typename _Tp, typename _CharT = char, - typename _Traits = char_traits<_CharT>, typename _Dist = ptrdiff_t> - class istream_iterator - : public iterator<input_iterator_tag, _Tp, _Dist, const _Tp*, const _Tp&> + /// Provides input iterator semantics for streams. + template<typename _Tp, typename _CharT = char, + typename _Traits = char_traits<_CharT>, typename _Dist = ptrdiff_t> + class istream_iterator + : public iterator<input_iterator_tag, _Tp, _Dist, const _Tp*, const _Tp&> { public: typedef _CharT char_type; @@ -50,107 +53,162 @@ namespace std typedef basic_istream<_CharT, _Traits> istream_type; private: - istream_type* _M_stream; - _Tp _M_value; - bool _M_ok; - - public: - istream_iterator() : _M_stream(0), _M_ok(false) {} - - istream_iterator(istream_type& __s) : _M_stream(&__s) { _M_read(); } + istream_type* _M_stream; + _Tp _M_value; + bool _M_ok; - istream_iterator(const istream_iterator& __obj) - : _M_stream(__obj._M_stream), _M_value(__obj._M_value), - _M_ok(__obj._M_ok) + public: + /// Construct end of input stream iterator. + istream_iterator() + : _M_stream(0), _M_ok(false) {} + + /// Construct start of input stream iterator. + istream_iterator(istream_type& __s) + : _M_stream(&__s) + { _M_read(); } + + istream_iterator(const istream_iterator& __obj) + : _M_stream(__obj._M_stream), _M_value(__obj._M_value), + _M_ok(__obj._M_ok) { } const _Tp& - operator*() const { return _M_value; } + operator*() const + { + __glibcxx_requires_cond(_M_ok, + _M_message(__gnu_debug::__msg_deref_istream) + ._M_iterator(*this)); + return _M_value; + } const _Tp* operator->() const { return &(operator*()); } - istream_iterator& - operator++() - { _M_read(); return *this; } + istream_iterator& + operator++() + { + __glibcxx_requires_cond(_M_ok, + _M_message(__gnu_debug::__msg_inc_istream) + ._M_iterator(*this)); + _M_read(); + return *this; + } - istream_iterator - operator++(int) + istream_iterator + operator++(int) { + __glibcxx_requires_cond(_M_ok, + _M_message(__gnu_debug::__msg_inc_istream) + ._M_iterator(*this)); istream_iterator __tmp = *this; _M_read(); return __tmp; } - bool + bool _M_equal(const istream_iterator& __x) const - { return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream);} + { return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream); } - private: - void - _M_read() + private: + void + _M_read() { _M_ok = (_M_stream && *_M_stream) ? true : false; - if (_M_ok) + if (_M_ok) { *_M_stream >> _M_value; _M_ok = *_M_stream ? true : false; } } }; - + + /// Return true if x and y are both end or not end, or x and y are the same. template<typename _Tp, typename _CharT, typename _Traits, typename _Dist> - inline bool + inline bool operator==(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, - const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) + const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) { return __x._M_equal(__y); } + /// Return false if x and y are both end or not end, or x and y are the same. template <class _Tp, class _CharT, class _Traits, class _Dist> - inline bool + inline bool operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, - const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) + const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) { return !__x._M_equal(__y); } - - template<typename _Tp, typename _CharT = char, + /** + * @brief Provides output iterator semantics for streams. + * + * This class provides an iterator to write to an ostream. The type Tp is + * the only type written by this iterator and there must be an + * operator<<(Tp) defined. + * + * @param Tp The type to write to the ostream. + * @param CharT The ostream char_type. + * @param Traits The ostream char_traits. + */ + template<typename _Tp, typename _CharT = char, typename _Traits = char_traits<_CharT> > - class ostream_iterator - : public iterator<output_iterator_tag, void, void, void, void> + class ostream_iterator + : public iterator<output_iterator_tag, void, void, void, void> { public: + //@{ + /// Public typedef typedef _CharT char_type; typedef _Traits traits_type; typedef basic_ostream<_CharT, _Traits> ostream_type; + //@} private: - ostream_type* _M_stream; - const _CharT* _M_string; + ostream_type* _M_stream; + const _CharT* _M_string; public: + /// Construct from an ostream. ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_string(0) {} - ostream_iterator(ostream_type& __s, const _CharT* __c) + /** + * Construct from an ostream. + * + * The delimiter string @a c is written to the stream after every Tp + * written to the stream. The delimiter is not copied, and thus must + * not be destroyed while this iterator is in use. + * + * @param s Underlying ostream to write to. + * @param c CharT delimiter string to insert. + */ + ostream_iterator(ostream_type& __s, const _CharT* __c) : _M_stream(&__s), _M_string(__c) { } + /// Copy constructor. ostream_iterator(const ostream_iterator& __obj) : _M_stream(__obj._M_stream), _M_string(__obj._M_string) { } - ostream_iterator& - operator=(const _Tp& __value) - { + /// Writes @a value to underlying ostream using operator<<. If + /// constructed with delimiter string, writes delimiter to ostream. + ostream_iterator& + operator=(const _Tp& __value) + { + __glibcxx_requires_cond(_M_stream != 0, + _M_message(__gnu_debug::__msg_output_ostream) + ._M_iterator(*this)); *_M_stream << __value; if (_M_string) *_M_stream << _M_string; return *this; } - - ostream_iterator& - operator*() { return *this; } - - ostream_iterator& - operator++() { return *this; } - - ostream_iterator& - operator++(int) { return *this; } + + ostream_iterator& + operator*() + { return *this; } + + ostream_iterator& + operator++() + { return *this; } + + ostream_iterator& + operator++(int) + { return *this; } }; } // namespace std #endif diff --git a/contrib/libstdc++/include/bits/streambuf.tcc b/contrib/libstdc++/include/bits/streambuf.tcc index be858621b85b..554d06178997 100644 --- a/contrib/libstdc++/include/bits/streambuf.tcc +++ b/contrib/libstdc++/include/bits/streambuf.tcc @@ -32,90 +32,14 @@ // ISO C++ 14882: 27.5 Stream buffers // -#ifndef _CPP_BITS_STREAMBUF_TCC -#define _CPP_BITS_STREAMBUF_TCC 1 +#ifndef _STREAMBUF_TCC +#define _STREAMBUF_TCC 1 #pragma GCC system_header -namespace std +namespace std { template<typename _CharT, typename _Traits> - const size_t - basic_streambuf<_CharT, _Traits>::_S_pback_size; - - template<typename _CharT, typename _Traits> - typename basic_streambuf<_CharT, _Traits>::int_type - basic_streambuf<_CharT, _Traits>:: - sbumpc() - { - int_type __ret; - if (_M_in_cur && _M_in_cur < _M_in_end) - { - char_type __c = *(this->gptr()); - _M_in_cur_move(1); - __ret = traits_type::to_int_type(__c); - } - else - __ret = this->uflow(); - return __ret; - } - - template<typename _CharT, typename _Traits> - typename basic_streambuf<_CharT, _Traits>::int_type - basic_streambuf<_CharT, _Traits>:: - sputbackc(char_type __c) - { - int_type __ret; - bool __testpos = _M_in_cur && _M_in_beg < _M_in_cur; - if (!__testpos || !traits_type::eq(__c, this->gptr()[-1])) - __ret = this->pbackfail(traits_type::to_int_type(__c)); - else - { - _M_in_cur_move(-1); - __ret = traits_type::to_int_type(*this->gptr()); - } - return __ret; - } - - template<typename _CharT, typename _Traits> - typename basic_streambuf<_CharT, _Traits>::int_type - basic_streambuf<_CharT, _Traits>:: - sungetc() - { - int_type __ret; - if (_M_in_cur && _M_in_beg < _M_in_cur) - { - _M_in_cur_move(-1); - __ret = traits_type::to_int_type(*_M_in_cur); - } - else - __ret = this->pbackfail(); - return __ret; - } - - // Don't test against _M_buf + _M_buf_size, because _M_buf reflects - // allocated space, and on certain (rare but entirely legal) - // situations, there will be no allocated space yet the internal - // buffers will still be valid. (This happens if setp is used to set - // the internal buffer to say some externally-allocated sequence.) - template<typename _CharT, typename _Traits> - typename basic_streambuf<_CharT, _Traits>::int_type - basic_streambuf<_CharT, _Traits>:: - sputc(char_type __c) - { - int_type __ret; - if (_M_out_buf_size()) - { - *_M_out_cur = __c; - _M_out_cur_move(1); - __ret = traits_type::to_int_type(__c); - } - else - __ret = this->overflow(traits_type::to_int_type(__c)); - return __ret; - } - - template<typename _CharT, typename _Traits> streamsize basic_streambuf<_CharT, _Traits>:: xsgetn(char_type* __s, streamsize __n) @@ -123,20 +47,20 @@ namespace std streamsize __ret = 0; while (__ret < __n) { - size_t __buf_len = _M_in_end - _M_in_cur; - if (__buf_len > 0) + const size_t __buf_len = this->egptr() - this->gptr(); + if (__buf_len) { - size_t __remaining = __n - __ret; - size_t __len = min(__buf_len, __remaining); - traits_type::copy(__s, _M_in_cur, __len); + const size_t __remaining = __n - __ret; + const size_t __len = std::min(__buf_len, __remaining); + traits_type::copy(__s, this->gptr(), __len); __ret += __len; __s += __len; - _M_in_cur_move(__len); + this->gbump(__len); } - + if (__ret < __n) { - int_type __c = this->uflow(); + const int_type __c = this->uflow(); if (!traits_type::eq_int_type(__c, traits_type::eof())) { traits_type::assign(*__s++, traits_type::to_char_type(__c)); @@ -149,11 +73,6 @@ namespace std return __ret; } - // Don't test against _M_buf + _M_buf_size, because _M_buf reflects - // allocated space, and on certain (rare but entirely legal) - // situations, there will be no allocated space yet the internal - // buffers will still be valid. (This happens if setp is used to set - // the internal buffer to say some externally-allocated sequence.) template<typename _CharT, typename _Traits> streamsize basic_streambuf<_CharT, _Traits>:: @@ -162,15 +81,15 @@ namespace std streamsize __ret = 0; while (__ret < __n) { - off_type __buf_len = _M_out_buf_size(); - if (__buf_len > 0) + const size_t __buf_len = this->epptr() - this->pptr(); + if (__buf_len) { - off_type __remaining = __n - __ret; - off_type __len = min(__buf_len, __remaining); - traits_type::copy(_M_out_cur, __s, __len); + const size_t __remaining = __n - __ret; + const size_t __len = std::min(__buf_len, __remaining); + traits_type::copy(this->pptr(), __s, __len); __ret += __len; __s += __len; - _M_out_cur_move(__len); + this->pbump(__len); } if (__ret < __n) @@ -194,64 +113,51 @@ namespace std // necessary. template<typename _CharT, typename _Traits> streamsize - __copy_streambufs(basic_ios<_CharT, _Traits>& __ios, - basic_streambuf<_CharT, _Traits>* __sbin, - basic_streambuf<_CharT, _Traits>* __sbout) - { - streamsize __ret = 0; - try - { - typename _Traits::int_type __c = __sbin->sgetc(); - while (!_Traits::eq_int_type(__c, _Traits::eof())) - { - const size_t __n = __sbin->_M_in_end - __sbin->_M_in_cur; - if (__n > 1) - { - const size_t __wrote = __sbout->sputn(__sbin->_M_in_cur, - __n); - __sbin->_M_in_cur_move(__wrote); - __ret += __wrote; - if (__wrote < __n) - break; - __c = __sbin->underflow(); - } - else - { - __c = __sbout->sputc(_Traits::to_char_type(__c)); - if (_Traits::eq_int_type(__c, _Traits::eof())) - break; - ++__ret; - __c = __sbin->snextc(); - } - } - } - catch(exception& __fail) - { - __ios.setstate(ios_base::failbit); - if ((__ios.exceptions() & ios_base::failbit) != 0) - __throw_exception_again; - } - return __ret; - } + __copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin, + basic_streambuf<_CharT, _Traits>* __sbout) + { + streamsize __ret = 0; + typename _Traits::int_type __c = __sbin->sgetc(); + while (!_Traits::eq_int_type(__c, _Traits::eof())) + { + const size_t __n = __sbin->egptr() - __sbin->gptr(); + if (__n > 1) + { + const size_t __wrote = __sbout->sputn(__sbin->gptr(), __n); + __sbin->gbump(__wrote); + __ret += __wrote; + if (__wrote < __n) + break; + __c = __sbin->underflow(); + } + else + { + __c = __sbout->sputc(_Traits::to_char_type(__c)); + if (_Traits::eq_int_type(__c, _Traits::eof())) + break; + ++__ret; + __c = __sbin->snextc(); + } + } + return __ret; + } // Inhibit implicit instantiations for required instantiations, - // which are defined via explicit instantiations elsewhere. + // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. -#if _GLIBCPP_EXTERN_TEMPLATE +#if _GLIBCXX_EXTERN_TEMPLATE extern template class basic_streambuf<char>; extern template streamsize - __copy_streambufs(basic_ios<char>&, basic_streambuf<char>*, - basic_streambuf<char>*); + __copy_streambufs(basic_streambuf<char>*, basic_streambuf<char>*); -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T extern template class basic_streambuf<wchar_t>; extern template streamsize - __copy_streambufs(basic_ios<wchar_t>&, basic_streambuf<wchar_t>*, - basic_streambuf<wchar_t>*); + __copy_streambufs(basic_streambuf<wchar_t>*, basic_streambuf<wchar_t>*); #endif #endif } // namespace std -#endif +#endif diff --git a/contrib/libstdc++/include/bits/streambuf_iterator.h b/contrib/libstdc++/include/bits/streambuf_iterator.h index d482aba82560..970933578c73 100644 --- a/contrib/libstdc++/include/bits/streambuf_iterator.h +++ b/contrib/libstdc++/include/bits/streambuf_iterator.h @@ -1,6 +1,6 @@ // Streambuf iterators -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -33,177 +33,223 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_STREAMBUF_ITERATOR_H -#define _CPP_BITS_STREAMBUF_ITERATOR_H 1 +#ifndef _STREAMBUF_ITERATOR_H +#define _STREAMBUF_ITERATOR_H 1 #pragma GCC system_header #include <streambuf> +#include <debug/debug.h> // NB: Should specialize copy, find algorithms for streambuf iterators. namespace std { // 24.5.3 Template class istreambuf_iterator + /// Provides input iterator semantics for streambufs. template<typename _CharT, typename _Traits> class istreambuf_iterator : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type, - _CharT*, _CharT&> + _CharT*, _CharT&> { public: // Types: - typedef _CharT char_type; - typedef _Traits traits_type; - typedef typename _Traits::int_type int_type; - typedef basic_streambuf<_CharT, _Traits> streambuf_type; - typedef basic_istream<_CharT, _Traits> istream_type; + //@{ + /// Public typedefs + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename _Traits::int_type int_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_istream<_CharT, _Traits> istream_type; + //@} private: - // 24.5.3 istreambuf_iterator - // p 1 + // 24.5.3 istreambuf_iterator + // p 1 // If the end of stream is reached (streambuf_type::sgetc() // returns traits_type::eof()), the iterator becomes equal to // the "end of stream" iterator value. // NB: This implementation assumes the "end of stream" value // is EOF, or -1. - mutable streambuf_type* _M_sbuf; - int_type _M_c; + mutable streambuf_type* _M_sbuf; + int_type _M_c; public: - istreambuf_iterator() throw() + /// Construct end of input stream iterator. + istreambuf_iterator() throw() : _M_sbuf(0), _M_c(traits_type::eof()) { } - + + /// Construct start of input stream iterator. istreambuf_iterator(istream_type& __s) throw() : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { } + /// Construct start of streambuf iterator. istreambuf_iterator(streambuf_type* __s) throw() : _M_sbuf(__s), _M_c(traits_type::eof()) { } - - // NB: The result of operator*() on an end of stream is undefined. - char_type + + /// Return the current character pointed to by iterator. This returns + /// streambuf.sgetc(). It cannot be assigned. NB: The result of + /// operator*() on an end of stream is undefined. + char_type operator*() const - { return traits_type::to_char_type(_M_get()); } - - istreambuf_iterator& + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + // Dereferencing a past-the-end istreambuf_iterator is a + // libstdc++ extension + __glibcxx_requires_cond(!_M_at_eof(), + _M_message(__gnu_debug::__msg_deref_istreambuf) + ._M_iterator(*this)); +#endif + return traits_type::to_char_type(_M_get()); + } + + /// Advance the iterator. Calls streambuf.sbumpc(). + istreambuf_iterator& operator++() - { + { + __glibcxx_requires_cond(!_M_at_eof(), + _M_message(__gnu_debug::__msg_inc_istreambuf) + ._M_iterator(*this)); const int_type __eof = traits_type::eof(); if (_M_sbuf && traits_type::eq_int_type(_M_sbuf->sbumpc(), __eof)) _M_sbuf = 0; else _M_c = __eof; - return *this; + return *this; } + /// Advance the iterator. Calls streambuf.sbumpc(). istreambuf_iterator operator++(int) { + __glibcxx_requires_cond(!_M_at_eof(), + _M_message(__gnu_debug::__msg_inc_istreambuf) + ._M_iterator(*this)); + const int_type __eof = traits_type::eof(); istreambuf_iterator __old = *this; if (_M_sbuf - && traits_type::eq_int_type((__old._M_c = _M_sbuf->sbumpc()), + && traits_type::eq_int_type((__old._M_c = _M_sbuf->sbumpc()), __eof)) _M_sbuf = 0; else _M_c = __eof; - return __old; + return __old; } -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + // _GLIBCXX_RESOLVE_LIB_DEFECTS // 110 istreambuf_iterator::equal not const // NB: there is also number 111 (NAD, Future) pending on this function. - bool + /// Return true both iterators are end or both are not end. + bool equal(const istreambuf_iterator& __b) const { - const int_type __eof = traits_type::eof(); - bool __thiseof = traits_type::eq_int_type(_M_get(), __eof); - bool __beof = traits_type::eq_int_type(__b._M_get(), __eof); + const bool __thiseof = _M_at_eof(); + const bool __beof = __b._M_at_eof(); return (__thiseof && __beof || (!__thiseof && !__beof)); } -#endif private: - int_type + int_type _M_get() const - { + { const int_type __eof = traits_type::eof(); int_type __ret = __eof; if (_M_sbuf) - { + { if (!traits_type::eq_int_type(_M_c, __eof)) __ret = _M_c; - else - if (traits_type::eq_int_type((__ret = _M_sbuf->sgetc()), __eof)) - _M_sbuf = 0; + else if (traits_type::eq_int_type((__ret = _M_sbuf->sgetc()), + __eof)) + _M_sbuf = 0; } return __ret; } + + bool + _M_at_eof() const + { + const int_type __eof = traits_type::eof(); + return traits_type::eq_int_type(_M_get(), __eof); + } }; template<typename _CharT, typename _Traits> - inline bool + inline bool operator==(const istreambuf_iterator<_CharT, _Traits>& __a, const istreambuf_iterator<_CharT, _Traits>& __b) { return __a.equal(__b); } template<typename _CharT, typename _Traits> - inline bool + inline bool operator!=(const istreambuf_iterator<_CharT, _Traits>& __a, const istreambuf_iterator<_CharT, _Traits>& __b) { return !__a.equal(__b); } + /// Provides output iterator semantics for streambufs. template<typename _CharT, typename _Traits> class ostreambuf_iterator : public iterator<output_iterator_tag, void, void, void, void> { public: // Types: + //@{ + /// Public typedefs typedef _CharT char_type; typedef _Traits traits_type; typedef basic_streambuf<_CharT, _Traits> streambuf_type; typedef basic_ostream<_CharT, _Traits> ostream_type; + //@} private: - streambuf_type* _M_sbuf; - bool _M_failed; + streambuf_type* _M_sbuf; + bool _M_failed; public: + /// Construct output iterator from ostream. ostreambuf_iterator(ostream_type& __s) throw () : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { } - + + /// Construct output iterator from streambuf. ostreambuf_iterator(streambuf_type* __s) throw () : _M_sbuf(__s), _M_failed(!_M_sbuf) { } - ostreambuf_iterator& + /// Write character to streambuf. Calls streambuf.sputc(). + ostreambuf_iterator& operator=(_CharT __c) { - if (!_M_failed && + if (!_M_failed && _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof())) _M_failed = true; return *this; } - ostreambuf_iterator& - operator*() throw() + /// Return *this. + ostreambuf_iterator& + operator*() { return *this; } - ostreambuf_iterator& - operator++(int) throw() + /// Return *this. + ostreambuf_iterator& + operator++(int) { return *this; } - ostreambuf_iterator& - operator++() throw() + /// Return *this. + ostreambuf_iterator& + operator++() { return *this; } - bool + /// Return true if previous operator=() failed. + bool failed() const throw() { return _M_failed; } - ostreambuf_iterator& + ostreambuf_iterator& _M_put(const _CharT* __ws, streamsize __len) { - if (__builtin_expect(!_M_failed, true) && - __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len, false)) + if (__builtin_expect(!_M_failed, true) + && __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len, + false)) _M_failed = true; return *this; } diff --git a/contrib/libstdc++/include/bits/stringfwd.h b/contrib/libstdc++/include/bits/stringfwd.h index db40befdab6a..99d3ce3a534e 100644 --- a/contrib/libstdc++/include/bits/stringfwd.h +++ b/contrib/libstdc++/include/bits/stringfwd.h @@ -36,8 +36,8 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_STRINGFWD_H -#define _CPP_BITS_STRINGFWD_H 1 +#ifndef _STRINGFWD_H +#define _STRINGFWD_H 1 #pragma GCC system_header @@ -45,25 +45,25 @@ namespace std { - template<typename _Alloc> + template<typename _Alloc> class allocator; template<class _CharT> struct char_traits; - template<typename _CharT, typename _Traits = char_traits<_CharT>, + template<typename _CharT, typename _Traits = char_traits<_CharT>, typename _Alloc = allocator<_CharT> > class basic_string; - + template<> struct char_traits<char>; typedef basic_string<char> string; -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T template<> struct char_traits<wchar_t>; typedef basic_string<wchar_t> wstring; #endif } // namespace std -#endif // _CPP_BITS_STRINGFWD_H +#endif // _STRINGFWD_H diff --git a/contrib/libstdc++/include/bits/type_traits.h b/contrib/libstdc++/include/bits/type_traits.h index 61bc43692758..9b91e5c5cdf0 100644 --- a/contrib/libstdc++/include/bits/type_traits.h +++ b/contrib/libstdc++/include/bits/type_traits.h @@ -1,6 +1,6 @@ // Type traits implementation -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -46,8 +46,8 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_TYPE_TRAITS_H -#define _CPP_BITS_TYPE_TRAITS_H 1 +#ifndef _TYPE_TRAITS_H +#define _TYPE_TRAITS_H 1 #pragma GCC system_header @@ -74,10 +74,10 @@ attain their correct values by one of these means: EXAMPLE: //Copy an array of elements which have non-trivial copy constructors -template <class _Tp> void +template <class _Tp> void copy(_Tp* __source,_Tp* __destination,int __n,__false_type); //Copy an array of elements which have trivial copy constructors. Use memcpy. -template <class _Tp> void +template <class _Tp> void copy(_Tp* __source,_Tp* __destination,int __n,__true_type); //Copy an array of any type by using the most efficient copy mechanism @@ -91,16 +91,17 @@ struct __true_type {}; struct __false_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 - automatically specializes __type_traits that this - __type_traits template is special. It just makes sure that - things work if an implementation is using a template - called __type_traits for something unrelated. */ + struct __type_traits + { + typedef __true_type this_dummy_member_must_be_first; + /* Do not remove this member. It informs a compiler which + automatically specializes __type_traits that this + __type_traits template is special. It just makes sure that + things work if an implementation is using a template + called __type_traits for something unrelated. */ /* The following restrictions should be observed for the sake of - compilers which automatically produce type specific specializations + compilers which automatically produce type specific specializations of this class: - You may reorder the members below if you wish - You may remove any of the members below if you wish @@ -108,231 +109,296 @@ struct __type_traits { name change in the compiler - Members you add will be treated like regular members unless you add the appropriate support in the compiler. */ - - typedef __false_type has_trivial_default_constructor; - typedef __false_type has_trivial_copy_constructor; - typedef __false_type has_trivial_assignment_operator; - typedef __false_type has_trivial_destructor; - typedef __false_type is_POD_type; -}; + + typedef __false_type has_trivial_default_constructor; + typedef __false_type has_trivial_copy_constructor; + typedef __false_type has_trivial_assignment_operator; + typedef __false_type has_trivial_destructor; + typedef __false_type is_POD_type; + }; // Provide some specializations. -template<> 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; -}; - -template<> 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; -}; - -template<> 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; -}; - -template<> 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; -}; - -template<> 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; -}; - -template<> struct __type_traits<short> { - typedef __true_type has_trivial_default_constructor; - typedef __true_type has_trivial_copy_constructor; - typedef __true_type has_trivial_assignment_operator; - typedef __true_type has_trivial_destructor; - typedef __true_type is_POD_type; -}; - -template<> struct __type_traits<unsigned short> { - typedef __true_type has_trivial_default_constructor; - typedef __true_type has_trivial_copy_constructor; - typedef __true_type has_trivial_assignment_operator; - typedef __true_type has_trivial_destructor; - typedef __true_type is_POD_type; -}; - -template<> struct __type_traits<int> { - typedef __true_type has_trivial_default_constructor; - typedef __true_type has_trivial_copy_constructor; - typedef __true_type has_trivial_assignment_operator; - typedef __true_type has_trivial_destructor; - typedef __true_type is_POD_type; -}; - -template<> struct __type_traits<unsigned int> { - typedef __true_type has_trivial_default_constructor; - typedef __true_type has_trivial_copy_constructor; - typedef __true_type has_trivial_assignment_operator; - typedef __true_type has_trivial_destructor; - typedef __true_type is_POD_type; -}; - -template<> struct __type_traits<long> { - typedef __true_type has_trivial_default_constructor; - typedef __true_type has_trivial_copy_constructor; - typedef __true_type has_trivial_assignment_operator; - typedef __true_type has_trivial_destructor; - typedef __true_type is_POD_type; -}; - -template<> struct __type_traits<unsigned long> { - typedef __true_type has_trivial_default_constructor; - typedef __true_type has_trivial_copy_constructor; - typedef __true_type has_trivial_assignment_operator; - typedef __true_type has_trivial_destructor; - typedef __true_type is_POD_type; -}; - -template<> 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; -}; - -template<> 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; -}; - -template<> struct __type_traits<float> { - typedef __true_type has_trivial_default_constructor; - typedef __true_type has_trivial_copy_constructor; - typedef __true_type has_trivial_assignment_operator; - typedef __true_type has_trivial_destructor; - typedef __true_type is_POD_type; -}; - -template<> struct __type_traits<double> { - typedef __true_type has_trivial_default_constructor; - typedef __true_type has_trivial_copy_constructor; - typedef __true_type has_trivial_assignment_operator; - typedef __true_type has_trivial_destructor; - typedef __true_type is_POD_type; -}; - -template<> struct __type_traits<long double> { - typedef __true_type has_trivial_default_constructor; - typedef __true_type has_trivial_copy_constructor; - typedef __true_type has_trivial_assignment_operator; - typedef __true_type has_trivial_destructor; - typedef __true_type is_POD_type; -}; +template<> + 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; + }; + +template<> + 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; + }; + +template<> + 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; + }; + +template<> + 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; + }; + +template<> + 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; + }; + +template<> + struct __type_traits<short> + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits<unsigned short> + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits<int> + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits<unsigned int> + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits<long> + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits<unsigned long> + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + 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; + }; + +template<> + 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; + }; + +template<> + struct __type_traits<float> + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits<double> + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +template<> + struct __type_traits<long double> + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; 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; - typedef __true_type has_trivial_destructor; - typedef __true_type is_POD_type; -}; - - -// The following could be written in terms of numeric_limits. + struct __type_traits<_Tp*> + { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; + }; + +// 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; -}; - -template<> struct _Is_integer<bool> { - typedef __true_type _Integral; -}; - -template<> struct _Is_integer<char> { - typedef __true_type _Integral; -}; - -template<> struct _Is_integer<signed char> { - typedef __true_type _Integral; -}; - -template<> struct _Is_integer<unsigned char> { - typedef __true_type _Integral; -}; - -template<> struct _Is_integer<wchar_t> { - typedef __true_type _Integral; -}; - -template<> struct _Is_integer<short> { - typedef __true_type _Integral; -}; - -template<> struct _Is_integer<unsigned short> { - typedef __true_type _Integral; -}; - -template<> struct _Is_integer<int> { - typedef __true_type _Integral; -}; - -template<> struct _Is_integer<unsigned int> { - typedef __true_type _Integral; -}; - -template<> struct _Is_integer<long> { - typedef __true_type _Integral; -}; - -template<> struct _Is_integer<unsigned long> { - typedef __true_type _Integral; -}; - -template<> struct _Is_integer<long long> { - typedef __true_type _Integral; -}; - -template<> struct _Is_integer<unsigned long long> { - typedef __true_type _Integral; -}; - -template<typename _Tp> struct _Is_normal_iterator { - typedef __false_type _Normal; -}; +template <class _Tp> + struct _Is_integer + { + typedef __false_type _Integral; + }; + +template<> + struct _Is_integer<bool> + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer<char> + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer<signed char> + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer<unsigned char> + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer<wchar_t> + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer<short> + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer<unsigned short> + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer<int> + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer<unsigned int> + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer<long> + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer<unsigned long> + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer<long long> + { + typedef __true_type _Integral; + }; + +template<> + struct _Is_integer<unsigned long long> + { + typedef __true_type _Integral; + }; + +template<typename _Tp> + struct _Is_normal_iterator + { + typedef __false_type _Normal; + }; // Forward declaration hack, should really include this from somewhere. namespace __gnu_cxx { - template<typename _Iterator, typename _Container> class __normal_iterator; + template<typename _Iterator, typename _Container> + class __normal_iterator; } template<typename _Iterator, typename _Container> -struct _Is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, _Container> > { - typedef __true_type _Normal; -}; + struct _Is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, + _Container> > + { + typedef __true_type _Normal; + }; -#endif /* _CPP_BITS_TYPE_TRAITS_H */ +#endif /* _TYPE_TRAITS_H */ // Local Variables: // mode:C++ diff --git a/contrib/libstdc++/include/bits/valarray_after.h b/contrib/libstdc++/include/bits/valarray_after.h new file mode 100644 index 000000000000..b74cab5dbac3 --- /dev/null +++ b/contrib/libstdc++/include/bits/valarray_after.h @@ -0,0 +1,499 @@ +// The template and inlines for the -*- C++ -*- internal _Meta class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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> + +/** @file valarray_meta.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VALARRAY_AFTER_H +#define _VALARRAY_AFTER_H 1 + +#pragma GCC system_header + +namespace std +{ + + // + // 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,std::_Expr,_Clos>, value_type> + operator+() const; + + _Expr<_UnClos<__negate,std::_Expr,_Clos>, value_type> + operator-() const; + + _Expr<_UnClos<__bitwise_not,std::_Expr,_Clos>, value_type> + operator~() const; + + _Expr<_UnClos<__logical_not,std::_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; + + value_type min() const; + value_type max() const; + + valarray<value_type> apply(value_type (*)(const value_type&)) const; + valarray<value_type> apply(value_type (*)(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 (); } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos, _Tp>::shift(int __n) const + { return valarray<_Tp>(_M_closure).shift(__n); } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos, _Tp>::cshift(int __n) const + { return valarray<_Tp>(_M_closure).cshift(__n); } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const + { return valarray<_Tp>(_M_closure).apply(__f); } + + template<class _Clos, typename _Tp> + inline valarray<_Tp> + _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const + { return valarray<_Tp>(_M_closure).apply(__f); } + + // XXX: replace this with a more robust summation algorithm. + template<class _Clos, typename _Tp> + inline _Tp + _Expr<_Clos,_Tp>::sum() const + { + size_t __n = _M_closure.size(); + if (__n == 0) + return _Tp(); + else + { + _Tp __s = _M_closure[--__n]; + while (__n != 0) + __s += _M_closure[--__n]; + return __s; + } + } + + template<class _Clos, typename _Tp> + inline _Tp + _Expr<_Clos, _Tp>::min() const + { return __valarray_min(_M_closure); } + + template<class _Clos, typename _Tp> + inline _Tp + _Expr<_Clos, _Tp>::max() const + { return __valarray_max(_M_closure); } + + template<class _Dom, typename _Tp> + inline _Expr<_UnClos<__logical_not,_Expr,_Dom>, bool> + _Expr<_Dom,_Tp>::operator!() const + { + typedef _UnClos<__logical_not,std::_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,std::_Expr,_Dom>,_Tp> \ + _Expr<_Dom,_Tp>::operator _Op() const \ + { \ + typedef _UnClos<_Name,std::_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 __fun<_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 __fun<_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 __fun<_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 __fun<_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 __fun<_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 __fun<_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 __fun<_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 __fun<_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 __fun<_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 __fun<_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) + _DEFINE_EXPR_BINARY_OPERATOR(&&, __logical_and) + _DEFINE_EXPR_BINARY_OPERATOR(||, __logical_or) + _DEFINE_EXPR_BINARY_OPERATOR(==, __equal_to) + _DEFINE_EXPR_BINARY_OPERATOR(!=, __not_equal_to) + _DEFINE_EXPR_BINARY_OPERATOR(<, __less) + _DEFINE_EXPR_BINARY_OPERATOR(>, __greater) + _DEFINE_EXPR_BINARY_OPERATOR(<=, __less_equal) + _DEFINE_EXPR_BINARY_OPERATOR(>=, __greater_equal) + +#undef _DEFINE_EXPR_BINARY_OPERATOR + +#define _DEFINE_EXPR_UNARY_FUNCTION(_Name) \ + template<class _Dom> \ + inline _Expr<_UnClos<__##_Name,_Expr,_Dom>,typename _Dom::value_type>\ + _Name(const _Expr<_Dom,typename _Dom::value_type>& __e) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _UnClos<__##_Name,_Expr,_Dom> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__e())); \ + } \ + \ + template<typename _Tp> \ + inline _Expr<_UnClos<__##_Name,_ValArray,_Tp>,_Tp> \ + _Name(const valarray<_Tp>& __v) \ + { \ + typedef _UnClos<__##_Name,_ValArray,_Tp> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__v)); \ + } + + _DEFINE_EXPR_UNARY_FUNCTION(abs) + _DEFINE_EXPR_UNARY_FUNCTION(cos) + _DEFINE_EXPR_UNARY_FUNCTION(acos) + _DEFINE_EXPR_UNARY_FUNCTION(cosh) + _DEFINE_EXPR_UNARY_FUNCTION(sin) + _DEFINE_EXPR_UNARY_FUNCTION(asin) + _DEFINE_EXPR_UNARY_FUNCTION(sinh) + _DEFINE_EXPR_UNARY_FUNCTION(tan) + _DEFINE_EXPR_UNARY_FUNCTION(tanh) + _DEFINE_EXPR_UNARY_FUNCTION(atan) + _DEFINE_EXPR_UNARY_FUNCTION(exp) + _DEFINE_EXPR_UNARY_FUNCTION(log) + _DEFINE_EXPR_UNARY_FUNCTION(log10) + _DEFINE_EXPR_UNARY_FUNCTION(sqrt) + +#undef _DEFINE_EXPR_UNARY_FUNCTION + +#define _DEFINE_EXPR_BINARY_FUNCTION(_Fun) \ + template<class _Dom1, class _Dom2> \ + inline _Expr<_BinClos<__##_Fun,_Expr,_Expr,_Dom1,_Dom2>, \ + typename _Dom1::value_type> \ + _Fun(const _Expr<_Dom1,typename _Dom1::value_type>& __e1, \ + const _Expr<_Dom2,typename _Dom2::value_type>& __e2) \ + { \ + typedef typename _Dom1::value_type _Tp; \ + typedef _BinClos<__##_Fun,_Expr,_Expr,_Dom1,_Dom2> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__e1(), __e2())); \ + } \ + \ + template<class _Dom> \ + inline _Expr<_BinClos<__##_Fun, _Expr, _ValArray, _Dom, \ + typename _Dom::value_type>, \ + typename _Dom::value_type> \ + _Fun(const _Expr<_Dom,typename _Dom::value_type>& __e, \ + const valarray<typename _Dom::value_type>& __v) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<__##_Fun, _Expr, _ValArray, _Dom, _Tp> _Closure;\ + return _Expr<_Closure,_Tp>(_Closure(__e(), __v)); \ + } \ + \ + template<class _Dom> \ + inline _Expr<_BinClos<__##_Fun, _ValArray, _Expr, \ + typename _Dom::value_type,_Dom>, \ + typename _Dom::value_type> \ + _Fun(const valarray<typename _Dom::valarray>& __v, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<__##_Fun,_ValArray,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__v, __e())); \ + } \ + \ + template<class _Dom> \ + inline _Expr<_BinClos<__##_Fun,_Expr,_Constant,_Dom, \ + typename _Dom::value_type>, \ + typename _Dom::value_type> \ + _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \ + const typename _Dom::value_type& __t) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<__##_Fun,_Expr,_Constant,_Dom,_Tp> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__e(), __t)); \ + } \ + \ + template<class _Dom> \ + inline _Expr<_BinClos<__##_Fun,_Constant,_Expr, \ + typename _Dom::value_type,_Dom>, \ + typename _Dom::value_type> \ + _Fun(const typename _Dom::value_type& __t, \ + const _Expr<_Dom,typename _Dom::value_type>& __e) \ + { \ + typedef typename _Dom::value_type _Tp; \ + typedef _BinClos<__##_Fun, _Constant,_Expr,_Tp,_Dom> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__t, __e())); \ + } \ + \ + template<typename _Tp> \ + inline _Expr<_BinClos<__##_Fun,_ValArray,_ValArray,_Tp,_Tp>, _Tp> \ + _Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ + { \ + typedef _BinClos<__##_Fun,_ValArray,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__v, __w)); \ + } \ + \ + template<typename _Tp> \ + inline _Expr<_BinClos<__##_Fun,_ValArray,_Constant,_Tp,_Tp>,_Tp> \ + _Fun(const valarray<_Tp>& __v, const _Tp& __t) \ + { \ + typedef _BinClos<__##_Fun,_ValArray,_Constant,_Tp,_Tp> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__v, __t)); \ + } \ + \ + template<typename _Tp> \ + inline _Expr<_BinClos<__##_Fun,_Constant,_ValArray,_Tp,_Tp>,_Tp> \ + _Fun(const _Tp& __t, const valarray<_Tp>& __v) \ + { \ + typedef _BinClos<__##_Fun,_Constant,_ValArray,_Tp,_Tp> _Closure; \ + return _Expr<_Closure,_Tp>(_Closure(__t, __v)); \ + } + +_DEFINE_EXPR_BINARY_FUNCTION(atan2) +_DEFINE_EXPR_BINARY_FUNCTION(pow) + +#undef _DEFINE_EXPR_BINARY_FUNCTION + +} // std:: + + +#endif /* _CPP_VALARRAY_AFTER_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/contrib/libstdc++/include/bits/valarray_array.h b/contrib/libstdc++/include/bits/valarray_array.h index c880478aa417..e18e8e8e9e81 100644 --- a/contrib/libstdc++/include/bits/valarray_array.h +++ b/contrib/libstdc++/include/bits/valarray_array.h @@ -1,6 +1,7 @@ // The template and inlines for the -*- C++ -*- internal _Array helper class. -// Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. +// Copyright (C) 1997, 1998, 1999, 2000, 2003 +// Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -34,8 +35,8 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_ARRAY_H -#define _CPP_BITS_ARRAY_H 1 +#ifndef _VALARRAY_ARRAY_H +#define _VALARRAY_ARRAY_H 1 #pragma GCC system_header @@ -50,18 +51,18 @@ namespace std // // Helper functions on raw pointers // - + // We get memory by the old fashion way inline void* __valarray_get_memory(size_t __n) { return operator new(__n); } - + template<typename _Tp> inline _Tp*__restrict__ __valarray_get_storage(size_t __n) { return static_cast<_Tp*__restrict__> - (__valarray_get_memory(__n * sizeof(_Tp))); + (std::__valarray_get_memory(__n * sizeof(_Tp))); } // Return memory to the system @@ -87,7 +88,7 @@ namespace std // For fundamental types, it suffices to say 'memset()' inline static void _S_do_it(_Tp* __restrict__ __b, _Tp* __restrict__ __e) - { memset(__b, 0, (__e - __b)*sizeof(_Tp)); } + { std::memset(__b, 0, (__e - __b)*sizeof(_Tp)); } }; template<typename _Tp> @@ -97,7 +98,7 @@ namespace std _Array_default_ctor<_Tp, __is_fundamental<_Tp>::_M_type>:: _S_do_it(__b, __e); } - + // Turn a raw-memory into an array of _Tp filled with __t // This is the required in valarray<T> v(n, t). Also // used in valarray<>::resize(). @@ -149,7 +150,7 @@ namespace std inline static void _S_do_it(const _Tp* __restrict__ __b, const _Tp* __restrict__ __e, _Tp* __restrict__ __o) - { memcpy(__o, __b, (__e - __b)*sizeof(_Tp)); } + { std::memcpy(__o, __b, (__e - __b)*sizeof(_Tp)); } }; template<typename _Tp> @@ -195,13 +196,13 @@ namespace std if (!__is_fundamental<_Tp>::_M_type) while (__b != __e) { __b->~_Tp(); ++__b; } } - + // Fill a 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 @@ -215,7 +216,7 @@ namespace std __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>] // For non-fundamental types, it is wrong to say 'memcpy()' template<typename _Tp, bool> @@ -223,7 +224,7 @@ namespace std { inline static void _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) - { while (__n--) *__b++ = *__a++; } + { while (__n--) *__b++ = *__a++; } }; template<typename _Tp> @@ -231,7 +232,7 @@ namespace std { inline static void _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) - { memcpy (__b, __a, __n * sizeof (_Tp)); } + { std::memcpy (__b, __a, __n * sizeof (_Tp)); } }; // Copy a plain array __a[<__n>] into a play array __b[<>] @@ -269,7 +270,7 @@ namespace std __dst[__i * __s2] = __src [ __i * __s1]; } - + // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>] template<typename _Tp> inline void @@ -340,7 +341,7 @@ namespace std } return __r; } - + template<typename _Ta> inline typename _Ta::value_type __valarray_max(const _Ta& __a) @@ -356,13 +357,13 @@ namespace std } return __r; } - + // // 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 { @@ -375,34 +376,34 @@ namespace std _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); } - + { std::__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); } - + { std::__valarray_fill (__a._M_data, __n, __s, __t); } + template<typename _Tp> inline void - __valarray_fill (_Array<_Tp> __a, _Array<size_t> __i, + __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); } + { std::__valarray_fill (__a._M_data, __i._M_data, __n, __t); } // Copy a plain array __a[<__n>] into a play array __b[<>] 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); } - + { std::__valarray_copy(__a._M_data, __n, __b._M_data); } + // Copy strided array __a[<__n : __s>] in plain __b[<__n>] 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); } + { std::__valarray_copy(__a._M_data, __n, __s, __b._M_data); } // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>] template<typename _Tp> @@ -416,22 +417,22 @@ namespace std inline void __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1, _Array<_Tp> __b, size_t __s2) - { __valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); } + { std::__valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); } + - // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>] template<typename _Tp> inline void - __valarray_copy(_Array<_Tp> __a, _Array<size_t> __i, + __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); } - + { std::__valarray_copy(__a._M_data, __i._M_data, __b._M_data, __n); } + // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]] template<typename _Tp> inline void - __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, + __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); } + { std::__valarray_copy(__a._M_data, __n, __b._M_data, __i._M_data); } // Copy the __n first elements of an indexed array __src[<__i>] into // another indexed array __dst[<__j>]. @@ -440,29 +441,29 @@ namespace std __valarray_copy(_Array<_Tp> __src, size_t __n, _Array<size_t> __i, _Array<_Tp> __dst, _Array<size_t> __j) { - __valarray_copy(__src._M_data, __n, __i._M_data, - __dst._M_data, __j._M_data); + std::__valarray_copy(__src._M_data, __n, __i._M_data, + __dst._M_data, __j._M_data); } template<typename _Tp> inline _Array<_Tp>::_Array (size_t __n) : _M_data(__valarray_get_storage<_Tp>(__n)) - { __valarray_default_construct(_M_data, _M_data + __n); } + { std::__valarray_default_construct(_M_data, _M_data + __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) + 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) + _Array<_Tp>::_Array (const _Tp* __restrict__ __b, size_t __s) : _M_data(__valarray_get_storage<_Tp>(__s)) - { __valarray_copy_construct(__b, __s, _M_data); } + { std::__valarray_copy_construct(__b, __s, _M_data); } template<typename _Tp> inline _Tp* @@ -489,7 +490,7 @@ _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \ \ template<typename _Tp, class _Dom> \ void \ -_Array_augmented_##_Name (_Array<_Tp> __a, \ +_Array_augmented_##_Name (_Array<_Tp> __a, \ const _Expr<_Dom,_Tp>& __e, size_t __n) \ { \ _Tp* __p (__a._M_data); \ @@ -498,9 +499,9 @@ _Array_augmented_##_Name (_Array<_Tp> __a, \ \ template<typename _Tp> \ inline void \ -_Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, size_t __s, \ +_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; \ @@ -508,7 +509,7 @@ _Array_augmented_##_Name (_Array<_Tp> __a, size_t __n, size_t __s, \ \ template<typename _Tp> \ inline void \ -_Array_augmented_##_Name (_Array<_Tp> __a, _Array<_Tp> __b, \ +_Array_augmented_##_Name (_Array<_Tp> __a, _Array<_Tp> __b, \ size_t __n, size_t __s) \ { \ _Tp* __q (__b._M_data); \ @@ -551,7 +552,7 @@ _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) \ + for (size_t __k=0; __k<__n; ++__k, ++__j) \ __a._M_data[*__j] _Op##= __e[__k]; \ } \ \ @@ -610,21 +611,15 @@ _Array_augmented_##_Name (_Array<_Tp> __a, _Array<bool> __m, \ _DEFINE_ARRAY_FUNCTION(%, __modulus) _DEFINE_ARRAY_FUNCTION(^, __bitwise_xor) _DEFINE_ARRAY_FUNCTION(|, __bitwise_or) - _DEFINE_ARRAY_FUNCTION(&, __bitwise_and) + _DEFINE_ARRAY_FUNCTION(&, __bitwise_and) _DEFINE_ARRAY_FUNCTION(<<, __shift_left) _DEFINE_ARRAY_FUNCTION(>>, __shift_right) -#undef _DEFINE_VALARRAY_FUNCTION - -} // std:: +#undef _DEFINE_VALARRAY_FUNCTION +} // namespace std -#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT -# define export -# include <bits/valarray_array.tcc> +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <bits/valarray_array.tcc> #endif - -#endif /* _CPP_BITS_ARRAY_H */ -// Local Variables: -// mode:c++ -// End: +#endif /* _ARRAY_H */ diff --git a/contrib/libstdc++/include/bits/valarray_array.tcc b/contrib/libstdc++/include/bits/valarray_array.tcc index ba4b0830a47e..fac5de6399b1 100644 --- a/contrib/libstdc++/include/bits/valarray_array.tcc +++ b/contrib/libstdc++/include/bits/valarray_array.tcc @@ -1,6 +1,6 @@ // The template and inlines for the -*- C++ -*- internal _Array helper class. -// Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. +// Copyright (C) 1997, 1998, 1999, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -29,133 +29,212 @@ // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> -#ifndef _CPP_BITS_VALARRAY_ARRAY_TCC -#define _CPP_BITS_VALARRAY_ARRAY_TCC 1 +#ifndef _VALARRAY_ARRAY_TCC +#define _VALARRAY_ARRAY_TCC 1 namespace std { - -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; + 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; + // Copy n elements of a into consecutive elements of b. When m is + // false, the corresponding element of a is skipped. m must contain + // at least n true elements. a must contain at least n elements and + // enough elements to match up with m through the nth true element + // of m. I.e. if n is 10, m has 15 elements with 5 false followed + // by 10 true, a must have 15 elements. + 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; + // Copy n consecutive elements from a into elements of b. Elements + // of b are skipped if the corresponding element of m is false. m + // must contain at least n true elements. b must have at least as + // many elements as the index of the nth true element of m. I.e. if + // m has 15 elements with 5 false followed by 10 true, b must have + // at least 15 elements. + 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]; + // Copy n elements from a into elements of b. Elements of a are + // skipped if the corresponding element of m is false. Elements of + // b are skipped if the corresponding element of k is false. m and + // k must contain at least n true elements. a and b must have at + // least as many elements as the index of the nth true element of m. + template<typename _Tp> + void + __valarray_copy(_Array<_Tp> __a, _Array<bool> __m, size_t __n, + _Array<_Tp> __b, _Array<bool> __k) + { + _Tp* __p (__a._M_data); + _Tp* __q (__b._M_data); + bool* __srcok (__m._M_data); + bool* __dstok (__k._M_data); + for (size_t __i = 0; __i < __n; + ++__srcok, ++__p, ++__dstok, ++__q, ++__i) + { + while (! *__srcok) + { + ++__srcok; + ++__p; + } + while (! *__dstok) + { + ++__dstok; + ++__q; + } + *__q = *__p; + } } -} + // Copy n consecutive elements of e into consecutive elements of a. + // I.e. a[i] = e[i]. + 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_construct (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) new (__p) _Tp(__e[__i]); -} + // Copy n consecutive elements of e into elements of a using stride + // s. I.e., a[0] = e[0], a[s] = e[1], a[2*s] = e[2]. + 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]; + } + // Copy n consecutive elements of e into elements of a indexed by + // contents of i. I.e., a[i[0]] = e[0]. + 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> -void -__valarray_copy_construct (_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; - } - new (__q) _Tp(*__p); + // Copy n elements of e indexed by contents of f into elements of a + // indexed by contents of i. I.e., a[i[0]] = e[f[0]]. + template<typename _Tp> + void + __valarray_copy(_Array<_Tp> __e, _Array<size_t> __f, + size_t __n, + _Array<_Tp> __a, _Array<size_t> __i) + { + size_t* __g (__f._M_data); + size_t* __j (__i._M_data); + for (size_t __k = 0; __k < __n; ++__k, ++__j, ++__g) + __a._M_data[*__j] = __e._M_data[*__g]; } -} + // Copy n consecutive elements of e into elements of a. Elements of + // a are skipped if the corresponding element of m is false. m must + // have at least n true elements and a must have at least as many + // elements as the index of the nth true element of m. I.e. if m + // has 5 false followed by 10 true elements and n == 10, a must have + // at least 15 elements. + 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]; + } + } + template<typename _Tp, class _Dom> + void + __valarray_copy_construct(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) + new (__p) _Tp(__e[__i]); + } -} // std:: -#endif /* _CPP_BITS_VALARRAY_ARRAY_TCC */ + template<typename _Tp> + void + __valarray_copy_construct(_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; + } + new (__q) _Tp(*__p); + } + } +} // namespace std -// Local Variables: -// mode:c++ -// End: +#endif /* _VALARRAY_ARRAY_TCC */ diff --git a/contrib/libstdc++/include/bits/valarray_before.h b/contrib/libstdc++/include/bits/valarray_before.h new file mode 100644 index 000000000000..263ac2f0e225 --- /dev/null +++ b/contrib/libstdc++/include/bits/valarray_before.h @@ -0,0 +1,701 @@ +// The template and inlines for the -*- C++ -*- internal _Meta class. + +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General 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> + +/** @file valarray_meta.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _VALARRAY_BEFORE_H +#define _VALARRAY_BEFORE_H 1 + +#pragma GCC system_header + +#include <bits/slice_array.h> + +namespace std +{ + // + // 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; + + // Implementations of unary functions applied to valarray<>s. + // I use hard-coded object functions here instead of a generic + // approach like pointers to function: + // 1) correctness: some functions take references, others values. + // we can't deduce the correct type afterwards. + // 2) efficiency -- object functions can be easily inlined + // 3) be Koenig-lookup-friendly + + struct __abs + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const { return abs(__t); } + }; + + struct __cos + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const { return cos(__t); } + }; + + struct __acos + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const { return acos(__t); } + }; + + struct __cosh + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const { return cosh(__t); } + }; + + struct __sin + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const { return sin(__t); } + }; + + struct __asin + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const { return asin(__t); } + }; + + struct __sinh + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const { return sinh(__t); } + }; + + struct __tan + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const { return tan(__t); } + }; + + struct __atan + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const { return atan(__t); } + }; + + struct __tanh + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const { return tanh(__t); } + }; + + struct __exp + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const { return exp(__t); } + }; + + struct __log + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const { return log(__t); } + }; + + struct __log10 + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const { return log10(__t); } + }; + + struct __sqrt + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const { return sqrt(__t); } + }; + + // In the past, we used to tailor operator applications semantics + // to the specialization of standard function objects (i.e. plus<>, etc.) + // That is incorrect. Therefore we provide our own surrogates. + + struct __unary_plus + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const { return +__t; } + }; + + struct __negate + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const { return -__t; } + }; + + struct __bitwise_not + { + template<typename _Tp> + _Tp operator()(const _Tp& __t) const { return ~__t; } + }; + + struct __plus + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x + __y; } + }; + + struct __minus + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x - __y; } + }; + + struct __multiplies + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x * __y; } + }; + + struct __divides + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x / __y; } + }; + + struct __modulus + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x % __y; } + }; + + struct __bitwise_xor + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x ^ __y; } + }; + + struct __bitwise_and + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x & __y; } + }; + + struct __bitwise_or + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x | __y; } + }; + + struct __shift_left + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x << __y; } + }; + + struct __shift_right + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return __x >> __y; } + }; + + struct __logical_and + { + template<typename _Tp> + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x && __y; } + }; + + struct __logical_or + { + template<typename _Tp> + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x || __y; } + }; + + struct __logical_not + { + template<typename _Tp> + bool operator()(const _Tp& __x) const { return !__x; } + }; + + struct __equal_to + { + template<typename _Tp> + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x == __y; } + }; + + struct __not_equal_to + { + template<typename _Tp> + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x != __y; } + }; + + struct __less + { + template<typename _Tp> + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x < __y; } + }; + + struct __greater + { + template<typename _Tp> + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x > __y; } + }; + + struct __less_equal + { + template<typename _Tp> + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x <= __y; } + }; + + struct __greater_equal + { + template<typename _Tp> + bool operator()(const _Tp& __x, const _Tp& __y) const + { return __x >= __y; } + }; + + // The few binary functions we miss. + struct __atan2 + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return atan2(__x, __y); } + }; + + struct __pow + { + template<typename _Tp> + _Tp operator()(const _Tp& __x, const _Tp& __y) const + { return pow(__x, __y); } + }; + + + // We need these bits in order to recover the return type of + // some functions/operators now that we're no longer using + // function templates. + template<typename, typename _Tp> + struct __fun + { + typedef _Tp result_type; + }; + + // several specializations for relational operators. + template<typename _Tp> + struct __fun<__logical_not, _Tp> + { + typedef bool result_type; + }; + + template<typename _Tp> + struct __fun<__logical_and, _Tp> + { + typedef bool result_type; + }; + + template<typename _Tp> + struct __fun<__logical_or, _Tp> + { + typedef bool result_type; + }; + + template<typename _Tp> + struct __fun<__less, _Tp> + { + typedef bool result_type; + }; + + template<typename _Tp> + struct __fun<__greater, _Tp> + { + typedef bool result_type; + }; + + template<typename _Tp> + struct __fun<__less_equal, _Tp> + { + typedef bool result_type; + }; + + template<typename _Tp> + struct __fun<__greater_equal, _Tp> + { + typedef bool result_type; + }; + + template<typename _Tp> + struct __fun<__equal_to, _Tp> + { + typedef bool result_type; + }; + + template<typename _Tp> + struct __fun<__not_equal_to, _Tp> + { + typedef bool result_type; + }; + + // + // 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<class _Oper, class _Arg> + class _UnBase + { + public: + typedef typename _Arg::value_type _Vt; + typedef typename __fun<_Oper, _Vt>::result_type value_type; + + _UnBase(const _Arg& __e) : _M_expr(__e) {} + + value_type operator[](size_t __i) const + { return _Oper()(_M_expr[__i]); } + + size_t size() const { return _M_expr.size(); } + + private: + const _Arg& _M_expr; + }; + + template<class _Oper, class _Dom> + struct _UnClos<_Oper, _Expr, _Dom> : _UnBase<_Oper, _Dom> + { + typedef _Dom _Arg; + typedef _UnBase<_Oper, _Dom> _Base; + typedef typename _Base::value_type value_type; + + _UnClos(const _Arg& __e) : _Base(__e) {} + }; + + template<class _Oper, typename _Tp> + struct _UnClos<_Oper, _ValArray, _Tp> : _UnBase<_Oper, valarray<_Tp> > + { + typedef valarray<_Tp> _Arg; + typedef _UnBase<_Oper, valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _UnClos(const _Arg& __e) : _Base(__e) {} + }; + + + // + // Binary expression closure. + // + + template<class _Oper, class _FirstArg, class _SecondArg> + class _BinBase + { + public: + typedef typename _FirstArg::value_type _Vt; + typedef typename __fun<_Oper, _Vt>::result_type value_type; + + _BinBase(const _FirstArg& __e1, const _SecondArg& __e2) + : _M_expr1(__e1), _M_expr2(__e2) {} + + value_type operator[](size_t __i) const + { return _Oper()(_M_expr1[__i], _M_expr2[__i]); } + + size_t size() const { return _M_expr1.size(); } + + private: + const _FirstArg& _M_expr1; + const _SecondArg& _M_expr2; + }; + + + template<class _Oper, class _Clos> + class _BinBase2 + { + public: + typedef typename _Clos::value_type _Vt; + typedef typename __fun<_Oper, _Vt>::result_type value_type; + + _BinBase2(const _Clos& __e, const _Vt& __t) + : _M_expr1(__e), _M_expr2(__t) {} + + value_type operator[](size_t __i) const + { return _Oper()(_M_expr1[__i], _M_expr2); } + + size_t size() const { return _M_expr1.size(); } + + private: + const _Clos& _M_expr1; + const _Vt& _M_expr2; + }; + + template<class _Oper, class _Clos> + class _BinBase1 + { + public: + typedef typename _Clos::value_type _Vt; + typedef typename __fun<_Oper, _Vt>::result_type value_type; + + _BinBase1(const _Vt& __t, const _Clos& __e) + : _M_expr1(__t), _M_expr2(__e) {} + + value_type operator[](size_t __i) const + { return _Oper()(_M_expr1, _M_expr2[__i]); } + + size_t size() const { return _M_expr2.size(); } + + private: + const _Vt& _M_expr1; + const _Clos& _M_expr2; + }; + + template<class _Oper, class _Dom1, class _Dom2> + struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2> + : _BinBase<_Oper,_Dom1,_Dom2> + { + typedef _BinBase<_Oper,_Dom1,_Dom2> _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {} + }; + + template<class _Oper, typename _Tp> + struct _BinClos<_Oper,_ValArray,_ValArray,_Tp,_Tp> + : _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > + { + typedef _BinBase<_Oper,valarray<_Tp>,valarray<_Tp> > _Base; + typedef _Tp value_type; + + _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w) + : _Base(__v, __w) {} + }; + + template<class _Oper, class _Dom> + struct _BinClos<_Oper,_Expr,_ValArray,_Dom,typename _Dom::value_type> + : _BinBase<_Oper,_Dom,valarray<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<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<class _Oper, class _Dom> + struct _BinClos<_Oper,_Expr,_Constant,_Dom,typename _Dom::value_type> + : _BinBase2<_Oper,_Dom> + { + typedef typename _Dom::value_type _Tp; + typedef _BinBase2<_Oper,_Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {} + }; + + template<class _Oper, class _Dom> + struct _BinClos<_Oper,_Constant,_Expr,typename _Dom::value_type,_Dom> + : _BinBase1<_Oper,_Dom> + { + typedef typename _Dom::value_type _Tp; + typedef _BinBase1<_Oper,_Dom> _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {} + }; + + template<class _Oper, typename _Tp> + struct _BinClos<_Oper,_ValArray,_Constant,_Tp,_Tp> + : _BinBase2<_Oper,valarray<_Tp> > + { + typedef _BinBase2<_Oper,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {} + }; + + template<class _Oper, typename _Tp> + struct _BinClos<_Oper,_Constant,_ValArray,_Tp,_Tp> + : _BinBase1<_Oper,valarray<_Tp> > + { + typedef _BinBase1<_Oper,valarray<_Tp> > _Base; + typedef typename _Base::value_type value_type; + + _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {} + }; + + + // + // slice_array closure. + // + template<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) {} + }; + +} // std:: + + +#endif /* _CPP_VALARRAY_BEFORE_H */ + +// Local Variables: +// mode:c++ +// End: diff --git a/contrib/libstdc++/include/bits/vector.tcc b/contrib/libstdc++/include/bits/vector.tcc index da5cf7edf832..abd1ba76250e 100644 --- a/contrib/libstdc++/include/bits/vector.tcc +++ b/contrib/libstdc++/include/bits/vector.tcc @@ -1,6 +1,6 @@ // Vector implementation (out of line) -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,10 +58,10 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_VECTOR_TCC -#define __GLIBCPP_INTERNAL_VECTOR_TCC +#ifndef _VECTOR_TCC +#define _VECTOR_TCC 1 -namespace std +namespace _GLIBCXX_STD { template<typename _Tp, typename _Alloc> void @@ -69,58 +69,61 @@ namespace std reserve(size_type __n) { if (__n > this->max_size()) - __throw_length_error("vector::reserve"); + __throw_length_error(__N("vector::reserve")); if (this->capacity() < __n) { const size_type __old_size = size(); - pointer __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; + pointer __tmp = _M_allocate_and_copy(__n, + this->_M_impl._M_start, + this->_M_impl._M_finish); + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __tmp; + this->_M_impl._M_finish = __tmp + __old_size; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; } } - + template<typename _Tp, typename _Alloc> typename vector<_Tp,_Alloc>::iterator vector<_Tp,_Alloc>:: insert(iterator __position, const value_type& __x) { size_type __n = __position - begin(); - if (_M_finish != _M_end_of_storage && __position == end()) + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage && __position == end()) { - _Construct(_M_finish, __x); - ++_M_finish; + std::_Construct(this->_M_impl._M_finish, __x); + ++this->_M_impl._M_finish; } else _M_insert_aux(__position, __x); return begin() + __n; } - + template<typename _Tp, typename _Alloc> typename vector<_Tp,_Alloc>::iterator vector<_Tp,_Alloc>:: erase(iterator __position) { if (__position + 1 != end()) - copy(__position + 1, end(), __position); - --_M_finish; - _Destroy(_M_finish); + std::copy(__position + 1, end(), __position); + --this->_M_impl._M_finish; + std::_Destroy(this->_M_impl._M_finish); return __position; } - + template<typename _Tp, typename _Alloc> typename vector<_Tp,_Alloc>::iterator vector<_Tp,_Alloc>:: erase(iterator __first, iterator __last) { iterator __i(copy(__last, end(), __first)); - _Destroy(__i, end()); - _M_finish = _M_finish - (__last - __first); + std::_Destroy(__i, end()); + this->_M_impl._M_finish = this->_M_impl._M_finish - (__last - __first); return __first; } - + template<typename _Tp, typename _Alloc> vector<_Tp,_Alloc>& vector<_Tp,_Alloc>:: @@ -132,26 +135,27 @@ namespace std if (__xlen > capacity()) { pointer __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; + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __tmp; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen; } else if (size() >= __xlen) { iterator __i(copy(__x.begin(), __x.end(), begin())); - _Destroy(__i, end()); + std::_Destroy(__i, end()); } else { - copy(__x.begin(), __x.begin() + size(), _M_start); - uninitialized_copy(__x.begin() + size(), __x.end(), _M_finish); + std::copy(__x.begin(), __x.begin() + size(), this->_M_impl._M_start); + std::uninitialized_copy(__x.begin() + size(), __x.end(), this->_M_impl._M_finish); } - _M_finish = _M_start + __xlen; + this->_M_impl._M_finish = this->_M_impl._M_start + __xlen; } return *this; } - + template<typename _Tp, typename _Alloc> void vector<_Tp,_Alloc>:: @@ -164,17 +168,18 @@ namespace std } else if (__n > size()) { - fill(begin(), end(), __val); - _M_finish = uninitialized_fill_n(_M_finish, __n - size(), __val); + std::fill(begin(), end(), __val); + this->_M_impl._M_finish + = std::uninitialized_fill_n(this->_M_impl._M_finish, __n - size(), __val); } else erase(fill_n(begin(), __n, __val), end()); } - - template<typename _Tp, typename _Alloc> template<typename _InputIter> + + template<typename _Tp, typename _Alloc> template<typename _InputIterator> void vector<_Tp,_Alloc>:: - _M_assign_aux(_InputIter __first, _InputIter __last, input_iterator_tag) + _M_assign_aux(_InputIterator __first, _InputIterator __last, input_iterator_tag) { iterator __cur(begin()); for ( ; __first != __last && __cur != end(); ++__cur, ++__first) @@ -184,124 +189,86 @@ namespace std else insert(end(), __first, __last); } - - template<typename _Tp, typename _Alloc> template<typename _ForwardIter> + + template<typename _Tp, typename _Alloc> template<typename _ForwardIterator> void vector<_Tp,_Alloc>:: - _M_assign_aux(_ForwardIter __first, _ForwardIter __last, + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag) { - size_type __len = distance(__first, __last); - + size_type __len = std::distance(__first, __last); + if (__len > capacity()) { pointer __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; + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __tmp; + this->_M_impl._M_end_of_storage = this->_M_impl._M_finish = this->_M_impl._M_start + __len; } else if (size() >= __len) { - iterator __new_finish(copy(__first, __last, _M_start)); - _Destroy(__new_finish, end()); - _M_finish = __new_finish.base(); + iterator __new_finish(copy(__first, __last, this->_M_impl._M_start)); + std::_Destroy(__new_finish, end()); + this->_M_impl._M_finish = __new_finish.base(); } else { - _ForwardIter __mid = __first; - advance(__mid, size()); - copy(__first, __mid, _M_start); - _M_finish = uninitialized_copy(__mid, __last, _M_finish); + _ForwardIterator __mid = __first; + std::advance(__mid, size()); + std::copy(__first, __mid, this->_M_impl._M_start); + this->_M_impl._M_finish = std::uninitialized_copy(__mid, __last, this->_M_impl._M_finish); } } - + template<typename _Tp, typename _Alloc> void vector<_Tp,_Alloc>:: _M_insert_aux(iterator __position, const _Tp& __x) { - if (_M_finish != _M_end_of_storage) + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) { - _Construct(_M_finish, *(_M_finish - 1)); - ++_M_finish; + std::_Construct(this->_M_impl._M_finish, *(this->_M_impl._M_finish - 1)); + ++this->_M_impl._M_finish; _Tp __x_copy = __x; - copy_backward(__position, iterator(_M_finish-2), iterator(_M_finish-1)); + std::copy_backward(__position, + iterator(this->_M_impl._M_finish-2), + iterator(this->_M_impl._M_finish-1)); *__position = __x_copy; } else { const size_type __old_size = size(); const size_type __len = __old_size != 0 ? 2 * __old_size : 1; - iterator __new_start(_M_allocate(__len)); + iterator __new_start(this->_M_allocate(__len)); iterator __new_finish(__new_start); try { - __new_finish = uninitialized_copy(iterator(_M_start), __position, - __new_start); - _Construct(__new_finish.base(), __x); + __new_finish = std::uninitialized_copy(iterator(this->_M_impl._M_start), + __position, + __new_start); + std::_Construct(__new_finish.base(), __x); ++__new_finish; - __new_finish = uninitialized_copy(__position, iterator(_M_finish), - __new_finish); + __new_finish = std::uninitialized_copy(__position, + iterator(this->_M_impl._M_finish), + __new_finish); } catch(...) { - _Destroy(__new_start,__new_finish); + std::_Destroy(__new_start,__new_finish); _M_deallocate(__new_start.base(),__len); __throw_exception_again; } - _Destroy(begin(), end()); - _M_deallocate(_M_start, _M_end_of_storage - _M_start); - _M_start = __new_start.base(); - _M_finish = __new_finish.base(); - _M_end_of_storage = __new_start.base() + __len; - } - } - - #ifdef _GLIBCPP_DEPRECATED - template<typename _Tp, typename _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, iterator(_M_finish - 2), - iterator(_M_finish - 1)); - *__position = value_type(); - } - else - { - const size_type __old_size = size(); - const size_type __len = __old_size != 0 ? 2 * __old_size : 1; - pointer __new_start = _M_allocate(__len); - pointer __new_finish = __new_start; - try - { - __new_finish = uninitialized_copy(iterator(_M_start), __position, - __new_start); - _Construct(__new_finish); - ++__new_finish; - __new_finish = uninitialized_copy(__position, iterator(_M_finish), - __new_finish); - } - catch(...) - { - _Destroy(__new_start,__new_finish); - _M_deallocate(__new_start,__len); - __throw_exception_again; - } - _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; + std::_Destroy(begin(), end()); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __new_start.base(); + this->_M_impl._M_finish = __new_finish.base(); + this->_M_impl._M_end_of_storage = __new_start.base() + __len; } } - #endif - + template<typename _Tp, typename _Alloc> void vector<_Tp,_Alloc>:: @@ -309,56 +276,61 @@ namespace std { if (__n != 0) { - if (size_type(_M_end_of_storage - _M_finish) >= __n) + if (size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish) >= __n) { value_type __x_copy = __x; const size_type __elems_after = end() - __position; - iterator __old_finish(_M_finish); + iterator __old_finish(this->_M_impl._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); + std::uninitialized_copy(this->_M_impl._M_finish - __n, + this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish += __n; + std::copy_backward(__position, __old_finish - __n, __old_finish); + std::fill(__position, __position + __n, __x_copy); } else { - uninitialized_fill_n(_M_finish, __n - __elems_after, __x_copy); - _M_finish += __n - __elems_after; - uninitialized_copy(__position, __old_finish, _M_finish); - _M_finish += __elems_after; - fill(__position, __old_finish, __x_copy); + std::uninitialized_fill_n(this->_M_impl._M_finish, + __n - __elems_after, + __x_copy); + this->_M_impl._M_finish += __n - __elems_after; + std::uninitialized_copy(__position, __old_finish, this->_M_impl._M_finish); + this->_M_impl._M_finish += __elems_after; + std::fill(__position, __old_finish, __x_copy); } } else { const size_type __old_size = size(); - const size_type __len = __old_size + max(__old_size, __n); - iterator __new_start(_M_allocate(__len)); + const size_type __len = __old_size + std::max(__old_size, __n); + iterator __new_start(this->_M_allocate(__len)); iterator __new_finish(__new_start); try { - __new_finish = uninitialized_copy(begin(), __position, - __new_start); - __new_finish = uninitialized_fill_n(__new_finish, __n, __x); - __new_finish = uninitialized_copy(__position, end(), - __new_finish); + __new_finish = std::uninitialized_copy(begin(), __position, + __new_start); + __new_finish = std::uninitialized_fill_n(__new_finish, __n, __x); + __new_finish = std::uninitialized_copy(__position, end(), + __new_finish); } catch(...) { - _Destroy(__new_start,__new_finish); + std::_Destroy(__new_start,__new_finish); _M_deallocate(__new_start.base(),__len); __throw_exception_again; } - _Destroy(_M_start, _M_finish); - _M_deallocate(_M_start, _M_end_of_storage - _M_start); - _M_start = __new_start.base(); - _M_finish = __new_finish.base(); - _M_end_of_storage = __new_start.base() + __len; + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __new_start.base(); + this->_M_impl._M_finish = __new_finish.base(); + this->_M_impl._M_end_of_storage = __new_start.base() + __len; } } } - + template<typename _Tp, typename _Alloc> template<typename _InputIterator> void vector<_Tp,_Alloc>:: @@ -372,66 +344,71 @@ namespace std ++__pos; } } - + template<typename _Tp, typename _Alloc> template<typename _ForwardIterator> void vector<_Tp,_Alloc>:: - _M_range_insert(iterator __position,_ForwardIterator __first, + _M_range_insert(iterator __position,_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag) { if (__first != __last) { - size_type __n = distance(__first, __last); - if (size_type(_M_end_of_storage - _M_finish) >= __n) + size_type __n = std::distance(__first, __last); + if (size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish) >= __n) { const size_type __elems_after = end() - __position; - iterator __old_finish(_M_finish); + iterator __old_finish(this->_M_impl._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); + std::uninitialized_copy(this->_M_impl._M_finish - __n, + this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish += __n; + std::copy_backward(__position, __old_finish - __n, __old_finish); + std::copy(__first, __last, __position); } else { _ForwardIterator __mid = __first; - advance(__mid, __elems_after); - uninitialized_copy(__mid, __last, _M_finish); - _M_finish += __n - __elems_after; - uninitialized_copy(__position, __old_finish, _M_finish); - _M_finish += __elems_after; - copy(__first, __mid, __position); + std::advance(__mid, __elems_after); + std::uninitialized_copy(__mid, __last, this->_M_impl._M_finish); + this->_M_impl._M_finish += __n - __elems_after; + std::uninitialized_copy(__position, __old_finish, this->_M_impl._M_finish); + this->_M_impl._M_finish += __elems_after; + std::copy(__first, __mid, __position); } } else { const size_type __old_size = size(); - const size_type __len = __old_size + max(__old_size, __n); - iterator __new_start(_M_allocate(__len)); + const size_type __len = __old_size + std::max(__old_size, __n); + iterator __new_start(this->_M_allocate(__len)); iterator __new_finish(__new_start); try { - __new_finish = uninitialized_copy(iterator(_M_start), - __position, __new_start); - __new_finish = uninitialized_copy(__first, __last, __new_finish); - __new_finish = uninitialized_copy(__position, iterator(_M_finish), - __new_finish); + __new_finish = std::uninitialized_copy(iterator(this->_M_impl._M_start), + __position, __new_start); + __new_finish = std::uninitialized_copy(__first, __last, + __new_finish); + __new_finish = std::uninitialized_copy(__position, + iterator(this->_M_impl._M_finish), + __new_finish); } catch(...) { - _Destroy(__new_start,__new_finish); + std::_Destroy(__new_start,__new_finish); _M_deallocate(__new_start.base(), __len); __throw_exception_again; } - _Destroy(_M_start, _M_finish); - _M_deallocate(_M_start, _M_end_of_storage - _M_start); - _M_start = __new_start.base(); - _M_finish = __new_finish.base(); - _M_end_of_storage = __new_start.base() + __len; + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __new_start.base(); + this->_M_impl._M_finish = __new_finish.base(); + this->_M_impl._M_end_of_storage = __new_start.base() + __len; } } } } // namespace std -#endif /* __GLIBCPP_INTERNAL_VECTOR_TCC */ +#endif /* _VECTOR_TCC */ diff --git a/contrib/libstdc++/include/c/std_cctype.h b/contrib/libstdc++/include/c/std_cctype.h index 9d84a3d68b72..3231f481fcfa 100644 --- a/contrib/libstdc++/include/c/std_cctype.h +++ b/contrib/libstdc++/include/c/std_cctype.h @@ -1,6 +1,6 @@ // -*- C++ -*- forwarding header. -// Copyright (C) 2000, 2002 Free Software Foundation, Inc. +// Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -31,11 +31,11 @@ // ISO C++ 14882: <ccytpe> // -#ifndef _CPP_CCTYPE -#define _CPP_CCTYPE 1 +#ifndef _GLIBCXX_CCTYPE +#define _GLIBCXX_CCTYPE 1 #pragma GCC system_header #include_next <ctype.h> -#endif +#endif diff --git a/contrib/libstdc++/include/c/std_cerrno.h b/contrib/libstdc++/include/c/std_cerrno.h index 646d60965740..84e0e534337a 100644 --- a/contrib/libstdc++/include/c/std_cerrno.h +++ b/contrib/libstdc++/include/c/std_cerrno.h @@ -1,6 +1,6 @@ // -*- C++ -*- forwarding header. -// Copyright (C) 2000, 2002 Free Software Foundation, Inc. +// Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -40,8 +40,8 @@ * contained in the namespace @c std. */ -#ifndef _CPP_CERRNO -#define _CPP_CERRNO 1 +#ifndef _GLIBCXX_CERRNO +#define _GLIBCXX_CERRNO 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c/std_cfloat.h b/contrib/libstdc++/include/c/std_cfloat.h index 9c95760b38bf..e9319d302ad9 100644 --- a/contrib/libstdc++/include/c/std_cfloat.h +++ b/contrib/libstdc++/include/c/std_cfloat.h @@ -1,6 +1,6 @@ // -*- C++ -*- forwarding header. -// Copyright (C) 2000, 2002 Free Software Foundation, Inc. +// Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -31,8 +31,8 @@ // ISO C++ 14882: 18.2.2 Implementation properties: C library // -#ifndef _CPP_CFLOAT -#define _CPP_CFLOAT 1 +#ifndef _GLIBCXX_CFLOAT +#define _GLIBCXX_CFLOAT 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c/std_climits.h b/contrib/libstdc++/include/c/std_climits.h index 9194cb9adf76..e1986f25a95b 100644 --- a/contrib/libstdc++/include/c/std_climits.h +++ b/contrib/libstdc++/include/c/std_climits.h @@ -1,6 +1,6 @@ // -*- C++ -*- forwarding header. -// Copyright (C) 2000, 2002 Free Software Foundation, Inc. +// Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -31,8 +31,8 @@ // ISO C++ 14882: 18.2.2 Implementation properties: C library // -#ifndef _CPP_CLIMITS -#define _CPP_CLIMITS 1 +#ifndef _GLIBCXX_CLIMITS +#define _GLIBCXX_CLIMITS 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c/std_clocale.h b/contrib/libstdc++/include/c/std_clocale.h index b6b3c22268ad..6aa937baf71d 100644 --- a/contrib/libstdc++/include/c/std_clocale.h +++ b/contrib/libstdc++/include/c/std_clocale.h @@ -1,6 +1,6 @@ // -*- C++ -*- forwarding header. -// Copyright (C) 2000, 2002 Free Software Foundation, Inc. +// Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -31,8 +31,8 @@ // ISO C++ 14882: 18.2.2 Implementation properties: C library // -#ifndef _CPP_CLOCALE -#define _CPP_CLOCALE 1 +#ifndef _GLIBCXX_CLOCALE +#define _GLIBCXX_CLOCALE 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c/std_cmath.h b/contrib/libstdc++/include/c/std_cmath.h index beb7141625ce..fcaa7594c973 100644 --- a/contrib/libstdc++/include/c/std_cmath.h +++ b/contrib/libstdc++/include/c/std_cmath.h @@ -1,6 +1,6 @@ // -*- C++ -*- forwarding header. -// Copyright (C) 2000, 2002 Free Software Foundation, Inc. +// Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -31,9 +31,9 @@ // ISO C++ 14882: 26.5 C library // -#ifndef _CPP_CMATH -#define _CPP_CMATH 1 - +#ifndef _GLIBCXX_CMATH +#define _GLIBCXX_CMATH 1 + #pragma GCC system_header #include <bits/c++config.h> @@ -79,7 +79,7 @@ #undef islessgreater #undef isunordered -namespace std +namespace std { inline double abs(double __x) @@ -93,11 +93,11 @@ namespace std abs(long double __x) { return __builtin_fabsl(__x); } -#if _GLIBCPP_HAVE_MODFF - inline float +#if _GLIBCXX_HAVE_MODFF + inline float modf(float __x, float* __iptr) { return modff(__x, __iptr); } #else - inline float + inline float modf(float __x, float* __iptr) { double __tmp; @@ -107,13 +107,13 @@ namespace std } #endif -#if _GLIBCPP_HAVE_MODFL - inline long double +#if _GLIBCXX_HAVE_MODFL + inline long double modf(long double __x, long double* __iptr) { return modfl(__x, __iptr); } #else - inline long double - modf(long double __x, long double* __iptr) - { + inline long double + modf(long double __x, long double* __iptr) + { double __tmp; double __res = modf(static_cast<double>(__x), &__tmp); * __iptr = static_cast<long double>(__tmp); diff --git a/contrib/libstdc++/include/c/std_csetjmp.h b/contrib/libstdc++/include/c/std_csetjmp.h index fe3f9c70bcdd..022753f46560 100644 --- a/contrib/libstdc++/include/c/std_csetjmp.h +++ b/contrib/libstdc++/include/c/std_csetjmp.h @@ -1,6 +1,6 @@ // -*- C++ -*- forwarding header. -// Copyright (C) 2000, 2002 Free Software Foundation, Inc. +// Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -31,8 +31,8 @@ // ISO C++ 14882: 20.4.6 C library // -#ifndef _CPP_CSETJMP -#define _CPP_CSETJMP 1 +#ifndef _GLIBCXX_CSETJMP +#define _GLIBCXX_CSETJMP 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c/std_csignal.h b/contrib/libstdc++/include/c/std_csignal.h index 09614e7ea019..6fa96071d92e 100644 --- a/contrib/libstdc++/include/c/std_csignal.h +++ b/contrib/libstdc++/include/c/std_csignal.h @@ -1,6 +1,6 @@ // -*- C++ -*- forwarding header. -// Copyright (C) 2000, 2002 Free Software Foundation, Inc. +// Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -31,8 +31,8 @@ // ISO C++ 14882: 20.4.6 C library // -#ifndef _CPP_CSIGNAL -#define _CPP_CSIGNAL 1 +#ifndef _GLIBCXX_CSIGNAL +#define _GLIBCXX_CSIGNAL 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c/std_cstdarg.h b/contrib/libstdc++/include/c/std_cstdarg.h index 39d019bc1c28..0c236344ed8d 100644 --- a/contrib/libstdc++/include/c/std_cstdarg.h +++ b/contrib/libstdc++/include/c/std_cstdarg.h @@ -1,6 +1,6 @@ // -*- C++ -*- forwarding header. -// Copyright (C) 2000, 2002 Free Software Foundation, Inc. +// Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -31,8 +31,8 @@ // ISO C++ 14882: 20.4.6 C library // -#ifndef _CPP_CSTDARG -#define _CPP_CSTDARG 1 +#ifndef _GLIBCXX_CSTDARG +#define _GLIBCXX_CSTDARG 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c/std_cstddef.h b/contrib/libstdc++/include/c/std_cstddef.h index 82561cdac7bc..4178ecf37eec 100644 --- a/contrib/libstdc++/include/c/std_cstddef.h +++ b/contrib/libstdc++/include/c/std_cstddef.h @@ -1,6 +1,6 @@ // -*- C++ -*- forwarding header. -// Copyright (C) 2000, 2002 Free Software Foundation, Inc. +// Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -31,8 +31,8 @@ // ISO C++ 14882: 18.1 Types // -#ifndef _CPP_CSTDDEF -#define _CPP_CSTDDEF 1 +#ifndef _GLIBCXX_CSTDDEF +#define _GLIBCXX_CSTDDEF 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c/std_cstdio.h b/contrib/libstdc++/include/c/std_cstdio.h index 3d6272aa62e3..fa04bc4518d2 100644 --- a/contrib/libstdc++/include/c/std_cstdio.h +++ b/contrib/libstdc++/include/c/std_cstdio.h @@ -1,6 +1,6 @@ // -*- C++ -*- forwarding header. -// Copyright (C) 2000, 2002 Free Software Foundation, Inc. +// Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -31,8 +31,8 @@ // ISO C++ 14882: 27.8.2 C Library files // -#ifndef _CPP_CSTDIO -#define _CPP_CSTDIO 1 +#ifndef _GLIBCXX_CSTDIO +#define _GLIBCXX_CSTDIO 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c/std_cstdlib.h b/contrib/libstdc++/include/c/std_cstdlib.h index 57ade0dfb363..90b2f1065760 100644 --- a/contrib/libstdc++/include/c/std_cstdlib.h +++ b/contrib/libstdc++/include/c/std_cstdlib.h @@ -1,6 +1,6 @@ // -*- C++ -*- forwarding header. -// Copyright (C) 2000, 2002 Free Software Foundation, Inc. +// Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -31,11 +31,11 @@ // ISO C++ 14882: 20.4.6 C library // -#ifndef _CPP_CSTDLIB -#define _CPP_CSTDLIB 1 +#ifndef _GLIBCXX_CSTDLIB +#define _GLIBCXX_CSTDLIB 1 #pragma GCC system_header #include_next <stdlib.h> -#endif +#endif diff --git a/contrib/libstdc++/include/c/std_cstring.h b/contrib/libstdc++/include/c/std_cstring.h index 656ff52be341..72ee44f9255e 100644 --- a/contrib/libstdc++/include/c/std_cstring.h +++ b/contrib/libstdc++/include/c/std_cstring.h @@ -31,8 +31,8 @@ // ISO C++ 14882: 20.4.6 C library // -#ifndef _CPP_CSTRING -#define _CPP_CSTRING 1 +#ifndef _GLIBCXX_CSTRING +#define _GLIBCXX_CSTRING 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c/std_ctime.h b/contrib/libstdc++/include/c/std_ctime.h index ba9103ee054f..197a1f8b8641 100644 --- a/contrib/libstdc++/include/c/std_ctime.h +++ b/contrib/libstdc++/include/c/std_ctime.h @@ -1,6 +1,6 @@ // -*- C++ -*- forwarding header. -// Copyright (C) 2000, 2002 Free Software Foundation, Inc. +// Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -31,8 +31,8 @@ // ISO C++ 14882: 20.5 Date and time // -#ifndef _CPP_CTIME -#define _CPP_CTIME 1 +#ifndef _GLIBCXX_CTIME +#define _GLIBCXX_CTIME 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c/std_cwchar.h b/contrib/libstdc++/include/c/std_cwchar.h index d06f5e4efcd7..0d2f6be54916 100644 --- a/contrib/libstdc++/include/c/std_cwchar.h +++ b/contrib/libstdc++/include/c/std_cwchar.h @@ -1,6 +1,6 @@ // -*- C++ -*- forwarding header. -// Copyright (C) 2000, 2002 Free Software Foundation, Inc. +// Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -31,8 +31,8 @@ // ISO C++ 14882: 21.4 // -#ifndef _CPP_CWCHAR -#define _CPP_CWCHAR 1 +#ifndef _GLIBCXX_CWCHAR +#define _GLIBCXX_CWCHAR 1 #pragma GCC system_header @@ -40,18 +40,18 @@ #include <cstddef> #include <ctime> -#if _GLIBCPP_HAVE_WCHAR_H +#if _GLIBCXX_HAVE_WCHAR_H #include_next <wchar.h> #endif // Need to do a bit of trickery here with mbstate_t as char_traits // assumes it is in wchar.h, regardless of wchar_t specializations. -#ifndef _GLIBCPP_HAVE_MBSTATE_T +#ifndef _GLIBCXX_HAVE_MBSTATE_T namespace std { - extern "C" + extern "C" { - typedef struct + typedef struct { int __fill[6]; } mbstate_t; @@ -59,4 +59,4 @@ namespace std } #endif -#endif +#endif diff --git a/contrib/libstdc++/include/c/std_cwctype.h b/contrib/libstdc++/include/c/std_cwctype.h index d51569843a67..9302864828ce 100644 --- a/contrib/libstdc++/include/c/std_cwctype.h +++ b/contrib/libstdc++/include/c/std_cwctype.h @@ -1,6 +1,6 @@ // -*- C++ -*- forwarding header. -// Copyright (C) 2000, 2002 Free Software Foundation, Inc. +// Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -31,15 +31,15 @@ // ISO C++ 14882: <cwctype> // -#ifndef _CPP_CWCTYPE -#define _CPP_CWCTYPE 1 +#ifndef _GLIBCXX_CWCTYPE +#define _GLIBCXX_CWCTYPE 1 #pragma GCC system_header #include <bits/c++config.h> -#if _GLIBCPP_HAVE_WCTYPE_H +#if _GLIBCXX_HAVE_WCTYPE_H #include_next <wctype.h> #endif -#endif +#endif diff --git a/contrib/libstdc++/include/c_compatibility/ctype.h b/contrib/libstdc++/include/c_compatibility/ctype.h index 1989347e2d86..3a610d1777b1 100644 --- a/contrib/libstdc++/include/c_compatibility/ctype.h +++ b/contrib/libstdc++/include/c_compatibility/ctype.h @@ -27,8 +27,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_CTYPE_H_ -#define _CPP_CTYPE_H_ 1 +#ifndef _GLIBCXX_CTYPE_H +#define _GLIBCXX_CTYPE_H 1 #include <cctype> diff --git a/contrib/libstdc++/include/c_compatibility/errno.h b/contrib/libstdc++/include/c_compatibility/errno.h index f890b5375495..f6b2b7686801 100644 --- a/contrib/libstdc++/include/c_compatibility/errno.h +++ b/contrib/libstdc++/include/c_compatibility/errno.h @@ -27,8 +27,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_ERRNO_H_ -#define _CPP_ERRNO_H_ 1 +#ifndef _GLIBCXX_ERRNO_H +#define _GLIBCXX_ERRNO_H 1 #include <cerrno> diff --git a/contrib/libstdc++/include/c_compatibility/float.h b/contrib/libstdc++/include/c_compatibility/float.h index 7d7b9d44f9ff..5eaaba6e593f 100644 --- a/contrib/libstdc++/include/c_compatibility/float.h +++ b/contrib/libstdc++/include/c_compatibility/float.h @@ -27,8 +27,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_FLOAT_H_ -#define _CPP_FLOAT_H_ 1 +#ifndef _GLIBCXX_FLOAT_H +#define _GLIBCXX_FLOAT_H 1 #include <cfloat> diff --git a/contrib/libstdc++/include/c_compatibility/iso646.h b/contrib/libstdc++/include/c_compatibility/iso646.h index 25b6140ba53c..83c536431f75 100644 --- a/contrib/libstdc++/include/c_compatibility/iso646.h +++ b/contrib/libstdc++/include/c_compatibility/iso646.h @@ -27,9 +27,9 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_ISO646_H_ -#define _CPP_ISO646_H_ 1 +#ifndef _GLIBCXX_ISO646_H +#define _GLIBCXX_ISO646_H 1 #include <ciso646> -#endif +#endif diff --git a/contrib/libstdc++/include/c_compatibility/limits.h b/contrib/libstdc++/include/c_compatibility/limits.h index 9ddbce8990e9..d9a753c1c6e3 100644 --- a/contrib/libstdc++/include/c_compatibility/limits.h +++ b/contrib/libstdc++/include/c_compatibility/limits.h @@ -27,9 +27,9 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_LIMITS_H_ -#define _CPP_LIMITS_H_ 1 +#ifndef _GLIBCXX_LIMITS_H +#define _GLIBCXX_LIMITS_H 1 #include <climits> -#endif +#endif diff --git a/contrib/libstdc++/include/c_compatibility/locale.h b/contrib/libstdc++/include/c_compatibility/locale.h index 4d7d72da7ab4..549bd7d5ea38 100644 --- a/contrib/libstdc++/include/c_compatibility/locale.h +++ b/contrib/libstdc++/include/c_compatibility/locale.h @@ -27,8 +27,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_LOCALE_H_ -#define _CPP_LOCALE_H_ 1 +#ifndef _GLIBCXX_LOCALE_H +#define _GLIBCXX_LOCALE_H 1 #include <clocale> @@ -36,4 +36,4 @@ using std::lconv; using std::setlocale; using std::localeconv; -#endif +#endif diff --git a/contrib/libstdc++/include/c_compatibility/math.h b/contrib/libstdc++/include/c_compatibility/math.h index 4c4fd0a21781..1cd48cf45db6 100644 --- a/contrib/libstdc++/include/c_compatibility/math.h +++ b/contrib/libstdc++/include/c_compatibility/math.h @@ -27,8 +27,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_MATH_H_ -#define _CPP_MATH_H_ 1 +#ifndef _GLIBCXX_MATH_H +#define _GLIBCXX_MATH_H 1 #include <cmath> @@ -56,7 +56,7 @@ using std::fabs; using std::floor; using std::fmod; -#if _GLIBCPP_USE_C99 +#if _GLIBCXX_USE_C99 using std::fpclassify; using std::isfinite; using std::isinf; diff --git a/contrib/libstdc++/include/c_compatibility/setjmp.h b/contrib/libstdc++/include/c_compatibility/setjmp.h index f194253f8689..0bcad031867e 100644 --- a/contrib/libstdc++/include/c_compatibility/setjmp.h +++ b/contrib/libstdc++/include/c_compatibility/setjmp.h @@ -27,8 +27,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_SETJMP_H_ -#define _CPP_SETJMP_H_ 1 +#ifndef _GLIBCXX_SETJMP_H +#define _GLIBCXX_SETJMP_H 1 #include <csetjmp> diff --git a/contrib/libstdc++/include/c_compatibility/signal.h b/contrib/libstdc++/include/c_compatibility/signal.h index 724ac8a1d665..b43deb5968a1 100644 --- a/contrib/libstdc++/include/c_compatibility/signal.h +++ b/contrib/libstdc++/include/c_compatibility/signal.h @@ -27,8 +27,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_SIGNAL_H_ -#define _CPP_SIGNAL_H_ 1 +#ifndef _GLIBCXX_SIGNAL_H +#define _GLIBCXX_SIGNAL_H 1 #include <csignal> diff --git a/contrib/libstdc++/include/c_compatibility/stdarg.h b/contrib/libstdc++/include/c_compatibility/stdarg.h index a1a62b1699e7..76d6c74b2a2e 100644 --- a/contrib/libstdc++/include/c_compatibility/stdarg.h +++ b/contrib/libstdc++/include/c_compatibility/stdarg.h @@ -27,8 +27,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_STDARG_H_ -#define _CPP_STDARG_H_ 1 +#ifndef _GLIBCXX_STDARG_H +#define _GLIBCXX_STDARG_H 1 #include <cstdarg> diff --git a/contrib/libstdc++/include/c_compatibility/stddef.h b/contrib/libstdc++/include/c_compatibility/stddef.h index 094c380ad02c..4dac7db2989b 100644 --- a/contrib/libstdc++/include/c_compatibility/stddef.h +++ b/contrib/libstdc++/include/c_compatibility/stddef.h @@ -27,8 +27,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_STDDEF_H_ -#define _CPP_STDDEF_H_ 1 +#ifndef _GLIBCXX_STDDEF_H +#define _GLIBCXX_STDDEF_H 1 #include <cstddef> diff --git a/contrib/libstdc++/include/c_compatibility/stdio.h b/contrib/libstdc++/include/c_compatibility/stdio.h index 930ffd4861db..2686a728035d 100644 --- a/contrib/libstdc++/include/c_compatibility/stdio.h +++ b/contrib/libstdc++/include/c_compatibility/stdio.h @@ -27,13 +27,13 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_STDIO_H_ -#define _CPP_STDIO_H_ 1 +#ifndef _GLIBCXX_STDIO_H +#define _GLIBCXX_STDIO_H 1 #include <cstdio> using std::FILE; -using std::fpos_t; +using std::fpos_t; using std::remove; using std::rename; diff --git a/contrib/libstdc++/include/c_compatibility/stdlib.h b/contrib/libstdc++/include/c_compatibility/stdlib.h index d516034d9d78..2b05c1a3b442 100644 --- a/contrib/libstdc++/include/c_compatibility/stdlib.h +++ b/contrib/libstdc++/include/c_compatibility/stdlib.h @@ -27,8 +27,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_STDLIB_H_ -#define _CPP_STDLIB_H_ 1 +#ifndef _GLIBCXX_STDLIB_H +#define _GLIBCXX_STDLIB_H 1 #include <cstdlib> diff --git a/contrib/libstdc++/include/c_compatibility/string.h b/contrib/libstdc++/include/c_compatibility/string.h index b639157ee593..a399f60b34bf 100644 --- a/contrib/libstdc++/include/c_compatibility/string.h +++ b/contrib/libstdc++/include/c_compatibility/string.h @@ -27,8 +27,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_STRING_H_ -#define _CPP_STRING_H_ 1 +#ifndef _GLIBCXX_STRING_H +#define _GLIBCXX_STRING_H 1 #include <cstring> @@ -55,4 +55,4 @@ using std::memset; using std::strerror; using std::strlen; -#endif +#endif diff --git a/contrib/libstdc++/include/c_compatibility/time.h b/contrib/libstdc++/include/c_compatibility/time.h index 6d07aa1aed61..0e7e2ad917b5 100644 --- a/contrib/libstdc++/include/c_compatibility/time.h +++ b/contrib/libstdc++/include/c_compatibility/time.h @@ -27,11 +27,11 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_TIME_H_ -#define _CPP_TIME_H_ 1 +#ifndef _GLIBCXX_TIME_H +#define _GLIBCXX_TIME_H 1 #include <ctime> - + // Get rid of those macros defined in <time.h> in lieu of real functions. #undef clock #undef difftime diff --git a/contrib/libstdc++/include/c_compatibility/wchar.h b/contrib/libstdc++/include/c_compatibility/wchar.h index e9485a54ded4..a962ff2ffb95 100644 --- a/contrib/libstdc++/include/c_compatibility/wchar.h +++ b/contrib/libstdc++/include/c_compatibility/wchar.h @@ -1,6 +1,6 @@ // -*- C++ -*- compatibility header. -// Copyright (C) 2002 Free Software Foundation, Inc. +// Copyright (C) 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -27,14 +27,14 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_WCHAR_H_ -#define _CPP_WCHAR_H_ 1 +#ifndef _GLIBCXX_WCHAR_H +#define _GLIBCXX_WCHAR_H 1 #include <cwchar> using std::mbstate_t; -#if _GLIBCPP_USE_WCHAR_T +#if _GLIBCXX_USE_WCHAR_T using std::wint_t; using std::btowc; @@ -50,11 +50,17 @@ using std::fwscanf; using std::swprintf; using std::swscanf; using std::vfwprintf; +#if _GLIBCXX_HAVE_VFWSCANF using std::vfwscanf; +#endif using std::vswprintf; +#if _GLIBCXX_HAVE_VSWSCANF using std::vswscanf; +#endif using std::vwprintf; +#if _GLIBCXX_HAVE_VWSCANF using std::vwscanf; +#endif using std::wprintf; using std::wscanf; using std::getwc; @@ -69,7 +75,9 @@ using std::putwchar; using std::ungetwc; using std::wcrtomb; using std::wcstod; +#if _GLIBCXX_HAVE_WCSTOF using std::wcstof; +#endif using std::wcstol; using std::wcstoul; using std::wcscpy; @@ -95,12 +103,12 @@ using std::wmemmove; using std::wmemset; using std::wcsftime; -#if _GLIBCPP_USE_C99 +#if _GLIBCXX_USE_C99 using std::wcstold; using std::wcstoll; using std::wcstoull; #endif -#endif //_GLIBCPP_USE_WCHAR_T +#endif //_GLIBCXX_USE_WCHAR_T #endif diff --git a/contrib/libstdc++/include/c_compatibility/wctype.h b/contrib/libstdc++/include/c_compatibility/wctype.h index 2c75ec8e960b..6086f3d62353 100644 --- a/contrib/libstdc++/include/c_compatibility/wctype.h +++ b/contrib/libstdc++/include/c_compatibility/wctype.h @@ -27,8 +27,8 @@ // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. -#ifndef _CPP_CWCTYPE_H_ -#define _CPP_CWCTYPE_H_ 1 +#ifndef _GLIBCXX_CWCTYPE_H +#define _GLIBCXX_CWCTYPE_H 1 #include <cwctype> @@ -52,4 +52,4 @@ using std::towupper; using std::wctrans; using std::wctype; -#endif +#endif diff --git a/contrib/libstdc++/include/c_std/cmath.tcc b/contrib/libstdc++/include/c_std/cmath.tcc index 9b86bbb9da6f..d771467ec61b 100644 --- a/contrib/libstdc++/include/c_std/cmath.tcc +++ b/contrib/libstdc++/include/c_std/cmath.tcc @@ -1,6 +1,6 @@ // -*- C++ -*- C math library. -// Copyright (C) 2000 Free Software Foundation, Inc. +// Copyright (C) 2000, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -29,13 +29,13 @@ // This file was written by Gabriel Dos Reis <gdr@codesourcery.com> -#ifndef _CPP_BITS_CMATH_TCC -#define _CPP_BITS_CMATH_TCC 1 +#ifndef _GLIBCXX_CMATH_TCC +#define _GLIBCXX_CMATH_TCC 1 -namespace std +namespace std { - export template<typename _Tp> - _Tp + template<typename _Tp> + inline _Tp __cmath_power(_Tp __x, unsigned int __n) { _Tp __y = __n % 2 ? __x : 1; diff --git a/contrib/libstdc++/include/c_std/std_cassert.h b/contrib/libstdc++/include/c_std/std_cassert.h index 06a0577acbdd..9fc1079b82a6 100644 --- a/contrib/libstdc++/include/c_std/std_cassert.h +++ b/contrib/libstdc++/include/c_std/std_cassert.h @@ -1,6 +1,6 @@ // -*- C++ -*- forwarding header. -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free diff --git a/contrib/libstdc++/include/c_std/std_cctype.h b/contrib/libstdc++/include/c_std/std_cctype.h index 4700809f3aac..65a4214657c9 100644 --- a/contrib/libstdc++/include/c_std/std_cctype.h +++ b/contrib/libstdc++/include/c_std/std_cctype.h @@ -40,8 +40,8 @@ * contained in the namespace @c std. */ -#ifndef _CPP_CCTYPE -#define _CPP_CCTYPE 1 +#ifndef _GLIBCXX_CCTYPE +#define _GLIBCXX_CCTYPE 1 #pragma GCC system_header @@ -80,4 +80,4 @@ namespace std using ::toupper; } -#endif +#endif diff --git a/contrib/libstdc++/include/c_std/std_cerrno.h b/contrib/libstdc++/include/c_std/std_cerrno.h index 7fcecd43917c..7915e14ba270 100644 --- a/contrib/libstdc++/include/c_std/std_cerrno.h +++ b/contrib/libstdc++/include/c_std/std_cerrno.h @@ -40,8 +40,8 @@ * contained in the namespace @c std. */ -#ifndef _CPP_CERRNO -#define _CPP_CERRNO 1 +#ifndef _GLIBCXX_CERRNO +#define _GLIBCXX_CERRNO 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c_std/std_cfloat.h b/contrib/libstdc++/include/c_std/std_cfloat.h index 3cc8d7218daa..4c5bb00f2042 100644 --- a/contrib/libstdc++/include/c_std/std_cfloat.h +++ b/contrib/libstdc++/include/c_std/std_cfloat.h @@ -40,8 +40,8 @@ * contained in the namespace @c std. */ -#ifndef _CPP_CFLOAT -#define _CPP_CFLOAT 1 +#ifndef _GLIBCXX_CFLOAT +#define _GLIBCXX_CFLOAT 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c_std/std_climits.h b/contrib/libstdc++/include/c_std/std_climits.h index 242913e60dfb..f4e1d8f77fa8 100644 --- a/contrib/libstdc++/include/c_std/std_climits.h +++ b/contrib/libstdc++/include/c_std/std_climits.h @@ -41,8 +41,8 @@ * contained in the namespace @c std. */ -#ifndef _CPP_CLIMITS -#define _CPP_CLIMITS 1 +#ifndef _GLIBCXX_CLIMITS +#define _GLIBCXX_CLIMITS 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c_std/std_clocale.h b/contrib/libstdc++/include/c_std/std_clocale.h index 66747d9244c5..988b84924af5 100644 --- a/contrib/libstdc++/include/c_std/std_clocale.h +++ b/contrib/libstdc++/include/c_std/std_clocale.h @@ -41,8 +41,8 @@ * contained in the namespace @c std. */ -#ifndef _CPP_CLOCALE -#define _CPP_CLOCALE 1 +#ifndef _GLIBCXX_CLOCALE +#define _GLIBCXX_CLOCALE 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c_std/std_cmath.h b/contrib/libstdc++/include/c_std/std_cmath.h index 1264c4dba69a..66866b2cc3a0 100644 --- a/contrib/libstdc++/include/c_std/std_cmath.h +++ b/contrib/libstdc++/include/c_std/std_cmath.h @@ -41,12 +41,13 @@ * contained in the namespace @c std. */ -#ifndef _CPP_CMATH -#define _CPP_CMATH 1 +#ifndef _GLIBCXX_CMATH +#define _GLIBCXX_CMATH 1 #pragma GCC system_header #include <bits/c++config.h> +#include <bits/cpp_type_traits.h> #include <math.h> @@ -76,92 +77,8 @@ #undef tan #undef tanh -// ...and in the darkness bind them... -namespace __gnu_cxx -{ - namespace __c99_binding - { -#if _GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_CHECK || \ - _GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC - extern "C" float (acosf)(float); - extern "C" float (asinf)(float); - extern "C" float (atanf)(float); - extern "C" float (atan2f)(float, float); - extern "C" float (ceilf)(float); - extern "C" float (coshf)(float); - extern "C" float (expf)(float); - extern "C" float (floorf)(float); - extern "C" float (fmodf)(float, float); - extern "C" float (frexpf)(float, int*); - extern "C" float (ldexpf)(float, int); - extern "C" float (logf)(float); - extern "C" float (log10f)(float); - extern "C" float (modff)(float, float*); - extern "C" float (powf)(float, float); - extern "C" float (sinhf)(float); - extern "C" float (tanf)(float); - extern "C" float (tanhf)(float); -#endif -#if !_GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC -#if _GLIBCPP_HAVE_ACOSF - using ::acosf; -#endif -#if _GLIBCPP_HAVE_ASINF - using ::asinf; -#endif -#if _GLIBCPP_HAVE_ATANF - using ::atanf; -#endif -#if _GLIBCPP_HAVE_ATAN2F - using ::atan2f; -#endif -#if _GLIBCPP_HAVE_CEILF - using ::ceilf; -#endif -#if _GLIBCPP_HAVE_COSHF - using ::coshf; -#endif -#if _GLIBCPP_HAVE_EXPF - using ::expf; -#endif -#if _GLIBCPP_HAVE_FLOORF - using ::floorf; -#endif -#if _GLIBCPP_HAVE_FMODF - using ::fmodf; -#endif -#if _GLIBCPP_HAVE_FREXPF - using ::frexpf; -#endif -#if _GLIBCPP_HAVE_LDEXPF - using ::ldexpf; -#endif -#if _GLIBCPP_HAVE_LOGF - using ::logf; -#endif -#if _GLIBCPP_HAVE_LOG10F - using ::log10f; -#endif -#if _GLIBCPP_HAVE_MODFF - using ::modff; -#endif -#if _GLIBCPP_HAVE_POWF - using ::powf; -#endif -#if _GLIBCPP_HAVE_SINHF - using ::sinhf; -#endif -#if _GLIBCPP_HAVE_TANF - using ::tanf; -#endif -#if _GLIBCPP_HAVE_TANHF - using ::tanhf; -#endif -#endif /* _GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC */ - } -} -namespace std +namespace std { // Forward declaration of a helper function. This really should be // an `exported' forward declaration. @@ -179,97 +96,83 @@ namespace std abs(long double __x) { return __builtin_fabsl(__x); } -#if _GLIBCPP_HAVE_ACOSF - inline float - acos(float __x) { return __gnu_cxx::__c99_binding::acosf(__x); } -#else - inline float - acos(float __x) { return ::acos(static_cast<double>(__x)); } -#endif - using ::acos; - -#if _GLIBCPP_HAVE_ACOSL - inline long double - acos(long double __x) { return ::acosl(__x); } -#else - inline long double - acos(long double __x) { return ::acos(static_cast<double>(__x)); } -#endif + + inline float + acos(float __x) + { return __builtin_acosf(__x); } + + inline long double + acos(long double __x) + { return __builtin_acosl(__x); } + + template<typename _Tp> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type + acos(_Tp __x) + { + return __builtin_acos(__x); + } using ::asin; -#if _GLIBCPP_HAVE_ASINF - inline float - asin(float __x) { return __gnu_cxx::__c99_binding::asinf(__x); } -#else - inline float - asin(float __x) { return ::asin(static_cast<double>(__x)); } -#endif + inline float + asin(float __x) + { return __builtin_asinf(__x); } -#if _GLIBCPP_HAVE_ASINL - inline long double - asin(long double __x) { return ::asinl(__x); } -#else - inline long double - asin(long double __x) { return ::asin(static_cast<double>(__x)); } -#endif + inline long double + asin(long double __x) + { return __builtin_asinl(__x); } + + template<typename _Tp> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type + asin(_Tp __x) + { return __builtin_asin(__x); } using ::atan; -#if _GLIBCPP_HAVE_ATANF - inline float - atan(float __x) { return __gnu_cxx::__c99_binding::atanf(__x); } -#else - inline float - atan(float __x) { return ::atan(static_cast<double>(__x)); } -#endif + inline float + atan(float __x) + { return __builtin_atanf(__x); } -#if _GLIBCPP_HAVE_ATANL - inline long double - atan(long double __x) { return ::atanl(__x); } -#else - inline long double - atan(long double __x) { return ::atan(static_cast<double>(__x)); } -#endif + inline long double + atan(long double __x) + { return __builtin_atanl(__x); } + + template<typename _Tp> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type + atan(_Tp __x) + { return __builtin_atan(__x); } using ::atan2; -#if _GLIBCPP_HAVE_ATAN2F - inline float - atan2(float __y, float __x) { return __gnu_cxx::__c99_binding::atan2f(__y, __x); } -#else - inline float + inline float atan2(float __y, float __x) - { return ::atan2(static_cast<double>(__y), static_cast<double>(__x)); } -#endif + { return __builtin_atan2f(__y, __x); } -#if _GLIBCPP_HAVE_ATAN2L - inline long double - atan2(long double __y, long double __x) { return ::atan2l(__y, __x); } -#else - inline long double - atan2(long double __y, long double __x) - { return ::atan2(static_cast<double>(__y), static_cast<double>(__x)); } -#endif + inline long double + atan2(long double __y, long double __x) + { return __builtin_atan2l(__y, __x); } + + template<typename _Tp, typename _Up> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type + && __is_integer<_Up>::_M_type>::_M_type + atan2(_Tp __y, _Up __x) + { return __builtin_atan2(__y, __x); } using ::ceil; -#if _GLIBCPP_HAVE_CEILF - inline float - ceil(float __x) { return __gnu_cxx::__c99_binding::ceilf(__x); } -#else - inline float - ceil(float __x) { return ::ceil(static_cast<double>(__x)); } -#endif + inline float + ceil(float __x) + { return __builtin_ceilf(__x); } -#if _GLIBCPP_HAVE_CEILL - inline long double - ceil(long double __x) { return ::ceill(__x); } -#else - inline long double - ceil(long double __x) { return ::ceil(static_cast<double>(__x)); } -#endif + inline long double + ceil(long double __x) + { return __builtin_ceill(__x); } + + template<typename _Tp> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type + ceil(_Tp __x) + { return __builtin_ceil(__x); } using ::cos; @@ -281,41 +184,40 @@ namespace std cos(long double __x) { return __builtin_cosl(__x); } + template<typename _Tp> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type + cos(_Tp __x) + { return __builtin_cos(__x); } + using ::cosh; -#if _GLIBCPP_HAVE_COSHF - inline float - cosh(float __x) { return __gnu_cxx::__c99_binding::coshf(__x); } -#else - inline float - cosh(float __x) { return ::cosh(static_cast<double>(__x)); } -#endif + inline float + cosh(float __x) + { return __builtin_coshf(__x); } -#if _GLIBCPP_HAVE_COSHL - inline long double - cosh(long double __x) { return ::coshl(__x); } -#else - inline long double - cosh(long double __x) { return ::cosh(static_cast<double>(__x)); } -#endif + inline long double + cosh(long double __x) + { return __builtin_coshl(__x); } + + template<typename _Tp> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type + cosh(_Tp __x) + { return __builtin_cosh(__x); } using ::exp; -#if _GLIBCPP_HAVE_EXPF - inline float - exp(float __x) { return __gnu_cxx::__c99_binding::expf(__x); } -#else - inline float - exp(float __x) { return ::exp(static_cast<double>(__x)); } -#endif + inline float + exp(float __x) + { return __builtin_expf(__x); } -#if _GLIBCPP_HAVE_EXPL - inline long double - exp(long double __x) { return ::expl(__x); } -#else - inline long double - exp(long double __x) { return ::exp(static_cast<double>(__x)); } -#endif + inline long double + exp(long double __x) + { return __builtin_expl(__x); } + + template<typename _Tp> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type + exp(_Tp __x) + { return __builtin_exp(__x); } using ::fabs; @@ -327,148 +229,105 @@ namespace std fabs(long double __x) { return __builtin_fabsl(__x); } + template<typename _Tp> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type + fabs(_Tp __x) + { return __builtin_fabs(__x); } + using ::floor; -#if _GLIBCPP_HAVE_FLOORF - inline float - floor(float __x) { return __gnu_cxx::__c99_binding::floorf(__x); } -#else - inline float - floor(float __x) { return ::floor(static_cast<double>(__x)); } -#endif + inline float + floor(float __x) + { return __builtin_floorf(__x); } -#if _GLIBCPP_HAVE_FLOORL - inline long double - floor(long double __x) { return ::floorl(__x); } -#else - inline long double - floor(long double __x) { return ::floor(static_cast<double>(__x)); } -#endif + inline long double + floor(long double __x) + { return __builtin_floorl(__x); } + + template<typename _Tp> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type + floor(_Tp __x) + { return __builtin_floor(__x); } using ::fmod; -#if _GLIBCPP_HAVE_FMODF - inline float - fmod(float __x, float __y) { return __gnu_cxx::__c99_binding::fmodf(__x, __y); } -#else - inline float + inline float fmod(float __x, float __y) - { return ::fmod(static_cast<double>(__x), static_cast<double>(__y)); } -#endif + { return __builtin_fmodf(__x, __y); } -#if _GLIBCPP_HAVE_FMODL - inline long double - fmod(long double __x, long double __y) { return ::fmodl(__x, __y); } -#else - inline long double - fmod(long double __x, long double __y) - { return ::fmod(static_cast<double>(__x), static_cast<double>(__y)); } -#endif + inline long double + fmod(long double __x, long double __y) + { return __builtin_fmodl(__x, __y); } using ::frexp; -#if _GLIBCPP_HAVE_FREXPF - inline float - frexp(float __x, int* __exp) { return __gnu_cxx::__c99_binding::frexpf(__x, __exp); } -#else - inline float - frexp(float __x, int* __exp) { return ::frexp(__x, __exp); } -#endif + inline float + frexp(float __x, int* __exp) + { return __builtin_frexpf(__x, __exp); } -#if _GLIBCPP_HAVE_FREXPL - inline long double - frexp(long double __x, int* __exp) { return ::frexpl(__x, __exp); } -#else - inline long double - frexp(long double __x, int* __exp) - { return ::frexp(static_cast<double>(__x), __exp); } -#endif + inline long double + frexp(long double __x, int* __exp) + { return __builtin_frexpl(__x, __exp); } + + template<typename _Tp> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type + frexp(_Tp __x, int* __exp) + { return __builtin_frexp(__x, __exp); } using ::ldexp; -#if _GLIBCPP_HAVE_LDEXPF - inline float - ldexp(float __x, int __exp) { return __gnu_cxx::__c99_binding::ldexpf(__x, __exp); } -#else - inline float + inline float ldexp(float __x, int __exp) - { return ::ldexp(static_cast<double>(__x), __exp); } -#endif + { return __builtin_ldexpf(__x, __exp); } -#if _GLIBCPP_HAVE_LDEXPL - inline long double - ldexp(long double __x, int __exp) { return ::ldexpl(__x, __exp); } -#else - inline long double - ldexp(long double __x, int __exp) - { return ::ldexp(static_cast<double>(__x), __exp); } -#endif + inline long double + ldexp(long double __x, int __exp) + { return __builtin_ldexpl(__x, __exp); } + + template<typename _Tp> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type + ldexp(_Tp __x, int __exp) + { return __builtin_ldexp(__x, __exp); } using ::log; -#if _GLIBCPP_HAVE_LOGF - inline float - log(float __x) { return __gnu_cxx::__c99_binding::logf(__x); } -#else - inline float log(float __x) - { return ::log(static_cast<double>(__x)); } -#endif + inline float + log(float __x) + { return __builtin_logf(__x); } -#if _GLIBCPP_HAVE_LOGL - inline long double - log(long double __x) { return ::logl(__x); } -#else - inline long double - log(long double __x) { return ::log(static_cast<double>(__x)); } -#endif + inline long double + log(long double __x) + { return __builtin_logl(__x); } + + template<typename _Tp> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type + log(_Tp __x) + { return __builtin_log(__x); } using ::log10; -#if _GLIBCPP_HAVE_LOG10F - inline float - log10(float __x) { return __gnu_cxx::__c99_binding::log10f(__x); } -#else - inline float - log10(float __x) { return ::log10(static_cast<double>(__x)); } -#endif + inline float + log10(float __x) + { return __builtin_log10f(__x); } -#if _GLIBCPP_HAVE_LOG10L - inline long double - log10(long double __x) { return ::log10l(__x); } -#else - inline long double - log10(long double __x) { return ::log10(static_cast<double>(__x)); } -#endif + inline long double + log10(long double __x) + { return __builtin_log10l(__x); } + + template<typename _Tp> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type + log10(_Tp __x) + { return __builtin_log10(__x); } using ::modf; -#if _GLIBCPP_HAVE_MODFF - inline float - modf(float __x, float* __iptr) { return __gnu_cxx::__c99_binding::modff(__x, __iptr); } -#else - inline float + inline float modf(float __x, float* __iptr) - { - double __tmp; - double __res = ::modf(static_cast<double>(__x), &__tmp); - *__iptr = static_cast<float>(__tmp); - return __res; - } -#endif + { return __builtin_modff(__x, __iptr); } -#if _GLIBCPP_HAVE_MODFL - inline long double - modf(long double __x, long double* __iptr) { return ::modfl(__x, __iptr); } -#else - inline long double - modf(long double __x, long double* __iptr) - { - double __tmp; - double __res = ::modf(static_cast<double>(__x), &__tmp); - * __iptr = static_cast<long double>(__tmp); - return __res; - } -#endif + inline long double + modf(long double __x, long double* __iptr) + { return __builtin_modfl(__x, __iptr); } template<typename _Tp> inline _Tp @@ -481,33 +340,23 @@ namespace std using ::pow; -#if _GLIBCPP_HAVE_POWF - inline float - pow(float __x, float __y) { return __gnu_cxx::__c99_binding::powf(__x, __y); } -#else - inline float + inline float pow(float __x, float __y) - { return ::pow(static_cast<double>(__x), static_cast<double>(__y)); } -#endif + { return __builtin_powf(__x, __y); } -#if _GLIBCPP_HAVE_POWL - inline long double - pow(long double __x, long double __y) { return ::powl(__x, __y); } -#else - inline long double - pow(long double __x, long double __y) - { return ::pow(static_cast<double>(__x), static_cast<double>(__y)); } -#endif + inline long double + pow(long double __x, long double __y) + { return __builtin_powl(__x, __y); } - inline double + inline double pow(double __x, int __i) { return __pow_helper(__x, __i); } - inline float + inline float pow(float __x, int __n) { return __pow_helper(__x, __n); } - inline long double + inline long double pow(long double __x, int __n) { return __pow_helper(__x, __n); } @@ -521,23 +370,25 @@ namespace std sin(long double __x) { return __builtin_sinl(__x); } + template<typename _Tp> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type + sin(_Tp __x) + { return __builtin_sin(__x); } + using ::sinh; -#if _GLIBCPP_HAVE_SINHF - inline float - sinh(float __x) { return __gnu_cxx::__c99_binding::sinhf(__x); } -#else - inline float - sinh(float __x) { return ::sinh(static_cast<double>(__x)); } -#endif + inline float + sinh(float __x) + { return __builtin_sinhf(__x); } -#if _GLIBCPP_HAVE_SINHL - inline long double - sinh(long double __x) { return ::sinhl(__x); } -#else - inline long double - sinh(long double __x) { return ::sinh(static_cast<double>(__x)); } -#endif + inline long double + sinh(long double __x) + { return __builtin_sinhl(__x); } + + template<typename _Tp> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type + sinh(_Tp __x) + { return __builtin_sinh(__x); } using ::sqrt; @@ -549,107 +400,104 @@ namespace std sqrt(long double __x) { return __builtin_sqrtl(__x); } + template<typename _Tp> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type + sqrt(_Tp __x) + { return __builtin_sqrt(__x); } + using ::tan; -#if _GLIBCPP_HAVE_TANF - inline float - tan(float __x) { return __gnu_cxx::__c99_binding::tanf(__x); } -#else - inline float - tan(float __x) { return ::tan(static_cast<double>(__x)); } -#endif + inline float + tan(float __x) + { return __builtin_tanf(__x); } -#if _GLIBCPP_HAVE_TANL - inline long double - tan(long double __x) { return ::tanl(__x); } -#else - inline long double - tan(long double __x) { return ::tan(static_cast<double>(__x)); } -#endif + inline long double + tan(long double __x) + { return __builtin_tanl(__x); } + + template<typename _Tp> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type + tan(_Tp __x) + { return __builtin_tan(__x); } using ::tanh; -#if _GLIBCPP_HAVE_TANHF - inline float - tanh(float __x) { return __gnu_cxx::__c99_binding::tanhf(__x); } -#else - inline float - tanh(float __x) { return ::tanh(static_cast<double>(__x)); } -#endif + inline float + tanh(float __x) + { return __builtin_tanhf(__x); } -#if _GLIBCPP_HAVE_TANHL - inline long double - tanh(long double __x) { return ::tanhl(__x); } -#else - inline long double - tanh(long double __x) { return ::tanh(static_cast<double>(__x)); } -#endif -} + inline long double + tanh(long double __x) + { return __builtin_tanhl(__x); } + template<typename _Tp> + inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type + tanh(_Tp __x) + { return __builtin_tanh(__x); } +} -#if _GLIBCPP_USE_C99 -#if !_GLIBCPP_USE_C99_FP_MACROS_DYNAMIC +#if _GLIBCXX_USE_C99_MATH +#if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC // These are possible macros imported from C99-land. For strict // conformance, remove possible C99-injected names from the global -// namespace, and sequester them in the __gnu_cxx extension namespace. +// namespace, and sequester them in the __gnu_cxx extension namespace. namespace __gnu_cxx { template<typename _Tp> - int + int __capture_fpclassify(_Tp __f) { return fpclassify(__f); } template<typename _Tp> - int + int __capture_isfinite(_Tp __f) { return isfinite(__f); } template<typename _Tp> - int + int __capture_isinf(_Tp __f) { return isinf(__f); } template<typename _Tp> - int + int __capture_isnan(_Tp __f) { return isnan(__f); } template<typename _Tp> - int + int __capture_isnormal(_Tp __f) { return isnormal(__f); } template<typename _Tp> - int + int __capture_signbit(_Tp __f) { return signbit(__f); } template<typename _Tp> - int + int __capture_isgreater(_Tp __f1, _Tp __f2) { return isgreater(__f1, __f2); } template<typename _Tp> - int - __capture_isgreaterequal(_Tp __f1, _Tp __f2) + int + __capture_isgreaterequal(_Tp __f1, _Tp __f2) { return isgreaterequal(__f1, __f2); } template<typename _Tp> - int + int __capture_isless(_Tp __f1, _Tp __f2) { return isless(__f1, __f2); } template<typename _Tp> - int - __capture_islessequal(_Tp __f1, _Tp __f2) + int + __capture_islessequal(_Tp __f1, _Tp __f2) { return islessequal(__f1, __f2); } template<typename _Tp> - int - __capture_islessgreater(_Tp __f1, _Tp __f2) + int + __capture_islessgreater(_Tp __f1, _Tp __f2) { return islessgreater(__f1, __f2); } template<typename _Tp> - int - __capture_isunordered(_Tp __f1, _Tp __f2) + int + __capture_isunordered(_Tp __f1, _Tp __f2) { return isunordered(__f1, __f2); } -} -#endif /* _GLIBCPP_USE_C99_FP_MACROS_DYNAMIC */ -#endif +} +// Only undefine the C99 FP macros, if actually captured for namespace movement #undef fpclassify #undef isfinite #undef isinf @@ -662,9 +510,11 @@ namespace __gnu_cxx #undef islessequal #undef islessgreater #undef isunordered +#endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */ +#endif -#if _GLIBCPP_USE_C99 -#if !_GLIBCPP_USE_C99_FP_MACROS_DYNAMIC +#if _GLIBCXX_USE_C99_MATH +#if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC namespace __gnu_cxx { template<typename _Tp> @@ -676,47 +526,47 @@ namespace __gnu_cxx isfinite(_Tp __f) { return __capture_isfinite(__f); } template<typename _Tp> - int + int isinf(_Tp __f) { return __capture_isinf(__f); } template<typename _Tp> - int + int isnan(_Tp __f) { return __capture_isnan(__f); } template<typename _Tp> - int + int isnormal(_Tp __f) { return __capture_isnormal(__f); } template<typename _Tp> - int + int signbit(_Tp __f) { return __capture_signbit(__f); } template<typename _Tp> - int + int isgreater(_Tp __f1, _Tp __f2) { return __capture_isgreater(__f1, __f2); } template<typename _Tp> - int - isgreaterequal(_Tp __f1, _Tp __f2) + int + isgreaterequal(_Tp __f1, _Tp __f2) { return __capture_isgreaterequal(__f1, __f2); } template<typename _Tp> - int + int isless(_Tp __f1, _Tp __f2) { return __capture_isless(__f1, __f2); } template<typename _Tp> - int - islessequal(_Tp __f1, _Tp __f2) + int + islessequal(_Tp __f1, _Tp __f2) { return __capture_islessequal(__f1, __f2); } template<typename _Tp> - int - islessgreater(_Tp __f1, _Tp __f2) + int + islessgreater(_Tp __f1, _Tp __f2) { return __capture_islessgreater(__f1, __f2); } template<typename _Tp> - int - isunordered(_Tp __f1, _Tp __f2) + int + isunordered(_Tp __f1, _Tp __f2) { return __capture_isunordered(__f1, __f2); } } @@ -735,12 +585,11 @@ namespace std using __gnu_cxx::islessgreater; using __gnu_cxx::isunordered; } -#endif /* _GLIBCPP_USE_C99_FP_MACROS_DYNAMIC */ +#endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */ #endif - -#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT -# define export -# include <bits/cmath.tcc> + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <bits/cmath.tcc> #endif #endif diff --git a/contrib/libstdc++/include/c_std/std_csetjmp.h b/contrib/libstdc++/include/c_std/std_csetjmp.h index f6df58150019..d5fe073f0fc5 100644 --- a/contrib/libstdc++/include/c_std/std_csetjmp.h +++ b/contrib/libstdc++/include/c_std/std_csetjmp.h @@ -41,8 +41,8 @@ * contained in the namespace @c std. */ -#ifndef _CPP_CSETJMP -#define _CPP_CSETJMP 1 +#ifndef _GLIBCXX_CSETJMP +#define _GLIBCXX_CSETJMP 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c_std/std_csignal.h b/contrib/libstdc++/include/c_std/std_csignal.h index 1017161d63f1..5734cf6d29a4 100644 --- a/contrib/libstdc++/include/c_std/std_csignal.h +++ b/contrib/libstdc++/include/c_std/std_csignal.h @@ -41,8 +41,8 @@ * contained in the namespace @c std. */ -#ifndef _CPP_CSIGNAL -#define _CPP_CSIGNAL 1 +#ifndef _GLIBCXX_CSIGNAL +#define _GLIBCXX_CSIGNAL 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c_std/std_cstdarg.h b/contrib/libstdc++/include/c_std/std_cstdarg.h index 9383adee9a53..ca362e4b412f 100644 --- a/contrib/libstdc++/include/c_std/std_cstdarg.h +++ b/contrib/libstdc++/include/c_std/std_cstdarg.h @@ -40,8 +40,8 @@ * contained in the namespace @c std. */ -#ifndef _CPP_CSTDARG -#define _CPP_CSTDARG 1 +#ifndef _GLIBCXX_CSTDARG +#define _GLIBCXX_CSTDARG 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c_std/std_cstddef.h b/contrib/libstdc++/include/c_std/std_cstddef.h index 7a740afb3981..4fa82c6aa9b4 100644 --- a/contrib/libstdc++/include/c_std/std_cstddef.h +++ b/contrib/libstdc++/include/c_std/std_cstddef.h @@ -40,14 +40,14 @@ * contained in the namespace @c std. */ -#ifndef _CPP_CSTDDEF -#define _CPP_CSTDDEF 1 +#ifndef _GLIBCXX_CSTDDEF +#define _GLIBCXX_CSTDDEF 1 #pragma GCC system_header #include <stddef.h> -namespace std +namespace std { using ::ptrdiff_t; using ::size_t; diff --git a/contrib/libstdc++/include/c_std/std_cstdio.h b/contrib/libstdc++/include/c_std/std_cstdio.h index 3b4a68567396..f31e58e6f249 100644 --- a/contrib/libstdc++/include/c_std/std_cstdio.h +++ b/contrib/libstdc++/include/c_std/std_cstdio.h @@ -41,8 +41,8 @@ * contained in the namespace @c std. */ -#ifndef _CPP_CSTDIO -#define _CPP_CSTDIO 1 +#ifndef _GLIBCXX_CSTDIO +#define _GLIBCXX_CSTDIO 1 #pragma GCC system_header @@ -94,7 +94,7 @@ #undef vprintf #undef vsprintf -namespace std +namespace std { using ::FILE; using ::fpos_t; @@ -142,7 +142,7 @@ namespace std using ::vsprintf; } -#if _GLIBCPP_USE_C99 +#if _GLIBCXX_USE_C99 #undef snprintf #undef vfscanf @@ -152,7 +152,7 @@ namespace std namespace __gnu_cxx { -#if _GLIBCPP_USE_C99_CHECK || _GLIBCPP_USE_C99_DYNAMIC +#if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC extern "C" int (snprintf)(char * restrict, size_t, const char * restrict, ...); extern "C" int @@ -163,7 +163,7 @@ namespace __gnu_cxx extern "C" int (vsscanf)(const char * restrict, const char * restrict, __gnuc_va_list); #endif -#if !_GLIBCPP_USE_C99_DYNAMIC +#if !_GLIBCXX_USE_C99_DYNAMIC using ::snprintf; using ::vfscanf; using ::vscanf; @@ -180,6 +180,6 @@ namespace std using __gnu_cxx::vsnprintf; using __gnu_cxx::vsscanf; } -#endif +#endif #endif diff --git a/contrib/libstdc++/include/c_std/std_cstdlib.h b/contrib/libstdc++/include/c_std/std_cstdlib.h index e1436be1d7a1..d2d6e37064b5 100644 --- a/contrib/libstdc++/include/c_std/std_cstdlib.h +++ b/contrib/libstdc++/include/c_std/std_cstdlib.h @@ -41,8 +41,8 @@ * contained in the namespace @c std. */ -#ifndef _CPP_CSTDLIB -#define _CPP_CSTDLIB 1 +#ifndef _GLIBCXX_CSTDLIB +#define _GLIBCXX_CSTDLIB 1 #pragma GCC system_header @@ -81,7 +81,7 @@ #undef wcstombs #undef wctomb -namespace std +namespace std { using ::div_t; using ::ldiv_t; @@ -101,9 +101,11 @@ namespace std using ::labs; using ::ldiv; using ::malloc; +#ifdef _GLIBCXX_HAVE_MBSTATE_T using ::mblen; using ::mbstowcs; using ::mbtowc; +#endif // _GLIBCXX_HAVE_MBSTATE_T using ::qsort; using ::rand; using ::realloc; @@ -112,17 +114,19 @@ namespace std using ::strtol; using ::strtoul; using ::system; +#ifdef _GLIBCXX_USE_WCHAR_T using ::wcstombs; using ::wctomb; +#endif // _GLIBCXX_USE_WCHAR_T - inline long + inline long abs(long __i) { return labs(__i); } inline ldiv_t div(long __i, long __j) { return ldiv(__i, __j); } -} +} -#if _GLIBCPP_USE_C99 +#if _GLIBCXX_USE_C99 #undef _Exit #undef llabs @@ -135,57 +139,57 @@ namespace std namespace __gnu_cxx { -#if !_GLIBCPP_USE_C99_LONG_LONG_DYNAMIC +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::lldiv_t; #endif -#if _GLIBCPP_USE_C99_CHECK || _GLIBCPP_USE_C99_DYNAMIC +#if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC extern "C" void (_Exit)(int); #endif -#if !_GLIBCPP_USE_C99_DYNAMIC +#if !_GLIBCXX_USE_C99_DYNAMIC using ::_Exit; #endif - inline long long + inline long long abs(long long __x) { return __x >= 0 ? __x : -__x; } - inline long long + inline long long llabs(long long __x) { return __x >= 0 ? __x : -__x; } -#if !_GLIBCPP_USE_C99_LONG_LONG_DYNAMIC - inline lldiv_t +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC + inline lldiv_t div(long long __n, long long __d) { lldiv_t __q; __q.quot = __n / __d; __q.rem = __n % __d; return __q; } - inline lldiv_t + inline lldiv_t lldiv(long long __n, long long __d) { lldiv_t __q; __q.quot = __n / __d; __q.rem = __n % __d; return __q; } #endif -#if _GLIBCPP_USE_C99_LONG_LONG_CHECK || _GLIBCPP_USE_C99_LONG_LONG_DYNAMIC +#if _GLIBCXX_USE_C99_LONG_LONG_CHECK || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC extern "C" long long int (atoll)(const char *); extern "C" long long int (strtoll)(const char * restrict, char ** restrict, int); extern "C" unsigned long long int (strtoull)(const char * restrict, char ** restrict, int); #endif -#if !_GLIBCPP_USE_C99_LONG_LONG_DYNAMIC +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::atoll; using ::strtoll; using ::strtoull; #endif using ::strtof; - using ::strtold; -} + using ::strtold; +} namespace std { -#if !_GLIBCPP_USE_C99_LONG_LONG_DYNAMIC +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using __gnu_cxx::lldiv_t; #endif using __gnu_cxx::_Exit; using __gnu_cxx::abs; - using __gnu_cxx::llabs; -#if !_GLIBCPP_USE_C99_LONG_LONG_DYNAMIC + using __gnu_cxx::llabs; +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using __gnu_cxx::div; using __gnu_cxx::lldiv; #endif @@ -197,4 +201,4 @@ namespace std } #endif -#endif +#endif diff --git a/contrib/libstdc++/include/c_std/std_cstring.h b/contrib/libstdc++/include/c_std/std_cstring.h index 066342aaaba7..dad40c290ad3 100644 --- a/contrib/libstdc++/include/c_std/std_cstring.h +++ b/contrib/libstdc++/include/c_std/std_cstring.h @@ -41,8 +41,8 @@ * contained in the namespace @c std. */ -#ifndef _CPP_CSTRING -#define _CPP_CSTRING 1 +#ifndef _GLIBCXX_CSTRING +#define _GLIBCXX_CSTRING 1 #pragma GCC system_header @@ -74,7 +74,7 @@ #undef strerror #undef strlen -namespace std +namespace std { using ::memcpy; using ::memmove; diff --git a/contrib/libstdc++/include/c_std/std_ctime.h b/contrib/libstdc++/include/c_std/std_ctime.h index 1b4c09b77ccf..fe890dfd580c 100644 --- a/contrib/libstdc++/include/c_std/std_ctime.h +++ b/contrib/libstdc++/include/c_std/std_ctime.h @@ -41,8 +41,8 @@ * contained in the namespace @c std. */ -#ifndef _CPP_CTIME -#define _CPP_CTIME 1 +#ifndef _GLIBCXX_CTIME +#define _GLIBCXX_CTIME 1 #pragma GCC system_header diff --git a/contrib/libstdc++/include/c_std/std_cwchar.h b/contrib/libstdc++/include/c_std/std_cwchar.h index 8b33c52282f1..d9e11e95a9ae 100644 --- a/contrib/libstdc++/include/c_std/std_cwchar.h +++ b/contrib/libstdc++/include/c_std/std_cwchar.h @@ -41,8 +41,8 @@ * contained in the namespace @c std. */ -#ifndef _CPP_CWCHAR -#define _CPP_CWCHAR 1 +#ifndef _GLIBCXX_CWCHAR +#define _GLIBCXX_CWCHAR 1 #pragma GCC system_header @@ -50,23 +50,23 @@ #include <cstddef> #include <ctime> -#if _GLIBCPP_HAVE_WCHAR_H +#if _GLIBCXX_HAVE_WCHAR_H #include <wchar.h> #endif // Need to do a bit of trickery here with mbstate_t as char_traits // assumes it is in wchar.h, regardless of wchar_t specializations. -#ifndef _GLIBCPP_HAVE_MBSTATE_T -extern "C" +#ifndef _GLIBCXX_HAVE_MBSTATE_T +extern "C" { - typedef struct + typedef struct { int __fill[6]; } mbstate_t; } #endif -namespace std +namespace std { using ::mbstate_t; } @@ -92,11 +92,17 @@ namespace std #undef swscanf #undef ungetwc #undef vfwprintf -#undef vfwscanf +#if _GLIBCXX_HAVE_VFWSCANF +# undef vfwscanf +#endif #undef vswprintf -#undef vswscanf +#if _GLIBCXX_HAVE_VSWSCANF +# undef vswscanf +#endif #undef vwprintf -#undef vwscanf +#if _GLIBCXX_HAVE_VWSCANF +# undef vwscanf +#endif #undef wcrtomb #undef wcscat #undef wcschr @@ -115,7 +121,9 @@ namespace std #undef wcsspn #undef wcsstr #undef wcstod -#undef wcstof +#if _GLIBCXX_HAVE_WCSTOF +# undef wcstof +#endif #undef wcstok #undef wcstol #undef wcstoul @@ -129,7 +137,7 @@ namespace std #undef wprintf #undef wscanf -#if _GLIBCPP_USE_WCHAR_T +#if _GLIBCXX_USE_WCHAR_T namespace std { using ::wint_t; @@ -154,11 +162,17 @@ namespace std using ::swscanf; using ::ungetwc; using ::vfwprintf; +#if _GLIBCXX_HAVE_VFWSCANF using ::vfwscanf; +#endif using ::vswprintf; +#if _GLIBCXX_HAVE_VSWSCANF using ::vswscanf; +#endif using ::vwprintf; +#if _GLIBCXX_HAVE_VWSCANF using ::vwscanf; +#endif using ::wcrtomb; using ::wcscat; using ::wcscmp; @@ -173,7 +187,9 @@ namespace std using ::wcsrtombs; using ::wcsspn; using ::wcstod; +#if _GLIBCXX_HAVE_WCSTOF using ::wcstof; +#endif using ::wcstok; using ::wcstol; using ::wcstoul; @@ -207,7 +223,7 @@ namespace std using ::wcsstr; inline wchar_t* - wcsstr(wchar_t* __s1, wchar_t* __s2) + wcsstr(wchar_t* __s1, const wchar_t* __s2) { return wcsstr(const_cast<const wchar_t*>(__s1), __s2); } using ::wmemchr; @@ -217,7 +233,7 @@ namespace std { return wmemchr(const_cast<const wchar_t*>(__p), __c, __n); } } -#if _GLIBCPP_USE_C99 +#if _GLIBCXX_USE_C99 #undef wcstold #undef wcstoll @@ -225,20 +241,20 @@ namespace std namespace __gnu_cxx { -#if _GLIBCPP_USE_C99_CHECK || _GLIBCPP_USE_C99_DYNAMIC +#if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC extern "C" long double (wcstold)(const wchar_t * restrict, wchar_t ** restrict); #endif -#if !_GLIBCPP_USE_C99_DYNAMIC +#if !_GLIBCXX_USE_C99_DYNAMIC using ::wcstold; #endif -#if _GLIBCPP_USE_C99_LONG_LONG_CHECK || _GLIBCPP_USE_C99_LONG_LONG_DYNAMIC +#if _GLIBCXX_USE_C99_LONG_LONG_CHECK || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC extern "C" long long int (wcstoll)(const wchar_t * restrict, wchar_t ** restrict, int); extern "C" unsigned long long int (wcstoull)(const wchar_t * restrict, wchar_t ** restrict, int); #endif -#if !_GLIBCPP_USE_C99_LONG_LONG_DYNAMIC +#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::wcstoll; using ::wcstoull; #endif @@ -252,6 +268,6 @@ namespace std } #endif -#endif //_GLIBCPP_USE_WCHAR_T +#endif //_GLIBCXX_USE_WCHAR_T -#endif +#endif diff --git a/contrib/libstdc++/include/c_std/std_cwctype.h b/contrib/libstdc++/include/c_std/std_cwctype.h index e469194aa197..970c53a8f3d2 100644 --- a/contrib/libstdc++/include/c_std/std_cwctype.h +++ b/contrib/libstdc++/include/c_std/std_cwctype.h @@ -1,6 +1,6 @@ // -*- C++ -*- forwarding header. -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -41,21 +41,23 @@ * contained in the namespace @c std. */ -#ifndef _CPP_CWCTYPE -#define _CPP_CWCTYPE 1 +#ifndef _GLIBCXX_CWCTYPE +#define _GLIBCXX_CWCTYPE 1 #pragma GCC system_header #include <bits/c++config.h> -#if _GLIBCPP_HAVE_WCTYPE_H +#if _GLIBCXX_HAVE_WCTYPE_H #include <wctype.h> #endif // Get rid of those macros defined in <wctype.h> in lieu of real functions. #undef iswalnum #undef iswalpha -#undef iswblank +#if _GLIBCXX_HAVE_ISWBLANK +# undef iswblank +#endif #undef iswcntrl #undef iswdigit #undef iswgraph @@ -66,24 +68,26 @@ #undef iswspace #undef iswupper #undef iswxdigit -#undef iswctype +#undef iswctype #undef towlower #undef towupper #undef towctrans #undef wctrans #undef wctype -#if _GLIBCPP_USE_WCHAR_T +#if _GLIBCXX_USE_WCHAR_T namespace std { - using ::wint_t; // cwchar + using ::wint_t; // cwchar using ::wctype_t; using ::wctrans_t; using ::iswalnum; using ::iswalpha; +#if _GLIBCXX_HAVE_ISWBLANK using ::iswblank; +#endif using ::iswcntrl; using ::iswdigit; using ::iswgraph; @@ -101,6 +105,6 @@ namespace std using ::wctrans; using ::wctype; } -#endif //_GLIBCPP_USE_WCHAR_T +#endif //_GLIBCXX_USE_WCHAR_T -#endif +#endif diff --git a/contrib/libstdc++/include/debug/bitset b/contrib/libstdc++/include/debug/bitset new file mode 100644 index 000000000000..2e2364ff9300 --- /dev/null +++ b/contrib/libstdc++/include/debug/bitset @@ -0,0 +1,299 @@ +// Debugging bitset implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_BITSET +#define _GLIBCXX_DEBUG_BITSET + +#include <bitset> +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_debug_def +{ + template<size_t _Nb> + class bitset + : public _GLIBCXX_STD::bitset<_Nb>, + public __gnu_debug::_Safe_sequence_base + { + typedef _GLIBCXX_STD::bitset<_Nb> _Base; + typedef __gnu_debug::_Safe_sequence_base _Safe_base; + + public: + // bit reference: + class reference + : private _Base::reference, public __gnu_debug::_Safe_iterator_base + { + typedef typename _Base::reference _Base_ref; + + friend class bitset; + reference(); + + reference(const _Base_ref& __base, bitset* __seq) + : _Base_ref(__base), _Safe_iterator_base(__seq, false) + { } + + public: + reference(const reference& __x) + : _Base_ref(__x), _Safe_iterator_base(__x, false) + { } + + reference& + operator=(bool __x) + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_write) + ._M_iterator(*this)); + *static_cast<_Base_ref*>(this) = __x; + return *this; + } + + reference& + operator=(const reference& __x) + { + _GLIBCXX_DEBUG_VERIFY(! __x._M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_read) + ._M_iterator(__x)); + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_write) + ._M_iterator(*this)); + *static_cast<_Base_ref*>(this) = __x; + return *this; + } + + bool + operator~() const + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_read) + ._M_iterator(*this)); + return ~(*static_cast<const _Base_ref*>(this)); + } + + operator bool() const + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_read) + ._M_iterator(*this)); + return *static_cast<const _Base_ref*>(this); + } + + reference& + flip() + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(::__gnu_debug::__msg_bad_bitset_flip) + ._M_iterator(*this)); + _Base_ref::flip(); + return *this; + } + }; + + // 23.3.5.1 constructors: + bitset() : _Base() { } + + bitset(unsigned long __val) : _Base(__val) { } + + template<typename _CharT, typename _Traits, typename _Allocator> + explicit + bitset(const std::basic_string<_CharT,_Traits,_Allocator>& __str, + typename std::basic_string<_CharT,_Traits,_Allocator>::size_type + __pos = 0, + typename std::basic_string<_CharT,_Traits,_Allocator>::size_type + __n = (std::basic_string<_CharT,_Traits,_Allocator>::npos)) + : _Base(__str, __pos, __n) { } + + bitset(const _Base& __x) : _Base(__x), _Safe_base() { } + + // 23.3.5.2 bitset operations: + bitset<_Nb>& + operator&=(const bitset<_Nb>& __rhs) + { + _M_base() &= __rhs; + return *this; + } + + bitset<_Nb>& + operator|=(const bitset<_Nb>& __rhs) + { + _M_base() |= __rhs; + return *this; + } + + bitset<_Nb>& + operator^=(const bitset<_Nb>& __rhs) + { + _M_base() ^= __rhs; + return *this; + } + + bitset<_Nb>& + operator<<=(size_t __pos) + { + _M_base() <<= __pos; + return *this; + } + + bitset<_Nb>& + operator>>=(size_t __pos) + { + _M_base() >>= __pos; + return *this; + } + + bitset<_Nb>& + set() + { + _Base::set(); + return *this; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 186. bitset::set() second parameter should be bool + bitset<_Nb>& + set(size_t __pos, bool __val = true) + { + _Base::set(__pos, __val); + return *this; + } + + bitset<_Nb>& + reset() + { + _Base::reset(); + return *this; + } + + bitset<_Nb>& + reset(size_t __pos) + { + _Base::reset(__pos); + return *this; + } + + bitset<_Nb> operator~() const { return bitset(~_M_base()); } + + bitset<_Nb>& + flip() + { + _Base::flip(); + return *this; + } + + bitset<_Nb>& + flip(size_t __pos) + { + _Base::flip(__pos); + return *this; + } + + // element access: + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 11. Bitset minor problems + reference + operator[](size_t __pos) + { + __glibcxx_check_subscript(__pos); + return reference(_M_base()[__pos], this); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 11. Bitset minor problems + bool + operator[](size_t __pos) const + { + __glibcxx_check_subscript(__pos); + return _M_base()[__pos]; + } + + using _Base::to_ulong; + + template <typename _CharT, typename _Traits, typename _Allocator> + std::basic_string<_CharT, _Traits, _Allocator> + to_string() const + { return _M_base().template to_string<_CharT, _Traits, _Allocator>(); } + + using _Base::count; + using _Base::size; + + bool + operator==(const bitset<_Nb>& __rhs) const + { return _M_base() == __rhs; } + + bool + operator!=(const bitset<_Nb>& __rhs) const + { return _M_base() != __rhs; } + + using _Base::test; + using _Base::any; + using _Base::none; + + bitset<_Nb> + operator<<(size_t __pos) const + { return bitset<_Nb>(_M_base() << __pos); } + + bitset<_Nb> + operator>>(size_t __pos) const + { return bitset<_Nb>(_M_base() >> __pos); } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + }; + + template<size_t _Nb> + bitset<_Nb> + operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { return bitset<_Nb>(__x) &= __y; } + + template<size_t _Nb> + bitset<_Nb> + operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { return bitset<_Nb>(__x) |= __y; } + + template<size_t _Nb> + bitset<_Nb> + operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) + { return bitset<_Nb>(__x) ^= __y; } + + template<typename _CharT, typename _Traits, size_t _Nb> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) + { return __is >> __x._M_base(); } + + template<typename _CharT, typename _Traits, size_t _Nb> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const bitset<_Nb>& __x) + { return __os << __x._M_base(); } +} // namespace __gnu_debug_def + +#endif diff --git a/contrib/libstdc++/include/debug/debug.h b/contrib/libstdc++/include/debug/debug.h new file mode 100644 index 000000000000..87bbcfa4db68 --- /dev/null +++ b/contrib/libstdc++/include/debug/debug.h @@ -0,0 +1,531 @@ +// Debugging support implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_DEBUG_H +#define _GLIBCXX_DEBUG_DEBUG_H 1 + +/** + * Macros used by the implementation to verify certain + * properties. These macros may only be used directly by the debug + * wrappers. Note that these are macros (instead of the more obviously + * "correct" choice of making them functions) because we need line and + * file information at the call site, to minimize the distance between + * the user error and where the error is reported. + * + */ +#define _GLIBCXX_DEBUG_VERIFY(_Condition,_ErrorMessage) \ + do { \ + if (! (_Condition)) \ + ::__gnu_debug::_Error_formatter::_M_at(__FILE__, __LINE__) \ + ._ErrorMessage._M_error(); \ + } while (false) + +// Verify that [_First, _Last) forms a valid iterator range. +#define __glibcxx_check_valid_range(_First,_Last) \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__valid_range(_First, _Last), \ + _M_message(::__gnu_debug::__msg_valid_range) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +/** Verify that we can insert into *this with the iterator _Position. + * Insertion into a container at a specific position requires that + * the iterator be nonsingular (i.e., either dereferenceable or + * past-the-end) and that it reference the sequence we are inserting + * into. Note that this macro is only valid when the container is a + * _Safe_sequence and the iterator is a _Safe_iterator. +*/ +#define __glibcxx_check_insert(_Position) \ +_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \ + _M_message(::__gnu_debug::__msg_insert_singular) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__msg_insert_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + +/** Verify that we can insert the values in the iterator range + * [_First, _Last) into *this with the iterator _Position. Insertion + * into a container at a specific position requires that the iterator + * be nonsingular (i.e., either dereferenceable or past-the-end), + * that it reference the sequence we are inserting into, and that the + * iterator range [_First, Last) is a valid (possibly empty) + * range. Note that this macro is only valid when the container is a + * _Safe_sequence and the iterator is a _Safe_iterator. + * + * @tbd We would like to be able to check for noninterference of + * _Position and the range [_First, _Last), but that can't (in + * general) be done. +*/ +#define __glibcxx_check_insert_range(_Position,_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \ + _M_message(::__gnu_debug::__msg_insert_singular) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__msg_insert_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + +/** Verify that we can erase the element referenced by the iterator + * _Position. We can erase the element if the _Position iterator is + * dereferenceable and references this sequence. +*/ +#define __glibcxx_check_erase(_Position) \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_dereferenceable(), \ + _M_message(::__gnu_debug::__msg_erase_bad) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__msg_erase_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + +/** Verify that we can erase the elements in the iterator range + * [_First, _Last). We can erase the elements if [_First, _Last) is a + * valid iterator range within this sequence. +*/ +#define __glibcxx_check_erase_range(_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this), \ + _M_message(::__gnu_debug::__msg_erase_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +// Verify that the subscript _N is less than the container's size. +#define __glibcxx_check_subscript(_N) \ +_GLIBCXX_DEBUG_VERIFY(_N < this->size(), \ + _M_message(::__gnu_debug::__msg_subscript_oob) \ + ._M_sequence(*this, "this") \ + ._M_integer(_N, #_N) \ + ._M_integer(this->size(), "size")) + +// Verify that the container is nonempty +#define __glibcxx_check_nonempty() \ +_GLIBCXX_DEBUG_VERIFY(! this->empty(), \ + _M_message(::__gnu_debug::__msg_empty) \ + ._M_sequence(*this, "this")) + +// Verify that the < operator for elements in the sequence is a +// StrictWeakOrdering by checking that it is irreflexive. +#define __glibcxx_check_strict_weak_ordering(_First,_Last) \ +_GLIBCXX_DEBUG_ASSERT(_First == _Last || !(*_First < *_First)) + +// Verify that the predicate is StrictWeakOrdering by checking that it +// is irreflexive. +#define __glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred) \ +_GLIBCXX_DEBUG_ASSERT(_First == _Last || !_Pred(*_First, *_First)) + + +// Verify that the iterator range [_First, _Last) is sorted +#define __glibcxx_check_sorted(_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +__glibcxx_check_strict_weak_ordering(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last), \ + _M_message(::__gnu_debug::__msg_unsorted) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +/** Verify that the iterator range [_First, _Last) is sorted by the + predicate _Pred. */ +#define __glibcxx_check_sorted_pred(_First,_Last,_Pred) \ +__glibcxx_check_valid_range(_First,_Last); \ +__glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last, _Pred), \ + _M_message(::__gnu_debug::__msg_unsorted_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred)) + +/** Verify that the iterator range [_First, _Last) is partitioned + w.r.t. the value _Value. */ +#define __glibcxx_check_partitioned(_First,_Last,_Value) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last, \ + _Value), \ + _M_message(::__gnu_debug::__msg_unpartitioned) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Value)) + +/** Verify that the iterator range [_First, _Last) is partitioned + w.r.t. the value _Value and predicate _Pred. */ +#define __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last, \ + _Value, _Pred), \ + _M_message(::__gnu_debug::__msg_unpartitioned_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred) \ + ._M_string(#_Value)) + +// Verify that the iterator range [_First, _Last) is a heap +#define __glibcxx_check_heap(_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last), \ + _M_message(::__gnu_debug::__msg_not_heap) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +/** Verify that the iterator range [_First, _Last) is a heap + w.r.t. the predicate _Pred. */ +#define __glibcxx_check_heap_pred(_First,_Last,_Pred) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last, _Pred), \ + _M_message(::__gnu_debug::__msg_not_heap_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred)) + +#ifdef _GLIBCXX_DEBUG_PEDANTIC +# define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0) +# define __glibcxx_check_string_len(_String,_Len) \ + _GLIBCXX_DEBUG_ASSERT(_String != 0 || _Len == 0) +#else +# define __glibcxx_check_string(_String) +# define __glibcxx_check_string_len(_String,_Len) +#endif + +/** Macros used by the implementation outside of debug wrappers to + * verify certain properties. The __glibcxx_requires_xxx macros are + * merely wrappers around the __glibcxx_check_xxx wrappers when we + * are compiling with debug mode, but disappear when we are in + * release mode so that there is no checking performed in, e.g., the + * standard library algorithms. +*/ +#ifdef _GLIBCXX_DEBUG +# define _GLIBCXX_DEBUG_ASSERT(_Condition) assert(_Condition) + +# ifdef _GLIBXX_DEBUG_PEDANTIC +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) assert(_Condition) +# else +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) +# endif + +# define __glibcxx_requires_cond(_Cond,_Msg) _GLIBCXX_DEBUG_VERIFY(_Cond,_Msg) +# define __glibcxx_requires_valid_range(_First,_Last) \ + __glibcxx_check_valid_range(_First,_Last) +# define __glibcxx_requires_sorted(_First,_Last) \ + __glibcxx_check_sorted(_First,_Last) +# define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) \ + __glibcxx_check_sorted_pred(_First,_Last,_Pred) +# define __glibcxx_requires_partitioned(_First,_Last,_Value) \ + __glibcxx_check_partitioned(_First,_Last,_Value) +# define __glibcxx_requires_partitioned_pred(_First,_Last,_Value,_Pred) \ + __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred) +# define __glibcxx_requires_heap(_First,_Last) \ + __glibcxx_check_heap(_First,_Last) +# define __glibcxx_requires_heap_pred(_First,_Last,_Pred) \ + __glibcxx_check_heap_pred(_First,_Last,_Pred) +# define __glibcxx_requires_nonempty() __glibcxx_check_nonempty() +# define __glibcxx_requires_string(_String) __glibcxx_check_string(_String) +# define __glibcxx_requires_string_len(_String,_Len) \ + __glibcxx_check_string_len(_String,_Len) +# define __glibcxx_requires_subscript(_N) __glibcxx_check_subscript(_N) +#else +# define _GLIBCXX_DEBUG_ASSERT(_Condition) +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) +# define __glibcxx_requires_cond(_Cond,_Msg) +# define __glibcxx_requires_valid_range(_First,_Last) +# define __glibcxx_requires_sorted(_First,_Last) +# define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) +# define __glibcxx_requires_partitioned(_First,_Last,_Value) +# define __glibcxx_requires_partitioned_pred(_First,_Last,_Value,_Pred) +# define __glibcxx_requires_heap(_First,_Last) +# define __glibcxx_requires_heap_pred(_First,_Last,_Pred) +# define __glibcxx_requires_nonempty() +# define __glibcxx_requires_string(_String) +# define __glibcxx_requires_string_len(_String,_Len) +# define __glibcxx_requires_subscript(_N) +#endif + +#include <cassert> // TBD: temporary + +#include <stddef.h> // for ptrdiff_t +#include <bits/stl_iterator_base_types.h> // for iterator_traits, categories +#include <bits/type_traits.h> // for _Is_integer + +namespace __gnu_debug +{ + template<typename _Iterator, typename _Sequence> + class _Safe_iterator; + + // An arbitrary iterator pointer is not singular. + inline bool + __check_singular_aux(const void*) { return false; } + + // We may have an iterator that derives from _Safe_iterator_base but isn't + // a _Safe_iterator. + template<typename _Iterator> + inline bool + __check_singular(_Iterator& __x) + { return __gnu_debug::__check_singular_aux(&__x); } + + /** Non-NULL pointers are nonsingular. */ + template<typename _Tp> + inline bool + __check_singular(const _Tp* __ptr) + { return __ptr == 0; } + + /** Safe iterators know if they are singular. */ + template<typename _Iterator, typename _Sequence> + inline bool + __check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x) + { return __x._M_singular(); } + + /** Assume that some arbitrary iterator is dereferenceable, because we + can't prove that it isn't. */ + template<typename _Iterator> + inline bool + __check_dereferenceable(_Iterator&) + { return true; } + + /** Non-NULL pointers are dereferenceable. */ + template<typename _Tp> + inline bool + __check_dereferenceable(const _Tp* __ptr) + { return __ptr; } + + /** Safe iterators know if they are singular. */ + template<typename _Iterator, typename _Sequence> + inline bool + __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x) + { return __x._M_dereferenceable(); } + + /** If the distance between two random access iterators is + * nonnegative, assume the range is valid. + */ + template<typename _RandomAccessIterator> + inline bool + __valid_range_aux2(const _RandomAccessIterator& __first, + const _RandomAccessIterator& __last, + std::random_access_iterator_tag) + { return __last - __first >= 0; } + + /** Can't test for a valid range with input iterators, because + * iteration may be destructive. So we just assume that the range + * is valid. + */ + template<typename _InputIterator> + inline bool + __valid_range_aux2(const _InputIterator&, const _InputIterator&, + std::input_iterator_tag) + { return true; } + + /** We say that integral types for a valid range, and defer to other + * routines to realize what to do with integral types instead of + * iterators. + */ + template<typename _Integral> + inline bool + __valid_range_aux(const _Integral&, const _Integral&, __true_type) + { return true; } + + /** We have iterators, so figure out what kind of iterators that are + * to see if we can check the range ahead of time. + */ + template<typename _InputIterator> + inline bool + __valid_range_aux(const _InputIterator& __first, + const _InputIterator& __last, __false_type) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __gnu_debug::__valid_range_aux2(__first, __last, _Category()); + } + + /** Don't know what these iterators are, or if they are even + * iterators (we may get an integral type for InputIterator), so + * see if they are integral and pass them on to the next phase + * otherwise. + */ + template<typename _InputIterator> + inline bool + __valid_range(const _InputIterator& __first, const _InputIterator& __last) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + return __gnu_debug::__valid_range_aux(__first, __last, _Integral()); + } + + /** Safe iterators know how to check if they form a valid range. */ + template<typename _Iterator, typename _Sequence> + inline bool + __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first, + const _Safe_iterator<_Iterator, _Sequence>& __last) + { return __first._M_valid_range(__last); } + + /* Checks that [first, last) is a valid range, and then returns + * __first. This routine is useful when we can't use a separate + * assertion statement because, e.g., we are in a constructor. + */ + template<typename _InputIterator> + inline _InputIterator + __check_valid_range(const _InputIterator& __first, + const _InputIterator& __last) + { + _GLIBCXX_DEBUG_ASSERT(__gnu_debug::__valid_range(__first, __last)); + return __first; + } + + /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ + template<typename _CharT, typename _Integer> + inline const _CharT* + __check_string(const _CharT* __s, const _Integer& __n) + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + _GLIBCXX_DEBUG_ASSERT(__s != 0 || __n == 0); +#endif + return __s; + } + + /** Checks that __s is non-NULL and then returns __s. */ + template<typename _CharT> + inline const _CharT* + __check_string(const _CharT* __s) + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + _GLIBCXX_DEBUG_ASSERT(__s != 0); +#endif + return __s; + } + + // Can't check if an input iterator sequence is sorted, because we + // can't step through the sequence. + template<typename _InputIterator> + inline bool + __check_sorted_aux(const _InputIterator&, const _InputIterator&, + std::input_iterator_tag) + { return true; } + + // Can verify if a forward iterator sequence is in fact sorted using + // std::__is_sorted + template<typename _ForwardIterator> + inline bool + __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (*__next < *__first) + return false; + } + + return true; + } + + // Can't check if an input iterator sequence is sorted, because we can't step + // through the sequence. + template<typename _InputIterator, typename _Predicate> + inline bool + __check_sorted_aux(const _InputIterator&, const _InputIterator&, + _Predicate, std::input_iterator_tag) + { return true; } + + // Can verify if a forward iterator sequence is in fact sorted using + // std::__is_sorted + template<typename _ForwardIterator, typename _Predicate> + inline bool + __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred, std::forward_iterator_tag) + { + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (__pred(*__next, *__first)) + return false; + } + + return true; + } + + // Determine if a sequence is sorted. + template<typename _InputIterator> + inline bool + __check_sorted(const _InputIterator& __first, const _InputIterator& __last) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __gnu_debug::__check_sorted_aux(__first, __last, _Category()); + } + + template<typename _InputIterator, typename _Predicate> + inline bool + __check_sorted(const _InputIterator& __first, const _InputIterator& __last, + _Predicate __pred) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __gnu_debug::__check_sorted_aux(__first, __last, __pred, + _Category()); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 270. Binary search requirements overly strict + // Determine if a sequence is partitioned w.r.t. this element. + template<typename _ForwardIterator, typename _Tp> + inline bool + __check_partitioned(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value) + { + while (__first != __last && *__first < __value) + ++__first; + while (__first != __last && !(*__first < __value)) + ++__first; + return __first == __last; + } + + // Determine if a sequence is partitioned w.r.t. this element. + template<typename _ForwardIterator, typename _Tp, typename _Pred> + inline bool + __check_partitioned(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value, _Pred __pred) + { + while (__first != __last && __pred(*__first, __value)) + ++__first; + while (__first != __last && !__pred(*__first, __value)) + ++__first; + return __first == __last; + } +} // namespace __gnu_debug + +#ifdef _GLIBCXX_DEBUG +// We need the error formatter +# include <debug/formatter.h> +#endif + +#endif diff --git a/contrib/libstdc++/include/debug/deque b/contrib/libstdc++/include/debug/deque new file mode 100644 index 000000000000..c39a49c04610 --- /dev/null +++ b/contrib/libstdc++/include/debug/deque @@ -0,0 +1,386 @@ +// Debugging deque implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_DEQUE +#define _GLIBCXX_DEBUG_DEQUE 1 + +#include <deque> +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_debug_def +{ + template<typename _Tp, typename _Allocator = std::allocator<_Tp> > + class deque + : public _GLIBCXX_STD::deque<_Tp, _Allocator>, + public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> > + { + typedef _GLIBCXX_STD::deque<_Tp, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<deque> _Safe_base; + + public: + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,deque> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,deque> + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + // 23.2.1.1 construct/copy/destroy: + explicit deque(const _Allocator& __a = _Allocator()) + : _Base(__a) { } + + explicit deque(size_type __n, const _Tp& __value = _Tp(), + const _Allocator& __a = _Allocator()) + : _Base(__n, __value, __a) { } + + template<class _InputIterator> + deque(_InputIterator __first, _InputIterator __last, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a) + { } + + deque(const deque<_Tp,_Allocator>& __x) : _Base(__x), _Safe_base() { } + + deque(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~deque() { } + + deque<_Tp,_Allocator>& + operator=(const deque<_Tp,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + template<class _InputIterator> + void + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + } + + void + assign(size_type __n, const _Tp& __t) + { + _Base::assign(__n, __t); + this->_M_invalidate_all(); + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + 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()); } + + // 23.2.1.2 capacity: + using _Base::size; + using _Base::max_size; + + void + resize(size_type __sz, _Tp __c = _Tp()) + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; + + bool __invalidate_all = __sz > this->size(); + if (__sz < this->size()) + this->_M_invalidate_if(_After_nth(__sz, _M_base().begin())); + + _Base::resize(__sz, __c); + + if (__invalidate_all) + this->_M_invalidate_all(); + } + + using _Base::empty; + + // element access: + reference + operator[](size_type __n) + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + const_reference + operator[](size_type __n) const + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + using _Base::at; + + reference + front() + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + const_reference + front() const + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + reference + back() + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + const_reference + back() const + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + // 23.2.1.3 modifiers: + void + push_front(const _Tp& __x) + { + _Base::push_front(__x); + this->_M_invalidate_all(); + } + + void + push_back(const _Tp& __x) + { + _Base::push_back(__x); + this->_M_invalidate_all(); + } + + iterator + insert(iterator __position, const _Tp& __x) + { + __glibcxx_check_insert(__position); + typename _Base::iterator __res = _Base::insert(__position.base(), __x); + this->_M_invalidate_all(); + return iterator(__res, this); + } + + void + insert(iterator __position, size_type __n, const _Tp& __x) + { + __glibcxx_check_insert(__position); + _Base::insert(__position.base(), __n, __x); + this->_M_invalidate_all(); + } + + template<class _InputIterator> + void + insert(iterator __position, + _InputIterator __first, _InputIterator __last) + { + __glibcxx_check_insert_range(__position, __first, __last); + _Base::insert(__position.base(), __first, __last); + this->_M_invalidate_all(); + } + + void + pop_front() + { + __glibcxx_check_nonempty(); + iterator __victim = begin(); + __victim._M_invalidate(); + _Base::pop_front(); + } + + void + pop_back() + { + __glibcxx_check_nonempty(); + iterator __victim = end(); + --__victim; + __victim._M_invalidate(); + _Base::pop_back(); + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + if (__position == begin() || __position == end()-1) + { + __position._M_invalidate(); + return iterator(_Base::erase(__position.base()), this); + } + else + { + typename _Base::iterator __res = _Base::erase(__position.base()); + this->_M_invalidate_all(); + return iterator(__res, this); + } + } + + iterator + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + if (__first == begin() || __last == end()) + { + this->_M_detach_singular(); + for (iterator __position = __first; __position != __last; ) + { + iterator __victim = __position++; + __victim._M_invalidate(); + } + try + { + return iterator(_Base::erase(__first.base(), __last.base()), + this); + } + catch (...) + { + this->_M_revalidate_singular(); + __throw_exception_again; + } + } + else + { + typename _Base::iterator __res = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_all(); + return iterator(__res, this); + } + } + + void + swap(deque<_Tp,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + }; + + template<typename _Tp, typename _Alloc> + inline bool + operator==(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator!=(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator<(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator<=(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator>=(const deque<_Tp, _Alloc>& __lhs, + const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator>(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline void + swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/contrib/libstdc++/include/debug/formatter.h b/contrib/libstdc++/include/debug/formatter.h new file mode 100644 index 000000000000..db555b0030db --- /dev/null +++ b/contrib/libstdc++/include/debug/formatter.h @@ -0,0 +1,391 @@ +// Debug-mode error formatting implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_FORMATTER_H +#define _GLIBCXX_DEBUG_FORMATTER_H 1 + +#include <typeinfo> +#include <debug/debug.h> + +namespace __gnu_debug +{ + using std::type_info; + + /** Determine if the two types are the same. */ + template<typename _Type1, typename _Type2> + struct __is_same + { + static const bool value = false; + }; + + template<typename _Type> + struct __is_same<_Type, _Type> + { + static const bool value = true; + }; + + template<bool> struct __truth { }; + + class _Safe_sequence_base; + + template<typename _Iterator, typename _Sequence> + class _Safe_iterator; + + template<typename _Sequence> + class _Safe_sequence; + + enum _Debug_msg_id + { + // General checks + __msg_valid_range, + __msg_insert_singular, + __msg_insert_different, + __msg_erase_bad, + __msg_erase_different, + __msg_subscript_oob, + __msg_empty, + __msg_unpartitioned, + __msg_unpartitioned_pred, + __msg_unsorted, + __msg_unsorted_pred, + __msg_not_heap, + __msg_not_heap_pred, + // std::bitset checks + __msg_bad_bitset_write, + __msg_bad_bitset_read, + __msg_bad_bitset_flip, + // std::list checks + __msg_self_splice, + __msg_splice_alloc, + __msg_splice_bad, + __msg_splice_other, + __msg_splice_overlap, + // iterator checks + __msg_init_singular, + __msg_init_copy_singular, + __msg_init_const_singular, + __msg_copy_singular, + __msg_bad_deref, + __msg_bad_inc, + __msg_bad_dec, + __msg_iter_subscript_oob, + __msg_advance_oob, + __msg_retreat_oob, + __msg_iter_compare_bad, + __msg_compare_different, + __msg_iter_order_bad, + __msg_order_different, + __msg_distance_bad, + __msg_distance_different, + // istream_iterator + __msg_deref_istream, + __msg_inc_istream, + // ostream_iterator + __msg_output_ostream, + // istreambuf_iterator + __msg_deref_istreambuf, + __msg_inc_istreambuf + }; + + class _Error_formatter + { + /// Whether an iterator is constant, mutable, or unknown + enum _Constness + { + __unknown_constness, + __const_iterator, + __mutable_iterator, + __last_constness + }; + + // The state of the iterator (fine-grained), if we know it. + enum _Iterator_state + { + __unknown_state, + __singular, // singular, may still be attached to a sequence + __begin, // dereferenceable, and at the beginning + __middle, // dereferenceable, not at the beginning + __end, // past-the-end, may be at beginning if sequence empty + __last_state + }; + + // Tags denoting the type of parameter for construction + struct _Is_iterator { }; + struct _Is_sequence { }; + + // A parameter that may be referenced by an error message + struct _Parameter + { + enum + { + __unused_param, + __iterator, + __sequence, + __integer, + __string + } _M_kind; + + union + { + // When _M_kind == __iterator + struct + { + const char* _M_name; + const void* _M_address; + const type_info* _M_type; + _Constness _M_constness; + _Iterator_state _M_state; + const void* _M_sequence; + const type_info* _M_seq_type; + } _M_iterator; + + // When _M_kind == __sequence + struct + { + const char* _M_name; + const void* _M_address; + const type_info* _M_type; + } _M_sequence; + + // When _M_kind == __integer + struct + { + const char* _M_name; + long _M_value; + } _M_integer; + + // When _M_kind == __string + struct + { + const char* _M_name; + const char* _M_value; + } _M_string; + } _M_variant; + + _Parameter() : _M_kind(__unused_param), _M_variant() { } + + _Parameter(long __value, const char* __name) + : _M_kind(__integer), _M_variant() + { + _M_variant._M_integer._M_name = __name; + _M_variant._M_integer._M_value = __value; + } + + _Parameter(const char* __value, const char* __name) + : _M_kind(__string), _M_variant() + { + _M_variant._M_string._M_name = __name; + _M_variant._M_string._M_value = __value; + } + + template<typename _Iterator, typename _Sequence> + _Parameter(const _Safe_iterator<_Iterator, _Sequence>& __it, + const char* __name, _Is_iterator) + : _M_kind(__iterator), _M_variant() + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = + __is_same<_Safe_iterator<_Iterator, _Sequence>, + typename _Sequence::iterator>:: + value? __mutable_iterator : __const_iterator; + _M_variant._M_iterator._M_sequence = __it._M_get_sequence(); + _M_variant._M_iterator._M_seq_type = &typeid(_Sequence); + + if (__it._M_singular()) + _M_variant._M_iterator._M_state = __singular; + else + { + bool __is_begin = __it._M_is_begin(); + bool __is_end = __it._M_is_end(); + if (__is_end) + _M_variant._M_iterator._M_state = __end; + else if (__is_begin) + _M_variant._M_iterator._M_state = __begin; + else + _M_variant._M_iterator._M_state = __middle; + } + } + + template<typename _Type> + _Parameter(const _Type*& __it, const char* __name, _Is_iterator) + : _M_kind(__iterator), _M_variant() + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = __mutable_iterator; + _M_variant._M_iterator._M_state = __it? __unknown_state : __singular; + _M_variant._M_iterator._M_sequence = 0; + _M_variant._M_iterator._M_seq_type = 0; + } + + template<typename _Type> + _Parameter(_Type*& __it, const char* __name, _Is_iterator) + : _M_kind(__iterator), _M_variant() + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = __const_iterator; + _M_variant._M_iterator._M_state = __it? __unknown_state : __singular; + _M_variant._M_iterator._M_sequence = 0; + _M_variant._M_iterator._M_seq_type = 0; + } + + template<typename _Iterator> + _Parameter(const _Iterator& __it, const char* __name, _Is_iterator) + : _M_kind(__iterator), _M_variant() + { + _M_variant._M_iterator._M_name = __name; + _M_variant._M_iterator._M_address = &__it; + _M_variant._M_iterator._M_type = &typeid(__it); + _M_variant._M_iterator._M_constness = __unknown_constness; + _M_variant._M_iterator._M_state = + __gnu_debug::__check_singular(__it)? __singular : __unknown_state; + _M_variant._M_iterator._M_sequence = 0; + _M_variant._M_iterator._M_seq_type = 0; + } + + template<typename _Sequence> + _Parameter(const _Safe_sequence<_Sequence>& __seq, + const char* __name, _Is_sequence) + : _M_kind(__sequence), _M_variant() + { + _M_variant._M_sequence._M_name = __name; + _M_variant._M_sequence._M_address = + static_cast<const _Sequence*>(&__seq); + _M_variant._M_sequence._M_type = &typeid(_Sequence); + } + + template<typename _Sequence> + _Parameter(const _Sequence& __seq, const char* __name, _Is_sequence) + : _M_kind(__sequence), _M_variant() + { + _M_variant._M_sequence._M_name = __name; + _M_variant._M_sequence._M_address = &__seq; + _M_variant._M_sequence._M_type = &typeid(_Sequence); + } + + void + _M_print_field(const _Error_formatter* __formatter, + const char* __name) const; + + void + _M_print_description(const _Error_formatter* __formatter) const; + }; + + friend struct _Parameter; + + public: + template<typename _Iterator> + const _Error_formatter& + _M_iterator(const _Iterator& __it, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__it, __name, + _Is_iterator()); + return *this; + } + + const _Error_formatter& + _M_integer(long __value, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__value, __name); + return *this; + } + + const _Error_formatter& + _M_string(const char* __value, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__value, __name); + return *this; + } + + template<typename _Sequence> + const _Error_formatter& + _M_sequence(const _Sequence& __seq, const char* __name = 0) const + { + if (_M_num_parameters < __max_parameters) + _M_parameters[_M_num_parameters++] = _Parameter(__seq, __name, + _Is_sequence()); + return *this; + } + + const _Error_formatter& + _M_message(const char* __text) const + { _M_text = __text; return *this; } + + const _Error_formatter& + _M_message(_Debug_msg_id __id) const; + + void + _M_error() const; + + private: + _Error_formatter(const char* __file, size_t __line) + : _M_file(__file), _M_line(__line), _M_num_parameters(0), _M_text(0), + _M_max_length(78), _M_column(1), _M_first_line(true), _M_wordwrap(false) + { } + + template<typename _Tp> + void + _M_format_word(char*, int, const char*, _Tp) const; + + void + _M_print_word(const char* __word) const; + + void + _M_print_string(const char* __string) const; + + enum { __max_parameters = 9 }; + + const char* _M_file; + size_t _M_line; + mutable _Parameter _M_parameters[__max_parameters]; + mutable size_t _M_num_parameters; + mutable const char* _M_text; + mutable size_t _M_max_length; + enum { _M_indent = 4 } ; + mutable size_t _M_column; + mutable bool _M_first_line; + mutable bool _M_wordwrap; + + public: + static _Error_formatter + _M_at(const char* __file, size_t __line) + { return _Error_formatter(__file, __line); } + }; +} // namespace __gnu_debug + +#endif diff --git a/contrib/libstdc++/include/debug/hash_map b/contrib/libstdc++/include/debug/hash_map new file mode 100644 index 000000000000..570a9af6b692 --- /dev/null +++ b/contrib/libstdc++/include/debug/hash_map @@ -0,0 +1,38 @@ +// Debugging hash_map/hash_multimap implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_HASH_MAP +#define _GLIBCXX_DEBUG_HASH_MAP 1 + +#include <hash_map> +#include <debug/dbg_hash_map.h> +#include <debug/dbg_hash_multimap.h> + +#endif diff --git a/contrib/libstdc++/include/debug/hash_map.h b/contrib/libstdc++/include/debug/hash_map.h new file mode 100644 index 000000000000..c2cd7b8ca693 --- /dev/null +++ b/contrib/libstdc++/include/debug/hash_map.h @@ -0,0 +1,270 @@ +// Debugging hash_map implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_HASH_MAP_H +#define _GLIBCXX_DEBUG_HASH_MAP_H 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_debug_def +{ + template<typename _Value, typename _Tp, + typename _HashFcn = __gnu_cxx::hash<_Value>, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_map + : public __gnu_cxx::hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>, + public __gnu_debug::_Safe_sequence<hash_map<_Value, _Tp, _HashFcn, + _EqualKey, _Alloc> > + { + typedef __gnu_cxx::hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc> + _Base; + typedef __gnu_debug::_Safe_sequence<hash_map> _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::data_type data_type; + typedef typename _Base::mapped_type mapped_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, hash_map> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + hash_map> + const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_map() { } + + explicit hash_map(size_type __n) : _Base(__n) { } + + hash_map(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) { } + + template<typename _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { } + + template<typename _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { } + + template<typename _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { } + + template<typename _InputIterator> + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) { } + + hash_map(const _Base& __x) : _Base(__x), _Safe_base() { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_map& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator + begin() { return iterator(_Base::begin(), this); } + + iterator + end() { return iterator(_Base::end(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + std::pair<iterator, bool> + insert(const value_type& __obj) + { + std::pair<typename _Base::iterator, bool> __res = _Base::insert(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + template <typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + + std::pair<iterator, bool> + insert_noresize(const value_type& __obj) + { + std::pair<typename _Base::iterator, bool> __res = + _Base::insert_noresize(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + iterator + find(const key_type& __key) + { return iterator(_Base::find(__key), this); } + + const_iterator + find(const key_type& __key) const + { return const_iterator(_Base::find(__key), this); } + + using _Base::operator[]; + using _Base::count; + + std::pair<iterator, iterator> + equal_range(const key_type& __key) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair<const_iterator, const_iterator> + equal_range(const key_type& __key) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + size_type + erase(const key_type& __key) + { + iterator __victim(_Base::find(__key), this); + if (__victim != end()) + return this->erase(__victim), 1; + else + return 0; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template<typename _Value, typename _Tp, typename _HashFcn, + typename _EqualKey, typename _Alloc> + inline bool + operator==(const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + + template<typename _Value, typename _Tp, typename _HashFcn, + typename _EqualKey, typename _Alloc> + inline bool + operator!=(const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + + template<typename _Value, typename _Tp, typename _HashFcn, + typename _EqualKey, typename _Alloc> + inline void + swap(hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/contrib/libstdc++/include/debug/hash_multimap.h b/contrib/libstdc++/include/debug/hash_multimap.h new file mode 100644 index 000000000000..83b4425aaf0c --- /dev/null +++ b/contrib/libstdc++/include/debug/hash_multimap.h @@ -0,0 +1,261 @@ +// Debugging hash_multimap implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_HASH_MULTIMAP_H +#define _GLIBCXX_DEBUG_HASH_MULTIMAP_H 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_debug_def +{ + template<typename _Value, typename _Tp, + typename _HashFcn = __gnu_cxx::hash<_Value>, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_multimap + : public __gnu_cxx::hash_multimap<_Value,_Tp,_HashFcn, _EqualKey,_Alloc>, + public __gnu_debug::_Safe_sequence<hash_multimap<_Value, _Tp, _HashFcn, + _EqualKey, _Alloc> > + { + typedef __gnu_cxx::hash_multimap<_Value,_Tp,_HashFcn, _EqualKey,_Alloc> + _Base; + typedef __gnu_debug::_Safe_sequence<hash_multimap> _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::data_type data_type; + typedef typename _Base::mapped_type mapped_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, + hash_multimap> iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + hash_multimap> const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_multimap() { } + + explicit hash_multimap(size_type __n) : _Base(__n) { } + + hash_multimap(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) { } + + template<typename _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { } + + template<typename _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { } + + template<typename _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { } + + template<typename _InputIterator> + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_multimap& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator + begin() { return iterator(_Base::begin(), this); } + + iterator + end() { return iterator(_Base::end(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + iterator + insert(const value_type& __obj) + { return iterator(_Base::insert(__obj), this); } + + template <typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + iterator + insert_noresize(const value_type& __obj) + { return iterator(_Base::insert_noresize(__obj), this); } + + iterator + find(const key_type& __key) + { return iterator(_Base::find(__key), this); } + + const_iterator + find(const key_type& __key) const + { return const_iterator(_Base::find(__key), this); } + + using _Base::count; + + std::pair<iterator, iterator> + equal_range(const key_type& __key) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair<const_iterator, const_iterator> + equal_range(const key_type& __key) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + size_type + erase(const key_type& __key) + { + std::pair<iterator, iterator> __victims = this->equal_range(__key); + size_t __num_victims = 0; + while (__victims.first != __victims.second) + { + this->erase(__victims.first++); + ++__num_victims; + } + return __num_victims; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template<typename _Value, typename _Tp, typename _HashFcn, + typename _EqualKey, typename _Alloc> + inline bool + operator==(const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __x, + const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + + template<typename _Value, typename _Tp, typename _HashFcn, + typename _EqualKey, typename _Alloc> + inline bool + operator!=(const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __x, + const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + + template<typename _Value, typename _Tp, typename _HashFcn, + typename _EqualKey, typename _Alloc> + inline void + swap(hash_multimap<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x, + hash_multimap<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/contrib/libstdc++/include/debug/hash_multiset.h b/contrib/libstdc++/include/debug/hash_multiset.h new file mode 100644 index 000000000000..705d8da25329 --- /dev/null +++ b/contrib/libstdc++/include/debug/hash_multiset.h @@ -0,0 +1,236 @@ +// Debugging hash_multiset implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_HASH_MULTISET_H +#define _GLIBCXX_DEBUG_HASH_MULTISET_H 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_debug_def +{ + template<typename _Value, + typename _HashFcn = __gnu_cxx::hash<_Value>, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_multiset + : public __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>, + public __gnu_debug::_Safe_sequence<hash_multiset<_Value, _HashFcn, + _EqualKey, _Alloc> > + { + typedef __gnu_cxx:: hash_multiset<_Value,_HashFcn, _EqualKey,_Alloc> + _Base; + typedef __gnu_debug::_Safe_sequence<hash_multiset> _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, + hash_multiset> iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + hash_multiset> const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_multiset() { } + + explicit hash_multiset(size_type __n) : _Base(__n) { } + + hash_multiset(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) + { } + + template<typename _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) + { } + + template<typename _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) + { } + + template<typename _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) + { } + + template<typename _InputIterator> + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) + { } + + hash_multiset(const _Base& __x) : _Base(__x), _Safe_base() { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_multiset& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator begin() const { return iterator(_Base::begin(), this); } + iterator end() const { return iterator(_Base::end(), this); } + + iterator + insert(const value_type& __obj) + { return iterator(_Base::insert(__obj), this); } + + template <typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + + iterator + insert_noresize(const value_type& __obj) + { return iterator(_Base::insert_noresize(__obj), this); } + + iterator + find(const key_type& __key) const + { return iterator(_Base::find(__key), this); } + + using _Base::count; + + std::pair<iterator, iterator> + equal_range(const key_type& __key) const + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + size_type + erase(const key_type& __key) + { + size_type __count = 0; + std::pair<iterator, iterator> __victims = this->equal_range(__key); + while (__victims.first != __victims.second) + { + this->erase(__victims++); + ++__count; + } + return __count; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& _M_base() { return *this; } + const _Base& _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + +template<typename _Value, typename _HashFcn, typename _EqualKey, typename _Alloc> + inline bool + operator==(const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + +template<typename _Value, typename _HashFcn, typename _EqualKey, typename _Alloc> + inline bool + operator!=(const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + +template<typename _Value, typename _HashFcn, typename _EqualKey, typename _Alloc> + inline void + swap(hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/contrib/libstdc++/include/debug/hash_set b/contrib/libstdc++/include/debug/hash_set new file mode 100644 index 000000000000..282cba27613a --- /dev/null +++ b/contrib/libstdc++/include/debug/hash_set @@ -0,0 +1,38 @@ +// Debugging hash_set/hash_multiset implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_HASH_SET +#define _GLIBCXX_DEBUG_HASH_SET 1 + +#include <hash_set> +#include <debug/dbg_hash_set.h> +#include <debug/dbg_hash_multiset.h> + +#endif diff --git a/contrib/libstdc++/include/debug/hash_set.h b/contrib/libstdc++/include/debug/hash_set.h new file mode 100644 index 000000000000..0f56d882935c --- /dev/null +++ b/contrib/libstdc++/include/debug/hash_set.h @@ -0,0 +1,245 @@ +// Debugging hash_set implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_HASH_SET_H +#define _GLIBCXX_DEBUG_HASH_SET_H 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_debug_def +{ + template<typename _Value, + typename _HashFcn = __gnu_cxx::hash<_Value>, + typename _EqualKey = std::equal_to<_Value>, + typename _Alloc = std::allocator<_Value> > + class hash_set + : public __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc>, + public __gnu_debug::_Safe_sequence<hash_set<_Value, _HashFcn, _EqualKey, + _Alloc> > + { + typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> _Base; + typedef __gnu_debug::_Safe_sequence<hash_set> _Safe_base; + + public: + typedef typename _Base::key_type key_type; + typedef typename _Base::value_type value_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, hash_set> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + hash_set> + const_iterator; + + typedef typename _Base::allocator_type allocator_type; + + using _Base::hash_funct; + using _Base::key_eq; + using _Base::get_allocator; + + hash_set() { } + + explicit hash_set(size_type __n) : _Base(__n) { } + + hash_set(size_type __n, const hasher& __hf) : _Base(__n, __hf) { } + + hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__n, __hf, __eql, __a) { } + + template<typename _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { } + + template<typename _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l, size_type __n) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { } + + template<typename _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { } + + template<typename _InputIterator> + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf, + __eql, __a) { } + + hash_set(const _Base& __x) : _Base(__x), _Safe_base() { } + + using _Base::size; + using _Base::max_size; + using _Base::empty; + + void + swap(hash_set& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + iterator + begin() const { return iterator(_Base::begin(), this); } + + iterator + end() const { return iterator(_Base::end(), this); } + + std::pair<iterator, bool> + insert(const value_type& __obj) + { + std::pair<typename _Base::iterator, bool> __res = + _Base::insert(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + template <typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first.base(), __last.base()); + } + + + std::pair<iterator, bool> + insert_noresize(const value_type& __obj) + { + std::pair<typename _Base::iterator, bool> __res = + _Base::insert_noresize(__obj); + return std::make_pair(iterator(__res.first, this), __res.second); + } + + iterator + find(const key_type& __key) const + { return iterator(_Base::find(__key), this); } + + using _Base::count; + + std::pair<iterator, iterator> + equal_range(const key_type& __key) const + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__key); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + size_type + erase(const key_type& __key) + { + iterator __victim(_Base::find(__key), this); + if (__victim != end()) + return this->erase(__victim), 1; + else + return 0; + } + + void + erase(iterator __it) + { + __glibcxx_check_erase(__it); + __it._M_invalidate(); + _Base::erase(__it.base()); + } + + void + erase(iterator __first, iterator __last) + { + __glibcxx_check_erase_range(__first, __last); + for (iterator __tmp = __first; __tmp != __last;) + { + iterator __victim = __tmp++; + __victim._M_invalidate(); + } + _Base::erase(__first.base(), __last.base()); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::resize; + using _Base::bucket_count; + using _Base::max_bucket_count; + using _Base::elems_in_bucket; + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template<typename _Value, typename _HashFcn, typename _EqualKey, + typename _Alloc> + inline bool + operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() == __y._M_base(); } + + template<typename _Value, typename _HashFcn, typename _EqualKey, + typename _Alloc> + inline bool + operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { return __x._M_base() != __y._M_base(); } + + template<typename _Value, typename _HashFcn, typename _EqualKey, + typename _Alloc> + inline void + swap(hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x, + hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y) + { __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/contrib/libstdc++/include/debug/list b/contrib/libstdc++/include/debug/list new file mode 100644 index 000000000000..556c9d9acff7 --- /dev/null +++ b/contrib/libstdc++/include/debug/list @@ -0,0 +1,505 @@ +// Debugging list implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_LIST +#define _GLIBCXX_DEBUG_LIST 1 + +#include <list> +#include <bits/stl_algo.h> +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_debug_def +{ + template<typename _Tp, typename _Allocator = std::allocator<_Tp> > + class list + : public _GLIBCXX_STD::list<_Tp, _Allocator>, + public __gnu_debug::_Safe_sequence<list<_Tp, _Allocator> > + { + typedef _GLIBCXX_STD::list<_Tp, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<list> _Safe_base; + + public: + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, list> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, list> + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + // 23.2.2.1 construct/copy/destroy: + explicit list(const _Allocator& __a = _Allocator()) + : _Base(__a) { } + + explicit list(size_type __n, const _Tp& __value = _Tp(), + const _Allocator& __a = _Allocator()) + : _Base(__n, __value, __a) { } + + template<class _InputIterator> + list(_InputIterator __first, _InputIterator __last, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a) + { } + + + list(const list& __x) : _Base(__x), _Safe_base() { } + + list(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~list() { } + + list& + operator=(const list& __x) + { + static_cast<_Base&>(*this) = __x; + this->_M_invalidate_all(); + return *this; + } + + template<class _InputIterator> + void + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + } + + void + assign(size_type __n, const _Tp& __t) + { + _Base::assign(__n, __t); + this->_M_invalidate_all(); + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + 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()); } + + // 23.2.2.2 capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + void + resize(size_type __sz, _Tp __c = _Tp()) + { + this->_M_detach_singular(); + + // if __sz < size(), invalidate all iterators in [begin+__sz, end()) + iterator __victim = begin(); + iterator __end = end(); + for (size_type __i = __sz; __victim != __end && __i > 0; --__i) + ++__victim; + + while (__victim != __end) + { + iterator __real_victim = __victim++; + __real_victim._M_invalidate(); + } + + try + { + _Base::resize(__sz, __c); + } + catch(...) + { + this->_M_revalidate_singular(); + __throw_exception_again; + } + } + + // element access: + reference + front() + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + const_reference + front() const + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + reference + back() + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + const_reference + back() const + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + // 23.2.2.3 modifiers: + using _Base::push_front; + + void + pop_front() + { + __glibcxx_check_nonempty(); + iterator __victim = begin(); + __victim._M_invalidate(); + _Base::pop_front(); + } + + using _Base::push_back; + + void + pop_back() + { + __glibcxx_check_nonempty(); + iterator __victim = end(); + --__victim; + __victim._M_invalidate(); + _Base::pop_back(); + } + + iterator + insert(iterator __position, const _Tp& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + void + insert(iterator __position, size_type __n, const _Tp& __x) + { + __glibcxx_check_insert(__position); + _Base::insert(__position.base(), __n, __x); + } + + template<class _InputIterator> + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + __glibcxx_check_insert_range(__position, __first, __last); + _Base::insert(__position.base(), __first, __last); + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + return iterator(_Base::erase(__position.base()), this); + } + + iterator + erase(iterator __position, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__position, __last); + for (iterator __victim = __position; __victim != __last; ) + { + iterator __old = __victim; + ++__victim; + __old._M_invalidate(); + } + return iterator(_Base::erase(__position.base(), __last.base()), this); + } + + void + swap(list& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + // 23.2.2.4 list operations: + void + splice(iterator __position, list& __x) + { + _GLIBCXX_DEBUG_VERIFY(&__x != this, + _M_message(::__gnu_debug::__msg_self_splice) + ._M_sequence(*this, "this")); + this->splice(__position, __x, __x.begin(), __x.end()); + } + + void + splice(iterator __position, list& __x, iterator __i) + { + __glibcxx_check_insert(__position); + _GLIBCXX_DEBUG_VERIFY(__x.get_allocator() == this->get_allocator(), + _M_message(::__gnu_debug::__msg_splice_alloc) + ._M_sequence(*this)._M_sequence(__x, "__x")); + _GLIBCXX_DEBUG_VERIFY(__i._M_dereferenceable(), + _M_message(::__gnu_debug::__msg_splice_bad) + ._M_iterator(__i, "__i")); + _GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__x), + _M_message(::__gnu_debug::__msg_splice_other) + ._M_iterator(__i, "__i")._M_sequence(__x, "__x")); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 250. splicing invalidates iterators + this->_M_transfer_iter(__i); + _Base::splice(__position.base(), __x._M_base(), __i.base()); + } + + void + splice(iterator __position, list& __x, iterator __first, iterator __last) + { + __glibcxx_check_insert(__position); + __glibcxx_check_valid_range(__first, __last); + _GLIBCXX_DEBUG_VERIFY(__first._M_attached_to(&__x), + _M_message(::__gnu_debug::__msg_splice_other) + ._M_sequence(__x, "x") + ._M_iterator(__first, "first")); + _GLIBCXX_DEBUG_VERIFY(__x.get_allocator() == this->get_allocator(), + _M_message(::__gnu_debug::__msg_splice_alloc) + ._M_sequence(*this)._M_sequence(__x)); + + for (iterator __tmp = __first; __tmp != __last; ) + { + _GLIBCXX_DEBUG_VERIFY(&__x != this || __tmp != __position, + _M_message(::__gnu_debug::__msg_splice_overlap) + ._M_iterator(__tmp, "position") + ._M_iterator(__first, "first") + ._M_iterator(__last, "last")); + iterator __victim = __tmp++; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 250. splicing invalidates iterators + this->_M_transfer_iter(__victim); + } + + _Base::splice(__position.base(), __x._M_base(), __first.base(), + __last.base()); + } + + void + remove(const _Tp& __value) + { + for (iterator __x = begin(); __x.base() != _Base::end(); ) + { + if (*__x == __value) + __x = erase(__x); + else + ++__x; + } + } + + template<class _Predicate> + void + remove_if(_Predicate __pred) + { + for (iterator __x = begin(); __x.base() != _Base::end(); ) + { + if (__pred(*__x)) + __x = erase(__x); + else + ++__x; + } + } + + void + unique() + { + iterator __first = begin(); + iterator __last = end(); + if (__first == __last) + return; + iterator __next = __first; + while (++__next != __last) + { + if (*__first == *__next) + erase(__next); + else + __first = __next; + __next = __first; + } + } + + template<class _BinaryPredicate> + void + 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; + } + } + + void + merge(list& __x) + { + __glibcxx_check_sorted(_Base::begin(), _Base::end()); + __glibcxx_check_sorted(__x.begin().base(), __x.end().base()); + for (iterator __tmp = __x.begin(); __tmp != __x.end(); ) + { + iterator __victim = __tmp++; + __victim._M_attach(&__x); + } + _Base::merge(__x._M_base()); + } + + template<class _Compare> + void + merge(list& __x, _Compare __comp) + { + __glibcxx_check_sorted_pred(_Base::begin(), _Base::end(), __comp); + __glibcxx_check_sorted_pred(__x.begin().base(), __x.end().base(), + __comp); + for (iterator __tmp = __x.begin(); __tmp != __x.end(); ) + { + iterator __victim = __tmp++; + __victim._M_attach(&__x); + } + _Base::merge(__x._M_base(), __comp); + } + + void + sort() { _Base::sort(); } + + template<typename _StrictWeakOrdering> + void + sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); } + + using _Base::reverse; + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template<typename _Tp, typename _Alloc> + inline bool + operator==(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator!=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator<(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator<=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator>=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator>(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline void + swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/contrib/libstdc++/include/debug/map b/contrib/libstdc++/include/debug/map new file mode 100644 index 000000000000..2c384048718a --- /dev/null +++ b/contrib/libstdc++/include/debug/map @@ -0,0 +1,38 @@ +// Debugging map/multimap implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_MAP +#define _GLIBCXX_DEBUG_MAP 1 + +#include <map> +#include <debug/map.h> +#include <debug/multimap.h> + +#endif diff --git a/contrib/libstdc++/include/debug/map.h b/contrib/libstdc++/include/debug/map.h new file mode 100644 index 000000000000..2a6794b31e0e --- /dev/null +++ b/contrib/libstdc++/include/debug/map.h @@ -0,0 +1,323 @@ +// Debugging map implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_MAP_H +#define _GLIBCXX_DEBUG_MAP_H 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> +#include <utility> + +namespace __gnu_debug_def +{ + template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>, + typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > > + class map + : public _GLIBCXX_STD::map<_Key, _Tp, _Compare, _Allocator>, + public __gnu_debug::_Safe_sequence<map<_Key, _Tp, _Compare, _Allocator> > + { + typedef _GLIBCXX_STD::map<_Key, _Tp, _Compare, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<map> _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair<const _Key, _Tp> value_type; + typedef _Compare key_compare; + typedef _Allocator allocator_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, map> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, map> + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + using _Base::value_compare; + + // 23.3.1.1 construct/copy/destroy: + explicit map(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) { } + + template<typename _InputIterator> + map(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a), _Safe_base() { } + + map(const map<_Key,_Tp,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() { } + + map(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~map() { } + + map<_Key,_Tp,_Compare,_Allocator>& + operator=(const map<_Key,_Tp,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 133. map missing get_allocator() + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + 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()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // 23.3.1.2 element access: + using _Base::operator[]; + + // modifiers: + std::pair<iterator, bool> + insert(const value_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, bool> __res = _Base::insert(__x); + return std::pair<iterator, bool>(iterator(__res.first, this), + __res.second); + } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template<typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + iterator __victim = find(__x); + if (__victim == end()) + return 0; + else + { + __victim._M_invalidate(); + _Base::erase(__victim.base()); + return 1; + } + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + while (__first != __last) + this->erase(__first++); + } + + void + swap(map<_Key,_Tp,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // 23.3.1.3 map operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair<iterator,iterator> + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair<const_iterator,const_iterator> + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_const_iterator; + std::pair<_Base_const_iterator, _Base_const_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator==(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator!=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator<(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator<=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator>=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator>(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, + const map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline void + swap(map<_Key,_Tp,_Compare,_Allocator>& __lhs, + map<_Key,_Tp,_Compare,_Allocator>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/contrib/libstdc++/include/debug/multimap.h b/contrib/libstdc++/include/debug/multimap.h new file mode 100644 index 000000000000..4de1e3b58f47 --- /dev/null +++ b/contrib/libstdc++/include/debug/multimap.h @@ -0,0 +1,314 @@ +// Debugging multimap implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_MULTIMAP_H +#define _GLIBCXX_DEBUG_MULTIMAP_H 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> +#include <utility> + +namespace __gnu_debug_def +{ + template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>, + typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > > + class multimap + : public _GLIBCXX_STD::multimap<_Key, _Tp, _Compare, _Allocator>, + public __gnu_debug::_Safe_sequence<multimap<_Key,_Tp,_Compare,_Allocator> > + { + typedef _GLIBCXX_STD::multimap<_Key, _Tp, _Compare, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<multimap> _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair<const _Key, _Tp> value_type; + typedef _Compare key_compare; + typedef _Allocator allocator_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, multimap> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + multimap> const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + using _Base::value_compare; + + // 23.3.1.1 construct/copy/destroy: + explicit multimap(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) { } + + template<typename _InputIterator> + multimap(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a) { } + + multimap(const multimap<_Key,_Tp,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() { } + + multimap(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~multimap() { } + + multimap<_Key,_Tp,_Compare,_Allocator>& + operator=(const multimap<_Key,_Tp,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + 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()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // modifiers: + iterator + insert(const value_type& __x) + { return iterator(_Base::insert(__x), this); } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template<typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + std::pair<iterator, iterator> __victims = this->equal_range(__x); + size_type __count = 0; + while (__victims.first != __victims.second) + { + iterator __victim = __victims.first++; + __victim._M_invalidate(); + _Base::erase(__victim.base()); + ++__count; + } + return __count; + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + while (__first != __last) + this->erase(__first++); + } + + void + swap(multimap<_Key,_Tp,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // 23.3.1.3 multimap operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair<iterator,iterator> + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + std::pair<const_iterator,const_iterator> + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_const_iterator; + std::pair<_Base_const_iterator, _Base_const_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator==(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator!=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator<(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator<=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator>=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline bool + operator>(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> + inline void + swap(multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, + multimap<_Key,_Tp,_Compare,_Allocator>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/contrib/libstdc++/include/debug/multiset.h b/contrib/libstdc++/include/debug/multiset.h new file mode 100644 index 000000000000..92042fef68ce --- /dev/null +++ b/contrib/libstdc++/include/debug/multiset.h @@ -0,0 +1,320 @@ +// Debugging multiset implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_MULTISET_H +#define _GLIBCXX_DEBUG_MULTISET_H 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> +#include <utility> + +namespace __gnu_debug_def +{ + template<typename _Key, typename _Compare = std::less<_Key>, + typename _Allocator = std::allocator<_Key> > + class multiset + : public _GLIBCXX_STD::multiset<_Key, _Compare, _Allocator>, + public __gnu_debug::_Safe_sequence<multiset<_Key, _Compare, _Allocator> > + { + typedef _GLIBCXX_STD::multiset<_Key, _Compare, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<multiset> _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + typedef _Allocator allocator_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, multiset> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + multiset> const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + // 23.3.3.1 construct/copy/destroy: + explicit multiset(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) { } + + template<typename _InputIterator> + multiset(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a) { } + + multiset(const multiset<_Key,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() { } + + multiset(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~multiset() { } + + multiset<_Key,_Compare,_Allocator>& + operator=(const multiset<_Key,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + 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()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // modifiers: + iterator + insert(const value_type& __x) + { return iterator(_Base::insert(__x), this); } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template<typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + std::pair<iterator, iterator> __victims = this->equal_range(__x); + size_type __count = 0; + while (__victims.first != __victims.second) + { + iterator __victim = __victims.first++; + __victim._M_invalidate(); + _Base::erase(__victim.base()); + ++__count; + } + return __count; + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + while (__first != __last) + this->erase(__first++); + } + + void + swap(multiset<_Key,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // multiset operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair<iterator,iterator> + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + std::pair<const_iterator,const_iterator> + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator==(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator!=(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator<(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator<=(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator>=(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator>(const multiset<_Key,_Compare,_Allocator>& __lhs, + const multiset<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + void + swap(multiset<_Key,_Compare,_Allocator>& __x, + multiset<_Key,_Compare,_Allocator>& __y) + { return __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/contrib/libstdc++/include/debug/safe_base.h b/contrib/libstdc++/include/debug/safe_base.h new file mode 100644 index 000000000000..a1af33ac5f77 --- /dev/null +++ b/contrib/libstdc++/include/debug/safe_base.h @@ -0,0 +1,207 @@ +// Safe sequence/iterator base implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_SAFE_BASE_H +#define _GLIBCXX_DEBUG_SAFE_BASE_H 1 + +namespace __gnu_debug +{ + class _Safe_sequence_base; + + /** \brief Basic functionality for a "safe" iterator. + * + * The %_Safe_iterator_base base class implements the functionality + * of a safe iterator that is not specific to a particular iterator + * type. It contains a pointer back to the sequence it references + * along with iterator version information and pointers to form a + * doubly-linked list of iterators referenced by the container. + * + * This class must not perform any operations that can throw an + * exception, or the exception guarantees of derived iterators will + * be broken. + */ + class _Safe_iterator_base + { + public: + /** The sequence this iterator references; may be NULL to indicate + a singular iterator. */ + _Safe_sequence_base* _M_sequence; + + /** The version number of this iterator. The sentinel value 0 is + * used to indicate an invalidated iterator (i.e., one that is + * singular because of an operation on the container). This + * version number must equal the version number in the sequence + * referenced by _M_sequence for the iterator to be + * non-singular. + */ + unsigned int _M_version; + + /** Pointer to the previous iterator in the sequence's list of + iterators. Only valid when _M_sequence != NULL. */ + _Safe_iterator_base* _M_prior; + + /** Pointer to the next iterator in the sequence's list of + iterators. Only valid when _M_sequence != NULL. */ + _Safe_iterator_base* _M_next; + + protected: + /** Initializes the iterator and makes it singular. */ + _Safe_iterator_base() + : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0) + { } + + /** Initialize the iterator to reference the sequence pointed to + * by @p__seq. @p __constant is true when we are initializing a + * constant iterator, and false if it is a mutable iterator. Note + * that @p __seq may be NULL, in which case the iterator will be + * singular. Otherwise, the iterator will reference @p __seq and + * be nonsingular. + */ + _Safe_iterator_base(const _Safe_sequence_base* __seq, bool __constant) + : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0) + { this->_M_attach(const_cast<_Safe_sequence_base*>(__seq), __constant); } + + /** Initializes the iterator to reference the same sequence that + @p __x does. @p __constant is true if this is a constant + iterator, and false if it is mutable. */ + _Safe_iterator_base(const _Safe_iterator_base& __x, bool __constant) + : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0) + { this->_M_attach(__x._M_sequence, __constant); } + + _Safe_iterator_base& + operator=(const _Safe_iterator_base&); + + explicit + _Safe_iterator_base(const _Safe_iterator_base&); + + ~_Safe_iterator_base() { this->_M_detach(); } + + public: + /** Attaches this iterator to the given sequence, detaching it + * from whatever sequence it was attached to originally. If the + * new sequence is the NULL pointer, the iterator is left + * unattached. + */ + void _M_attach(_Safe_sequence_base* __seq, bool __constant); + + /** Detach the iterator for whatever sequence it is attached to, + * if any. + */ + void _M_detach(); + + /** Determines if we are attached to the given sequence. */ + bool _M_attached_to(const _Safe_sequence_base* __seq) const + { return _M_sequence == __seq; } + + /** Is this iterator singular? */ + bool _M_singular() const; + + /** Can we compare this iterator to the given iterator @p __x? + Returns true if both iterators are nonsingular and reference + the same sequence. */ + bool _M_can_compare(const _Safe_iterator_base& __x) const; + }; + + /** + * @brief Base class that supports tracking of iterators that + * reference a sequence. + * + * The %_Safe_sequence_base class provides basic support for + * tracking iterators into a sequence. Sequences that track + * iterators must derived from %_Safe_sequence_base publicly, so + * that safe iterators (which inherit _Safe_iterator_base) can + * attach to them. This class contains two linked lists of + * iterators, one for constant iterators and one for mutable + * iterators, and a version number that allows very fast + * invalidation of all iterators that reference the container. + * + * This class must ensure that no operation on it may throw an + * exception, otherwise "safe" sequences may fail to provide the + * exception-safety guarantees required by the C++ standard. + */ + class _Safe_sequence_base + { + public: + /// The list of mutable iterators that reference this container + _Safe_iterator_base* _M_iterators; + + /// The list of constant iterators that reference this container + _Safe_iterator_base* _M_const_iterators; + + /// The container version number. This number may never be 0. + mutable unsigned int _M_version; + + protected: + // Initialize with a version number of 1 and no iterators + _Safe_sequence_base() + : _M_iterators(0), _M_const_iterators(0), _M_version(1) + { } + + /** Notify all iterators that reference this sequence that the + sequence is being destroyed. */ + ~_Safe_sequence_base() + { this->_M_detach_all(); } + + /** Detach all iterators, leaving them singular. */ + void + _M_detach_all(); + + /** Detach all singular iterators. + * @post for all iterators i attached to this sequence, + * i->_M_version == _M_version. + */ + void + _M_detach_singular(); + + /** Revalidates all attached singular iterators. This method may + * be used to validate iterators that were invalidated before + * (but for some reasion, such as an exception, need to become + * valid again). + */ + void + _M_revalidate_singular(); + + /** Swap this sequence with the given sequence. This operation + * also swaps ownership of the iterators, so that when the + * operation is complete all iterators that originally referenced + * one container now reference the other container. + */ + void + _M_swap(_Safe_sequence_base& __x); + + public: + /** Invalidates all iterators. */ + void + _M_invalidate_all() const + { if (++_M_version == 0) _M_version = 1; } + }; +} // namespace __gnu_debug + +#endif diff --git a/contrib/libstdc++/include/debug/safe_iterator.h b/contrib/libstdc++/include/debug/safe_iterator.h new file mode 100644 index 000000000000..8a4123af6944 --- /dev/null +++ b/contrib/libstdc++/include/debug/safe_iterator.h @@ -0,0 +1,618 @@ +// Safe iterator implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H +#define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1 + +#include <bits/stl_pair.h> +#include <debug/debug.h> +#include <debug/formatter.h> +#include <debug/safe_base.h> +#include <bits/cpp_type_traits.h> + +namespace __gnu_debug +{ + using std::iterator_traits; + using std::pair; + + /** Iterators that derive from _Safe_iterator_base but that aren't + * _Safe_iterators can be determined singular or non-singular via + * _Safe_iterator_base. + */ + inline bool __check_singular_aux(const _Safe_iterator_base* __x) + { return __x->_M_singular(); } + + /** \brief Safe iterator wrapper. + * + * The class template %_Safe_iterator is a wrapper around an + * iterator that tracks the iterator's movement among sequences and + * checks that operations performed on the "safe" iterator are + * legal. In additional to the basic iterator operations (which are + * validated, and then passed to the underlying iterator), + * %_Safe_iterator has member functions for iterator invalidation, + * attaching/detaching the iterator from sequences, and querying + * the iterator's state. + */ + template<typename _Iterator, typename _Sequence> + class _Safe_iterator : public _Safe_iterator_base + { + typedef _Safe_iterator _Self; + + /** The precision to which we can calculate the distance between + * two iterators. + */ + enum _Distance_precision + { + __dp_equality, //< Can compare iterator equality, only + __dp_sign, //< Can determine equality and ordering + __dp_exact //< Can determine distance precisely + }; + + /// The underlying iterator + _Iterator _M_current; + + /// Determine if this is a constant iterator. + bool + _M_constant() const + { + typedef typename _Sequence::const_iterator const_iterator; + return __is_same<const_iterator, _Safe_iterator>::value; + } + + typedef iterator_traits<_Iterator> _Traits; + + public: + typedef _Iterator _Base_iterator; + typedef typename _Traits::iterator_category iterator_category; + typedef typename _Traits::value_type value_type; + typedef typename _Traits::difference_type difference_type; + typedef typename _Traits::reference reference; + typedef typename _Traits::pointer pointer; + + /// @post the iterator is singular and unattached + _Safe_iterator() : _M_current() { } + + /** + * @brief Safe iterator construction from an unsafe iterator and + * its sequence. + * + * @pre @p seq is not NULL + * @post this is not singular + */ + _Safe_iterator(const _Iterator& __i, const _Sequence* __seq) + : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i) + { + _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(), + _M_message(__msg_init_singular) + ._M_iterator(*this, "this")); + } + + /** + * @brief Copy construction. + * @pre @p x is not singular + */ + _Safe_iterator(const _Safe_iterator& __x) + : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current) + { + _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), + _M_message(__msg_init_copy_singular) + ._M_iterator(*this, "this") + ._M_iterator(__x, "other")); + } + + /** + * @brief Converting constructor from a mutable iterator to a + * constant iterator. + * + * @pre @p x is not singular + */ + template<typename _MutableIterator> + _Safe_iterator( + const _Safe_iterator<_MutableIterator, + typename std::__enable_if< + _Sequence, + (std::__are_same<_MutableIterator, + typename _Sequence::iterator::_Base_iterator>::_M_type) + >::_M_type>& __x) + : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base()) + { + _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), + _M_message(__msg_init_const_singular) + ._M_iterator(*this, "this") + ._M_iterator(__x, "other")); + } + + /** + * @brief Copy assignment. + * @pre @p x is not singular + */ + _Safe_iterator& + operator=(const _Safe_iterator& __x) + { + _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(), + _M_message(__msg_copy_singular) + ._M_iterator(*this, "this") + ._M_iterator(__x, "other")); + _M_current = __x._M_current; + this->_M_attach(static_cast<_Sequence*>(__x._M_sequence)); + return *this; + } + + /** + * @brief Iterator dereference. + * @pre iterator is dereferenceable + */ + reference + operator*() const + { + + _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), + _M_message(__msg_bad_deref) + ._M_iterator(*this, "this")); + return *_M_current; + } + + /** + * @brief Iterator dereference. + * @pre iterator is dereferenceable + * @todo Make this correct w.r.t. iterators that return proxies + * @todo Use addressof() instead of & operator + */ + pointer + operator->() const + { + _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), + _M_message(__msg_bad_deref) + ._M_iterator(*this, "this")); + return &*_M_current; + } + + // ------ Input iterator requirements ------ + /** + * @brief Iterator preincrement + * @pre iterator is incrementable + */ + _Safe_iterator& + operator++() + { + _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), + _M_message(__msg_bad_inc) + ._M_iterator(*this, "this")); + ++_M_current; + return *this; + } + + /** + * @brief Iterator postincrement + * @pre iterator is incrementable + */ + _Safe_iterator + operator++(int) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), + _M_message(__msg_bad_inc) + ._M_iterator(*this, "this")); + _Safe_iterator __tmp(*this); + ++_M_current; + return __tmp; + } + + // ------ Bidirectional iterator requirements ------ + /** + * @brief Iterator predecrement + * @pre iterator is decrementable + */ + _Safe_iterator& + operator--() + { + _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), + _M_message(__msg_bad_dec) + ._M_iterator(*this, "this")); + --_M_current; + return *this; + } + + /** + * @brief Iterator postdecrement + * @pre iterator is decrementable + */ + _Safe_iterator + operator--(int) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), + _M_message(__msg_bad_dec) + ._M_iterator(*this, "this")); + _Safe_iterator __tmp(*this); + --_M_current; + return __tmp; + } + + // ------ Random access iterator requirements ------ + reference + operator[](const difference_type& __n) const + { + _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n) + && this->_M_can_advance(__n+1), + _M_message(__msg_iter_subscript_oob) + ._M_iterator(*this)._M_integer(__n)); + + return _M_current[__n]; + } + + _Safe_iterator& + operator+=(const difference_type& __n) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n), + _M_message(__msg_advance_oob) + ._M_iterator(*this)._M_integer(__n)); + _M_current += __n; + return *this; + } + + _Safe_iterator + operator+(const difference_type& __n) const + { + _Safe_iterator __tmp(*this); + __tmp += __n; + return __tmp; + } + + _Safe_iterator& + operator-=(const difference_type& __n) + { + _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n), + _M_message(__msg_retreat_oob) + ._M_iterator(*this)._M_integer(__n)); + _M_current += -__n; + return *this; + } + + _Safe_iterator + operator-(const difference_type& __n) const + { + _Safe_iterator __tmp(*this); + __tmp -= __n; + return __tmp; + } + + // ------ Utilities ------ + /** + * @brief Return the underlying iterator + */ + _Iterator + base() const { return _M_current; } + + /** + * @brief Conversion to underlying non-debug iterator to allow + * better interaction with non-debug containers. + */ + operator _Iterator() const { return _M_current; } + + /** Attach iterator to the given sequence. */ + void + _M_attach(const _Sequence* __seq) + { + _Safe_iterator_base::_M_attach(const_cast<_Sequence*>(__seq), + _M_constant()); + } + + /** Invalidate the iterator, making it singular. */ + void + _M_invalidate(); + + /// Is the iterator dereferenceable? + bool + _M_dereferenceable() const + { return !this->_M_singular() && !_M_is_end(); } + + /// Is the iterator incrementable? + bool + _M_incrementable() const { return this->_M_dereferenceable(); } + + // Is the iterator decrementable? + bool + _M_decrementable() const { return !_M_singular() && !_M_is_begin(); } + + // Can we advance the iterator @p __n steps (@p __n may be negative) + bool + _M_can_advance(const difference_type& __n) const; + + // Is the iterator range [*this, __rhs) valid? + template<typename _Other> + bool + _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const; + + // The sequence this iterator references. + const _Sequence* + _M_get_sequence() const + { return static_cast<const _Sequence*>(_M_sequence); } + + /** Determine the distance between two iterators with some known + * precision. + */ + template<typename _Iterator1, typename _Iterator2> + static pair<difference_type, _Distance_precision> + _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs) + { + typedef typename iterator_traits<_Iterator1>::iterator_category + _Category; + return _M_get_distance(__lhs, __rhs, _Category()); + } + + template<typename _Iterator1, typename _Iterator2> + static pair<difference_type, _Distance_precision> + _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, + std::random_access_iterator_tag) + { + return std::make_pair(__rhs.base() - __lhs.base(), __dp_exact); + } + + template<typename _Iterator1, typename _Iterator2> + static pair<difference_type, _Distance_precision> + _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, + std::forward_iterator_tag) + { + return std::make_pair(__lhs.base() == __rhs.base()? 0 : 1, + __dp_equality); + } + + /// Is this iterator equal to the sequence's begin() iterator? + bool _M_is_begin() const + { return *this == static_cast<const _Sequence*>(_M_sequence)->begin(); } + + /// Is this iterator equal to the sequence's end() iterator? + bool _M_is_end() const + { return *this == static_cast<const _Sequence*>(_M_sequence)->end(); } + }; + + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + inline bool + operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() == __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + inline bool + operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() == __rhs.base(); + } + + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + inline bool + operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() != __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + inline bool + operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_compare_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_compare_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() != __rhs.base(); + } + + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + inline bool + operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() < __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + inline bool + operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() < __rhs.base(); + } + + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + inline bool + operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() <= __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + inline bool + operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() <= __rhs.base(); + } + + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + inline bool + operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() > __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + inline bool + operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() > __rhs.base(); + } + + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + inline bool + operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() >= __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + inline bool + operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, + const _Safe_iterator<_Iterator, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_iter_order_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_order_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() >= __rhs.base(); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // According to the resolution of DR179 not only the various comparison + // operators but also operator- must accept mixed iterator/const_iterator + // parameters. + template<typename _IteratorL, typename _IteratorR, typename _Sequence> + inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type + operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs, + const _Safe_iterator<_IteratorR, _Sequence>& __rhs) + { + _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), + _M_message(__msg_distance_bad) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs), + _M_message(__msg_distance_different) + ._M_iterator(__lhs, "lhs") + ._M_iterator(__rhs, "rhs")); + return __lhs.base() - __rhs.base(); + } + + template<typename _Iterator, typename _Sequence> + inline _Safe_iterator<_Iterator, _Sequence> + operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n, + const _Safe_iterator<_Iterator, _Sequence>& __i) + { return __i + __n; } +} // namespace __gnu_debug + +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <debug/safe_iterator.tcc> +#endif + +#endif diff --git a/contrib/libstdc++/include/debug/safe_iterator.tcc b/contrib/libstdc++/include/debug/safe_iterator.tcc new file mode 100644 index 000000000000..cede969d168d --- /dev/null +++ b/contrib/libstdc++/include/debug/safe_iterator.tcc @@ -0,0 +1,140 @@ +// Debugging iterator implementation (out of line) -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file safe_iterator.tcc + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC +#define _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC 1 + +namespace __gnu_debug +{ + template<typename _Iterator, typename _Sequence> + bool + _Safe_iterator<_Iterator, _Sequence>:: + _M_can_advance(const difference_type& __n) const + { + typedef typename _Sequence::const_iterator const_iterator; + + if (this->_M_singular()) + return false; + if (__n == 0) + return true; + if (__n < 0) + { + const_iterator __begin = + static_cast<const _Sequence*>(_M_sequence)->begin(); + pair<difference_type, _Distance_precision> __dist = + this->_M_get_distance(__begin, *this); + bool __ok = (__dist.second == __dp_exact && __dist.first >= -__n + || __dist.second != __dp_exact && __dist.first > 0); + return __ok; + } + else + { + const_iterator __end = + static_cast<const _Sequence*>(_M_sequence)->end(); + pair<difference_type, _Distance_precision> __dist = + this->_M_get_distance(*this, __end); + bool __ok = (__dist.second == __dp_exact && __dist.first >= __n + || __dist.second != __dp_exact && __dist.first > 0); + return __ok; + } + } + + template<typename _Iterator, typename _Sequence> + template<typename _Other> + bool + _Safe_iterator<_Iterator, _Sequence>:: + _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const + { + if (!_M_can_compare(__rhs)) + return false; + + /* Determine if we can order the iterators without the help of + the container */ + pair<difference_type, _Distance_precision> __dist = + this->_M_get_distance(*this, __rhs); + switch (__dist.second) { + case __dp_equality: + if (__dist.first == 0) + return true; + break; + + case __dp_sign: + case __dp_exact: + return __dist.first >= 0; + } + + /* We can only test for equality, but check if one of the + iterators is at an extreme. */ + if (_M_is_begin() || __rhs._M_is_end()) + return true; + else if (_M_is_end() || __rhs._M_is_begin()) + return false; + + // Assume that this is a valid range; we can't check anything else + return true; + } + + template<typename _Iterator, typename _Sequence> + void + _Safe_iterator<_Iterator, _Sequence>:: + _M_invalidate() + { + typedef typename _Sequence::iterator iterator; + typedef typename _Sequence::const_iterator const_iterator; + + if (!this->_M_singular()) + { + for (_Safe_iterator_base* iter = _M_sequence->_M_iterators; iter; ) + { + iterator* __victim = static_cast<iterator*>(iter); + iter = iter->_M_next; + if (this->base() == __victim->base()) + __victim->_M_version = 0; + } + for (_Safe_iterator_base* iter2 = _M_sequence->_M_const_iterators; + iter2; /* increment in loop */) + { + const_iterator* __victim = static_cast<const_iterator*>(iter2); + iter2 = iter2->_M_next; + if (this->base() == __victim->base()) + __victim->_M_version = 0; + } + _M_version = 0; + } + } +} // namespace __gnu_debug + +#endif + diff --git a/contrib/libstdc++/include/debug/safe_sequence.h b/contrib/libstdc++/include/debug/safe_sequence.h new file mode 100644 index 000000000000..f050530a997c --- /dev/null +++ b/contrib/libstdc++/include/debug/safe_sequence.h @@ -0,0 +1,180 @@ +// Safe sequence implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_SAFE_SEQUENCE_H +#define _GLIBCXX_DEBUG_SAFE_SEQUENCE_H 1 + +#include <debug/debug.h> +#include <debug/safe_base.h> + +namespace __gnu_debug +{ + template<typename _Iterator, typename _Sequence> + class _Safe_iterator; + + /** A simple function object that returns true if the passed-in + * value is not equal to the stored value. It saves typing over + * using both bind1st and not_equal. + */ + template<typename _Type> + class _Not_equal_to + { + _Type __value; + + public: + explicit _Not_equal_to(const _Type& __v) : __value(__v) { } + + bool + operator()(const _Type& __x) const + { return __value != __x; } + }; + + /** A function object that returns true when the given random access + iterator is at least @c n steps away from the given iterator. */ + template<typename _Iterator> + class _After_nth_from + { + typedef typename std::iterator_traits<_Iterator>::difference_type + difference_type; + + _Iterator _M_base; + difference_type _M_n; + + public: + _After_nth_from(const difference_type& __n, const _Iterator& __base) + : _M_base(__base), _M_n(__n) { } + + bool + operator()(const _Iterator& __x) const + { return __x - _M_base >= _M_n; } + }; + + /** + * @brief Base class for constructing a "safe" sequence type that + * tracks iterators that reference it. + * + * The class template %_Safe_sequence simplifies the construction of + * "safe" sequences that track the iterators that reference the + * sequence, so that the iterators are notified of changes in the + * sequence that may affect their operation, e.g., if the container + * invalidates its iterators or is destructed. This class template + * may only be used by deriving from it and passing the name of the + * derived class as its template parameter via the curiously + * recurring template pattern. The derived class must have @c + * iterator and @const_iterator types that are instantiations of + * class template _Safe_iterator for this sequence. Iterators will + * then be tracked automatically. + */ + template<typename _Sequence> + class _Safe_sequence : public _Safe_sequence_base + { + public: + /** Invalidates all iterators @c x that reference this sequence, + are not singular, and for which @c pred(x) returns @c + true. The user of this routine should be careful not to make + copies of the iterators passed to @p pred, as the copies may + interfere with the invalidation. */ + template<typename _Predicate> + void + _M_invalidate_if(_Predicate __pred); + + /** Transfers all iterators that reference this memory location + to this sequence from whatever sequence they are attached + to. */ + template<typename _Iterator> + void + _M_transfer_iter(const _Safe_iterator<_Iterator, _Sequence>& __x); + }; + + template<typename _Sequence> + template<typename _Predicate> + void + _Safe_sequence<_Sequence>:: + _M_invalidate_if(_Predicate __pred) + { + typedef typename _Sequence::iterator iterator; + typedef typename _Sequence::const_iterator const_iterator; + + for (_Safe_iterator_base* __iter = _M_iterators; __iter; ) + { + iterator* __victim = static_cast<iterator*>(__iter); + __iter = __iter->_M_next; + if (!__victim->_M_singular()) + { + if (__pred(__victim->base())) + __victim->_M_invalidate(); + } + } + + for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2; ) + { + const_iterator* __victim = static_cast<const_iterator*>(__iter2); + __iter2 = __iter2->_M_next; + if (!__victim->_M_singular()) + { + if (__pred(__victim->base())) + __victim->_M_invalidate(); + } + } + } + + template<typename _Sequence> + template<typename _Iterator> + void + _Safe_sequence<_Sequence>:: + _M_transfer_iter(const _Safe_iterator<_Iterator, _Sequence>& __x) + { + _Safe_sequence_base* __from = __x._M_sequence; + if (!__from) + return; + + typedef typename _Sequence::iterator iterator; + typedef typename _Sequence::const_iterator const_iterator; + + for (_Safe_iterator_base* __iter = __from->_M_iterators; __iter; ) + { + iterator* __victim = static_cast<iterator*>(__iter); + __iter = __iter->_M_next; + if (!__victim->_M_singular() && __victim->base() == __x.base()) + __victim->_M_attach(static_cast<_Sequence*>(this)); + } + + for (_Safe_iterator_base* __iter2 = __from->_M_const_iterators; + __iter2;) + { + const_iterator* __victim = static_cast<const_iterator*>(__iter2); + __iter2 = __iter2->_M_next; + if (!__victim->_M_singular() && __victim->base() == __x.base()) + __victim->_M_attach(static_cast<_Sequence*>(this)); + } + } +} // namespace __gnu_debug + +#endif diff --git a/contrib/libstdc++/include/debug/set b/contrib/libstdc++/include/debug/set new file mode 100644 index 000000000000..a1a69efb4f4c --- /dev/null +++ b/contrib/libstdc++/include/debug/set @@ -0,0 +1,38 @@ +// Debugging set/multiset implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_SET +#define _GLIBCXX_DEBUG_SET 1 + +#include <set> +#include <debug/set.h> +#include <debug/multiset.h> + +#endif diff --git a/contrib/libstdc++/include/debug/set.h b/contrib/libstdc++/include/debug/set.h new file mode 100644 index 000000000000..8656cb0aff67 --- /dev/null +++ b/contrib/libstdc++/include/debug/set.h @@ -0,0 +1,325 @@ +// Debugging set implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_SET_H +#define _GLIBCXX_DEBUG_SET_H 1 + +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> +#include <utility> + +namespace __gnu_debug_def +{ + template<typename _Key, typename _Compare = std::less<_Key>, + typename _Allocator = std::allocator<_Key> > + class set + : public _GLIBCXX_STD::set<_Key,_Compare,_Allocator>, + public __gnu_debug::_Safe_sequence<set<_Key, _Compare, _Allocator> > + { + typedef _GLIBCXX_STD::set<_Key,_Compare,_Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<set> _Safe_base; + + public: + // types: + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + typedef _Allocator allocator_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, set> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, set> + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + // 23.3.3.1 construct/copy/destroy: + explicit set(const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__comp, __a) { } + + template<typename _InputIterator> + set(_InputIterator __first, _InputIterator __last, + const _Compare& __comp = _Compare(), + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, + __comp, __a) { } + + set(const set<_Key,_Compare,_Allocator>& __x) + : _Base(__x), _Safe_base() { } + + set(const _Base& __x) : _Base(__x), _Safe_base() { } + + ~set() { } + + set<_Key,_Compare,_Allocator>& + operator=(const set<_Key,_Compare,_Allocator>& __x) + { + *static_cast<_Base*>(this) = __x; + this->_M_invalidate_all(); + return *this; + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + 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()); } + + // capacity: + using _Base::empty; + using _Base::size; + using _Base::max_size; + + // modifiers: + std::pair<iterator, bool> + insert(const value_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, bool> __res = _Base::insert(__x); + return std::pair<iterator, bool>(iterator(__res.first, this), + __res.second); + } + + iterator + insert(iterator __position, const value_type& __x) + { + __glibcxx_check_insert(__position); + return iterator(_Base::insert(__position.base(), __x), this); + } + + template <typename _InputIterator> + void + insert(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::insert(__first, __last); + } + + void + erase(iterator __position) + { + __glibcxx_check_erase(__position); + __position._M_invalidate(); + _Base::erase(__position.base()); + } + + size_type + erase(const key_type& __x) + { + iterator __victim = find(__x); + if (__victim == end()) + return 0; + else + { + __victim._M_invalidate(); + _Base::erase(__victim.base()); + return 1; + } + } + + void + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + + while (__first != __last) + this->erase(__first++); + } + + void + swap(set<_Key,_Compare,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + } + + void + clear() + { this->erase(begin(), end()); } + + // observers: + using _Base::key_comp; + using _Base::value_comp; + + // set operations: + iterator + find(const key_type& __x) + { return iterator(_Base::find(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + find(const key_type& __x) const + { return const_iterator(_Base::find(__x), this); } + + using _Base::count; + + iterator + lower_bound(const key_type& __x) + { return iterator(_Base::lower_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + lower_bound(const key_type& __x) const + { return const_iterator(_Base::lower_bound(__x), this); } + + iterator + upper_bound(const key_type& __x) + { return iterator(_Base::upper_bound(__x), this); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + const_iterator + upper_bound(const key_type& __x) const + { return const_iterator(_Base::upper_bound(__x), this); } + + std::pair<iterator,iterator> + equal_range(const key_type& __x) + { + typedef typename _Base::iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(iterator(__res.first, this), + iterator(__res.second, this)); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + std::pair<const_iterator,const_iterator> + equal_range(const key_type& __x) const + { + typedef typename _Base::const_iterator _Base_iterator; + std::pair<_Base_iterator, _Base_iterator> __res = + _Base::equal_range(__x); + return std::make_pair(const_iterator(__res.first, this), + const_iterator(__res.second, this)); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + void + _M_invalidate_all() + { + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; + this->_M_invalidate_if(_Not_equal(_M_base().end())); + } + }; + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator==(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator!=(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator<(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator<=(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator>=(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + inline bool + operator>(const set<_Key,_Compare,_Allocator>& __lhs, + const set<_Key,_Compare,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Key, typename _Compare, typename _Allocator> + void + swap(set<_Key,_Compare,_Allocator>& __x, + set<_Key,_Compare,_Allocator>& __y) + { return __x.swap(__y); } +} // namespace __gnu_debug_def + +#endif diff --git a/contrib/libstdc++/include/debug/string b/contrib/libstdc++/include/debug/string new file mode 100644 index 000000000000..a91c004e9379 --- /dev/null +++ b/contrib/libstdc++/include/debug/string @@ -0,0 +1,1001 @@ +// Debugging string implementation -*- C++ -*- + +// Copyright (C) 2003 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_STRING +#define _GLIBCXX_DEBUG_STRING 1 + +#include <string> +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> + +namespace __gnu_debug +{ + template<typename _CharT, typename _Traits, typename _Allocator> + class basic_string + : public std::basic_string<_CharT, _Traits, _Allocator>, + public __gnu_debug::_Safe_sequence<basic_string<_CharT, _Traits, + _Allocator> > + { + typedef std::basic_string<_CharT, _Traits, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<basic_string> _Safe_base; + + public: + // types: + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef _Allocator allocator_type; + typedef typename _Allocator::size_type size_type; + typedef typename _Allocator::difference_type difference_type; + typedef typename _Allocator::reference reference; + typedef typename _Allocator::const_reference const_reference; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, basic_string> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, + basic_string> const_iterator; + + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + using _Base::npos; + + // 21.3.1 construct/copy/destroy: + explicit basic_string(const _Allocator& __a = _Allocator()) + : _Base(__a) + { } + + // Provides conversion from a release-mode string to a debug-mode string + basic_string(const _Base& __base) : _Base(__base), _Safe_base() { } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 42. string ctors specify wrong default allocator + basic_string(const basic_string& __str) + : _Base(__str, 0, _Base::npos, __str.get_allocator()), _Safe_base() + { } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 42. string ctors specify wrong default allocator + basic_string(const basic_string& __str, size_type __pos, + size_type __n = _Base::npos, + const _Allocator& __a = _Allocator()) + : _Base(__str, __pos, __n, __a) + { } + + basic_string(const _CharT* __s, size_type __n, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_string(__s, __n), __n, __a) + { } + + basic_string(const _CharT* __s, const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_string(__s), __a) + { this->assign(__s); } + + basic_string(size_type __n, _CharT __c, + const _Allocator& __a = _Allocator()) + : _Base(__n, __c, __a) + { } + + template<typename _InputIterator> + basic_string(_InputIterator __begin, _InputIterator __end, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__begin, __end), __end, __a) + { } + + ~basic_string() { } + + basic_string& + operator=(const basic_string& __str) + { + *static_cast<_Base*>(this) = __str; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator=(const _CharT* __s) + { + __glibcxx_check_string(__s); + *static_cast<_Base*>(this) = __s; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator=(_CharT __c) + { + *static_cast<_Base*>(this) = __c; + this->_M_invalidate_all(); + return *this; + } + + // 21.3.2 iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + 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()); } + + // 21.3.3 capacity: + using _Base::size; + using _Base::length; + using _Base::max_size; + + void + resize(size_type __n, _CharT __c) + { + _Base::resize(__n, __c); + this->_M_invalidate_all(); + } + + void + resize(size_type __n) + { this->resize(__n, _CharT()); } + + using _Base::capacity; + using _Base::reserve; + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + } + + using _Base::empty; + + // 21.3.4 element access: + const_reference + operator[](size_type __pos) const + { + _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(), + _M_message(::__gnu_debug::__msg_subscript_oob) + ._M_sequence(*this, "this") + ._M_integer(__pos, "__pos") + ._M_integer(this->size(), "size")); + return _M_base()[__pos]; + } + + reference + operator[](size_type __pos) + { + __glibcxx_check_subscript(__pos); + return _M_base()[__pos]; + } + + using _Base::at; + + // 21.3.5 modifiers: + basic_string& + operator+=(const basic_string& __str) + { + _M_base() += __str; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator+=(const _CharT* __s) + { + __glibcxx_check_string(__s); + _M_base() += __s; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + operator+=(_CharT __c) + { + _M_base() += __c; + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const basic_string& __str) + { + _Base::append(__str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const basic_string& __str, size_type __pos, size_type __n) + { + _Base::append(__str, __pos, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const _CharT* __s, size_type __n) + { + __glibcxx_check_string_len(__s, __n); + _Base::append(__s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::append(__s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + append(size_type __n, _CharT __c) + { + _Base::append(__n, __c); + this->_M_invalidate_all(); + return *this; + } + + template<typename _InputIterator> + basic_string& + append(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::append(__first, __last); + this->_M_invalidate_all(); + return *this; + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 7. string clause minor problems + void + push_back(_CharT __c) + { + _Base::push_back(__c); + this->_M_invalidate_all(); + } + + basic_string& + assign(const basic_string& __x) + { + _Base::assign(__x); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(const basic_string& __str, size_type __pos, size_type __n) + { + _Base::assign(__str, __pos, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(const _CharT* __s, size_type __n) + { + __glibcxx_check_string_len(__s, __n); + _Base::assign(__s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::assign(__s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + assign(size_type __n, _CharT __c) + { + _Base::assign(__n, __c); + this->_M_invalidate_all(); + return *this; + } + + template<typename _InputIterator> + basic_string& + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos1, const basic_string& __str) + { + _Base::insert(__pos1, __str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos1, const basic_string& __str, + size_type __pos2, size_type __n) + { + _Base::insert(__pos1, __str, __pos2, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos, const _CharT* __s, size_type __n) + { + __glibcxx_check_string(__s); + _Base::insert(__pos, __s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos, const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::insert(__pos, __s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + insert(size_type __pos, size_type __n, _CharT __c) + { + _Base::insert(__pos, __n, __c); + this->_M_invalidate_all(); + return *this; + } + + iterator + insert(iterator __p, _CharT __c) + { + __glibcxx_check_insert(__p); + typename _Base::iterator __res = _Base::insert(__p.base(), __c); + this->_M_invalidate_all(); + return iterator(__res, this); + } + + void + insert(iterator __p, size_type __n, _CharT __c) + { + __glibcxx_check_insert(__p); + _Base::insert(__p.base(), __n, __c); + this->_M_invalidate_all(); + } + + template<typename _InputIterator> + void + insert(iterator __p, _InputIterator __first, _InputIterator __last) + { + __glibcxx_check_insert_range(__p, __first, __last); + _Base::insert(__p.base(), __first, __last); + this->_M_invalidate_all(); + } + + basic_string& + erase(size_type __pos = 0, size_type __n = _Base::npos) + { + _Base::erase(__pos, __n); + this->_M_invalidate_all(); + return *this; + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + typename _Base::iterator __res = _Base::erase(__position.base()); + this->_M_invalidate_all(); + return iterator(__res, this); + } + + iterator + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + typename _Base::iterator __res = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_all(); + return iterator(__res, this); + } + + basic_string& + replace(size_type __pos1, size_type __n1, const basic_string& __str) + { + _Base::replace(__pos1, __n1, __str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) + { + _Base::replace(__pos1, __n1, __str, __pos2, __n2); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) + { + __glibcxx_check_string_len(__s, __n2); + _Base::replace(__pos, __n1, __s, __n2); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s) + { + __glibcxx_check_string(__s); + _Base::replace(__pos, __n1, __s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) + { + _Base::replace(__pos, __n1, __n2, __c); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, const basic_string& __str) + { + __glibcxx_check_erase_range(__i1, __i2); + _Base::replace(__i1.base(), __i2.base(), __str); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n) + { + __glibcxx_check_erase_range(__i1, __i2); + __glibcxx_check_string_len(__s, __n); + _Base::replace(__i1.base(), __i2.base(), __s, __n); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, const _CharT* __s) + { + __glibcxx_check_erase_range(__i1, __i2); + __glibcxx_check_string(__s); + _Base::replace(__i1.base(), __i2.base(), __s); + this->_M_invalidate_all(); + return *this; + } + + basic_string& + replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) + { + __glibcxx_check_erase_range(__i1, __i2); + _Base::replace(__i1.base(), __i2.base(), __n, __c); + this->_M_invalidate_all(); + return *this; + } + + template<typename _InputIterator> + basic_string& + replace(iterator __i1, iterator __i2, + _InputIterator __j1, _InputIterator __j2) + { + __glibcxx_check_erase_range(__i1, __i2); + __glibcxx_check_valid_range(__j1, __j2); + _Base::replace(__i1.base(), __i2.base(), __j1, __j2); + this->_M_invalidate_all(); + return *this; + } + + size_type + copy(_CharT* __s, size_type __n, size_type __pos = 0) const + { + __glibcxx_check_string_len(__s, __n); + return _Base::copy(__s, __n, __pos); + } + + void + swap(basic_string<_CharT,_Traits,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + this->_M_invalidate_all(); + __x._M_invalidate_all(); + } + + // 21.3.6 string operations: + const _CharT* + c_str() const + { + const _CharT* __res = _Base::c_str(); + this->_M_invalidate_all(); + return __res; + } + + const _CharT* + data() const + { + const _CharT* __res = _Base::data(); + this->_M_invalidate_all(); + return __res; + } + + using _Base::get_allocator; + + size_type + find(const basic_string& __str, size_type __pos = 0) const + { return _Base::find(__str, __pos); } + + size_type + find(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find(__s, __pos, __n); + } + + size_type + find(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_check_string(__s); + return _Base::find(__s, __pos); + } + + size_type + find(_CharT __c, size_type __pos = 0) const + { return _Base::find(__c, __pos); } + + size_type + rfind(const basic_string& __str, size_type __pos = _Base::npos) const + { return _Base::rfind(__str, __pos); } + + size_type + rfind(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string_len(__s, __n); + return _Base::rfind(__s, __pos, __n); + } + + size_type + rfind(const _CharT* __s, size_type __pos = _Base::npos) const + { + __glibcxx_check_string(__s); + return _Base::rfind(__s, __pos); + } + + size_type + rfind(_CharT __c, size_type __pos = _Base::npos) const + { return _Base::rfind(__c, __pos); } + + size_type + find_first_of(const basic_string& __str, size_type __pos = 0) const + { return _Base::find_first_of(__str, __pos); } + + size_type + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find_first_of(__s, __pos, __n); + } + + size_type + find_first_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_check_string(__s); + return _Base::find_first_of(__s, __pos); + } + + size_type + find_first_of(_CharT __c, size_type __pos = 0) const + { return _Base::find_first_of(__c, __pos); } + + size_type + find_last_of(const basic_string& __str, size_type __pos = _Base::npos) const + { return _Base::find_last_of(__str, __pos); } + + size_type + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find_last_of(__s, __pos, __n); + } + + size_type + find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const + { + __glibcxx_check_string(__s); + return _Base::find_last_of(__s, __pos); + } + + size_type + find_last_of(_CharT __c, size_type __pos = _Base::npos) const + { return _Base::find_last_of(__c, __pos); } + + size_type + find_first_not_of(const basic_string& __str, size_type __pos = 0) const + { return _Base::find_first_not_of(__str, __pos); } + + size_type + find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string_len(__s, __n); + return _Base::find_first_not_of(__s, __pos, __n); + } + + size_type + find_first_not_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_check_string(__s); + return _Base::find_first_not_of(__s, __pos); + } + + size_type + find_first_not_of(_CharT __c, size_type __pos = 0) const + { return _Base::find_first_not_of(__c, __pos); } + + size_type + find_last_not_of(const basic_string& __str, + size_type __pos = _Base::npos) const + { return _Base::find_last_not_of(__str, __pos); } + + size_type + find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + __glibcxx_check_string(__s); + return _Base::find_last_not_of(__s, __pos, __n); + } + + size_type + find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const + { + __glibcxx_check_string(__s); + return _Base::find_last_not_of(__s, __pos); + } + + size_type + find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const + { return _Base::find_last_not_of(__c, __pos); } + + basic_string + substr(size_type __pos = 0, size_type __n = _Base::npos) const + { return basic_string(_Base::substr(__pos, __n)); } + + int + compare(const basic_string& __str) const + { return _Base::compare(__str); } + + int + compare(size_type __pos1, size_type __n1, + const basic_string& __str) const + { return _Base::compare(__pos1, __n1, __str); } + + int + compare(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) const + { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); } + + int + compare(const _CharT* __s) const + { + __glibcxx_check_string(__s); + return _Base::compare(__s); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 5. string::compare specification questionable + int + compare(size_type __pos1, size_type __n1, const _CharT* __s) const + { + __glibcxx_check_string(__s); + return _Base::compare(__pos1, __n1, __s); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 5. string::compare specification questionable + int + compare(size_type __pos1, size_type __n1,const _CharT* __s, + size_type __n2) const + { + __glibcxx_check_string_len(__s, __n2); + return _Base::compare(__pos1, __n1, __s, __n2); + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + using _Safe_base::_M_invalidate_all; + }; + + template<typename _CharT, typename _Traits, typename _Allocator> + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline basic_string<_CharT,_Traits,_Allocator> + operator+(_CharT __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline basic_string<_CharT,_Traits,_Allocator> + operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + _CharT __rhs) + { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator==(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs == __rhs._M_base(); + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() == __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator!=(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs != __rhs._M_base(); + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() != __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator<(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs < __rhs._M_base(); + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() < __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator<=(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs <= __rhs._M_base(); + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() <= __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator>=(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs >= __rhs._M_base(); + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() >= __rhs; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator>(const _CharT* __lhs, + const basic_string<_CharT,_Traits,_Allocator>& __rhs) + { + __glibcxx_check_string(__lhs); + return __lhs > __rhs._M_base(); + } + + template<typename _CharT, typename _Traits, typename _Allocator> + inline bool + operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs, + const _CharT* __rhs) + { + __glibcxx_check_string(__rhs); + return __lhs._M_base() > __rhs; + } + + // 21.3.7.8: + template<typename _CharT, typename _Traits, typename _Allocator> + inline void + swap(basic_string<_CharT,_Traits,_Allocator>& __lhs, + basic_string<_CharT,_Traits,_Allocator>& __rhs) + { __lhs.swap(__rhs); } + + template<typename _CharT, typename _Traits, typename _Allocator> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const basic_string<_CharT, _Traits, _Allocator>& __str) + { return __os << __str._M_base(); } + + template<typename _CharT, typename _Traits, typename _Allocator> + std::basic_istream<_CharT,_Traits>& + operator>>(std::basic_istream<_CharT,_Traits>& __is, + basic_string<_CharT,_Traits,_Allocator>& __str) + { + std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base(); + __str._M_invalidate_all(); + return __res; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + std::basic_istream<_CharT,_Traits>& + getline(std::basic_istream<_CharT,_Traits>& __is, + basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim) + { + std::basic_istream<_CharT,_Traits>& __res = getline(__is, + __str._M_base(), + __delim); + __str._M_invalidate_all(); + return __res; + } + + template<typename _CharT, typename _Traits, typename _Allocator> + std::basic_istream<_CharT,_Traits>& + getline(std::basic_istream<_CharT,_Traits>& __is, + basic_string<_CharT,_Traits,_Allocator>& __str) + { + std::basic_istream<_CharT,_Traits>& __res = getline(__is, + __str._M_base()); + __str._M_invalidate_all(); + return __res; + } +} // namespace __gnu_debug + +#endif diff --git a/contrib/libstdc++/include/debug/vector b/contrib/libstdc++/include/debug/vector new file mode 100644 index 000000000000..0cc2997b9754 --- /dev/null +++ b/contrib/libstdc++/include/debug/vector @@ -0,0 +1,412 @@ +// Debugging vector implementation -*- C++ -*- + +// Copyright (C) 2003, 2004 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_VECTOR +#define _GLIBCXX_DEBUG_VECTOR 1 + +#include <vector> +#include <debug/safe_sequence.h> +#include <debug/safe_iterator.h> +#include <utility> + +namespace __gnu_debug_def +{ + template<typename _Tp, + typename _Allocator = std::allocator<_Tp> > + class vector + : public _GLIBCXX_STD::vector<_Tp, _Allocator>, + public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> > + { + typedef _GLIBCXX_STD::vector<_Tp, _Allocator> _Base; + typedef __gnu_debug::_Safe_sequence<vector> _Safe_base; + + typedef typename _Base::const_iterator _Base_const_iterator; + typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; + + public: + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + + typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,vector> + iterator; + typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,vector> + const_iterator; + + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename _Allocator::pointer pointer; + typedef typename _Allocator::const_pointer const_pointer; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + // 23.2.4.1 construct/copy/destroy: + explicit vector(const _Allocator& __a = _Allocator()) + : _Base(__a), _M_guaranteed_capacity(0) { } + + explicit vector(size_type __n, const _Tp& __value = _Tp(), + const _Allocator& __a = _Allocator()) + : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { } + + template<class _InputIterator> + vector(_InputIterator __first, _InputIterator __last, + const _Allocator& __a = _Allocator()) + : _Base(__gnu_debug::__check_valid_range(__first, __last), + __last, __a), + _M_guaranteed_capacity(0) + { _M_update_guaranteed_capacity(); } + + vector(const vector<_Tp,_Allocator>& __x) + : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { } + + /// Construction from a release-mode vector + vector(const _Base& __x) + : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { } + + ~vector() { } + + vector<_Tp,_Allocator>& + operator=(const vector<_Tp,_Allocator>& __x) + { + static_cast<_Base&>(*this) = __x; + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + return *this; + } + + template<typename _InputIterator> + void + assign(_InputIterator __first, _InputIterator __last) + { + __glibcxx_check_valid_range(__first, __last); + _Base::assign(__first, __last); + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + } + + void + assign(size_type __n, const _Tp& __u) + { + _Base::assign(__n, __u); + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + } + + using _Base::get_allocator; + + // iterators: + iterator + begin() + { return iterator(_Base::begin(), this); } + + const_iterator + begin() const + { return const_iterator(_Base::begin(), this); } + + iterator + end() + { return iterator(_Base::end(), this); } + + const_iterator + end() const + { return const_iterator(_Base::end(), this); } + + 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()); } + + // 23.2.4.2 capacity: + using _Base::size; + using _Base::max_size; + + void + resize(size_type __sz, _Tp __c = _Tp()) + { + bool __realloc = _M_requires_reallocation(__sz); + if (__sz < this->size()) + this->_M_invalidate_if(_After_nth(__sz, _M_base().begin())); + _Base::resize(__sz, __c); + if (__realloc) + this->_M_invalidate_all(); + } + + using _Base::capacity; + using _Base::empty; + + void + reserve(size_type __n) + { + bool __realloc = _M_requires_reallocation(__n); + _Base::reserve(__n); + if (__n > _M_guaranteed_capacity) + _M_guaranteed_capacity = __n; + if (__realloc) + this->_M_invalidate_all(); + } + + // element access: + reference + operator[](size_type __n) + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + const_reference + operator[](size_type __n) const + { + __glibcxx_check_subscript(__n); + return _M_base()[__n]; + } + + using _Base::at; + + reference + front() + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + const_reference + front() const + { + __glibcxx_check_nonempty(); + return _Base::front(); + } + + reference + back() + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + const_reference + back() const + { + __glibcxx_check_nonempty(); + return _Base::back(); + } + + // 23.2.4.3 modifiers: + void + push_back(const _Tp& __x) + { + bool __realloc = _M_requires_reallocation(this->size() + 1); + _Base::push_back(__x); + if (__realloc) + this->_M_invalidate_all(); + _M_update_guaranteed_capacity(); + } + + void + pop_back() + { + __glibcxx_check_nonempty(); + iterator __victim = end() - 1; + __victim._M_invalidate(); + _Base::pop_back(); + } + + iterator + insert(iterator __position, const _Tp& __x) + { + __glibcxx_check_insert(__position); + bool __realloc = _M_requires_reallocation(this->size() + 1); + difference_type __offset = __position - begin(); + typename _Base::iterator __res = _Base::insert(__position.base(),__x); + if (__realloc) + this->_M_invalidate_all(); + else + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + _M_update_guaranteed_capacity(); + return iterator(__res, this); + } + + void + insert(iterator __position, size_type __n, const _Tp& __x) + { + __glibcxx_check_insert(__position); + bool __realloc = _M_requires_reallocation(this->size() + __n); + difference_type __offset = __position - begin(); + _Base::insert(__position.base(), __n, __x); + if (__realloc) + this->_M_invalidate_all(); + else + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + _M_update_guaranteed_capacity(); + } + + template<class _InputIterator> + void + insert(iterator __position, + _InputIterator __first, _InputIterator __last) + { + __glibcxx_check_insert_range(__position, __first, __last); + + /* Hard to guess if invalidation will occur, because __last + - __first can't be calculated in all cases, so we just + punt here by checking if it did occur. */ + typename _Base::iterator __old_begin = _M_base().begin(); + difference_type __offset = __position - begin(); + _Base::insert(__position.base(), __first, __last); + + if (_M_base().begin() != __old_begin) + this->_M_invalidate_all(); + else + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + _M_update_guaranteed_capacity(); + } + + iterator + erase(iterator __position) + { + __glibcxx_check_erase(__position); + difference_type __offset = __position - begin(); + typename _Base::iterator __res = _Base::erase(__position.base()); + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + return iterator(__res, this); + } + + iterator + erase(iterator __first, iterator __last) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 151. can't currently clear() empty container + __glibcxx_check_erase_range(__first, __last); + + difference_type __offset = __first - begin(); + typename _Base::iterator __res = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_if(_After_nth(__offset, _M_base().begin())); + return iterator(__res, this); + } + + void + swap(vector<_Tp,_Allocator>& __x) + { + _Base::swap(__x); + this->_M_swap(__x); + std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity); + } + + void + clear() + { + _Base::clear(); + this->_M_invalidate_all(); + _M_guaranteed_capacity = 0; + } + + _Base& + _M_base() { return *this; } + + const _Base& + _M_base() const { return *this; } + + private: + size_type _M_guaranteed_capacity; + + bool + _M_requires_reallocation(size_type __elements) + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + return __elements > this->capacity(); +#else + return __elements > _M_guaranteed_capacity; +#endif + } + + void + _M_update_guaranteed_capacity() + { + if (this->size() > _M_guaranteed_capacity) + _M_guaranteed_capacity = this->size(); + } + }; + + template<typename _Tp, typename _Alloc> + inline bool + operator==(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() == __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator!=(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() != __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator<(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() < __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator<=(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() <= __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator>=(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() >= __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline bool + operator>(const vector<_Tp, _Alloc>& __lhs, + const vector<_Tp, _Alloc>& __rhs) + { return __lhs._M_base() > __rhs._M_base(); } + + template<typename _Tp, typename _Alloc> + inline void + swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) + { __lhs.swap(__rhs); } +} // namespace __gnu_debug_def + +#endif diff --git a/contrib/libstdc++/include/ext/algorithm b/contrib/libstdc++/include/ext/algorithm index b35d36f5e422..07ac4cbe4d31 100644 --- a/contrib/libstdc++/include/ext/algorithm +++ b/contrib/libstdc++/include/ext/algorithm @@ -60,9 +60,10 @@ */ #ifndef _EXT_ALGORITHM -#define _EXT_ALGORITHM +#define _EXT_ALGORITHM 1 #pragma GCC system_header + #include <algorithm> namespace __gnu_cxx @@ -77,10 +78,10 @@ namespace __gnu_cxx //-------------------------------------------------- // copy_n (not part of the C++ standard) - template<typename _InputIter, typename _Size, typename _OutputIter> - pair<_InputIter, _OutputIter> - __copy_n(_InputIter __first, _Size __count, - _OutputIter __result, + template<typename _InputIterator, typename _Size, typename _OutputIterator> + pair<_InputIterator, _OutputIterator> + __copy_n(_InputIterator __first, _Size __count, + _OutputIterator __result, input_iterator_tag) { for ( ; __count > 0; --__count) { @@ -88,17 +89,17 @@ namespace __gnu_cxx ++__first; ++__result; } - return pair<_InputIter, _OutputIter>(__first, __result); + return pair<_InputIterator, _OutputIterator>(__first, __result); } - template<typename _RAIter, typename _Size, typename _OutputIter> - inline pair<_RAIter, _OutputIter> - __copy_n(_RAIter __first, _Size __count, - _OutputIter __result, + template<typename _RAIterator, typename _Size, typename _OutputIterator> + inline pair<_RAIterator, _OutputIterator> + __copy_n(_RAIterator __first, _Size __count, + _OutputIterator __result, random_access_iterator_tag) { - _RAIter __last = __first + __count; - return pair<_RAIter, _OutputIter>(__last, + _RAIterator __last = __first + __count; + return pair<_RAIterator, _OutputIterator>(__last, std::copy(__first, __last, __result)); } @@ -116,23 +117,23 @@ namespace __gnu_cxx * optimizations such as unrolling). * @ingroup SGIextensions */ - template<typename _InputIter, typename _Size, typename _OutputIter> - inline pair<_InputIter, _OutputIter> - copy_n(_InputIter __first, _Size __count, _OutputIter __result) + template<typename _InputIterator, typename _Size, typename _OutputIterator> + inline pair<_InputIterator, _OutputIterator> + copy_n(_InputIterator __first, _Size __count, _OutputIterator __result) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_InputIter>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_InputIterator>::value_type>) return __copy_n(__first, __count, __result, std::__iterator_category(__first)); } - template<typename _InputIter1, typename _InputIter2> + template<typename _InputIterator1, typename _InputIterator2> int - __lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, _InputIter2 __last2) + __lexicographical_compare_3way(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) { while (__first1 != __last1 && __first2 != __last2) { if (*__first1 < *__first2) @@ -159,11 +160,11 @@ namespace __gnu_cxx const ptrdiff_t __len1 = __last1 - __first1; const ptrdiff_t __len2 = __last2 - __first2; const int __result = std::memcmp(__first1, __first2, min(__len1, __len2)); - return __result != 0 ? __result + return __result != 0 ? __result : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1)); } - inline int + inline int __lexicographical_compare_3way(const char* __first1, const char* __last1, const char* __first2, const char* __last2) { @@ -195,18 +196,20 @@ namespace __gnu_cxx * This is an SGI extension. * @ingroup SGIextensions */ - template<typename _InputIter1, typename _InputIter2> + template<typename _InputIterator1, typename _InputIterator2> int - lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1, - _InputIter2 __first2, _InputIter2 __last2) + lexicographical_compare_3way(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _InputIterator2 __last2) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>) - __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>) - __glibcpp_function_requires(_LessThanComparableConcept< - typename iterator_traits<_InputIter1>::value_type>) - __glibcpp_function_requires(_LessThanComparableConcept< - typename iterator_traits<_InputIter2>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator1>::value_type>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_InputIterator2>::value_type>) + __glibcxx_requires_valid_range(__first1, __last1); + __glibcxx_requires_valid_range(__first2, __last2); return __lexicographical_compare_3way(__first1, __last1, __first2, __last2); } @@ -214,32 +217,36 @@ namespace __gnu_cxx // count and count_if: this version, whose return type is void, was present // in the HP STL, and is retained as an extension for backward compatibility. - template<typename _InputIter, typename _Tp, typename _Size> + template<typename _InputIterator, typename _Tp, typename _Size> void - count(_InputIter __first, _InputIter __last, + count(_InputIterator __first, _InputIterator __last, const _Tp& __value, _Size& __n) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_EqualityComparableConcept< - typename iterator_traits<_InputIter>::value_type >) - __glibcpp_function_requires(_EqualityComparableConcept<_Tp>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_EqualityComparableConcept< + typename iterator_traits<_InputIterator>::value_type >) + __glibcxx_function_requires(_EqualityComparableConcept<_Tp>) + __glibcxx_requires_valid_range(__first, __last); + for ( ; __first != __last; ++__first) if (*__first == __value) ++__n; } - template<typename _InputIter, typename _Predicate, typename _Size> + template<typename _InputIterator, typename _Predicate, typename _Size> void - count_if(_InputIter __first, _InputIter __last, + count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred, _Size& __n) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_UnaryPredicateConcept<_Predicate, - typename iterator_traits<_InputIter>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, + typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + for ( ; __first != __last; ++__first) if (__pred(*__first)) ++__n; @@ -252,21 +259,22 @@ namespace __gnu_cxx * @ingroup SGIextensions * @doctodo */ - template<typename _ForwardIter, typename _OutputIter, typename _Distance> - _OutputIter - random_sample_n(_ForwardIter __first, _ForwardIter __last, - _OutputIter __out, const _Distance __n) + template<typename _ForwardIterator, typename _OutputIterator, typename _Distance> + _OutputIterator + random_sample_n(_ForwardIterator __first, _ForwardIterator __last, + _OutputIterator __out, const _Distance __n) { // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_ForwardIter>::value_type>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); _Distance __remaining = std::distance(__first, __last); _Distance __m = min(__n, __remaining); while (__m > 0) { - if (std::__random_number(__remaining) < __m) { + if ((std::rand() % __remaining) < __m) { *__out = *__first; ++__out; --__m; @@ -283,19 +291,20 @@ namespace __gnu_cxx * @ingroup SGIextensions * @doctodo */ - template<typename _ForwardIter, typename _OutputIter, typename _Distance, + template<typename _ForwardIterator, typename _OutputIterator, typename _Distance, typename _RandomNumberGenerator> - _OutputIter - random_sample_n(_ForwardIter __first, _ForwardIter __last, - _OutputIter __out, const _Distance __n, + _OutputIterator + random_sample_n(_ForwardIterator __first, _ForwardIterator __last, + _OutputIterator __out, const _Distance __n, _RandomNumberGenerator& __rand) { // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter, - typename iterator_traits<_ForwardIter>::value_type>) - __glibcpp_function_requires(_UnaryFunctionConcept< + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_function_requires(_UnaryFunctionConcept< _RandomNumberGenerator, _Distance, _Distance>) + __glibcxx_requires_valid_range(__first, __last); _Distance __remaining = std::distance(__first, __last); _Distance __m = min(__n, __remaining); @@ -313,20 +322,20 @@ namespace __gnu_cxx return __out; } - template<typename _InputIter, typename _RandomAccessIter, typename _Distance> - _RandomAccessIter - __random_sample(_InputIter __first, _InputIter __last, - _RandomAccessIter __out, + template<typename _InputIterator, typename _RandomAccessIterator, typename _Distance> + _RandomAccessIterator + __random_sample(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __out, const _Distance __n) { _Distance __m = 0; _Distance __t = __n; - for ( ; __first != __last && __m < __n; ++__m, ++__first) + for ( ; __first != __last && __m < __n; ++__m, ++__first) __out[__m] = *__first; while (__first != __last) { ++__t; - _Distance __M = std::__random_number(__t); + _Distance __M = std::rand() % (__t); if (__M < __n) __out[__M] = *__first; ++__first; @@ -335,16 +344,16 @@ namespace __gnu_cxx return __out + __m; } - template<typename _InputIter, typename _RandomAccessIter, + template<typename _InputIterator, typename _RandomAccessIterator, typename _RandomNumberGenerator, typename _Distance> - _RandomAccessIter - __random_sample(_InputIter __first, _InputIter __last, - _RandomAccessIter __out, + _RandomAccessIterator + __random_sample(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __out, _RandomNumberGenerator& __rand, const _Distance __n) { // concept requirements - __glibcpp_function_requires(_UnaryFunctionConcept< + __glibcxx_function_requires(_UnaryFunctionConcept< _RandomNumberGenerator, _Distance, _Distance>) _Distance __m = 0; @@ -368,15 +377,17 @@ namespace __gnu_cxx * @ingroup SGIextensions * @doctodo */ - template<typename _InputIter, typename _RandomAccessIter> - inline _RandomAccessIter - random_sample(_InputIter __first, _InputIter __last, - _RandomAccessIter __out_first, _RandomAccessIter __out_last) + template<typename _InputIterator, typename _RandomAccessIterator> + inline _RandomAccessIterator + random_sample(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __out_first, _RandomAccessIterator __out_last) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< - _RandomAccessIter>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__out_first, __out_last); return __random_sample(__first, __last, __out_first, __out_last - __out_first); @@ -387,72 +398,41 @@ namespace __gnu_cxx * @ingroup SGIextensions * @doctodo */ - template<typename _InputIter, typename _RandomAccessIter, + template<typename _InputIterator, typename _RandomAccessIterator, typename _RandomNumberGenerator> - inline _RandomAccessIter - random_sample(_InputIter __first, _InputIter __last, - _RandomAccessIter __out_first, _RandomAccessIter __out_last, - _RandomNumberGenerator& __rand) + inline _RandomAccessIterator + random_sample(_InputIterator __first, _InputIterator __last, + _RandomAccessIterator __out_first, _RandomAccessIterator __out_last, + _RandomNumberGenerator& __rand) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< - _RandomAccessIter>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_valid_range(__out_first, __out_last); return __random_sample(__first, __last, __out_first, __rand, __out_last - __out_first); } - - // is_heap, a predicate testing whether or not a range is - // a heap. This function is an extension, not part of the C++ - // standard. - - template<typename _RandomAccessIter, typename _Distance> - bool - __is_heap(_RandomAccessIter __first, _Distance __n) - { - _Distance __parent = 0; - for (_Distance __child = 1; __child < __n; ++__child) { - if (__first[__parent] < __first[__child]) - return false; - if ((__child & 1) == 0) - ++__parent; - } - return true; - } - - template<typename _RandomAccessIter, typename _Distance, - typename _StrictWeakOrdering> - bool - __is_heap(_RandomAccessIter __first, _StrictWeakOrdering __comp, - _Distance __n) - { - _Distance __parent = 0; - for (_Distance __child = 1; __child < __n; ++__child) { - if (__comp(__first[__parent], __first[__child])) - return false; - if ((__child & 1) == 0) - ++__parent; - } - return true; - } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ - template<typename _RandomAccessIter> + template<typename _RandomAccessIterator> inline bool - is_heap(_RandomAccessIter __first, _RandomAccessIter __last) + is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements - __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIter>) - __glibcpp_function_requires(_LessThanComparableConcept< - typename iterator_traits<_RandomAccessIter>::value_type>) + __glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); - return __is_heap(__first, __last - __first); + return std::__is_heap(__first, __last - __first); } /** @@ -460,18 +440,19 @@ namespace __gnu_cxx * @ingroup SGIextensions * @doctodo */ - template<typename _RandomAccessIter, typename _StrictWeakOrdering> + template<typename _RandomAccessIterator, typename _StrictWeakOrdering> inline bool - is_heap(_RandomAccessIter __first, _RandomAccessIter __last, + is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _StrictWeakOrdering __comp) { // concept requirements - __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIter>) - __glibcpp_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, - typename iterator_traits<_RandomAccessIter>::value_type, - typename iterator_traits<_RandomAccessIter>::value_type>) + __glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, + typename iterator_traits<_RandomAccessIterator>::value_type, + typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); - return __is_heap(__first, __comp, __last - __first); + return std::__is_heap(__first, __comp, __last - __first); } // is_sorted, a predicated testing whether a range is sorted in @@ -483,19 +464,20 @@ namespace __gnu_cxx * @ingroup SGIextensions * @doctodo */ - template<typename _ForwardIter> + template<typename _ForwardIterator> bool - is_sorted(_ForwardIter __first, _ForwardIter __last) + is_sorted(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_LessThanComparableConcept< - typename iterator_traits<_ForwardIter>::value_type>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return true; - _ForwardIter __next = __first; + _ForwardIterator __next = __first; for (++__next; __next != __last; __first = __next, ++__next) { if (*__next < *__first) return false; @@ -509,20 +491,21 @@ namespace __gnu_cxx * @ingroup SGIextensions * @doctodo */ - template<typename _ForwardIter, typename _StrictWeakOrdering> + template<typename _ForwardIterator, typename _StrictWeakOrdering> bool - is_sorted(_ForwardIter __first, _ForwardIter __last, _StrictWeakOrdering __comp) + is_sorted(_ForwardIterator __first, _ForwardIterator __last, _StrictWeakOrdering __comp) { // concept requirements - __glibcpp_function_requires(_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, - typename iterator_traits<_ForwardIter>::value_type, - typename iterator_traits<_ForwardIter>::value_type>) + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return true; - _ForwardIter __next = __first; + _ForwardIterator __next = __first; for (++__next; __next != __last; __first = __next, ++__next) { if (__comp(*__next, *__first)) return false; @@ -530,7 +513,6 @@ namespace __gnu_cxx return true; } - } // namespace __gnu_cxx #endif /* _EXT_ALGORITHM */ diff --git a/contrib/libstdc++/include/ext/bitmap_allocator.h b/contrib/libstdc++/include/ext/bitmap_allocator.h new file mode 100644 index 000000000000..9a0d16209848 --- /dev/null +++ b/contrib/libstdc++/include/ext/bitmap_allocator.h @@ -0,0 +1,859 @@ +// Bitmapped Allocator. -*- C++ -*- + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + + + +#if !defined _BITMAP_ALLOCATOR_H +#define _BITMAP_ALLOCATOR_H 1 + +#include <cstddef> +//For std::size_t, and ptrdiff_t. +#include <utility> +//For std::pair. +#include <algorithm> +//std::find_if, and std::lower_bound. +#include <vector> +//For the free list of exponentially growing memory blocks. At max, +//size of the vector should be not more than the number of bits in an +//integer or an unsigned integer. +#include <functional> +//For greater_equal, and less_equal. +#include <new> +//For operator new. +#include <bits/gthr.h> +//For __gthread_mutex_t, __gthread_mutex_lock and __gthread_mutex_unlock. +#include <ext/new_allocator.h> +//For __gnu_cxx::new_allocator for std::vector. + +#include <cassert> +#define NDEBUG + +//#define CHECK_FOR_ERRORS +//#define __CPU_HAS_BACKWARD_BRANCH_PREDICTION + +namespace __gnu_cxx +{ + namespace { +#if defined __GTHREADS + bool const __threads_enabled = __gthread_active_p(); +#endif + + } + +#if defined __GTHREADS + class _Mutex { + __gthread_mutex_t _M_mut; + //Prevent Copying and assignment. + _Mutex (_Mutex const&); + _Mutex& operator= (_Mutex const&); + public: + _Mutex () + { + if (__threads_enabled) + { +#if !defined __GTHREAD_MUTEX_INIT + __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mut); +#else + __gthread_mutex_t __mtemp = __GTHREAD_MUTEX_INIT; + _M_mut = __mtemp; +#endif + } + } + ~_Mutex () + { + //Gthreads does not define a Mutex Destruction Function. + } + __gthread_mutex_t *_M_get() { return &_M_mut; } + }; + + class _Lock { + _Mutex* _M_pmt; + bool _M_locked; + //Prevent Copying and assignment. + _Lock (_Lock const&); + _Lock& operator= (_Lock const&); + public: + _Lock(_Mutex* __mptr) + : _M_pmt(__mptr), _M_locked(false) + { this->_M_lock(); } + void _M_lock() + { + if (__threads_enabled) + { + _M_locked = true; + __gthread_mutex_lock(_M_pmt->_M_get()); + } + } + void _M_unlock() + { + if (__threads_enabled) + { + if (__builtin_expect(_M_locked, true)) + { + __gthread_mutex_unlock(_M_pmt->_M_get()); + _M_locked = false; + } + } + } + ~_Lock() { this->_M_unlock(); } + }; +#endif + + + + namespace __aux_balloc { + static const unsigned int _Bits_Per_Byte = 8; + static const unsigned int _Bits_Per_Block = sizeof(unsigned int) * _Bits_Per_Byte; + + template <typename _Addr_Pair_t> + inline size_t __balloc_num_blocks (_Addr_Pair_t __ap) + { + return (__ap.second - __ap.first) + 1; + } + + template <typename _Addr_Pair_t> + inline size_t __balloc_num_bit_maps (_Addr_Pair_t __ap) + { + return __balloc_num_blocks(__ap) / _Bits_Per_Block; + } + + //T should be a pointer type. + template <typename _Tp> + class _Inclusive_between : public std::unary_function<typename std::pair<_Tp, _Tp>, bool> { + typedef _Tp pointer; + pointer _M_ptr_value; + typedef typename std::pair<_Tp, _Tp> _Block_pair; + + public: + _Inclusive_between (pointer __ptr) : _M_ptr_value(__ptr) { } + bool operator () (_Block_pair __bp) const throw () + { + if (std::less_equal<pointer> ()(_M_ptr_value, __bp.second) && + std::greater_equal<pointer> ()(_M_ptr_value, __bp.first)) + return true; + else + return false; + } + }; + + //Used to pass a Functor to functions by reference. + template <typename _Functor> + class _Functor_Ref : + public std::unary_function<typename _Functor::argument_type, typename _Functor::result_type> { + _Functor& _M_fref; + + public: + typedef typename _Functor::argument_type argument_type; + typedef typename _Functor::result_type result_type; + + _Functor_Ref (_Functor& __fref) : _M_fref(__fref) { } + result_type operator() (argument_type __arg) { return _M_fref (__arg); } + }; + + + //T should be a pointer type, and A is the Allocator for the vector. + template <typename _Tp, typename _Alloc> + class _Ffit_finder + : public std::unary_function<typename std::pair<_Tp, _Tp>, bool> { + typedef typename std::vector<std::pair<_Tp, _Tp>, _Alloc> _BPVector; + typedef typename _BPVector::difference_type _Counter_type; + typedef typename std::pair<_Tp, _Tp> _Block_pair; + + unsigned int *_M_pbitmap; + unsigned int _M_data_offset; + + public: + _Ffit_finder () + : _M_pbitmap (0), _M_data_offset (0) + { } + + bool operator() (_Block_pair __bp) throw() + { + //Set the _rover to the last unsigned integer, which is the + //bitmap to the first free block. Thus, the bitmaps are in exact + //reverse order of the actual memory layout. So, we count down + //the bimaps, which is the same as moving up the memory. + + //If the used count stored at the start of the Bit Map headers + //is equal to the number of Objects that the current Block can + //store, then there is definitely no space for another single + //object, so just return false. + _Counter_type __diff = __gnu_cxx::__aux_balloc::__balloc_num_bit_maps (__bp); + + assert (*(reinterpret_cast<unsigned int*>(__bp.first) - (__diff + 1)) <= + __gnu_cxx::__aux_balloc::__balloc_num_blocks (__bp)); + + if (*(reinterpret_cast<unsigned int*>(__bp.first) - (__diff + 1)) == + __gnu_cxx::__aux_balloc::__balloc_num_blocks (__bp)) + return false; + + unsigned int *__rover = reinterpret_cast<unsigned int*>(__bp.first) - 1; + for (_Counter_type __i = 0; __i < __diff; ++__i) + { + _M_data_offset = __i; + if (*__rover) + { + _M_pbitmap = __rover; + return true; + } + --__rover; + } + return false; + } + + unsigned int *_M_get () { return _M_pbitmap; } + unsigned int _M_offset () { return _M_data_offset * _Bits_Per_Block; } + }; + + //T should be a pointer type. + template <typename _Tp, typename _Alloc> + class _Bit_map_counter { + + typedef typename std::vector<std::pair<_Tp, _Tp>, _Alloc> _BPVector; + typedef typename _BPVector::size_type _Index_type; + typedef _Tp pointer; + + _BPVector& _M_vbp; + unsigned int *_M_curr_bmap; + unsigned int *_M_last_bmap_in_block; + _Index_type _M_curr_index; + + public: + //Use the 2nd parameter with care. Make sure that such an entry + //exists in the vector before passing that particular index to + //this ctor. + _Bit_map_counter (_BPVector& Rvbp, int __index = -1) + : _M_vbp(Rvbp) + { + this->_M_reset(__index); + } + + void _M_reset (int __index = -1) throw() + { + if (__index == -1) + { + _M_curr_bmap = 0; + _M_curr_index = (_Index_type)-1; + return; + } + + _M_curr_index = __index; + _M_curr_bmap = reinterpret_cast<unsigned int*>(_M_vbp[_M_curr_index].first) - 1; + + assert (__index <= (int)_M_vbp.size() - 1); + + _M_last_bmap_in_block = _M_curr_bmap - + ((_M_vbp[_M_curr_index].second - _M_vbp[_M_curr_index].first + 1) / _Bits_Per_Block - 1); + } + + //Dangerous Function! Use with extreme care. Pass to this + //function ONLY those values that are known to be correct, + //otherwise this will mess up big time. + void _M_set_internal_bit_map (unsigned int *__new_internal_marker) throw() + { + _M_curr_bmap = __new_internal_marker; + } + + bool _M_finished () const throw() + { + return (_M_curr_bmap == 0); + } + + _Bit_map_counter& operator++ () throw() + { + if (_M_curr_bmap == _M_last_bmap_in_block) + { + if (++_M_curr_index == _M_vbp.size()) + { + _M_curr_bmap = 0; + } + else + { + this->_M_reset (_M_curr_index); + } + } + else + { + --_M_curr_bmap; + } + return *this; + } + + unsigned int *_M_get () + { + return _M_curr_bmap; + } + + pointer _M_base () { return _M_vbp[_M_curr_index].first; } + unsigned int _M_offset () + { + return _Bits_Per_Block * ((reinterpret_cast<unsigned int*>(this->_M_base()) - _M_curr_bmap) - 1); + } + + unsigned int _M_where () { return _M_curr_index; } + }; + } + + //Generic Version of the bsf instruction. + typedef unsigned int _Bit_map_type; + static inline unsigned int _Bit_scan_forward (register _Bit_map_type __num) + { + return static_cast<unsigned int>(__builtin_ctz(__num)); + } + + struct _OOM_handler { + static std::new_handler _S_old_handler; + static bool _S_handled_oom; + typedef void (*_FL_clear_proc)(void); + static _FL_clear_proc _S_oom_fcp; + + _OOM_handler (_FL_clear_proc __fcp) + { + _S_oom_fcp = __fcp; + _S_old_handler = std::set_new_handler (_S_handle_oom_proc); + _S_handled_oom = false; + } + + static void _S_handle_oom_proc() + { + _S_oom_fcp(); + std::set_new_handler (_S_old_handler); + _S_handled_oom = true; + } + + ~_OOM_handler () + { + if (!_S_handled_oom) + std::set_new_handler (_S_old_handler); + } + }; + + std::new_handler _OOM_handler::_S_old_handler; + bool _OOM_handler::_S_handled_oom = false; + _OOM_handler::_FL_clear_proc _OOM_handler::_S_oom_fcp = 0; + + + class _BA_free_list_store { + struct _LT_pointer_compare { + template <typename _Tp> + bool operator() (_Tp* __pt, _Tp const& __crt) const throw() + { + return *__pt < __crt; + } + }; + +#if defined __GTHREADS + static _Mutex _S_bfl_mutex; +#endif + static std::vector<unsigned int*> _S_free_list; + typedef std::vector<unsigned int*>::iterator _FLIter; + + static void _S_validate_free_list(unsigned int *__addr) throw() + { + const unsigned int __max_size = 64; + if (_S_free_list.size() >= __max_size) + { + //Ok, the threshold value has been reached. + //We determine which block to remove from the list of free + //blocks. + if (*__addr >= *_S_free_list.back()) + { + //Ok, the new block is greater than or equal to the last + //block in the list of free blocks. We just free the new + //block. + operator delete((void*)__addr); + return; + } + else + { + //Deallocate the last block in the list of free lists, and + //insert the new one in it's correct position. + operator delete((void*)_S_free_list.back()); + _S_free_list.pop_back(); + } + } + + //Just add the block to the list of free lists + //unconditionally. + _FLIter __temp = std::lower_bound(_S_free_list.begin(), _S_free_list.end(), + *__addr, _LT_pointer_compare ()); + //We may insert the new free list before _temp; + _S_free_list.insert(__temp, __addr); + } + + static bool _S_should_i_give(unsigned int __block_size, unsigned int __required_size) throw() + { + const unsigned int __max_wastage_percentage = 36; + if (__block_size >= __required_size && + (((__block_size - __required_size) * 100 / __block_size) < __max_wastage_percentage)) + return true; + else + return false; + } + + public: + typedef _BA_free_list_store _BFL_type; + + static inline void _S_insert_free_list(unsigned int *__addr) throw() + { +#if defined __GTHREADS + _Lock __bfl_lock(&_S_bfl_mutex); +#endif + //Call _S_validate_free_list to decide what should be done with this + //particular free list. + _S_validate_free_list(--__addr); + } + + static unsigned int *_S_get_free_list(unsigned int __sz) throw (std::bad_alloc) + { +#if defined __GTHREADS + _Lock __bfl_lock(&_S_bfl_mutex); +#endif + _FLIter __temp = std::lower_bound(_S_free_list.begin(), _S_free_list.end(), + __sz, _LT_pointer_compare()); + if (__temp == _S_free_list.end() || !_S_should_i_give (**__temp, __sz)) + { + //We hold the lock because the OOM_Handler is a stateless + //entity. + _OOM_handler __set_handler(_BFL_type::_S_clear); + unsigned int *__ret_val = reinterpret_cast<unsigned int*> + (operator new (__sz + sizeof(unsigned int))); + *__ret_val = __sz; + return ++__ret_val; + } + else + { + unsigned int* __ret_val = *__temp; + _S_free_list.erase (__temp); + return ++__ret_val; + } + } + + //This function just clears the internal Free List, and gives back + //all the memory to the OS. + static void _S_clear() + { +#if defined __GTHREADS + _Lock __bfl_lock(&_S_bfl_mutex); +#endif + _FLIter __iter = _S_free_list.begin(); + while (__iter != _S_free_list.end()) + { + operator delete((void*)*__iter); + ++__iter; + } + _S_free_list.clear(); + } + + }; + +#if defined __GTHREADS + _Mutex _BA_free_list_store::_S_bfl_mutex; +#endif + std::vector<unsigned int*> _BA_free_list_store::_S_free_list; + + template <typename _Tp> class bitmap_allocator; + // specialize for void: + template <> class bitmap_allocator<void> { + public: + typedef void* pointer; + typedef const void* const_pointer; + // reference-to-void members are impossible. + typedef void value_type; + template <typename _Tp1> struct rebind { typedef bitmap_allocator<_Tp1> other; }; + }; + + template <typename _Tp> class bitmap_allocator : private _BA_free_list_store { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + template <typename _Tp1> struct rebind { typedef bitmap_allocator<_Tp1> other; }; + + private: + static const unsigned int _Bits_Per_Byte = 8; + static const unsigned int _Bits_Per_Block = sizeof(unsigned int) * _Bits_Per_Byte; + + static inline void _S_bit_allocate(unsigned int *__pbmap, unsigned int __pos) throw() + { + unsigned int __mask = 1 << __pos; + __mask = ~__mask; + *__pbmap &= __mask; + } + + static inline void _S_bit_free(unsigned int *__pbmap, unsigned int __pos) throw() + { + unsigned int __mask = 1 << __pos; + *__pbmap |= __mask; + } + + static inline void *_S_memory_get(size_t __sz) throw (std::bad_alloc) + { + return operator new(__sz); + } + + static inline void _S_memory_put(void *__vptr) throw () + { + operator delete(__vptr); + } + + typedef typename std::pair<pointer, pointer> _Block_pair; + typedef typename __gnu_cxx::new_allocator<_Block_pair> _BPVec_allocator_type; + typedef typename std::vector<_Block_pair, _BPVec_allocator_type> _BPVector; + + +#if defined CHECK_FOR_ERRORS + //Complexity: O(lg(N)). Where, N is the number of block of size + //sizeof(value_type). + static void _S_check_for_free_blocks() throw() + { + typedef typename __gnu_cxx::__aux_balloc::_Ffit_finder<pointer, _BPVec_allocator_type> _FFF; + _FFF __fff; + typedef typename _BPVector::iterator _BPiter; + _BPiter __bpi = std::find_if(_S_mem_blocks.begin(), _S_mem_blocks.end(), + __gnu_cxx::__aux_balloc::_Functor_Ref<_FFF>(__fff)); + assert(__bpi == _S_mem_blocks.end()); + } +#endif + + + //Complexity: O(1), but internally depends upon the complexity of + //the function _BA_free_list_store::_S_get_free_list. The part + //where the bitmap headers are written is of worst case complexity: + //O(X),where X is the number of blocks of size sizeof(value_type) + //within the newly acquired block. Having a tight bound. + static void _S_refill_pool() throw (std::bad_alloc) + { +#if defined CHECK_FOR_ERRORS + _S_check_for_free_blocks(); +#endif + + const unsigned int __num_bit_maps = _S_block_size / _Bits_Per_Block; + const unsigned int __size_to_allocate = sizeof(unsigned int) + + _S_block_size * sizeof(value_type) + __num_bit_maps*sizeof(unsigned int); + + unsigned int *__temp = + reinterpret_cast<unsigned int*>(_BA_free_list_store::_S_get_free_list(__size_to_allocate)); + *__temp = 0; + ++__temp; + + //The Header information goes at the Beginning of the Block. + _Block_pair __bp = std::make_pair(reinterpret_cast<pointer>(__temp + __num_bit_maps), + reinterpret_cast<pointer>(__temp + __num_bit_maps) + + _S_block_size - 1); + + //Fill the Vector with this information. + _S_mem_blocks.push_back(__bp); + + unsigned int __bit_mask = 0; //0 Indicates all Allocated. + __bit_mask = ~__bit_mask; //1 Indicates all Free. + + for (unsigned int __i = 0; __i < __num_bit_maps; ++__i) + __temp[__i] = __bit_mask; + + //On some implementations, operator new might throw bad_alloc, or + //malloc might fail if the size passed is too large, therefore, we + //limit the size passed to malloc or operator new. + _S_block_size *= 2; + } + + static _BPVector _S_mem_blocks; + static unsigned int _S_block_size; + static __gnu_cxx::__aux_balloc::_Bit_map_counter<pointer, _BPVec_allocator_type> _S_last_request; + static typename _BPVector::size_type _S_last_dealloc_index; +#if defined __GTHREADS + static _Mutex _S_mut; +#endif + + //Complexity: Worst case complexity is O(N), but that is hardly ever + //hit. if and when this particular case is encountered, the next few + //cases are guaranteed to have a worst case complexity of O(1)! + //That's why this function performs very well on the average. you + //can consider this function to be having a complexity refrred to + //commonly as: Amortized Constant time. + static pointer _S_allocate_single_object() + { +#if defined __GTHREADS + _Lock __bit_lock(&_S_mut); +#endif + + //The algorithm is something like this: The last_requst variable + //points to the last accessed Bit Map. When such a condition + //occurs, we try to find a free block in the current bitmap, or + //succeeding bitmaps until the last bitmap is reached. If no free + //block turns up, we resort to First Fit method. + + //WARNING: Do not re-order the condition in the while statement + //below, because it relies on C++'s short-circuit + //evaluation. The return from _S_last_request->_M_get() will NOT + //be dereferenceable if _S_last_request->_M_finished() returns + //true. This would inevitibly lead to a NULL pointer dereference + //if tinkered with. + while (_S_last_request._M_finished() == false && (*(_S_last_request._M_get()) == 0)) + { + _S_last_request.operator++(); + } + + if (__builtin_expect(_S_last_request._M_finished() == true, false)) + { + //Fall Back to First Fit algorithm. + typedef typename __gnu_cxx::__aux_balloc::_Ffit_finder<pointer, _BPVec_allocator_type> _FFF; + _FFF __fff; + typedef typename _BPVector::iterator _BPiter; + _BPiter __bpi = std::find_if(_S_mem_blocks.begin(), _S_mem_blocks.end(), + __gnu_cxx::__aux_balloc::_Functor_Ref<_FFF>(__fff)); + + if (__bpi != _S_mem_blocks.end()) + { + //Search was successful. Ok, now mark the first bit from + //the right as 0, meaning Allocated. This bit is obtained + //by calling _M_get() on __fff. + unsigned int __nz_bit = _Bit_scan_forward(*__fff._M_get()); + _S_bit_allocate(__fff._M_get(), __nz_bit); + + _S_last_request._M_reset(__bpi - _S_mem_blocks.begin()); + + //Now, get the address of the bit we marked as allocated. + pointer __ret_val = __bpi->first + __fff._M_offset() + __nz_bit; + unsigned int *__puse_count = reinterpret_cast<unsigned int*>(__bpi->first) - + (__gnu_cxx::__aux_balloc::__balloc_num_bit_maps(*__bpi) + 1); + ++(*__puse_count); + return __ret_val; + } + else + { + //Search was unsuccessful. We Add more memory to the pool + //by calling _S_refill_pool(). + _S_refill_pool(); + + //_M_Reset the _S_last_request structure to the first free + //block's bit map. + _S_last_request._M_reset(_S_mem_blocks.size() - 1); + + //Now, mark that bit as allocated. + } + } + //_S_last_request holds a pointer to a valid bit map, that points + //to a free block in memory. + unsigned int __nz_bit = _Bit_scan_forward(*_S_last_request._M_get()); + _S_bit_allocate(_S_last_request._M_get(), __nz_bit); + + pointer __ret_val = _S_last_request._M_base() + _S_last_request._M_offset() + __nz_bit; + + unsigned int *__puse_count = reinterpret_cast<unsigned int*> + (_S_mem_blocks[_S_last_request._M_where()].first) - + (__gnu_cxx::__aux_balloc::__balloc_num_bit_maps(_S_mem_blocks[_S_last_request._M_where()]) + 1); + ++(*__puse_count); + return __ret_val; + } + + //Complexity: O(lg(N)), but the worst case is hit quite often! I + //need to do something about this. I'll be able to work on it, only + //when I have some solid figures from a few real apps. + static void _S_deallocate_single_object(pointer __p) throw() + { +#if defined __GTHREADS + _Lock __bit_lock(&_S_mut); +#endif + + typedef typename _BPVector::iterator _Iterator; + typedef typename _BPVector::difference_type _Difference_type; + + _Difference_type __diff; + int __displacement; + + assert(_S_last_dealloc_index >= 0); + + if (__gnu_cxx::__aux_balloc::_Inclusive_between<pointer>(__p)(_S_mem_blocks[_S_last_dealloc_index])) + { + assert(_S_last_dealloc_index <= _S_mem_blocks.size() - 1); + + //Initial Assumption was correct! + __diff = _S_last_dealloc_index; + __displacement = __p - _S_mem_blocks[__diff].first; + } + else + { + _Iterator _iter = (std::find_if(_S_mem_blocks.begin(), _S_mem_blocks.end(), + __gnu_cxx::__aux_balloc::_Inclusive_between<pointer>(__p))); + assert(_iter != _S_mem_blocks.end()); + + __diff = _iter - _S_mem_blocks.begin(); + __displacement = __p - _S_mem_blocks[__diff].first; + _S_last_dealloc_index = __diff; + } + + //Get the position of the iterator that has been found. + const unsigned int __rotate = __displacement % _Bits_Per_Block; + unsigned int *__bit_mapC = reinterpret_cast<unsigned int*>(_S_mem_blocks[__diff].first) - 1; + __bit_mapC -= (__displacement / _Bits_Per_Block); + + _S_bit_free(__bit_mapC, __rotate); + unsigned int *__puse_count = reinterpret_cast<unsigned int*> + (_S_mem_blocks[__diff].first) - + (__gnu_cxx::__aux_balloc::__balloc_num_bit_maps(_S_mem_blocks[__diff]) + 1); + + assert(*__puse_count != 0); + + --(*__puse_count); + + if (__builtin_expect(*__puse_count == 0, false)) + { + _S_block_size /= 2; + + //We may safely remove this block. + _Block_pair __bp = _S_mem_blocks[__diff]; + _S_insert_free_list(__puse_count); + _S_mem_blocks.erase(_S_mem_blocks.begin() + __diff); + + //We reset the _S_last_request variable to reflect the erased + //block. We do this to protect future requests after the last + //block has been removed from a particular memory Chunk, + //which in turn has been returned to the free list, and + //hence had been erased from the vector, so the size of the + //vector gets reduced by 1. + if ((_Difference_type)_S_last_request._M_where() >= __diff--) + { + _S_last_request._M_reset(__diff); + // assert(__diff >= 0); + } + + //If the Index into the vector of the region of memory that + //might hold the next address that will be passed to + //deallocated may have been invalidated due to the above + //erase procedure being called on the vector, hence we try + //to restore this invariant too. + if (_S_last_dealloc_index >= _S_mem_blocks.size()) + { + _S_last_dealloc_index =(__diff != -1 ? __diff : 0); + assert(_S_last_dealloc_index >= 0); + } + } + } + + public: + bitmap_allocator() throw() + { } + + bitmap_allocator(const bitmap_allocator&) { } + + template <typename _Tp1> bitmap_allocator(const bitmap_allocator<_Tp1>&) throw() + { } + + ~bitmap_allocator() throw() + { } + + //Complexity: O(1), but internally the complexity depends upon the + //complexity of the function(s) _S_allocate_single_object and + //_S_memory_get. + pointer allocate(size_type __n) + { + if (__builtin_expect(__n == 1, true)) + return _S_allocate_single_object(); + else + return reinterpret_cast<pointer>(_S_memory_get(__n * sizeof(value_type))); + } + + //Complexity: Worst case complexity is O(N) where N is the number of + //blocks of size sizeof(value_type) within the free lists that the + //allocator holds. However, this worst case is hit only when the + //user supplies a bogus argument to hint. If the hint argument is + //sensible, then the complexity drops to O(lg(N)), and in extreme + //cases, even drops to as low as O(1). So, if the user supplied + //argument is good, then this function performs very well. + pointer allocate(size_type __n, typename bitmap_allocator<void>::const_pointer) + { + return allocate(__n); + } + + void deallocate(pointer __p, size_type __n) throw() + { + if (__builtin_expect(__n == 1, true)) + _S_deallocate_single_object(__p); + else + _S_memory_put(__p); + } + + pointer address(reference r) const { return &r; } + const_pointer address(const_reference r) const { return &r; } + + size_type max_size(void) const throw() { return (size_type()-1)/sizeof(value_type); } + + void construct (pointer p, const_reference __data) + { + ::new(p) value_type(__data); + } + + void destroy (pointer p) + { + p->~value_type(); + } + + }; + + template <typename _Tp> + typename bitmap_allocator<_Tp>::_BPVector bitmap_allocator<_Tp>::_S_mem_blocks; + + template <typename _Tp> + unsigned int bitmap_allocator<_Tp>::_S_block_size = bitmap_allocator<_Tp>::_Bits_Per_Block; + + template <typename _Tp> + typename __gnu_cxx::bitmap_allocator<_Tp>::_BPVector::size_type + bitmap_allocator<_Tp>::_S_last_dealloc_index = 0; + + template <typename _Tp> + __gnu_cxx::__aux_balloc::_Bit_map_counter + <typename bitmap_allocator<_Tp>::pointer, typename bitmap_allocator<_Tp>::_BPVec_allocator_type> + bitmap_allocator<_Tp>::_S_last_request(_S_mem_blocks); + +#if defined __GTHREADS + template <typename _Tp> + __gnu_cxx::_Mutex + bitmap_allocator<_Tp>::_S_mut; +#endif + + template <typename _Tp1, typename _Tp2> + bool operator== (const bitmap_allocator<_Tp1>&, const bitmap_allocator<_Tp2>&) throw() + { + return true; + } + + template <typename _Tp1, typename _Tp2> + bool operator!= (const bitmap_allocator<_Tp1>&, const bitmap_allocator<_Tp2>&) throw() + { + return false; + } +} + + +#endif //_BITMAP_ALLOCATOR_H diff --git a/contrib/libstdc++/include/ext/debug_allocator.h b/contrib/libstdc++/include/ext/debug_allocator.h new file mode 100644 index 000000000000..7ea6fb42f980 --- /dev/null +++ b/contrib/libstdc++/include/ext/debug_allocator.h @@ -0,0 +1,121 @@ +// Allocators -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/debug_allocator.h + * This file is a GNU extension to the Standard C++ Library. + * You should only include this header if you are using GCC 3 or later. + */ + +#ifndef _DEBUG_ALLOCATOR_H +#define _DEBUG_ALLOCATOR_H 1 + +#include <cstdlib> + +namespace __gnu_cxx +{ + /** + * @brief A meta-allocator with debugging bits, as per [20.4]. + * + * This is precisely the allocator defined in the C++ Standard. + * - all allocation calls operator new + * - all deallocation calls operator delete + * + * (See @link Allocators allocators info @endlink for more.) + */ + template<typename _Alloc> + class debug_allocator + { + public: + typedef typename _Alloc::size_type size_type; + typedef typename _Alloc::difference_type difference_type; + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Alloc::value_type value_type; + + private: + // _M_extra is the number of objects that correspond to the + // extra space where debug information is stored. + size_type _M_extra; + + _Alloc _M_allocator; + + public: + debug_allocator() + { + const size_t __obj_size = sizeof(value_type); + _M_extra = (sizeof(size_type) + __obj_size - 1) / __obj_size; + } + + pointer + allocate(size_type __n) + { + pointer __res = _M_allocator.allocate(__n + _M_extra); + size_type* __ps = reinterpret_cast<size_type*>(__res); + *__ps = __n; + return __res + _M_extra; + } + + pointer + allocate(size_type __n, const void* __hint) + { + pointer __res = _M_allocator.allocate(__n + _M_extra, __hint); + size_type* __ps = reinterpret_cast<size_type*>(__res); + *__ps = __n; + return __res + _M_extra; + } + + void + deallocate(pointer __p, size_type __n) + { + if (!__p) + abort(); + pointer __real_p = __p - _M_extra; + if (*reinterpret_cast<size_type*>(__real_p) != __n) + abort(); + _M_allocator.deallocate(__real_p, __n + _M_extra); + } + }; +} // namespace __gnu_cxx + +#endif diff --git a/contrib/libstdc++/include/ext/demangle.h b/contrib/libstdc++/include/ext/demangle.h new file mode 100644 index 000000000000..5de4f04a2246 --- /dev/null +++ b/contrib/libstdc++/include/ext/demangle.h @@ -0,0 +1,2789 @@ +// C++ IA64 / g++ v3 demangler -*- C++ -*- + +// Copyright (C) 2003, 2004 Free Software Foundation, Inc. +// Written by Carlo Wood <carlo@alinoe.com> +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// This file implements demangling of "C++ ABI for Itanium"-mangled symbol +// and type names as described in Revision 1.73 of the C++ ABI as can be found +// at http://www.codesourcery.com/cxx-abi/abi.html#mangling + +#ifndef _DEMANGLER_H +#define _DEMANGLER_H 1 + +#include <vector> +#include <string> +#include <ext/new_allocator.h> + +#ifndef _GLIBCXX_DEMANGLER_DEBUG +#define _GLIBCXX_DEMANGLER_CWDEBUG 0 +#define _GLIBCXX_DEMANGLER_DEBUG(x) +#define _GLIBCXX_DEMANGLER_DOUT(cntrl, data) +#define _GLIBCXX_DEMANGLER_DOUT_ENTERING(x) +#define _GLIBCXX_DEMANGLER_DOUT_ENTERING2(x) +#define _GLIBCXX_DEMANGLER_DOUT_ENTERING3(x) +#define _GLIBCXX_DEMANGLER_RETURN return M_result +#define _GLIBCXX_DEMANGLER_RETURN2 return M_result +#define _GLIBCXX_DEMANGLER_RETURN3 +#define _GLIBCXX_DEMANGLER_FAILURE \ + do { M_result = false; return false; } while(0) +#else +#define _GLIBCXX_DEMANGLER_CWDEBUG 1 +#endif + +namespace __gnu_cxx +{ + namespace demangler + { + enum substitution_nt + { + type, + template_template_param, + nested_name_prefix, + nested_name_template_prefix, + unscoped_template_name + }; + + struct substitution_st + { + int M_start_pos; + substitution_nt M_type; + int M_number_of_prefixes; + + substitution_st(int start_pos, + substitution_nt type, + int number_of_prefixes) + : M_start_pos(start_pos), M_type(type), + M_number_of_prefixes(number_of_prefixes) + { } + }; + + enum simple_qualifier_nt + { + complex_or_imaginary = 'G', + pointer = 'P', + reference = 'R' + }; + + enum cv_qualifier_nt + { + cv_qualifier = 'K' + }; + + enum param_qualifier_nt + { + vendor_extension = 'U', + array = 'A', + pointer_to_member = 'M' + }; + + template<typename Tp, typename Allocator = __gnu_cxx::new_allocator<Tp> > + class qualifier; + + template<typename Tp, typename Allocator = __gnu_cxx::new_allocator<Tp> > + class qualifier_list; + + template<typename Tp, typename Allocator = __gnu_cxx::new_allocator<Tp> > + class session; + + template<typename Tp, typename Allocator> + class qualifier + { + typedef typename Allocator::template rebind<char>::other + char_Allocator; + typedef std::basic_string<char, std::char_traits<char>, char_Allocator> + string_type; + + private: + char M_qualifier1; + char M_qualifier2; + char M_qualifier3; + mutable unsigned char M_cnt; + string_type M_optional_type; + int M_start_pos; + bool M_part_of_substitution; + + public: + qualifier(int start_pos, + simple_qualifier_nt simple_qualifier, + int inside_substitution) + : M_qualifier1(simple_qualifier), + M_start_pos(start_pos), + M_part_of_substitution(inside_substitution) + { } + + qualifier(int start_pos, + cv_qualifier_nt, + char const* start, + int count, + int inside_substitution) + : M_qualifier1(start[0]), + M_qualifier2((count > 1) ? start[1] : '\0'), + M_qualifier3((count > 2) ? start[2] : '\0'), + M_start_pos(start_pos), + M_part_of_substitution(inside_substitution) + { } + + qualifier(int start_pos, + param_qualifier_nt param_qualifier, + string_type optional_type, + int inside_substitution) + : M_qualifier1(param_qualifier), + M_optional_type(optional_type), + M_start_pos(start_pos), + M_part_of_substitution(inside_substitution) + { } + + int + get_start_pos(void) const + { return M_start_pos; } + + char + first_qualifier(void) const + { M_cnt = 1; return M_qualifier1; } + + char + next_qualifier(void) const + { + return (++M_cnt == 2) ? M_qualifier2 + : ((M_cnt == 3) ? M_qualifier3 : 0); + } + + string_type const& + get_optional_type(void) const + { return M_optional_type; } + + bool + part_of_substitution(void) const + { return M_part_of_substitution; } + +#if _GLIBCXX_DEMANGLER_CWDEBUG + friend std::ostream& operator<<(std::ostream& os, qualifier const& qual) + { + os << (char)qual.M_qualifier1; + if (qual.M_qualifier1 == vendor_extension || + qual.M_qualifier1 == array || + qual.M_qualifier1 == pointer_to_member) + os << " [" << qual.M_optional_type << ']'; + else if (qual.M_qualifier1 == 'K' || + qual.M_qualifier1 == 'V' || + qual.M_qualifier1 == 'r') + { + if (qual.M_qualifier2) + { + os << (char)qual.M_qualifier2; + if (qual.M_qualifier3) + os << (char)qual.M_qualifier3; + } + } + return os; + } +#endif + }; + + template<typename Tp, typename Allocator> + class qualifier_list + { + typedef typename Allocator::template rebind<char>::other + char_Allocator; + typedef std::basic_string<char, std::char_traits<char>, char_Allocator> + string_type; + + private: + mutable bool M_printing_suppressed; + typedef qualifier<Tp, Allocator> qual; + typedef typename Allocator::template rebind<qual>::other qual_Allocator; + typedef std::vector<qual, qual_Allocator> qual_vector; + qual_vector M_qualifier_starts; + session<Tp, Allocator>& M_demangler; + + void decode_KVrA(string_type& prefix, string_type& postfix, int cvq, + typename qual_vector:: + const_reverse_iterator const& iter_array) const; + + public: + qualifier_list(session<Tp, Allocator>& demangler_obj) + : M_printing_suppressed(false), M_demangler(demangler_obj) + { } + + void + add_qualifier_start(simple_qualifier_nt simple_qualifier, + int start_pos, + int inside_substitution) + { M_qualifier_starts. + push_back(qualifier<Tp, Allocator>(start_pos, + simple_qualifier, inside_substitution)); } + + void + add_qualifier_start(cv_qualifier_nt cv_qualifier, + int start_pos, + int count, + int inside_substitution) + { M_qualifier_starts. + push_back(qualifier<Tp, Allocator>(start_pos, + cv_qualifier, &M_demangler.M_str[start_pos], + count, inside_substitution)); } + + void + add_qualifier_start(param_qualifier_nt param_qualifier, + int start_pos, + string_type optional_type, + int inside_substitution) + { M_qualifier_starts. + push_back(qualifier<Tp, Allocator>(start_pos, + param_qualifier, optional_type, inside_substitution)); } + + void + decode_qualifiers(string_type& prefix, + string_type& postfix, + bool member_function_pointer_qualifiers) const; + + bool + suppressed(void) const + { return M_printing_suppressed; } + + void + printing_suppressed(void) + { M_printing_suppressed = true; } + + size_t + size(void) const + { return M_qualifier_starts.size(); } + +#if _GLIBCXX_DEMANGLER_CWDEBUG + friend std::ostream& operator<<(std::ostream& os, qualifier_list const& list) + { + typename qual_vector::const_iterator + iter = list.M_qualifier_starts.begin(); + if (iter != list.M_qualifier_starts.end()) + { + os << "{ " << *iter; + while (++iter != list.M_qualifier_starts.end()) + os << ", " << *iter; + os << " }"; + } + else + os << "{ }"; + return os; + } +#endif + }; + + struct implementation_details + { + private: + unsigned int M_style; + + public: + // The following flags change the behaviour of the demangler. The + // default behaviour is that none of these flags is set. + + static unsigned int const style_void = 1; + // Default behaviour: int f() + // Use (void) instead of (): int f(void) + + static unsigned int const style_literal = 2; + // Default behaviour: (long)13, + // (unsigned long long)19 + // Use extensions 'u', 'l' and 'll' for integral + // literals (as in template arguments): 13l, 19ull + + static unsigned int const style_literal_int = 4; + // Default behaviour: 4 + // Use also an explicit + // cast for int in literals: (int)4 + + static unsigned int const style_compact_expr_ops = 8; + // Default behaviour: (i) < (3), sizeof (int) + // Don't output spaces around + // operators in expressions: (i)<(3), sizeof(int) + + static unsigned int const style_sizeof_typename = 16; + // Default behaviour: sizeof (X::t) + // Put 'typename' infront of <nested-name> + // types inside a 'sizeof': sizeof (typename X::t) + + public: + implementation_details(unsigned int style_flags = 0) : + M_style(style_flags) { } + virtual ~implementation_details() { } + bool get_style_void(void) const + { return (M_style & style_void); } + bool get_style_literal(void) const + { return (M_style & style_literal); } + bool get_style_literal_int(void) const + { return (M_style & style_literal_int); } + bool get_style_compact_expr_ops(void) const + { return (M_style & style_compact_expr_ops); } + bool get_style_sizeof_typename(void) const + { return (M_style & style_sizeof_typename); } + // This can be overridden by user implementations. + virtual bool decode_real(char* /* output */, unsigned long* /* input */, + size_t /* size_of_real */) const + { return false; } + }; + + template<typename Tp, typename Allocator> + class session + { + public: + friend class qualifier_list<Tp, Allocator>; + typedef typename Allocator::template rebind<char>::other + char_Allocator; + typedef std::basic_string<char, std::char_traits<char>, char_Allocator> + string_type; + + private: + char const* M_str; + int M_pos; + int M_maxpos; + bool M_result; + int M_inside_template_args; + int M_inside_type; + int M_inside_substitution; + bool M_saw_destructor; + bool M_name_is_cdtor; + bool M_name_is_template; + bool M_name_is_conversion_operator; + bool M_template_args_need_space; + string_type M_function_name; + typedef typename Allocator::template rebind<int>::other + int_Allocator; + typedef typename Allocator::template rebind<substitution_st>::other + subst_Allocator; + std::vector<int, int_Allocator> M_template_arg_pos; + int M_template_arg_pos_offset; + std::vector<substitution_st, subst_Allocator> M_substitutions_pos; + implementation_details const& M_implementation_details; + typedef typename Allocator::template + rebind<qualifier_list<Allocator> >::other qualifier_list_Allocator; + qualifier_list_Allocator M_qualifier_list_alloc; +#if _GLIBCXX_DEMANGLER_CWDEBUG + bool M_inside_add_substitution; +#endif + + public: + explicit session(char const* in, int len, + implementation_details const& id = implementation_details()) + : M_str(in), M_pos(0), M_maxpos(len - 1), M_result(true), + M_inside_template_args(0), M_inside_type(0), + M_inside_substitution(0), M_saw_destructor(false), + M_name_is_cdtor(false), M_name_is_template(false), + M_name_is_conversion_operator(false), + M_template_args_need_space(false), M_template_arg_pos_offset(0), + M_implementation_details(id) +#if _GLIBCXX_DEMANGLER_CWDEBUG + , M_inside_add_substitution(false) +#endif + { } + + static int + decode_encoding(string_type& output, char const* input, int len, + implementation_details const& id = implementation_details()); + + bool + decode_type(string_type& output, + qualifier_list<Tp, Allocator>* qualifiers = NULL) + { + string_type postfix; + bool res = decode_type_with_postfix(output, postfix, qualifiers); + output += postfix; + return res; + } + + bool + remaining_input_characters(void) const + { return current() != 0; } + + private: + char + current(void) const + { return (M_pos > M_maxpos) ? 0 : M_str[M_pos]; } + + char + next_peek(void) const + { return (M_pos >= M_maxpos) ? 0 : M_str[M_pos + 1]; } + + char + next(void) + { return (M_pos >= M_maxpos) ? 0 : M_str[++M_pos]; } + + char + eat_current(void) + { return (M_pos > M_maxpos) ? 0 : M_str[M_pos++]; } + + void + store(int& saved_pos) + { saved_pos = M_pos; } + + void + restore(int saved_pos) + { M_pos = saved_pos; M_result = true; } + + void + add_substitution(int start_pos, + substitution_nt sub_type, + int number_of_prefixes); + + bool decode_type_with_postfix(string_type& prefix, + string_type& postfix, qualifier_list<Tp, Allocator>* qualifiers = NULL); + bool decode_bare_function_type(string_type& output); + bool decode_builtin_type(string_type& output); + bool decode_call_offset(string_type& output); + bool decode_class_enum_type(string_type& output); + bool decode_expression(string_type& output); + bool decode_literal(string_type& output); + bool decode_local_name(string_type& output); + bool decode_name(string_type& output, + string_type& nested_name_qualifiers); + bool decode_nested_name(string_type& output, + string_type& qualifiers); + bool decode_number(string_type& output); + bool decode_operator_name(string_type& output); + bool decode_source_name(string_type& output); + bool decode_substitution(string_type& output, + qualifier_list<Tp, Allocator>* qualifiers = NULL); + bool decode_template_args(string_type& output); + bool decode_template_param(string_type& output, + qualifier_list<Tp, Allocator>* qualifiers = NULL); + bool decode_unqualified_name(string_type& output); + bool decode_unscoped_name(string_type& output); + bool decode_non_negative_decimal_integer(string_type& output); + bool decode_special_name(string_type& output); + bool decode_real(string_type& output, size_t size_of_real); + }; + + template<typename Tp, typename Allocator> +#if !_GLIBCXX_DEMANGLER_CWDEBUG + inline +#endif + void + session<Tp, Allocator>::add_substitution(int start_pos, + substitution_nt sub_type, + int number_of_prefixes = 0) + { + if (!M_inside_substitution) + { +#if _GLIBCXX_DEMANGLER_CWDEBUG + if (M_inside_add_substitution) + return; +#endif + M_substitutions_pos. + push_back(substitution_st(start_pos, + sub_type, number_of_prefixes)); +#if _GLIBCXX_DEMANGLER_CWDEBUG + if (!DEBUGCHANNELS::dc::demangler.is_on()) + return; + string_type substitution_name("S"); + int n = M_substitutions_pos.size() - 1; + if (n > 0) + substitution_name += (n <= 10) ? (char)(n + '0' - 1) + : (char)(n + 'A' - 11); + substitution_name += '_'; + string_type subst; + int saved_pos = M_pos; + M_pos = start_pos; + M_inside_add_substitution = true; + _GLIBCXX_DEMANGLER_DEBUG( dc::demangler.off() ); + switch(sub_type) + { + case type: + decode_type(subst); + break; + case template_template_param: + decode_template_param(subst); + break; + case nested_name_prefix: + case nested_name_template_prefix: + for (int cnt = number_of_prefixes; cnt > 0; --cnt) + { + if (current() == 'I') + { + subst += ' '; + decode_template_args(subst); + } + else + { + if (cnt < number_of_prefixes) + subst += "::"; + if (current() == 'S') + decode_substitution(subst); + else if (current() == 'T') + decode_template_param(subst); + else + decode_unqualified_name(subst); + } + } + break; + case unscoped_template_name: + decode_unscoped_name(subst); + break; + } + M_pos = saved_pos; + _GLIBCXX_DEMANGLER_DEBUG( dc::demangler.on() ); + _GLIBCXX_DEMANGLER_DOUT(dc::demangler, + "Adding substitution " << substitution_name + << " : " << subst + << " (from " << location_ct((char*)__builtin_return_address(0) + + builtin_return_address_offset) + << " <- " << location_ct((char*)__builtin_return_address(1) + + builtin_return_address_offset) + << " <- " << location_ct((char*)__builtin_return_address(2) + + builtin_return_address_offset) + << ")."); + M_inside_add_substitution = false; +#endif + } + } + + // We don't want to depend on locale (or include <cctype> for that matter). + // We also don't want to use "safe-ctype.h" because that headerfile is not + // available to the users. + inline bool isdigit(char c) { return c >= '0' && c <= '9'; } + inline bool islower(char c) { return c >= 'a' && c <= 'z'; } + inline bool isupper(char c) { return c >= 'A' && c <= 'Z'; } + inline char tolower(char c) { return isupper(c) ? c - 'A' + 'a' : c; } + + // + // <non-negative decimal integer> ::= 0 + // ::= 1|2|3|4|5|6|7|8|9 [<digit>+] + // <digit> ::= 0|1|2|3|4|5|6|7|8|9 + // + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>:: + decode_non_negative_decimal_integer(string_type& output) + { + char c = current(); + if (c == '0') + { + output += '0'; + eat_current(); + } + else if (!isdigit(c)) + M_result = false; + else + { + do + { + output += c; + } + while (isdigit((c = next()))); + } + return M_result; + } + + // <number> ::= [n] <non-negative decimal integer> + // + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_number(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_number"); + if (current() != 'n') + decode_non_negative_decimal_integer(output); + else + { + output += '-'; + eat_current(); + decode_non_negative_decimal_integer(output); + } + _GLIBCXX_DEMANGLER_RETURN; + } + + // <builtin-type> ::= v # void + // ::= w # wchar_t + // ::= b # bool + // ::= c # char + // ::= a # signed char + // ::= h # unsigned char + // ::= s # short + // ::= t # unsigned short + // ::= i # int + // ::= j # unsigned int + // ::= l # long + // ::= m # unsigned long + // ::= x # long long, __int64 + // ::= y # unsigned long long, __int64 + // ::= n # __int128 + // ::= o # unsigned __int128 + // ::= f # float + // ::= d # double + // ::= e # long double, __float80 + // ::= g # __float128 + // ::= z # ellipsis + // ::= u <source-name> # vendor extended type + // + char const* const builtin_type_c[26] = + { + "signed char", // a + "bool", // b + "char", // c + "double", // d + "long double", // e + "float", // f + "__float128", // g + "unsigned char", // h + "int", // i + "unsigned int", // j + NULL, // k + "long", // l + "unsigned long", // m + "__int128", // n + "unsigned __int128", // o + NULL, // p + NULL, // q + NULL, // r + "short", // s + "unsigned short", // t + NULL, // u + "void", // v + "wchar_t", // w + "long long", // x + "unsigned long long", // y + "..." // z + }; + + // + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_builtin_type(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_builtin_type"); + char const* bt; + if (!islower(current()) || !(bt = builtin_type_c[current() - 'a'])) + _GLIBCXX_DEMANGLER_FAILURE; + output += bt; + eat_current(); + _GLIBCXX_DEMANGLER_RETURN; + } + + // <class-enum-type> ::= <name> + // + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_class_enum_type(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_class_enum_type"); + string_type nested_name_qualifiers; + if (!decode_name(output, nested_name_qualifiers)) + _GLIBCXX_DEMANGLER_FAILURE; + output += nested_name_qualifiers; + _GLIBCXX_DEMANGLER_RETURN; + } + + // <substitution> ::= + // S <seq-id> _ + // S_ + // St # ::std:: + // Sa # ::std::allocator + // Sb # ::std::basic_string + // Ss # ::std::basic_string<char, std::char_traits<char>, + // std::allocator<char> > + // Si # ::std::basic_istream<char, std::char_traits<char> > + // So # ::std::basic_ostream<char, std::char_traits<char> > + // Sd # ::std::basic_iostream<char, std::char_traits<char> > + // + // <seq-id> ::= + // 0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z + // [<seq-id>] # Base 36 number + // + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_substitution(string_type& output, + qualifier_list<Tp, Allocator>* qualifiers) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_substitution"); + unsigned int value = 0; + char c = next(); + if (c != '_') + { + switch(c) + { + case 'a': + { + output += "std::allocator"; + if (!M_inside_template_args) + { + M_function_name = "allocator"; + M_name_is_template = true; + M_name_is_cdtor = false; + M_name_is_conversion_operator = false; + } + eat_current(); + if (qualifiers) + qualifiers->printing_suppressed(); + _GLIBCXX_DEMANGLER_RETURN; + } + case 'b': + { + output += "std::basic_string"; + if (!M_inside_template_args) + { + M_function_name = "basic_string"; + M_name_is_template = true; + M_name_is_cdtor = false; + M_name_is_conversion_operator = false; + } + eat_current(); + if (qualifiers) + qualifiers->printing_suppressed(); + _GLIBCXX_DEMANGLER_RETURN; + } + case 'd': + output += "std::iostream"; + if (!M_inside_template_args) + { + M_function_name = "iostream"; + M_name_is_template = true; + M_name_is_cdtor = false; + M_name_is_conversion_operator = false; + } + eat_current(); + if (qualifiers) + qualifiers->printing_suppressed(); + _GLIBCXX_DEMANGLER_RETURN; + case 'i': + output += "std::istream"; + if (!M_inside_template_args) + { + M_function_name = "istream"; + M_name_is_template = true; + M_name_is_cdtor = false; + M_name_is_conversion_operator = false; + } + eat_current(); + if (qualifiers) + qualifiers->printing_suppressed(); + _GLIBCXX_DEMANGLER_RETURN; + case 'o': + output += "std::ostream"; + if (!M_inside_template_args) + { + M_function_name = "ostream"; + M_name_is_template = true; + M_name_is_cdtor = false; + M_name_is_conversion_operator = false; + } + eat_current(); + if (qualifiers) + qualifiers->printing_suppressed(); + _GLIBCXX_DEMANGLER_RETURN; + case 's': + output += "std::string"; + if (!M_inside_template_args) + { + M_function_name = "string"; + M_name_is_template = true; + M_name_is_cdtor = false; + M_name_is_conversion_operator = false; + } + eat_current(); + if (qualifiers) + qualifiers->printing_suppressed(); + _GLIBCXX_DEMANGLER_RETURN; + case 't': + output += "std"; + eat_current(); + if (qualifiers) + qualifiers->printing_suppressed(); + _GLIBCXX_DEMANGLER_RETURN; + default: + for(;; c = next()) + { + if (isdigit(c)) + value = value * 36 + c - '0'; + else if (isupper(c)) + value = value * 36 + c - 'A' + 10; + else if (c == '_') + break; + else + _GLIBCXX_DEMANGLER_FAILURE; + } + ++value; + break; + } + } + eat_current(); + if (value >= M_substitutions_pos.size() || + M_inside_type > 20) // Rather than core dump. + _GLIBCXX_DEMANGLER_FAILURE; + ++M_inside_substitution; + int saved_pos = M_pos; + substitution_st& substitution(M_substitutions_pos[value]); + M_pos = substitution.M_start_pos; + switch(substitution.M_type) + { + case type: + decode_type(output, qualifiers); + break; + case template_template_param: + decode_template_param(output, qualifiers); + break; + case nested_name_prefix: + case nested_name_template_prefix: + for (int cnt = substitution.M_number_of_prefixes; cnt > 0; --cnt) + { + if (current() == 'I') + { + if (M_template_args_need_space) + output += ' '; + M_template_args_need_space = false; + if (!decode_template_args(output)) + _GLIBCXX_DEMANGLER_FAILURE; + } + else + { + if (cnt < substitution.M_number_of_prefixes) + output += "::"; + if (current() == 'S') + { + if (!decode_substitution(output)) + _GLIBCXX_DEMANGLER_FAILURE; + } + else if (!decode_unqualified_name(output)) + _GLIBCXX_DEMANGLER_FAILURE; + } + } + if (qualifiers) + qualifiers->printing_suppressed(); + break; + case unscoped_template_name: + decode_unscoped_name(output); + if (qualifiers) + qualifiers->printing_suppressed(); + break; + } + M_pos = saved_pos; + --M_inside_substitution; + _GLIBCXX_DEMANGLER_RETURN; + } + + // <template-param> ::= T_ # first template parameter + // ::= T <parameter-2 non-negative number> _ + // + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_template_param(string_type& output, + qualifier_list<Tp, Allocator>* qualifiers) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_template_parameter"); + if (current() != 'T') + _GLIBCXX_DEMANGLER_FAILURE; + unsigned int value = 0; + char c; + if ((c = next()) != '_') + { + while(isdigit(c)) + { + value = value * 10 + c - '0'; + c = next(); + } + ++value; + } + if (eat_current() != '_') + _GLIBCXX_DEMANGLER_FAILURE; + value += M_template_arg_pos_offset; + if (value >= M_template_arg_pos.size()) + _GLIBCXX_DEMANGLER_FAILURE; + int saved_pos = M_pos; + M_pos = M_template_arg_pos[value]; + if (M_inside_type > 20) // Rather than core dump. + _GLIBCXX_DEMANGLER_FAILURE; + ++M_inside_substitution; + if (current() == 'X') + { + eat_current(); + decode_expression(output); + } + else if (current() == 'L') + decode_literal(output); + else + decode_type(output, qualifiers); + --M_inside_substitution; + M_pos = saved_pos; + _GLIBCXX_DEMANGLER_RETURN; + } + + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_real(string_type& output, size_t size_of_real) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_real"); + + unsigned long words[4]; // 32 bit per long, maximum of 128 bits. + unsigned long* word = &words[0]; + + int saved_pos; + store(saved_pos); + + // The following assumes that leading zeroes are also included in the + // mangled name, I am not sure that is conforming to the C++-ABI, but + // it is what g++ does. + unsigned char nibble, c = current(); + for(size_t word_cnt = size_of_real / 4; word_cnt > 0; --word_cnt) + { + for (int nibble_cnt = 0; nibble_cnt < 8; ++nibble_cnt) + { + // Translate character into nibble. + if (c < '0' || c > 'f') + _GLIBCXX_DEMANGLER_FAILURE; + if (c <= '9') + nibble = c - '0'; + else if (c >= 'a') + nibble = c - 'a' + 10; + else + _GLIBCXX_DEMANGLER_FAILURE; + // Write nibble into word array. + if (nibble_cnt == 0) + *word = nibble << 28; + else + *word |= (nibble << (28 - 4 * nibble_cnt)); + c = next(); + } + ++word; + } + char buf[24]; + if (M_implementation_details.decode_real(buf, words, size_of_real)) + { + output += buf; + _GLIBCXX_DEMANGLER_RETURN; + } + restore(saved_pos); + + output += '['; + c = current(); + for(size_t nibble_cnt = 0; nibble_cnt < 2 * size_of_real; ++nibble_cnt) + { + if (c < '0' || c > 'f' || (c > '9' && c < 'a')) + _GLIBCXX_DEMANGLER_FAILURE; + output += c; + c = next(); + } + output += ']'; + + _GLIBCXX_DEMANGLER_RETURN; + } + + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_literal(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_literal"); + eat_current(); // Eat the 'L'. + if (current() == '_') + { + if (next() != 'Z') + _GLIBCXX_DEMANGLER_FAILURE; + eat_current(); + if ((M_pos += decode_encoding(output, M_str + M_pos, + M_maxpos - M_pos + 1, M_implementation_details)) < 0) + _GLIBCXX_DEMANGLER_FAILURE; + } + else + { + // Special cases + if (current() == 'b') + { + if (next() == '0') + output += "false"; + else + output += "true"; + eat_current(); + _GLIBCXX_DEMANGLER_RETURN; + } + char c = current(); + if ((c == 'i' || c == 'j' || c == 'l' || + c == 'm' || c == 'x' || c == 'y') && + M_implementation_details.get_style_literal()) + eat_current(); + else if (c == 'i' && + !M_implementation_details.get_style_literal_int()) + eat_current(); + else + { + output += '('; + if (!decode_type(output)) + _GLIBCXX_DEMANGLER_FAILURE; + output += ')'; + } + if (c >= 'd' && c <= 'g') + { + size_t size_of_real = (c == 'd') ? sizeof(double) : + ((c == 'f') ? sizeof(float) : + (c == 'e') ? sizeof(long double) : 16); + if (!decode_real(output, size_of_real)) + _GLIBCXX_DEMANGLER_FAILURE; + } + else if (!decode_number(output)) + _GLIBCXX_DEMANGLER_FAILURE; + if (M_implementation_details.get_style_literal()) + { + if (c == 'j' || c == 'm' || c == 'y') + output += 'u'; + if (c == 'l' || c == 'm') + output += 'l'; + if (c == 'x' || c == 'y') + output += "ll"; + } + } + _GLIBCXX_DEMANGLER_RETURN; + } + + // <operator-name> ::= + // nw # new + // na # new[] + // dl # delete + // da # delete[] + // ps # + (unary) + // ng # - (unary) + // ad # & (unary) + // de # * (unary) + // co # ~ + // pl # + + // mi # - + // ml # * + // dv # / + // rm # % + // an # & + // or # | + // eo # ^ + // aS # = + // pL # += + // mI # -= + // mL # *= + // dV # /= + // rM # %= + // aN # &= + // oR # |= + // eO # ^= + // ls # << + // rs # >> + // lS # <<= + // rS # >>= + // eq # == + // ne # != + // lt # < + // gt # > + // le # <= + // ge # >= + // nt # ! + // aa # && + // oo # || + // pp # ++ + // mm # -- + // cm # , + // pm # ->* + // pt # -> + // cl # () + // ix # [] + // qu # ? + // st # sizeof (a type) + // sz # sizeof (an expression) + // cv <type> # (cast) + // v <digit> <source-name> # vendor extended operator + // + // Symbol operator codes exist of two characters, we need to find a + // quick hash so that their names can be looked up in a table. + // + // The puzzle :) + // Shift the rows so that there is at most one character per column. + // + // A perfect solution (Oh no, it's THE MATRIX!): + // horizontal + // ....................................... offset + 'a' + // a, a||d|||||||||n||||s|||||||||||||||||||| 0 + // c, || |||||||lm o||| |||||||||||||||||||| 0 + // d, || a|||e|| l|| ||||||v||||||||||||| 4 + // e, || ||| || || |||o|q ||||||||||||| 8 + // g, || ||| || || e|| | ||||||||t|||| 15 + // i, || ||| || || || | |||||||| |||x 15 + // l, |e ||| || st || | |||||||| ||| -2 + // m, | |i| lm || | |||||||| ||| -2 + // n, a e g t| w |||||||| ||| 1 + // o, | ||||o||r ||| 16 + // p, | ||lm |p st| 17 + // q, | u| | | 6 + // r, m s | | 9 + // s, t z 12 + // ....................................... + // ^ ^__ second character + // |___ first character + // + + // Putting that solution in tables: + + char const offset_table_c [1 + CHAR_MAX - CHAR_MIN ] = + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +#if (CHAR_MIN < 0) + // Add -CHAR_MIN extra zeroes (128): + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // a b c d e f g h i j k + 0, -97, 0, -97, -93, -89, 0, -82, 0, -82, 0, 0, + // l m n o p q r s t u v + -99, -99, -96, -81, -80, -91, -88, -85, 0, 0, 0, +#else + // a b c d e f g h i j k + 0, 159, 0, 159, 163, 167, 0, 174, 0, 174, 0, 0, + // l m n o p q r s t u v + 157, 157, 160, 175, 176, 165, 168, 171, 0, 0, 0, +#endif + // ... more zeros + }; + + enum xary_nt { + unary, + binary, + trinary + }; + + struct entry_st + { + char const* opcode; + char const* symbol_name; + xary_nt type; + }; + + entry_st const symbol_name_table_c[39] = { + { "aa", "operator&&", binary }, + { "na", "operator new[]", unary }, + { "le", "operator<=", binary }, + { "ad", "operator&", unary }, + { "da", "operator delete[]", unary }, + { "ne", "operator!=", binary }, + { "mi=", "operator-", binary }, + { "ng", "operator-", unary }, + { "de", "operator*", unary }, + { "ml=", "operator*", binary }, + { "mm", "operator--", unary }, + { "cl", "operator()", unary }, + { "cm", "operator,", binary }, + { "an=", "operator&", binary }, + { "co", "operator~", binary }, + { "dl", "operator delete", unary }, + { "ls=", "operator<<", binary }, + { "lt", "operator<", binary }, + { "as=", "operator", binary }, + { "ge", "operator>=", binary }, + { "nt", "operator!", unary }, + { "rm=", "operator%", binary }, + { "eo=", "operator^", binary }, + { "nw", "operator new", unary }, + { "eq", "operator==", binary }, + { "dv=", "operator/", binary }, + { "qu", "operator?", trinary }, + { "rs=", "operator>>", binary }, + { "pl=", "operator+", binary }, + { "pm", "operator->*", binary }, + { "oo", "operator||", binary }, + { "st", "sizeof", unary }, + { "pp", "operator++", unary }, + { "or=", "operator|", binary }, + { "gt", "operator>", binary }, + { "ps", "operator+", unary }, + { "pt", "operator->", binary }, + { "sz", "sizeof", unary }, + { "ix", "operator[]", unary } + }; + + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_operator_name(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_operator_name"); + + char opcode0 = current(); + char opcode1 = tolower(next()); + + register char hash; + if ((hash = offset_table_c[opcode0 - CHAR_MIN])) + { + hash += opcode1; + if ( +#if (CHAR_MIN < 0) + hash >= 0 && +#endif + hash < 39) + { + int index = static_cast<int>(static_cast<unsigned char>(hash)); + entry_st entry = symbol_name_table_c[index]; + if (entry.opcode[0] == opcode0 && entry.opcode[1] == opcode1 + && (opcode1 == current() || entry.opcode[2] == '=')) + { + output += entry.symbol_name; + if (opcode1 != current()) + output += '='; + eat_current(); + if (hash == 16 || hash == 17) + M_template_args_need_space = true; + _GLIBCXX_DEMANGLER_RETURN; + } + else if (opcode0 == 'c' && opcode1 == 'v') // casting operator + { + eat_current(); + output += "operator "; + if (current() == 'T') + { + // This is a templated cast operator. + // It must be of the form "cvT_I...E". + // Let M_template_arg_pos already point + // to the template argument. + M_template_arg_pos_offset = M_template_arg_pos.size(); + M_template_arg_pos.push_back(M_pos + 3); + } + if (!decode_type(output)) + _GLIBCXX_DEMANGLER_FAILURE; + if (!M_inside_template_args) + M_name_is_conversion_operator = true; + _GLIBCXX_DEMANGLER_RETURN; + } + } + } + _GLIBCXX_DEMANGLER_FAILURE; + } + + // + // <expression> ::= <unary operator-name> <expression> + // ::= <binary operator-name> <expression> <expression> + // ::= <trinary operator-name> <expression> <expression> <expression> + // ::= st <type> + // ::= <template-param> + // ::= sr <type> <unqualified-name> # dependent name + // ::= sr <type> <unqualified-name> <template-args> # dependent template-id + // ::= <expr-primary> + // + // <expr-primary> ::= L <type> <value number> E # integer literal + // ::= L <type> <value float> E # floating literal + // ::= L <mangled-name> E # external name + // + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_expression(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_expression"); + if (current() == 'T') + { + if (!decode_template_param(output)) + _GLIBCXX_DEMANGLER_FAILURE; + _GLIBCXX_DEMANGLER_RETURN; + } + else if (current() == 'L') + { + if (!decode_literal(output)) + _GLIBCXX_DEMANGLER_FAILURE; + if (current() != 'E') + _GLIBCXX_DEMANGLER_FAILURE; + eat_current(); + _GLIBCXX_DEMANGLER_RETURN; + } + else if (current() == 's') + { + char opcode1 = next(); + if (opcode1 == 't' || opcode1 == 'z') + { + eat_current(); + if (M_implementation_details.get_style_compact_expr_ops()) + output += "sizeof("; + else + output += "sizeof ("; + if (opcode1 == 't') + { + // I cannot think of a mangled name that is valid for both cases + // when just replacing the 't' by a 'z' or vica versa, which + // indicates that there is no ambiguity that dictates the need + // for a seperate "st" case, except to be able catch invalid + // mangled names. However there CAN be ambiguity in the demangled + // name when there are both a type and a symbol of the same name, + // which then leads to different encoding (of course) with + // sizeof (type) or sizeof (expression) respectively, but that + // ambiguity is not per se related to "sizeof" except that that + // is the only place where both a type AND an expression are valid + // in as part of a (template function) type. + // + // Example: + // + // struct B { typedef int t; }; + // struct A : public B { static int t[2]; }; + // template<int i, int j> struct C { typedef int q; }; + // template<int i, typename T> + // void f(typename C<sizeof (typename T::t), + // sizeof (T::t)>::q) { } + // void instantiate() { f<5, A>(0); } + // + // Leads to _Z1fILi5E1AEvN1CIXstN1T1tEEXszsrS2_1tEE1qE which + // demangles as + // void f<5, A>(C<sizeof (T::t), sizeof (T::t)>::q) + // + // This is ambiguity is very unlikely to happen and it is kind + // of fuzzy to detect when adding a 'typename' makes sense. + // + if (M_implementation_details.get_style_sizeof_typename()) + { + // We can only get here inside a template parameter, + // so this is syntactically correct if the given type is + // a typedef. The only disadvantage is that it is inconsistent + // with all other places where the 'typename' keyword should be + // used and we don't. + // With this, the above example will demangle as + // void f<5, A>(C<sizeof (typename T::t), sizeof (T::t)>::q) + if (current() == 'N' || // <nested-name> + // This should be a safe bet. + (current() == 'S' && + next_peek() == 't')) // std::something, guess that + // this involves a typedef. + output += "typename "; + } + if (!decode_type(output)) + _GLIBCXX_DEMANGLER_FAILURE; + } + else + { + if (!decode_expression(output)) + _GLIBCXX_DEMANGLER_FAILURE; + } + output += ')'; + _GLIBCXX_DEMANGLER_RETURN; + } + else if (current() == 'r') + { + eat_current(); + if (!decode_type(output)) + _GLIBCXX_DEMANGLER_FAILURE; + output += "::"; + if (!decode_unqualified_name(output)) + _GLIBCXX_DEMANGLER_FAILURE; + if (current() != 'I' || decode_template_args(output)) + _GLIBCXX_DEMANGLER_RETURN; + } + } + else + { + char opcode0 = current(); + char opcode1 = tolower(next()); + + register char hash; + if ((hash = offset_table_c[opcode0 - CHAR_MIN])) + { + hash += opcode1; + if ( +#if (CHAR_MIN < 0) + hash >= 0 && +#endif + hash < 39) + { + int index = static_cast<int>(static_cast<unsigned char>(hash)); + entry_st entry = symbol_name_table_c[index]; + if (entry.opcode[0] == opcode0 && entry.opcode[1] == opcode1 + && (opcode1 == current() || entry.opcode[2] == '=')) + { + char const* op = entry.symbol_name + 8; // Skip "operator". + if (*op == ' ') // operator new and delete. + ++op; + if (entry.type == unary) + output += op; + bool is_eq = (opcode1 != current()); + eat_current(); + if (index == 34 && M_inside_template_args) // operator> + output += '('; + output += '('; + if (!decode_expression(output)) + _GLIBCXX_DEMANGLER_FAILURE; + output += ')'; + if (entry.type != unary) + { + if (!M_implementation_details.get_style_compact_expr_ops()) + output += ' '; + output += op; + if (is_eq) + output += '='; + if (!M_implementation_details.get_style_compact_expr_ops()) + output += ' '; + output += '('; + if (!decode_expression(output)) + _GLIBCXX_DEMANGLER_FAILURE; + output += ')'; + if (index == 34 && M_inside_template_args) + output += ')'; + if (entry.type == trinary) + { + if (M_implementation_details.get_style_compact_expr_ops()) + output += ":("; + else + output += " : ("; + if (!decode_expression(output)) + _GLIBCXX_DEMANGLER_FAILURE; + output += ')'; + } + } + _GLIBCXX_DEMANGLER_RETURN; + } + else if (opcode0 == 'c' && + opcode1 == 'v') // casting operator. + { + eat_current(); + output += '('; + if (!decode_type(output)) + _GLIBCXX_DEMANGLER_FAILURE; + output += ")("; + if (!decode_expression(output)) + _GLIBCXX_DEMANGLER_FAILURE; + output += ')'; + _GLIBCXX_DEMANGLER_RETURN; + } + } + } + } + _GLIBCXX_DEMANGLER_FAILURE; + } + + // + // <template-args> ::= I <template-arg>+ E + // <template-arg> ::= <type> # type or template + // ::= L <type> <value number> E # integer literal + // ::= L <type> <value float> E # floating literal + // ::= L <mangled-name> E # external name + // ::= X <expression> E # expression + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_template_args(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_template_args"); + if (eat_current() != 'I') + _GLIBCXX_DEMANGLER_FAILURE; + int prev_size = M_template_arg_pos.size(); + ++M_inside_template_args; + if (M_template_args_need_space) + { + output += ' '; + M_template_args_need_space = false; + } + output += '<'; + for(;;) + { + if (M_inside_template_args == 1 && !M_inside_type) + M_template_arg_pos.push_back(M_pos); + if (current() == 'X') + { + eat_current(); + if (!decode_expression(output)) + _GLIBCXX_DEMANGLER_FAILURE; + if (current() != 'E') + _GLIBCXX_DEMANGLER_FAILURE; + eat_current(); + } + else if (current() == 'L') + { + if (!decode_literal(output)) + _GLIBCXX_DEMANGLER_FAILURE; + if (current() != 'E') + _GLIBCXX_DEMANGLER_FAILURE; + eat_current(); + } + else if (!decode_type(output)) + _GLIBCXX_DEMANGLER_FAILURE; + if (current() == 'E') + break; + output += ", "; + } + eat_current(); + if (*(output.rbegin()) == '>') + output += ' '; + output += '>'; + --M_inside_template_args; + if (!M_inside_template_args && !M_inside_type) + { + M_name_is_template = true; + M_template_arg_pos_offset = prev_size; + } + _GLIBCXX_DEMANGLER_RETURN; + } + + // <bare-function-type> ::= + // <signature type>+ # Types are parameter types. + // + // Note that the possible return type of the <bare-function-type> + // has already been eaten before we call this function. This makes + // our <bare-function-type> slightly different from the one in + // the C++-ABI description. + // + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_bare_function_type(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_bare_function_type"); + if (M_saw_destructor) + { + if (eat_current() != 'v' || (current() != 'E' && current() != 0)) + _GLIBCXX_DEMANGLER_FAILURE; + output += "()"; + M_saw_destructor = false; + _GLIBCXX_DEMANGLER_RETURN; + } + if (current() == 'v' && !M_implementation_details.get_style_void()) + { + eat_current(); + if (current() != 'E' && current() != 0) + _GLIBCXX_DEMANGLER_FAILURE; + output += "()"; + M_saw_destructor = false; + _GLIBCXX_DEMANGLER_RETURN; + } + output += '('; + M_template_args_need_space = false; + if (!decode_type(output)) // Must have at least one parameter. + _GLIBCXX_DEMANGLER_FAILURE; + while (current() != 'E' && current() != 0) + { + output += ", "; + if (!decode_type(output)) + _GLIBCXX_DEMANGLER_FAILURE; + } + output += ')'; + _GLIBCXX_DEMANGLER_RETURN; + } + + // <type> ::= + // <builtin-type> # Starts with a lower case character != r. + // <function-type> # Starts with F + // <class-enum-type> # Starts with N, S, C, D, Z, a digit or a lower + // # case character. Since a lower case character + // # would be an operator name, that would be an + // # error. The S is a substitution or St + // # (::std::). A 'C' would be a constructor and + // # thus also an error. + // <template-param> # Starts with T + // <substitution> # Starts with S + // <template-template-param> <template-args> # Starts with T or S, + // # equivalent with the above. + // + // <array-type> # Starts with A + // <pointer-to-member-type> # Starts with M + // <CV-qualifiers> <type> # Starts with r, V or K + // P <type> # pointer-to # Starts with P + // R <type> # reference-to # Starts with R + // C <type> # complex (C 2000) # Starts with C + // G <type> # imaginary (C 2000)# Starts with G + // U <source-name> <type> # vendor extended type qualifier, + // # starts with U + // + // <template-template-param> ::= <template-param> + // ::= <substitution> + + // My own analysis of how to decode qualifiers: + // + // F is a <function-type>, <T> is a <builtin-type>, <class-enum-type>, + // <template-param> or <template-template-param> <template-args>. + // <Q> represents a series of qualifiers (not G or C). + // <C> is an unqualified type. + // <R> is a qualified type. + // <B> is the bare-function-type without return type. + // <I> is the array index. + // Substitutions: + // <Q>M<C><Q2>F<R><B>E ==> R (C::*Q)B Q2 "<C>", "F<R><B>E" + // (<R> and <B> recursive), + // "M<C><Q2>F<R><B>E". + // <Q>F<R><B>E ==> R (Q)B "<R>", "<B>" (<B> recursive) + // and "F<R><B>E". + // + // Note that if <R> has postfix qualifiers (an array or function), then + // those are added AFTER the (member) function type. For example: + // <Q>FPA<R><B>E ==> R (*(Q)B) [], where the PA added the prefix + // "(*" and the postfix ") []". + // + // <Q>G<T> ==> imaginary T Q "<T>", "G<T>" (<T> recursive). + // <Q>C<T> ==> complex T Q "<T>", "C<T>" (<T> recursive). + // <Q><T> ==> T Q "<T>" (<T> recursive). + // + // where <Q> is any of: + // + // <Q>P ==> *Q "P..." + // <Q>R ==> &Q "R..." + // <Q>[K|V|r]+ ==> [ const| volatile| restrict]+Q "KVr..." + // <Q>U<S> ==> SQ "U<S>..." + // <Q>M<C> ==> C::*Q "M<C>..." (<C> recurs.) + // A<I> ==> [I] "A<I>..." (<I> recurs.) + // <Q>A<I> ==> (Q) [I] "A<I>..." (<I> recurs.) + // Note that when <Q> ends on an A<I2> then the brackets are omitted + // and no space is written between the two: + // A<I2>A<I> ==> [I2][I] + // If <Q> ends on [KVr]+, which can happen in combination with + // substitutions only, then special handling is required, see below. + // + // A <substitution> is handled with an input position switch during which + // new substitutions are turned off. Because recursive handling of types + // (and therefore the order in which substitutions must be generated) must + // be done left to right, but the generation of Q needs processing right to + // left, substitutions per <type> are generated by reading the input left + // to right and marking the starts of all substitutions only - implicitly + // finishing them at the end of the type. Then the output and real + // substitutions are generated. + // + // The following comment was for the demangling of g++ version 3.0.x. The + // mangling (and I believe even the ABI description) have been fixed now + // (as of g++ version 3.1). + // + // g++ 3.0.x only: + // The ABI specifies for pointer-to-member function types the format + // <Q>M<T>F<R><B>E. In other words, the qualifier <Q2> (see above) is + // implicitely contained in <T> instead of explicitly part of the M format. + // I am convinced that this is a bug in the ABI. Unfortunately, this is + // how we have to demangle things as it has a direct impact on the order + // in which substitutions are stored. This ill-formed design results in + // rather ill-formed demangler code too however :/ + // + // <Q2> is now explicitely part of the M format. + // For some weird reason, g++ (3.2.1) does not add substitutions for + // qualified member function pointers. I think that is another bug. + // + + // In the case of + // <Q>A<I> + // where <Q> ends on [K|V|r]+ then that part should be processed as + // if it was behind the A<I> instead of in front of it. This is + // because a constant array of ints is normally always mangled as + // an array of constant ints. KVr qualifiers can end up in front + // of an array when the array is part of a substitution or template + // parameter, but the demangling should still result in the same + // syntax; thus KA2_i (const array of ints) must result in the same + // demangling as A2_Ki (array of const ints). As a result we must + // demangle ...[...[[KVr]+A<I0>][KVr]+A<I1>]...[KVr]+A<In>[KVr]+ + // as A<I0>A<I1>...A<In>[KVr]+ where each K, V and r in the series + // collapses to a single character at the right of the string. + // For example: + // VA9_KrA6_KVi --> A9_A6_KVri --> int volatile const restrict [9][6] + // Note that substitutions are still added as usual (the translation + // to A9_A6_KVri does not really happen). + // + // This decoding is achieved by delaying the decoding of any sequence + // of [KVrA]'s and processing them together in the order: first the + // short-circuited KVr part and then the arrays. + static int const cvq_K = 1; // Saw at least one K + static int const cvq_V = 2; // Saw at least one V + static int const cvq_r = 4; // Saw at least one r + static int const cvq_A = 8; // Saw at least one A + static int const cvq_last = 16; // No remaining qualifiers. + static int const cvq_A_cnt = 32; // Bit 5 and higher represent the + // number of A's in the series. + // In the function below, iter_array points to the first (right most) + // A in the series, if any. + template<typename Tp, typename Allocator> + void + qualifier_list<Tp, Allocator>::decode_KVrA( + string_type& prefix, string_type& postfix, int cvq, + typename qual_vector::const_reverse_iterator const& iter_array) const + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_KVrA"); + if ((cvq & cvq_K)) + prefix += " const"; + if ((cvq & cvq_V)) + prefix += " volatile"; + if ((cvq & cvq_r)) + prefix += " restrict"; + if ((cvq & cvq_A)) + { + int n = cvq >> 5; + for (typename qual_vector:: + const_reverse_iterator iter = iter_array; + iter != M_qualifier_starts.rend(); ++iter) + { + switch((*iter).first_qualifier()) + { + case 'K': + case 'V': + case 'r': + break; + case 'A': + { + string_type index = (*iter).get_optional_type(); + if (--n == 0 && (cvq & cvq_last)) + postfix = " [" + index + "]" + postfix; + else if (n > 0) + postfix = "[" + index + "]" + postfix; + else + { + prefix += " ("; + postfix = ") [" + index + "]" + postfix; + } + break; + } + default: + _GLIBCXX_DEMANGLER_RETURN3; + } + } + } + _GLIBCXX_DEMANGLER_RETURN3; + } + + template<typename Tp, typename Allocator> + void + qualifier_list<Tp, Allocator>::decode_qualifiers( + string_type& prefix, + string_type& postfix, + bool member_function_pointer_qualifiers = false) const + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_qualifiers"); + int cvq = 0; + typename qual_vector::const_reverse_iterator iter_array; + for(typename qual_vector:: + const_reverse_iterator iter = M_qualifier_starts.rbegin(); + iter != M_qualifier_starts.rend(); ++iter) + { + if (!member_function_pointer_qualifiers + && !(*iter).part_of_substitution()) + { + int saved_inside_substitution = M_demangler.M_inside_substitution; + M_demangler.M_inside_substitution = 0; + M_demangler.add_substitution((*iter).get_start_pos(), type); + M_demangler.M_inside_substitution = saved_inside_substitution; + } + char qualifier_char = (*iter).first_qualifier(); + for(; qualifier_char; qualifier_char = (*iter).next_qualifier()) + { + switch(qualifier_char) + { + case 'P': + if (cvq) + { + decode_KVrA(prefix, postfix, cvq, iter_array); + cvq = 0; + } + prefix += "*"; + break; + case 'R': + if (cvq) + { + decode_KVrA(prefix, postfix, cvq, iter_array); + cvq = 0; + } + prefix += "&"; + break; + case 'K': + cvq |= cvq_K; + continue; + case 'V': + cvq |= cvq_V; + continue; + case 'r': + cvq |= cvq_r; + continue; + case 'A': + if (!(cvq & cvq_A)) + { + cvq |= cvq_A; + iter_array = iter; + } + cvq += cvq_A_cnt; + break; + case 'M': + if (cvq) + { + decode_KVrA(prefix, postfix, cvq, iter_array); + cvq = 0; + } + prefix += " "; + prefix += (*iter).get_optional_type(); + prefix += "::*"; + break; + case 'U': + if (cvq) + { + decode_KVrA(prefix, postfix, cvq, iter_array); + cvq = 0; + } + prefix += " "; + prefix += (*iter).get_optional_type(); + break; + case 'G': // Only here so we added a substitution. + break; + } + break; + } + } + if (cvq) + decode_KVrA(prefix, postfix, cvq|cvq_last, iter_array); + M_printing_suppressed = false; + _GLIBCXX_DEMANGLER_RETURN3; + } + + // + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_type_with_postfix( + string_type& prefix, string_type& postfix, + qualifier_list<Tp, Allocator>* qualifiers) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING2("decode_type"); + ++M_inside_type; + bool recursive_template_param_or_substitution_call; + if (!(recursive_template_param_or_substitution_call = qualifiers)) + { + qualifier_list<Allocator>* raw_qualifiers = M_qualifier_list_alloc.allocate(1); + qualifiers = new (raw_qualifiers) qualifier_list<Allocator>(*this); + } + // First eat all qualifiers. + bool failure = false; + for(;;) // So we can use 'continue' to eat the next qualifier. + { + int start_pos = M_pos; + switch(current()) + { + case 'P': + qualifiers->add_qualifier_start(pointer, start_pos, + M_inside_substitution); + eat_current(); + continue; + case 'R': + qualifiers->add_qualifier_start(reference, start_pos, + M_inside_substitution); + eat_current(); + continue; + case 'K': + case 'V': + case 'r': + { + char c; + int count = 0; + do + { + ++count; + c = next(); + } + while(c == 'K' || c == 'V' || c == 'r'); + qualifiers->add_qualifier_start(cv_qualifier, start_pos, count, + M_inside_substitution); + continue; + } + case 'U': + { + eat_current(); + string_type source_name; + if (!decode_source_name(source_name)) + { + failure = true; + break; + } + qualifiers->add_qualifier_start(vendor_extension, start_pos, + source_name, M_inside_substitution); + continue; + } + case 'A': + { + // <array-type> ::= A <positive dimension number> _ <element type> + // ::= A [<dimension expression>] _ <element type> + // + string_type index; + int saved_pos; + store(saved_pos); + if (next() == 'n' || !decode_number(index)) + { + restore(saved_pos); + if (next() != '_' && !decode_expression(index)) + { + failure = true; + break; + } + } + if (eat_current() != '_') + { + failure = true; + break; + } + qualifiers->add_qualifier_start(array, start_pos, index, + M_inside_substitution); + continue; + } + case 'M': + { + // <pointer-to-member-type> ::= M <class type> <member type> + // <Q>M<C> or <Q>M<C><Q2>F<R><B>E + eat_current(); + string_type class_type; + if (!decode_type(class_type)) // Substitution: "<C>". + { + failure = true; + break; + } + char c = current(); + if (c == 'F' || c == 'K' || c == 'V' || c == 'r') + // Must be CV-qualifiers and a member function pointer. + { + // <Q>M<C><Q2>F<R><B>E ==> R (C::*Q)B Q2 + // substitutions: "<C>", "F<R><B>E" (<R> and <B> + // recursive), "M<C><Q2>F<R><B>E". + int count = 0; + int Q2_start_pos = M_pos; + while(c == 'K' || c == 'V' || c == 'r') // Decode <Q2>. + { + ++count; + c = next(); + } + qualifier_list<Tp, Allocator> class_type_qualifiers(*this); + if (count) + class_type_qualifiers. + add_qualifier_start(cv_qualifier, Q2_start_pos, + count, M_inside_substitution); + string_type member_function_qualifiers; + // It is unclear why g++ doesn't add a substitution for + // "<Q2>F<R><B>E" as it should I think. + string_type member_function_qualifiers_postfix; + class_type_qualifiers. + decode_qualifiers(member_function_qualifiers, + member_function_qualifiers_postfix, true); + member_function_qualifiers += + member_function_qualifiers_postfix; + // I don't think this substitution is actually ever used. + int function_pos = M_pos; + if (eat_current() != 'F') + { + failure = true; + break; + } + // Return type. + // Constructors, destructors and conversion operators don't + // have a return type, but seem to never get here. + string_type return_type_postfix; + if (!decode_type_with_postfix(prefix, return_type_postfix)) + // substitution: <R> recursive + { + failure = true; + break; + } + prefix += " ("; + prefix += class_type; + prefix += "::*"; + string_type bare_function_type; + if (!decode_bare_function_type(bare_function_type) + || eat_current() != 'E') // Substitution: <B> recursive. + { + failure = true; + break; + } + // substitution: "F<R><B>E". + add_substitution(function_pos, type); + // substitution: "M<C><Q2>F<R><B>E". + add_substitution(start_pos, type); + // substitution: all qualified types if any. + qualifiers->decode_qualifiers(prefix, postfix); + postfix += ")"; + postfix += bare_function_type; + postfix += member_function_qualifiers; + postfix += return_type_postfix; + goto decode_type_exit; + } + qualifiers->add_qualifier_start(pointer_to_member, start_pos, + class_type, M_inside_substitution); + continue; + } + default: + break; + } + break; + } + if (!failure) + { + // <Q>G<T> ==> imaginary T Q + // substitutions: "<T>", "G<T>" (<T> recursive). + // <Q>C<T> ==> complex T Q + // substitutions: "<T>", "C<T>" (<T> recursive). + if (current() == 'C' || current() == 'G') + { + prefix += current() == 'C' ? "complex " : "imaginary "; + qualifiers->add_qualifier_start(complex_or_imaginary, M_pos, + M_inside_substitution); + eat_current(); + } + int start_pos = M_pos; + switch(current()) + { + case 'F': + { + // <function-type> ::= F [Y] <bare-function-type> E + // + // Note that g++ never generates the 'Y', but we try to + // demangle it anyway. + bool extern_C = (next() == 'Y'); + if (extern_C) + eat_current(); + + // <Q>F<R><B>E ==> R (Q)B + // substitution: "<R>", "<B>" (<B> recursive) and "F<R><B>E". + + // Return type. + string_type return_type_postfix; + if (!decode_type_with_postfix(prefix, return_type_postfix)) + // Substitution: "<R>". + { + failure = true; + break; + } + // Only array and function (pointer) types have a postfix. + // In that case we don't want the space but expect something + // like prefix is "int (*" and postfix is ") [1]". + // We do want the space if this pointer is qualified. + if (return_type_postfix.size() == 0 || + (prefix.size() > 0 && *prefix.rbegin() != '*')) + prefix += ' '; + prefix += '('; + string_type bare_function_type; + if (!decode_bare_function_type(bare_function_type) + // substitution: "<B>" (<B> recursive). + || eat_current() != 'E') + { + failure = true; + break; + } + add_substitution(start_pos, type); // Substitution: "F<R><B>E". + qualifiers->decode_qualifiers(prefix, postfix); + // substitution: all qualified types, if any. + postfix += ")"; + if (extern_C) + postfix += " [extern \"C\"] "; + postfix += bare_function_type; + postfix += return_type_postfix; + break; + } + case 'T': + if (!decode_template_param(prefix, qualifiers)) + { + failure = true; + break; + } + if (current() == 'I') + { + add_substitution(start_pos, template_template_param); + // substitution: "<template-template-param>". + if (!decode_template_args(prefix)) + { + failure = true; + break; + } + } + if (!recursive_template_param_or_substitution_call + && qualifiers->suppressed()) + { + add_substitution(start_pos, type); + // substitution: "<template-param>" or + // "<template-template-param> <template-args>". + qualifiers->decode_qualifiers(prefix, postfix); + // substitution: all qualified types, if any. + } + break; + case 'S': + if (M_pos >= M_maxpos) + { + failure = true; + break; + } + if (M_str[M_pos + 1] != 't') + { + if (!decode_substitution(prefix, qualifiers)) + { + failure = true; + break; + } + if (current() == 'I') + { + if (!decode_template_args(prefix)) + { + failure = true; + break; + } + if (!recursive_template_param_or_substitution_call + && qualifiers->suppressed()) + add_substitution(start_pos, type); + // Substitution: + // "<template-template-param> <template-args>". + } + if (!recursive_template_param_or_substitution_call + && qualifiers->suppressed()) + qualifiers->decode_qualifiers(prefix, postfix); + // Substitution: all qualified types, if any. + break; + } + /* Fall-through for St */ + case 'N': + case 'Z': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + // <Q><T> ==> T Q + // substitutions: "<T>" (<T> recursive). + if (!decode_class_enum_type(prefix)) + { + failure = true; + break; + } + if (!recursive_template_param_or_substitution_call) + { + add_substitution(start_pos, type); + // substitution: "<class-enum-type>". + qualifiers->decode_qualifiers(prefix, postfix); + // substitution: all qualified types, if any. + } + else + qualifiers->printing_suppressed(); + break; + default: + // <Q><T> ==> T Q + // substitutions: "<T>" (<T> recursive). + if (!decode_builtin_type(prefix)) + { + failure = true; + break; + } + // If decode_type was called from decode_template_param then we + // need to suppress calling qualifiers here in order to get a + // substitution added anyway (for the <template-param>). + if (!recursive_template_param_or_substitution_call) + qualifiers->decode_qualifiers(prefix, postfix); + else + qualifiers->printing_suppressed(); + break; + } + } + decode_type_exit: + --M_inside_type; + if (!recursive_template_param_or_substitution_call) + { + qualifiers->~qualifier_list<Allocator>(); + M_qualifier_list_alloc.deallocate(qualifiers, 1); + } + if (failure) + _GLIBCXX_DEMANGLER_FAILURE; + _GLIBCXX_DEMANGLER_RETURN2; + } + + // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E + // ::= N [<CV-qualifiers>] <template-prefix> <template-args> E + // + // <prefix> ::= <prefix> <unqualified-name> + // ::= <template-prefix> <template-args> + // ::= <template-param> + // ::= # empty + // ::= <substitution> + // + // <template-prefix> ::= <prefix> <template unqualified-name> + // ::= <template-param> + // ::= <substitution> + // + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_nested_name(string_type& output, + string_type& qualifiers) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_nested_name"); + + if (current() != 'N' || M_pos >= M_maxpos) + _GLIBCXX_DEMANGLER_FAILURE; + + // <CV-qualifiers> ::= [r] [V] [K] # restrict (C99), volatile, const + char const* qualifiers_start = &M_str[M_pos + 1]; + for (char c = next(); c == 'K' || c == 'V' || c == 'r'; c = next()); + for (char const* qualifier_ptr = &M_str[M_pos - 1]; + qualifier_ptr >= qualifiers_start; --qualifier_ptr) + switch(*qualifier_ptr) + { + case 'K': + qualifiers += " const"; + break; + case 'V': + qualifiers += " volatile"; + break; + case 'r': + qualifiers += " restrict"; + break; + } + + int number_of_prefixes = 0; + int substitution_start = M_pos; + for(;;) + { + ++number_of_prefixes; + if (current() == 'S') + { + if (!decode_substitution(output)) + _GLIBCXX_DEMANGLER_FAILURE; + } + else if (current() == 'I') + { + if (!decode_template_args(output)) + _GLIBCXX_DEMANGLER_FAILURE; + if (current() != 'E') + { + // substitution: "<template-prefix> <template-args>". + add_substitution(substitution_start, nested_name_prefix, + number_of_prefixes); + } + } + else + { + if (current() == 'T') + { + if (!decode_template_param(output)) + _GLIBCXX_DEMANGLER_FAILURE; + } + else if (!decode_unqualified_name(output)) + _GLIBCXX_DEMANGLER_FAILURE; + if (current() != 'E') + { + // substitution: "<prefix> <unqualified-name>" or + // "<prefix> <template unqualified-name>". + add_substitution(substitution_start, + (current() == 'I') ? nested_name_template_prefix + : nested_name_prefix, + number_of_prefixes); + } + } + if (current() == 'E') + { + eat_current(); + _GLIBCXX_DEMANGLER_RETURN; + } + if (current() != 'I') + output += "::"; + else if (M_template_args_need_space) + output += ' '; + M_template_args_need_space = false; + } + _GLIBCXX_DEMANGLER_FAILURE; + } + + // <local-name> := Z <function encoding> E <entity name> [<discriminator>] + // := Z <function encoding> E s [<discriminator>] + // <discriminator> := _ <non-negative number> + // + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_local_name(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_local_name"); + if (current() != 'Z' || M_pos >= M_maxpos) + _GLIBCXX_DEMANGLER_FAILURE; + if ((M_pos += decode_encoding(output, M_str + M_pos + 1, + M_maxpos - M_pos, M_implementation_details) + 1) < 0 || + eat_current() != 'E') + _GLIBCXX_DEMANGLER_FAILURE; + output += "::"; + if (current() == 's') + { + eat_current(); + output += "string literal"; + } + else + { + string_type nested_name_qualifiers; + if (!decode_name(output, nested_name_qualifiers)) + _GLIBCXX_DEMANGLER_FAILURE; + output += nested_name_qualifiers; + } + string_type discriminator; + if (current() == '_' && next() != 'n' && !decode_number(discriminator)) + _GLIBCXX_DEMANGLER_FAILURE; + _GLIBCXX_DEMANGLER_RETURN; + } + + // <source-name> ::= <positive length number> <identifier> + // + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_source_name(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_source_name"); + int length = current() - '0'; + if (length < 1 || length > 9) + _GLIBCXX_DEMANGLER_FAILURE; + while(isdigit(next())) + length = 10 * length + current() - '0'; + char const* ptr = &M_str[M_pos]; + if (length > 11 && !strncmp(ptr, "_GLOBAL_", 8) && ptr[9] == 'N' + && ptr[8] == ptr[10]) + { + output += "(anonymous namespace)"; + if ((M_pos += length) > M_maxpos + 1) + _GLIBCXX_DEMANGLER_FAILURE; + } + else + while(length--) + { + if (current() == 0) + _GLIBCXX_DEMANGLER_FAILURE; + output += eat_current(); + } + _GLIBCXX_DEMANGLER_RETURN; + } + + // <unqualified-name> ::= <operator-name> # Starts with lower case. + // ::= <ctor-dtor-name> # Starts with 'C' or 'D'. + // ::= <source-name> # Starts with a digit. + // + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_unqualified_name(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_unqualified_name"); + if (M_inside_template_args) + { + if (!decode_source_name(output)) + _GLIBCXX_DEMANGLER_FAILURE; + } + else if (isdigit(current())) + { + bool recursive_unqualified_name = (&M_function_name == &output); + // This can be a recursive call when we are decoding + // an <operator-name> that is a cast operator for a some + // <unqualified-name>; for example "operator Foo()". + // In that case this is thus not a ctor or dtor and we + // are not interested in updating M_function_name. + if (!recursive_unqualified_name) + M_function_name.clear(); + M_name_is_template = false; + M_name_is_cdtor = false; + M_name_is_conversion_operator = false; + if (!decode_source_name(M_function_name)) + _GLIBCXX_DEMANGLER_FAILURE; + if (!recursive_unqualified_name) + output += M_function_name; + } + else if (islower(current())) + { + M_function_name.clear(); + M_name_is_template = false; + M_name_is_cdtor = false; + M_name_is_conversion_operator = false; + if (!decode_operator_name(M_function_name)) + _GLIBCXX_DEMANGLER_FAILURE; + output += M_function_name; + } + else if (current() == 'C' || current() == 'D') + { + // <ctor-dtor-name> ::= + // C1 # complete object (in-charge) constructor + // C2 # base object (not-in-charge) constructor + // C3 # complete object (in-charge) allocating constructor + // D0 # deleting (in-charge) destructor + // D1 # complete object (in-charge) destructor + // D2 # base object (not-in-charge) destructor + // + if (current() == 'C') + { + char c = next(); + if (c < '1' || c > '3') + _GLIBCXX_DEMANGLER_FAILURE; + } + else + { + char c = next(); + if (c < '0' || c > '2') + _GLIBCXX_DEMANGLER_FAILURE; + output += '~'; + M_saw_destructor = true; + } + M_name_is_cdtor = true; + eat_current(); + output += M_function_name; + } + else + _GLIBCXX_DEMANGLER_FAILURE; + _GLIBCXX_DEMANGLER_RETURN; + } + + // <unscoped-name> ::= + // <unqualified-name> # Starts not with an 'S' + // St <unqualified-name> # ::std:: + // + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_unscoped_name(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_unscoped_name"); + if (current() == 'S') + { + if (next() != 't') + _GLIBCXX_DEMANGLER_FAILURE; + eat_current(); + output += "std::"; + } + decode_unqualified_name(output); + _GLIBCXX_DEMANGLER_RETURN; + } + + // <name> ::= + // <nested-name> # Starts with 'N' + // <unscoped-template-name> <template-args> # idem + // <local-name> # Starts with 'Z' + // <unscoped-name> # Starts with 'S', 'C', 'D', + // # a digit or a lower case + // # character. + // + // <unscoped-template-name> ::= <unscoped-name> + // ::= <substitution> + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_name(string_type& output, + string_type& nested_name_qualifiers) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_name"); + int substitution_start = M_pos; + if (current() == 'S' && (M_pos >= M_maxpos || M_str[M_pos + 1] != 't')) + { + if (!decode_substitution(output)) + _GLIBCXX_DEMANGLER_FAILURE; + } + else if (current() == 'N') + { + decode_nested_name(output, nested_name_qualifiers); + _GLIBCXX_DEMANGLER_RETURN; + } + else if (current() == 'Z') + { + decode_local_name(output); + _GLIBCXX_DEMANGLER_RETURN; + } + else if (!decode_unscoped_name(output)) + _GLIBCXX_DEMANGLER_FAILURE; + if (current() == 'I') + { + // Must have been an <unscoped-template-name>. + add_substitution(substitution_start, unscoped_template_name); + if (!decode_template_args(output)) + _GLIBCXX_DEMANGLER_FAILURE; + } + M_template_args_need_space = false; + _GLIBCXX_DEMANGLER_RETURN; + } + + // <call-offset> ::= h <nv-offset> _ + // ::= v <v-offset> _ + // <nv-offset> ::= <offset number> + // non-virtual base override + // + // <v-offset> ::= <offset number> _ <virtual offset number> + // virtual base override, with vcall offset + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_call_offset(string_type& +#if _GLIBCXX_DEMANGLER_CWDEBUG + output +#endif + ) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_call_offset"); + if (current() == 'h') + { + string_type dummy; + eat_current(); + if (decode_number(dummy) && current() == '_') + { + eat_current(); + _GLIBCXX_DEMANGLER_RETURN; + } + } + else if (current() == 'v') + { + string_type dummy; + eat_current(); + if (decode_number(dummy) && current() == '_') + { + eat_current(); + if (decode_number(dummy) && current() == '_') + { + eat_current(); + _GLIBCXX_DEMANGLER_RETURN; + } + } + } + _GLIBCXX_DEMANGLER_FAILURE; + } + + // + // <special-name> ::= + // TV <type> # virtual table + // TT <type> # VTT structure (construction + // vtable index). + // TI <type> # typeinfo structure + // TS <type> # typeinfo name (null-terminated + // byte string). + // GV <object name> # Guard variable for one-time + // initialization of static objects in + // a local scope. + // T <call-offset> <base encoding># base is the nominal target function + // of thunk. + // Tc <call-offset> <call-offset> <base encoding> # base is the nominal + // target function of thunk; first + // call-offset is 'this' adjustment; + // second call-offset is result + // adjustment + // + template<typename Tp, typename Allocator> + bool + session<Tp, Allocator>::decode_special_name(string_type& output) + { + _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_special_name"); + if (current() == 'G') + { + if (next() != 'V') + _GLIBCXX_DEMANGLER_FAILURE; + output += "guard variable for "; + string_type nested_name_qualifiers; + eat_current(); + if (!decode_name(output, nested_name_qualifiers)) + _GLIBCXX_DEMANGLER_FAILURE; + output += nested_name_qualifiers; + _GLIBCXX_DEMANGLER_RETURN; + } + else if (current() != 'T') + _GLIBCXX_DEMANGLER_FAILURE; + switch(next()) + { + case 'V': + output += "vtable for "; + eat_current(); + decode_type(output); + _GLIBCXX_DEMANGLER_RETURN; + case 'T': + output += "VTT for "; + eat_current(); + decode_type(output); + _GLIBCXX_DEMANGLER_RETURN; + case 'I': + output += "typeinfo for "; + eat_current(); + decode_type(output); + _GLIBCXX_DEMANGLER_RETURN; + case 'S': + output += "typeinfo name for "; + eat_current(); + decode_type(output); + _GLIBCXX_DEMANGLER_RETURN; + case 'c': + output += "covariant return thunk to "; + if (!decode_call_offset(output) + || !decode_call_offset(output) + || (M_pos += decode_encoding(output, M_str + M_pos, + M_maxpos - M_pos + 1, M_implementation_details)) < 0) + _GLIBCXX_DEMANGLER_FAILURE; + _GLIBCXX_DEMANGLER_RETURN; + case 'C': // GNU extension? + { + string_type first; + output += "construction vtable for "; + eat_current(); + if (!decode_type(first)) + _GLIBCXX_DEMANGLER_FAILURE; + while(isdigit(current())) + eat_current(); + if (eat_current() != '_') + _GLIBCXX_DEMANGLER_FAILURE; + if (!decode_type(output)) + _GLIBCXX_DEMANGLER_FAILURE; + output += "-in-"; + output += first; + _GLIBCXX_DEMANGLER_RETURN; + } + default: + if (current() == 'v') + output += "virtual thunk to "; + else + output += "non-virtual thunk to "; + if (!decode_call_offset(output) + || (M_pos += decode_encoding(output, M_str + M_pos, + M_maxpos - M_pos + 1, M_implementation_details)) < 0) + _GLIBCXX_DEMANGLER_FAILURE; + _GLIBCXX_DEMANGLER_RETURN; + } + } + + // <encoding> ::= + // <function name> <bare-function-type> # Starts with 'C', 'D', 'N', + // 'S', a digit or a lower case + // character. + // <data name> # Idem. + // <special-name> # Starts with 'T' or 'G'. + template<typename Tp, typename Allocator> + int + session<Tp, Allocator>::decode_encoding(string_type& output, + char const* in, int len, implementation_details const& id) + { +#if _GLIBCXX_DEMANGLER_CWDEBUG + _GLIBCXX_DEMANGLER_DOUT(dc::demangler, + "Output thus far: \"" << output << '"'); + string_type input(in, len > 0x40000000 ? strlen(in) : len); + _GLIBCXX_DEMANGLER_DOUT( + dc::demangler, "Entering decode_encoding(\"" << input << "\")"); +#endif + if (len <= 0) + return INT_MIN; + session<Tp, Allocator> demangler_session(in, len, id); + string_type nested_name_qualifiers; + int saved_pos; + demangler_session.store(saved_pos); + if (demangler_session.decode_special_name(output)) + return demangler_session.M_pos; + demangler_session.restore(saved_pos); + string_type name; + if (!demangler_session.decode_name(name, nested_name_qualifiers)) + return INT_MIN; + if (demangler_session.current() == 0 + || demangler_session.current() == 'E') + { + output += name; + output += nested_name_qualifiers; + return demangler_session.M_pos; + } + // Must have been a <function name>. + string_type return_type_postfix; + if (demangler_session.M_name_is_template + && !(demangler_session.M_name_is_cdtor + || demangler_session.M_name_is_conversion_operator)) + { + // Return type of function + if (!demangler_session.decode_type_with_postfix(output, + return_type_postfix)) + return INT_MIN; + output += ' '; + } + output += name; + if (!demangler_session.decode_bare_function_type(output)) + return INT_MIN; + output += nested_name_qualifiers; + output += return_type_postfix; + return demangler_session.M_pos; + } + + } // namespace demangler + + // Public interface + template<typename Tp, typename Allocator> + struct demangle + { + typedef typename Allocator::template rebind<char>::other char_Allocator; + typedef std::basic_string<char, std::char_traits<char>, char_Allocator> + string_type; + static string_type symbol(char const* in, + demangler::implementation_details const& id); + static string_type type(char const* in, + demangler::implementation_details const& id); + }; + + // demangle::symbol() + // + // Demangle `input' which should be a mangled function name as for + // instance returned by nm(1). + template<typename Tp, typename Allocator> + typename demangle<Tp, Allocator>::string_type + demangle<Tp, Allocator>::symbol(char const* input, + demangler::implementation_details const& id) + { + // <mangled-name> ::= _Z <encoding> + // <mangled-name> ::= _GLOBAL_ _<type>_ <disambiguation part> + // <type> can be I or D (GNU extension) + typedef demangler::session<Tp, Allocator> demangler_type; + string_type result; + bool failure = (input[0] != '_'); + + if (!failure) + { + if (input[1] == 'G') + { + if (!strncmp(input, "_GLOBAL__", 9) + && (input[9] == 'D' || input[9] == 'I') + && input[10] == '_') + { + if (input[9] == 'D') + result.assign("global destructors keyed to ", 28); + else + result.assign("global constructors keyed to ", 29); + // Output the disambiguation part as-is. + result += input + 11; + } + else + failure = true; + } + else if (input[1] == 'Z') + { + int cnt = + demangler_type::decode_encoding(result, input + 2, INT_MAX, id); + if (cnt < 0 || input[cnt + 2] != 0) + failure = true; + } + else + failure = true; + } + + // Failure to demangle, return the mangled name. + if (failure) + result.assign(input, strlen(input)); + + return result; + } + + // demangle::type() + // Demangle `input' which must be a zero terminated mangled type + // name as for instance returned by std::type_info::name(). + template<typename Tp, typename Allocator> + typename demangle<Tp, Allocator>::string_type + demangle<Tp, Allocator>::type(char const* input, + demangler::implementation_details const& id) + { + std::basic_string<char, std::char_traits<char>, Allocator> result; + if (input == NULL) + result = "(null)"; + else + { + demangler::session<Tp, Allocator> demangler_session(input, INT_MAX, id); + if (!demangler_session.decode_type(result) + || demangler_session.remaining_input_characters()) + { + // Failure to demangle, return the mangled name. + result = input; + } + } + return result; + } +} // namespace __gnu_cxx + +#endif // __DEMANGLE_H diff --git a/contrib/libstdc++/include/ext/enc_filebuf.h b/contrib/libstdc++/include/ext/enc_filebuf.h index e1152bd26f9f..39f4ef724d19 100644 --- a/contrib/libstdc++/include/ext/enc_filebuf.h +++ b/contrib/libstdc++/include/ext/enc_filebuf.h @@ -1,6 +1,6 @@ -// __enc_traits layer for filebuf -*- C++ -*- +// filebuf with __enc_traits state type -*- C++ -*- -// Copyright (C) 2002 Free Software Foundation, Inc. +// Copyright (C) 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -32,12 +32,14 @@ namespace __gnu_cxx { - // Custom traits type with __enc_traits for state type, all other bits - // equivalent to the required char_traits instantiations. + // Custom traits type with __enc_traits for the state type, and the + // associated fpos<__enc_traits> for the position type, all other + // bits equivalent to the required char_traits instantiations. template<typename _CharT> struct enc_char_traits: public std::char_traits<_CharT> { - typedef std::__enc_traits state_type; + typedef std::__enc_traits state_type; + typedef typename std::fpos<state_type> pos_type; }; template<typename _CharT> @@ -45,17 +47,22 @@ namespace __gnu_cxx : public std::basic_filebuf<_CharT, enc_char_traits<_CharT> > { public: - typedef typename enc_char_traits<_CharT>::state_type state_type; - + typedef enc_char_traits<_CharT> traits_type; + typedef typename traits_type::state_type state_type; + typedef typename traits_type::pos_type pos_type; + enc_filebuf(state_type& __state) : std::basic_filebuf<_CharT, enc_char_traits<_CharT> >() - { - // Set state type to something useful. - // Something more than copyconstructible is needed here, so - // require copyconstructible + assignment operator. - __glibcpp_class_requires(state_type, _SGIAssignableConcept); - _M_state_cur = __state; - _M_state_cur._M_init(); - }; + { + this->_M_state_beg = __state; + this->_M_state_beg._M_init(); + } + + private: + // concept requirements: + // Set state type to something useful. + // Something more than copyconstructible is needed here, so + // require default and copy constructible + assignment operator. + __glibcxx_class_requires(state_type, _SGIAssignableConcept) }; } // namespace __gnu_cxx diff --git a/contrib/libstdc++/include/ext/functional b/contrib/libstdc++/include/ext/functional index c482aa1b67d1..1a378173177a 100644 --- a/contrib/libstdc++/include/ext/functional +++ b/contrib/libstdc++/include/ext/functional @@ -60,9 +60,10 @@ */ #ifndef _EXT_FUNCTIONAL -#define _EXT_FUNCTIONAL +#define _EXT_FUNCTIONAL 1 #pragma GCC system_header + #include <functional> namespace __gnu_cxx @@ -99,7 +100,7 @@ template <class _Tp> inline _Tp identity_element(std::multiplies<_Tp>) { * Calling @c operator() with a single argument @c x returns @c f(g(x)). * The function @c compose1 takes the two functions and constructs a * @c unary_compose variable for you. - * + * * @c binary_compose is constructed from three functors, @c f, @c g1, * and @c g2. Its @c operator() returns @c f(g1(x),g2(x)). The function * @compose2 takes f, g1, and g2, and constructs the @c binary_compose @@ -123,13 +124,13 @@ template <class _Tp> inline _Tp identity_element(std::multiplies<_Tp>) { template <class _Operation1, class _Operation2> class unary_compose : public unary_function<typename _Operation2::argument_type, - typename _Operation1::result_type> + typename _Operation1::result_type> { protected: _Operation1 _M_fn1; _Operation2 _M_fn2; public: - unary_compose(const _Operation1& __x, const _Operation2& __y) + unary_compose(const _Operation1& __x, const _Operation2& __y) : _M_fn1(__x), _M_fn2(__y) {} typename _Operation1::result_type operator()(const typename _Operation2::argument_type& __x) const { @@ -139,7 +140,7 @@ public: /// An \link SGIextensions SGI extension \endlink. template <class _Operation1, class _Operation2> -inline unary_compose<_Operation1,_Operation2> +inline unary_compose<_Operation1,_Operation2> compose1(const _Operation1& __fn1, const _Operation2& __fn2) { return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); @@ -155,8 +156,8 @@ protected: _Operation2 _M_fn2; _Operation3 _M_fn3; public: - binary_compose(const _Operation1& __x, const _Operation2& __y, - const _Operation3& __z) + binary_compose(const _Operation1& __x, const _Operation2& __y, + const _Operation3& __z) : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { } typename _Operation1::result_type operator()(const typename _Operation2::argument_type& __x) const { @@ -166,8 +167,8 @@ public: /// An \link SGIextensions SGI extension \endlink. template <class _Operation1, class _Operation2, class _Operation3> -inline binary_compose<_Operation1, _Operation2, _Operation3> -compose2(const _Operation1& __fn1, const _Operation2& __fn2, +inline binary_compose<_Operation1, _Operation2, _Operation3> +compose2(const _Operation1& __fn1, const _Operation2& __fn2, const _Operation3& __fn3) { return binary_compose<_Operation1,_Operation2,_Operation3> @@ -219,7 +220,7 @@ struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> { */ /// An \link SGIextensions SGI extension \endlink. -template <class _Arg1, class _Arg2> +template <class _Arg1, class _Arg2> struct project1st : public _Project1st<_Arg1, _Arg2> {}; /// An \link SGIextensions SGI extension \endlink. @@ -235,7 +236,7 @@ struct _Constant_void_fun { _Constant_void_fun(const result_type& __v) : _M_val(__v) {} const result_type& operator()() const { return _M_val; } -}; +}; template <class _Result, class _Argument> struct _Constant_unary_fun { @@ -278,7 +279,7 @@ struct _Constant_binary_fun { template <class _Result> struct constant_void_fun : public _Constant_void_fun<_Result> { constant_void_fun(const _Result& __v) : _Constant_void_fun<_Result>(__v) {} -}; +}; /// An \link SGIextensions SGI extension \endlink. template <class _Result, @@ -316,7 +317,7 @@ inline constant_unary_fun<_Result,_Result> constant1(const _Result& __val) /// An \link SGIextensions SGI extension \endlink. template <class _Result> -inline constant_binary_fun<_Result,_Result,_Result> +inline constant_binary_fun<_Result,_Result,_Result> constant2(const _Result& __val) { return constant_binary_fun<_Result,_Result,_Result>(__val); @@ -368,7 +369,7 @@ public: subtractive_rng() { _M_initialize(161803398u); } }; -// Mem_fun adaptor helper functions mem_fun1 and mem_fun1_ref, +// Mem_fun adaptor helper functions mem_fun1 and mem_fun1_ref, // provided for backward compatibility, they are no longer part of // the C++ standard. @@ -388,8 +389,7 @@ template <class _Ret, class _Tp, class _Arg> inline const_mem_fun1_ref_t<_Ret,_Tp,_Arg> mem_fun1_ref(_Ret (_Tp::*__f)(_Arg) const) { return const_mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } - } // namespace __gnu_cxx -#endif /* _EXT_FUNCTIONAL */ +#endif diff --git a/contrib/libstdc++/include/ext/hash_fun.h b/contrib/libstdc++/include/ext/hash_fun.h new file mode 100644 index 000000000000..27453a6b006b --- /dev/null +++ b/contrib/libstdc++/include/ext/hash_fun.h @@ -0,0 +1,122 @@ +// 'struct hash' from SGI -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file ext/hash_fun.h + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). You should only + * include this header if you are using GCC 3 or later. + */ + +#ifndef _HASH_FUN_H +#define _HASH_FUN_H 1 + +#include <cstddef> + +namespace __gnu_cxx +{ + using std::size_t; + + template <class _Key> struct hash { }; + + inline size_t + __stl_hash_string(const char* __s) + { + unsigned long __h = 0; + for ( ; *__s; ++__s) + __h = 5*__h + *__s; + return size_t(__h); + } + + template<> struct hash<char*> + { + size_t operator()(const char* __s) const + { return __stl_hash_string(__s); } + }; + + template<> struct hash<const char*> + { + size_t operator()(const char* __s) const + { return __stl_hash_string(__s); } + }; + + template<> struct hash<char> + { size_t operator()(char __x) const { return __x; } }; + + template<> struct hash<unsigned char> + { size_t operator()(unsigned char __x) const { return __x; } }; + + template<> struct hash<signed char> + { size_t operator()(unsigned char __x) const { return __x; } }; + + template<> struct hash<short> + { size_t operator()(short __x) const { return __x; } }; + + template<> struct hash<unsigned short> + { size_t operator()(unsigned short __x) const { return __x; } }; + + template<> struct hash<int> + { size_t operator()(int __x) const { return __x; } }; + + template<> struct hash<unsigned int> + { size_t operator()(unsigned int __x) const { return __x; } }; + + template<> struct hash<long> + { size_t operator()(long __x) const { return __x; } }; + + template<> struct hash<unsigned long> + { size_t operator()(unsigned long __x) const { return __x; } }; +} // namespace __gnu_cxx + +#endif diff --git a/contrib/libstdc++/include/ext/hash_map b/contrib/libstdc++/include/ext/hash_map index b66758de4462..5032c7b3f21f 100644 --- a/contrib/libstdc++/include/ext/hash_map +++ b/contrib/libstdc++/include/ext/hash_map @@ -59,30 +59,28 @@ * include this header if you are using GCC 3 or later. */ -#ifndef __SGI_STL_INTERNAL_HASH_MAP_H -#define __SGI_STL_INTERNAL_HASH_MAP_H +#ifndef _HASH_MAP +#define _HASH_MAP 1 -#include <ext/stl_hashtable.h> +#include <ext/hashtable.h> #include <bits/concept_check.h> namespace __gnu_cxx { -using std::equal_to; -using std::allocator; -using std::pair; -using std::_Select1st; - -// Forward declaration of equality operator; needed for friend declaration. - -template <class _Key, class _Tp, - class _HashFcn = hash<_Key>, - class _EqualKey = equal_to<_Key>, - class _Alloc = allocator<_Tp> > -class hash_map; - -template <class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> -inline bool operator==(const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&, - const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&); + using std::equal_to; + using std::allocator; + using std::pair; + using std::_Select1st; + + // Forward declaration of equality operator; needed for friend + // declaration. + template<class _Key, class _Tp, class _HashFcn = hash<_Key>, + class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> > + class hash_map; + + template<class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> + inline bool operator==(const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&, + const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&); /** * This is an SGI extension. * @ingroup SGIextensions @@ -104,7 +102,7 @@ public: 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; @@ -173,10 +171,10 @@ public: void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_unique(__f,__l); } pair<iterator,bool> insert_noresize(const value_type& __obj) - { return _M_ht.insert_unique_noresize(__obj); } + { return _M_ht.insert_unique_noresize(__obj); } iterator find(const key_type& __key) { return _M_ht.find(__key); } - const_iterator find(const key_type& __key) const + const_iterator find(const key_type& __key) const { return _M_ht.find(__key); } _Tp& operator[](const key_type& __key) { @@ -184,7 +182,7 @@ public: } size_type count(const key_type& __key) const { return _M_ht.count(__key); } - + pair<iterator, iterator> equal_range(const key_type& __key) { return _M_ht.equal_range(__key); } pair<const_iterator, const_iterator> @@ -204,7 +202,7 @@ public: }; template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> -inline bool +inline bool operator==(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { @@ -212,14 +210,14 @@ operator==(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, } template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> -inline bool +inline bool operator!=(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { return !(__hm1 == __hm2); } template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> -inline void +inline void swap(hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { @@ -235,7 +233,7 @@ template <class _Key, class _Tp, class hash_multimap; template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> -inline bool +inline bool operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2); @@ -248,14 +246,14 @@ template <class _Key, class _Tp, class _HashFcn, class _EqualKey, class _Alloc> class hash_multimap { // concept requirements - __glibcpp_class_requires(_Key, _SGIAssignableConcept) - __glibcpp_class_requires(_Tp, _SGIAssignableConcept) - __glibcpp_class_requires3(_HashFcn, size_t, _Key, _UnaryFunctionConcept); - __glibcpp_class_requires3(_EqualKey, _Key, _Key, _BinaryPredicateConcept); + __glibcxx_class_requires(_Key, _SGIAssignableConcept) + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires3(_HashFcn, size_t, _Key, _UnaryFunctionConcept) + __glibcxx_class_requires3(_EqualKey, _Key, _Key, _BinaryPredicateConcept) private: typedef hashtable<pair<const _Key, _Tp>, _Key, _HashFcn, - _Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc> + _Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc> _Ht; _Ht _M_ht; @@ -329,20 +327,20 @@ public: const_iterator end() const { return _M_ht.end(); } public: - iterator insert(const value_type& __obj) + iterator insert(const value_type& __obj) { return _M_ht.insert_equal(__obj); } template <class _InputIterator> - void insert(_InputIterator __f, _InputIterator __l) + void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_equal(__f,__l); } iterator insert_noresize(const value_type& __obj) - { return _M_ht.insert_equal_noresize(__obj); } + { return _M_ht.insert_equal_noresize(__obj); } iterator find(const key_type& __key) { return _M_ht.find(__key); } - const_iterator find(const key_type& __key) const + const_iterator find(const key_type& __key) const { return _M_ht.find(__key); } size_type count(const key_type& __key) const { return _M_ht.count(__key); } - + pair<iterator, iterator> equal_range(const key_type& __key) { return _M_ht.equal_range(__key); } pair<const_iterator, const_iterator> @@ -363,7 +361,7 @@ public: }; template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> -inline bool +inline bool operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2) { @@ -371,14 +369,14 @@ operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, } template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> -inline bool +inline bool operator!=(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2) { return !(__hm1 == __hm2); } template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> -inline void +inline void swap(hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { @@ -409,7 +407,7 @@ public: insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} insert_iterator<_Container>& - operator=(const typename _Container::value_type& __value) { + operator=(const typename _Container::value_type& __value) { container->insert(__value); return *this; } @@ -436,7 +434,7 @@ public: insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} insert_iterator<_Container>& - operator=(const typename _Container::value_type& __value) { + operator=(const typename _Container::value_type& __value) { container->insert(__value); return *this; } @@ -444,11 +442,6 @@ public: insert_iterator<_Container>& operator++() { return *this; } insert_iterator<_Container>& operator++(int) { return *this; } }; - } // namespace std -#endif /* __SGI_STL_INTERNAL_HASH_MAP_H */ - -// Local Variables: -// mode:C++ -// End: +#endif diff --git a/contrib/libstdc++/include/ext/hash_set b/contrib/libstdc++/include/ext/hash_set index 0f420e2dd7eb..fee64fcbdb0e 100644 --- a/contrib/libstdc++/include/ext/hash_set +++ b/contrib/libstdc++/include/ext/hash_set @@ -59,31 +59,30 @@ * include this header if you are using GCC 3 or later. */ -#ifndef __SGI_STL_INTERNAL_HASH_SET_H -#define __SGI_STL_INTERNAL_HASH_SET_H +#ifndef _HASH_SET +#define _HASH_SET 1 -#include <ext/stl_hashtable.h> +#include <ext/hashtable.h> #include <bits/concept_check.h> namespace __gnu_cxx { -using std::equal_to; -using std::allocator; -using std::pair; -using std::_Identity; - -// Forward declaration of equality operator; needed for friend declaration. - -template <class _Value, - class _HashFcn = hash<_Value>, - class _EqualKey = equal_to<_Value>, - class _Alloc = allocator<_Value> > -class hash_set; - -template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> -inline bool -operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, - const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2); + using std::equal_to; + using std::allocator; + using std::pair; + using std::_Identity; + + // Forward declaration of equality operator; needed for friend + // declaration. + template <class _Value, class _HashFcn = hash<_Value>, + class _EqualKey = equal_to<_Value>, + class _Alloc = allocator<_Value> > + class hash_set; + + template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> + inline bool + operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2); /** * This is an SGI extension. @@ -94,12 +93,12 @@ template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> class hash_set { // concept requirements - __glibcpp_class_requires(_Value, _SGIAssignableConcept) - __glibcpp_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept); - __glibcpp_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept); + __glibcxx_class_requires(_Value, _SGIAssignableConcept) + __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) + __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) private: - typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, + typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey, _Alloc> _Ht; _Ht _M_ht; @@ -111,10 +110,10 @@ public: 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 _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; typedef typename _Ht::const_iterator iterator; typedef typename _Ht::const_iterator const_iterator; @@ -162,7 +161,7 @@ public: bool empty() const { return _M_ht.empty(); } void swap(hash_set& __hs) { _M_ht.swap(__hs._M_ht); } - template <class _Val, class _HF, class _EqK, class _Al> + template <class _Val, class _HF, class _EqK, class _Al> friend bool operator== (const hash_set<_Val, _HF, _EqK, _Al>&, const hash_set<_Val, _HF, _EqK, _Al>&); @@ -176,11 +175,11 @@ public: return pair<iterator,bool>(__p.first, __p.second); } template <class _InputIterator> - void insert(_InputIterator __f, _InputIterator __l) + void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_unique(__f,__l); } pair<iterator, bool> insert_noresize(const value_type& __obj) { - pair<typename _Ht::iterator, bool> __p = + pair<typename _Ht::iterator, bool> __p = _M_ht.insert_unique_noresize(__obj); return pair<iterator, bool>(__p.first, __p.second); } @@ -188,7 +187,7 @@ public: iterator find(const key_type& __key) const { return _M_ht.find(__key); } size_type count(const key_type& __key) const { return _M_ht.count(__key); } - + pair<iterator, iterator> equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } @@ -206,7 +205,7 @@ public: }; template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> -inline bool +inline bool operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2) { @@ -214,14 +213,14 @@ operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, } template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> -inline bool +inline bool operator!=(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2) { return !(__hs1 == __hs2); } template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> -inline void +inline void swap(hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { @@ -236,7 +235,7 @@ template <class _Value, class hash_multiset; template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> -inline bool +inline bool operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2); @@ -250,12 +249,12 @@ template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> class hash_multiset { // concept requirements - __glibcpp_class_requires(_Value, _SGIAssignableConcept) - __glibcpp_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept); - __glibcpp_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept); + __glibcxx_class_requires(_Value, _SGIAssignableConcept) + __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) + __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) private: - typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, + typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey, _Alloc> _Ht; _Ht _M_ht; @@ -267,10 +266,10 @@ public: 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 _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; typedef typename _Ht::const_iterator iterator; typedef typename _Ht::const_iterator const_iterator; @@ -318,7 +317,7 @@ public: bool empty() const { return _M_ht.empty(); } void swap(hash_multiset& hs) { _M_ht.swap(hs._M_ht); } - template <class _Val, class _HF, class _EqK, class _Al> + template <class _Val, class _HF, class _EqK, class _Al> friend bool operator== (const hash_multiset<_Val, _HF, _EqK, _Al>&, const hash_multiset<_Val, _HF, _EqK, _Al>&); @@ -329,15 +328,15 @@ public: iterator insert(const value_type& __obj) { return _M_ht.insert_equal(__obj); } template <class _InputIterator> - void insert(_InputIterator __f, _InputIterator __l) + void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_equal(__f,__l); } iterator insert_noresize(const value_type& __obj) - { return _M_ht.insert_equal_noresize(__obj); } + { return _M_ht.insert_equal_noresize(__obj); } iterator find(const key_type& __key) const { return _M_ht.find(__key); } size_type count(const key_type& __key) const { return _M_ht.count(__key); } - + pair<iterator, iterator> equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } @@ -355,7 +354,7 @@ public: }; template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> -inline bool +inline bool operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { @@ -363,14 +362,14 @@ operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, } template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> -inline bool +inline bool operator!=(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { return !(__hs1 == __hs2); } template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> -inline void +inline void swap(hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { __hs1.swap(__hs2); @@ -400,7 +399,7 @@ public: insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} insert_iterator<_Container>& - operator=(const typename _Container::value_type& __value) { + operator=(const typename _Container::value_type& __value) { container->insert(__value); return *this; } @@ -427,7 +426,7 @@ public: insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} insert_iterator<_Container>& - operator=(const typename _Container::value_type& __value) { + operator=(const typename _Container::value_type& __value) { container->insert(__value); return *this; } @@ -435,11 +434,6 @@ public: insert_iterator<_Container>& operator++() { return *this; } insert_iterator<_Container>& operator++(int) { return *this; } }; - } // namespace std -#endif /* __SGI_STL_INTERNAL_HASH_SET_H */ - -// Local Variables: -// mode:C++ -// End: +#endif diff --git a/contrib/libstdc++/include/ext/hashtable.h b/contrib/libstdc++/include/ext/hashtable.h new file mode 100644 index 000000000000..f81a8580b15a --- /dev/null +++ b/contrib/libstdc++/include/ext/hashtable.h @@ -0,0 +1,994 @@ +// Hashtable implementation used by containers -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +/** @file ext/hashtable.h + * This file is a GNU extension to the Standard C++ Library (possibly + * containing extensions from the HP/SGI STL subset). You should only + * include this header if you are using GCC 3 or later. + */ + +#ifndef _HASHTABLE_H +#define _HASHTABLE_H 1 + +// Hashtable class, used to implement the hashed associative containers +// hash_set, hash_map, hash_multiset, and hash_multimap. + +#include <vector> +#include <iterator> +#include <bits/stl_algo.h> +#include <bits/stl_function.h> +#include <ext/hash_fun.h> + +namespace __gnu_cxx +{ +using std::size_t; +using std::ptrdiff_t; +using std::forward_iterator_tag; +using std::input_iterator_tag; +using std::_Construct; +using std::_Destroy; +using std::distance; +using std::vector; +using std::pair; +using std::__iterator_category; + +template <class _Val> +struct _Hashtable_node +{ + _Hashtable_node* _M_next; + _Val _M_val; +}; + +template <class _Val, class _Key, class _HashFcn, class _ExtractKey, + class _EqualKey, class _Alloc = std::allocator<_Val> > +class hashtable; + +template <class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> +struct _Hashtable_iterator; + +template <class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> +struct _Hashtable_const_iterator; + +template <class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> +struct _Hashtable_iterator { + typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + _Hashtable; + typedef _Hashtable_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + const_iterator; + typedef _Hashtable_node<_Val> _Node; + + typedef forward_iterator_tag iterator_category; + typedef _Val value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef _Val& reference; + typedef _Val* pointer; + + _Node* _M_cur; + _Hashtable* _M_ht; + + _Hashtable_iterator(_Node* __n, _Hashtable* __tab) + : _M_cur(__n), _M_ht(__tab) {} + _Hashtable_iterator() {} + reference operator*() const { return _M_cur->_M_val; } + pointer operator->() const { return &(operator*()); } + iterator& operator++(); + iterator operator++(int); + bool operator==(const iterator& __it) const + { return _M_cur == __it._M_cur; } + bool operator!=(const iterator& __it) const + { return _M_cur != __it._M_cur; } +}; + + +template <class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> +struct _Hashtable_const_iterator { + typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + _Hashtable; + typedef _Hashtable_iterator<_Val,_Key,_HashFcn, + _ExtractKey,_EqualKey,_Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + const_iterator; + typedef _Hashtable_node<_Val> _Node; + + typedef forward_iterator_tag iterator_category; + typedef _Val value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef const _Val& reference; + typedef const _Val* pointer; + + const _Node* _M_cur; + const _Hashtable* _M_ht; + + _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab) + : _M_cur(__n), _M_ht(__tab) {} + _Hashtable_const_iterator() {} + _Hashtable_const_iterator(const iterator& __it) + : _M_cur(__it._M_cur), _M_ht(__it._M_ht) {} + reference operator*() const { return _M_cur->_M_val; } + pointer operator->() const { return &(operator*()); } + const_iterator& operator++(); + const_iterator operator++(int); + bool operator==(const const_iterator& __it) const + { return _M_cur == __it._M_cur; } + bool operator!=(const const_iterator& __it) const + { return _M_cur != __it._M_cur; } +}; + +// Note: assumes long is at least 32 bits. +enum { _S_num_primes = 28 }; + +static const unsigned long __stl_prime_list[_S_num_primes] = +{ + 53ul, 97ul, 193ul, 389ul, 769ul, + 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, + 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, + 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, + 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, + 1610612741ul, 3221225473ul, 4294967291ul +}; + +inline unsigned long __stl_next_prime(unsigned long __n) +{ + const unsigned long* __first = __stl_prime_list; + const unsigned long* __last = __stl_prime_list + (int)_S_num_primes; + const unsigned long* pos = std::lower_bound(__first, __last, __n); + return pos == __last ? *(__last - 1) : *pos; +} + +// Forward declaration of operator==. + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +class hashtable; + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, + const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2); + + +// Hashtables handle allocators a bit differently than other +// containers do. If we're using standard-conforming allocators, then +// a hashtable unconditionally has a member variable to hold its +// allocator, even if it so happens that all instances of the +// allocator type are identical. This is because, for hashtables, +// this extra storage is negligible. Additionally, a base class +// wouldn't serve any other purposes; it wouldn't, for example, +// simplify the exception-handling code. + +template <class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> +class hashtable { +public: + typedef _Key key_type; + typedef _Val value_type; + typedef _HashFcn hasher; + typedef _EqualKey key_equal; + + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + hasher hash_funct() const { return _M_hash; } + key_equal key_eq() const { return _M_equals; } + +private: + typedef _Hashtable_node<_Val> _Node; + +public: + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return _M_node_allocator; } +private: + typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc; + typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc; + typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type; + + _Node_Alloc _M_node_allocator; + _Node* _M_get_node() { return _M_node_allocator.allocate(1); } + void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); } + +private: + hasher _M_hash; + key_equal _M_equals; + _ExtractKey _M_get_key; + _Vector_type _M_buckets; + size_type _M_num_elements; + +public: + typedef _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey, + _Alloc> + const_iterator; + + friend struct + _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>; + friend struct + _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>; + +public: + hashtable(size_type __n, + const _HashFcn& __hf, + const _EqualKey& __eql, + const _ExtractKey& __ext, + const allocator_type& __a = allocator_type()) + : _M_node_allocator(__a), + _M_hash(__hf), + _M_equals(__eql), + _M_get_key(__ext), + _M_buckets(__a), + _M_num_elements(0) + { + _M_initialize_buckets(__n); + } + + hashtable(size_type __n, + const _HashFcn& __hf, + const _EqualKey& __eql, + const allocator_type& __a = allocator_type()) + : _M_node_allocator(__a), + _M_hash(__hf), + _M_equals(__eql), + _M_get_key(_ExtractKey()), + _M_buckets(__a), + _M_num_elements(0) + { + _M_initialize_buckets(__n); + } + + hashtable(const hashtable& __ht) + : _M_node_allocator(__ht.get_allocator()), + _M_hash(__ht._M_hash), + _M_equals(__ht._M_equals), + _M_get_key(__ht._M_get_key), + _M_buckets(__ht.get_allocator()), + _M_num_elements(0) + { + _M_copy_from(__ht); + } + + hashtable& operator= (const hashtable& __ht) + { + if (&__ht != this) { + clear(); + _M_hash = __ht._M_hash; + _M_equals = __ht._M_equals; + _M_get_key = __ht._M_get_key; + _M_copy_from(__ht); + } + return *this; + } + + ~hashtable() { clear(); } + + size_type size() const { return _M_num_elements; } + size_type max_size() const { return size_type(-1); } + bool empty() const { return size() == 0; } + + void swap(hashtable& __ht) + { + std::swap(_M_hash, __ht._M_hash); + std::swap(_M_equals, __ht._M_equals); + std::swap(_M_get_key, __ht._M_get_key); + _M_buckets.swap(__ht._M_buckets); + std::swap(_M_num_elements, __ht._M_num_elements); + } + + iterator begin() + { + for (size_type __n = 0; __n < _M_buckets.size(); ++__n) + if (_M_buckets[__n]) + return iterator(_M_buckets[__n], this); + return end(); + } + + iterator end() { return iterator(0, this); } + + const_iterator begin() const + { + for (size_type __n = 0; __n < _M_buckets.size(); ++__n) + if (_M_buckets[__n]) + return const_iterator(_M_buckets[__n], this); + return end(); + } + + const_iterator end() const { return const_iterator(0, this); } + + template <class _Vl, class _Ky, class _HF, class _Ex, class _Eq, class _Al> + friend bool operator== (const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&, + const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&); +public: + + size_type bucket_count() const { return _M_buckets.size(); } + + size_type max_bucket_count() const + { return __stl_prime_list[(int)_S_num_primes - 1]; } + + size_type elems_in_bucket(size_type __bucket) const + { + size_type __result = 0; + for (_Node* __cur = _M_buckets[__bucket]; __cur; __cur = __cur->_M_next) + __result += 1; + return __result; + } + + pair<iterator, bool> insert_unique(const value_type& __obj) + { + resize(_M_num_elements + 1); + return insert_unique_noresize(__obj); + } + + iterator insert_equal(const value_type& __obj) + { + resize(_M_num_elements + 1); + return insert_equal_noresize(__obj); + } + + pair<iterator, bool> insert_unique_noresize(const value_type& __obj); + iterator insert_equal_noresize(const value_type& __obj); + + template <class _InputIterator> + void insert_unique(_InputIterator __f, _InputIterator __l) + { + insert_unique(__f, __l, __iterator_category(__f)); + } + + template <class _InputIterator> + void insert_equal(_InputIterator __f, _InputIterator __l) + { + insert_equal(__f, __l, __iterator_category(__f)); + } + + template <class _InputIterator> + void insert_unique(_InputIterator __f, _InputIterator __l, + input_iterator_tag) + { + for ( ; __f != __l; ++__f) + insert_unique(*__f); + } + + template <class _InputIterator> + void insert_equal(_InputIterator __f, _InputIterator __l, + input_iterator_tag) + { + for ( ; __f != __l; ++__f) + insert_equal(*__f); + } + + template <class _ForwardIterator> + void insert_unique(_ForwardIterator __f, _ForwardIterator __l, + forward_iterator_tag) + { + size_type __n = distance(__f, __l); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_unique_noresize(*__f); + } + + template <class _ForwardIterator> + void insert_equal(_ForwardIterator __f, _ForwardIterator __l, + forward_iterator_tag) + { + size_type __n = distance(__f, __l); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_equal_noresize(*__f); + } + + reference find_or_insert(const value_type& __obj); + + iterator find(const key_type& __key) + { + size_type __n = _M_bkt_num_key(__key); + _Node* __first; + for ( __first = _M_buckets[__n]; + __first && !_M_equals(_M_get_key(__first->_M_val), __key); + __first = __first->_M_next) + {} + return iterator(__first, this); + } + + const_iterator find(const key_type& __key) const + { + size_type __n = _M_bkt_num_key(__key); + const _Node* __first; + for ( __first = _M_buckets[__n]; + __first && !_M_equals(_M_get_key(__first->_M_val), __key); + __first = __first->_M_next) + {} + return const_iterator(__first, this); + } + + size_type count(const key_type& __key) const + { + const size_type __n = _M_bkt_num_key(__key); + size_type __result = 0; + + for (const _Node* __cur = _M_buckets[__n]; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), __key)) + ++__result; + return __result; + } + + pair<iterator, iterator> + equal_range(const key_type& __key); + + pair<const_iterator, const_iterator> + equal_range(const key_type& __key) const; + + size_type erase(const key_type& __key); + void erase(const iterator& __it); + void erase(iterator __first, iterator __last); + + void erase(const const_iterator& __it); + void erase(const_iterator __first, const_iterator __last); + + void resize(size_type __num_elements_hint); + void clear(); + +private: + size_type _M_next_size(size_type __n) const + { return __stl_next_prime(__n); } + + void _M_initialize_buckets(size_type __n) + { + const size_type __n_buckets = _M_next_size(__n); + _M_buckets.reserve(__n_buckets); + _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0); + _M_num_elements = 0; + } + + size_type _M_bkt_num_key(const key_type& __key) const + { + return _M_bkt_num_key(__key, _M_buckets.size()); + } + + size_type _M_bkt_num(const value_type& __obj) const + { + return _M_bkt_num_key(_M_get_key(__obj)); + } + + size_type _M_bkt_num_key(const key_type& __key, size_t __n) const + { + return _M_hash(__key) % __n; + } + + size_type _M_bkt_num(const value_type& __obj, size_t __n) const + { + return _M_bkt_num_key(_M_get_key(__obj), __n); + } + + _Node* _M_new_node(const value_type& __obj) + { + _Node* __n = _M_get_node(); + __n->_M_next = 0; + try { + _Construct(&__n->_M_val, __obj); + return __n; + } + catch(...) + { + _M_put_node(__n); + __throw_exception_again; + } + } + + void _M_delete_node(_Node* __n) + { + _Destroy(&__n->_M_val); + _M_put_node(__n); + } + + void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last); + void _M_erase_bucket(const size_type __n, _Node* __last); + + void _M_copy_from(const hashtable& __ht); + +}; + +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& +_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++() +{ + const _Node* __old = _M_cur; + _M_cur = _M_cur->_M_next; + if (!_M_cur) { + size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); + while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) + _M_cur = _M_ht->_M_buckets[__bucket]; + } + return *this; +} + +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +inline _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All> +_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int) +{ + iterator __tmp = *this; + ++*this; + return __tmp; +} + +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& +_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++() +{ + const _Node* __old = _M_cur; + _M_cur = _M_cur->_M_next; + if (!_M_cur) { + size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); + while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) + _M_cur = _M_ht->_M_buckets[__bucket]; + } + return *this; +} + +template <class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> +inline _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All> +_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int) +{ + const_iterator __tmp = *this; + ++*this; + return __tmp; +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, + const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) +{ + typedef typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::_Node _Node; + if (__ht1._M_buckets.size() != __ht2._M_buckets.size()) + return false; + for (size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n) { + _Node* __cur1 = __ht1._M_buckets[__n]; + _Node* __cur2 = __ht2._M_buckets[__n]; + // Check same length of lists + for ( ; __cur1 && __cur2; + __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) + {} + if (__cur1 || __cur2) + return false; + // Now check one's elements are in the other + for (__cur1 = __ht1._M_buckets[__n] ; __cur1; __cur1 = __cur1->_M_next) + { + bool _found__cur1 = false; + for (_Node* __cur2 = __ht2._M_buckets[__n]; + __cur2; __cur2 = __cur2->_M_next) + { + if (__cur1->_M_val == __cur2->_M_val) + { + _found__cur1 = true; + break; + } + } + if (!_found__cur1) + return false; + } + } + return true; +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +inline bool operator!=(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, + const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) { + return !(__ht1 == __ht2); +} + +template <class _Val, class _Key, class _HF, class _Extract, class _EqKey, + class _All> +inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, + hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) { + __ht1.swap(__ht2); +} + + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, bool> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::insert_unique_noresize(const value_type& __obj) +{ + const size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) + return pair<iterator, bool>(iterator(__cur, this), false); + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return pair<iterator, bool>(iterator(__tmp, this), true); +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::insert_equal_noresize(const value_type& __obj) +{ + const size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) { + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __cur->_M_next; + __cur->_M_next = __tmp; + ++_M_num_elements; + return iterator(__tmp, this); + } + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return iterator(__tmp, this); +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::reference +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::find_or_insert(const value_type& __obj) +{ + resize(_M_num_elements + 1); + + size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) + return __cur->_M_val; + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return __tmp->_M_val; +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator, + typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key) +{ + typedef pair<iterator, iterator> _Pii; + const size_type __n = _M_bkt_num_key(__key); + + for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next) + if (_M_equals(_M_get_key(__first->_M_val), __key)) { + for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next) + if (!_M_equals(_M_get_key(__cur->_M_val), __key)) + return _Pii(iterator(__first, this), iterator(__cur, this)); + for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) + if (_M_buckets[__m]) + return _Pii(iterator(__first, this), + iterator(_M_buckets[__m], this)); + return _Pii(iterator(__first, this), end()); + } + return _Pii(end(), end()); +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +pair<typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator, + typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::equal_range(const key_type& __key) const +{ + typedef pair<const_iterator, const_iterator> _Pii; + const size_type __n = _M_bkt_num_key(__key); + + for (const _Node* __first = _M_buckets[__n] ; + __first; + __first = __first->_M_next) { + if (_M_equals(_M_get_key(__first->_M_val), __key)) { + for (const _Node* __cur = __first->_M_next; + __cur; + __cur = __cur->_M_next) + if (!_M_equals(_M_get_key(__cur->_M_val), __key)) + return _Pii(const_iterator(__first, this), + const_iterator(__cur, this)); + for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) + if (_M_buckets[__m]) + return _Pii(const_iterator(__first, this), + const_iterator(_M_buckets[__m], this)); + return _Pii(const_iterator(__first, this), end()); + } + } + return _Pii(end(), end()); +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::size_type +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const key_type& __key) +{ + const size_type __n = _M_bkt_num_key(__key); + _Node* __first = _M_buckets[__n]; + size_type __erased = 0; + + if (__first) { + _Node* __cur = __first; + _Node* __next = __cur->_M_next; + while (__next) { + if (_M_equals(_M_get_key(__next->_M_val), __key)) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + ++__erased; + --_M_num_elements; + } + else { + __cur = __next; + __next = __cur->_M_next; + } + } + if (_M_equals(_M_get_key(__first->_M_val), __key)) { + _M_buckets[__n] = __first->_M_next; + _M_delete_node(__first); + ++__erased; + --_M_num_elements; + } + } + return __erased; +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it) +{ + _Node* __p = __it._M_cur; + if (__p) { + const size_type __n = _M_bkt_num(__p->_M_val); + _Node* __cur = _M_buckets[__n]; + + if (__cur == __p) { + _M_buckets[__n] = __cur->_M_next; + _M_delete_node(__cur); + --_M_num_elements; + } + else { + _Node* __next = __cur->_M_next; + while (__next) { + if (__next == __p) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + --_M_num_elements; + break; + } + else { + __cur = __next; + __next = __cur->_M_next; + } + } + } + } +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::erase(iterator __first, iterator __last) +{ + size_type __f_bucket = __first._M_cur ? + _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size(); + size_type __l_bucket = __last._M_cur ? + _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size(); + + if (__first._M_cur == __last._M_cur) + return; + else if (__f_bucket == __l_bucket) + _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur); + else { + _M_erase_bucket(__f_bucket, __first._M_cur, 0); + for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n) + _M_erase_bucket(__n, 0); + if (__l_bucket != _M_buckets.size()) + _M_erase_bucket(__l_bucket, __last._M_cur); + } +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +inline void +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const_iterator __first, + const_iterator __last) +{ + erase(iterator(const_cast<_Node*>(__first._M_cur), + const_cast<hashtable*>(__first._M_ht)), + iterator(const_cast<_Node*>(__last._M_cur), + const_cast<hashtable*>(__last._M_ht))); +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +inline void +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const const_iterator& __it) +{ + erase(iterator(const_cast<_Node*>(__it._M_cur), + const_cast<hashtable*>(__it._M_ht))); +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::resize(size_type __num_elements_hint) +{ + const size_type __old_n = _M_buckets.size(); + if (__num_elements_hint > __old_n) { + const size_type __n = _M_next_size(__num_elements_hint); + if (__n > __old_n) { + _Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator()); + try { + for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) { + _Node* __first = _M_buckets[__bucket]; + while (__first) { + size_type __new_bucket = _M_bkt_num(__first->_M_val, __n); + _M_buckets[__bucket] = __first->_M_next; + __first->_M_next = __tmp[__new_bucket]; + __tmp[__new_bucket] = __first; + __first = _M_buckets[__bucket]; + } + } + _M_buckets.swap(__tmp); + } + catch(...) { + for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) { + while (__tmp[__bucket]) { + _Node* __next = __tmp[__bucket]->_M_next; + _M_delete_node(__tmp[__bucket]); + __tmp[__bucket] = __next; + } + } + __throw_exception_again; + } + } + } +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last) +{ + _Node* __cur = _M_buckets[__n]; + if (__cur == __first) + _M_erase_bucket(__n, __last); + else { + _Node* __next; + for (__next = __cur->_M_next; + __next != __first; + __cur = __next, __next = __cur->_M_next) + ; + while (__next != __last) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + --_M_num_elements; + } + } +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::_M_erase_bucket(const size_type __n, _Node* __last) +{ + _Node* __cur = _M_buckets[__n]; + while (__cur != __last) { + _Node* __next = __cur->_M_next; + _M_delete_node(__cur); + __cur = __next; + _M_buckets[__n] = __cur; + --_M_num_elements; + } +} + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::clear() +{ + for (size_type __i = 0; __i < _M_buckets.size(); ++__i) { + _Node* __cur = _M_buckets[__i]; + while (__cur != 0) { + _Node* __next = __cur->_M_next; + _M_delete_node(__cur); + __cur = __next; + } + _M_buckets[__i] = 0; + } + _M_num_elements = 0; +} + + +template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::_M_copy_from(const hashtable& __ht) +{ + _M_buckets.clear(); + _M_buckets.reserve(__ht._M_buckets.size()); + _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0); + try { + for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { + const _Node* __cur = __ht._M_buckets[__i]; + if (__cur) { + _Node* __local_copy = _M_new_node(__cur->_M_val); + _M_buckets[__i] = __local_copy; + + for (_Node* __next = __cur->_M_next; + __next; + __cur = __next, __next = __cur->_M_next) { + __local_copy->_M_next = _M_new_node(__next->_M_val); + __local_copy = __local_copy->_M_next; + } + } + } + _M_num_elements = __ht._M_num_elements; + } + catch(...) + { + clear(); + __throw_exception_again; + } +} +} // namespace __gnu_cxx + +#endif diff --git a/contrib/libstdc++/include/ext/iterator b/contrib/libstdc++/include/ext/iterator index f23212f241d6..094313c76e47 100644 --- a/contrib/libstdc++/include/ext/iterator +++ b/contrib/libstdc++/include/ext/iterator @@ -60,36 +60,37 @@ */ #ifndef _EXT_ITERATOR -#define _EXT_ITERATOR +#define _EXT_ITERATOR 1 #pragma GCC system_header + #include <bits/concept_check.h> #include <iterator> namespace __gnu_cxx { - - // There are two signatures for distance. In addition to the one taking - // two iterators and returning a result, there is another taking two - // iterators and a reference-to-result variable, and returning nothing. - // The latter seems to be an SGI extension. -- pedwards + // There are two signatures for distance. In addition to the one + // taking two iterators and returning a result, there is another + // taking two iterators and a reference-to-result variable, and + // returning nothing. The latter seems to be an SGI extension. + // -- pedwards template<typename _InputIterator, typename _Distance> inline void __distance(_InputIterator __first, _InputIterator __last, _Distance& __n, std::input_iterator_tag) { // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>) + __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) while (__first != __last) { ++__first; ++__n; } } template<typename _RandomAccessIterator, typename _Distance> inline void - __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, + __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, _Distance& __n, std::random_access_iterator_tag) { // concept requirements - __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) + __glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) __n += __last - __first; } @@ -106,8 +107,7 @@ namespace __gnu_cxx // concept requirements -- taken care of in __distance __distance(__first, __last, __n, std::__iterator_category(__first)); } - } // namespace __gnu_cxx -#endif /* _EXT_ITERATOR */ +#endif diff --git a/contrib/libstdc++/include/ext/malloc_allocator.h b/contrib/libstdc++/include/ext/malloc_allocator.h new file mode 100644 index 000000000000..938380c36f6e --- /dev/null +++ b/contrib/libstdc++/include/ext/malloc_allocator.h @@ -0,0 +1,118 @@ +// Allocator that wraps "C" malloc -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _MALLOC_ALLOCATOR_H +#define _MALLOC_ALLOCATOR_H 1 + +#include <new> + +namespace __gnu_cxx +{ + /** + * @brief An allocator that uses malloc + * + * This is precisely the allocator defined in the C++ Standard. + * - all allocation calls malloc + * - all deallocation calls free + * + * (See @link Allocators allocators info @endlink for more.) + */ + template<typename _Tp> + class malloc_allocator + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template<typename _Tp1> + struct rebind + { typedef malloc_allocator<_Tp1> other; }; + + malloc_allocator() throw() { } + + malloc_allocator(const malloc_allocator&) throw() { } + + template<typename _Tp1> + malloc_allocator(const malloc_allocator<_Tp1>&) throw() { } + + ~malloc_allocator() throw() { } + + pointer + address(reference __x) const { return &__x; } + + const_pointer + address(const_reference __x) const { return &__x; } + + // NB: __n is permitted to be 0. The C++ standard says nothing + // about what the return value is when __n == 0. + pointer + allocate(size_type __n, const void* = 0) + { + pointer __ret = static_cast<_Tp*>(malloc(__n * sizeof(_Tp))); + if (!__ret) + throw std::bad_alloc(); + return __ret; + } + + // __p is not permitted to be a null pointer. + void + deallocate(pointer __p, size_type) + { free(static_cast<void*>(__p)); } + + size_type + max_size() const throw() + { return size_t(-1) / sizeof(_Tp); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_] allocator::construct + void + construct(pointer __p, const _Tp& __val) + { ::new(__p) value_type(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } + }; + + template<typename _Tp> + inline bool + operator==(const malloc_allocator<_Tp>&, const malloc_allocator<_Tp>&) + { return true; } + + template<typename _Tp> + inline bool + operator!=(const malloc_allocator<_Tp>&, const malloc_allocator<_Tp>&) + { return false; } +} // namespace __gnu_cxx + +#endif diff --git a/contrib/libstdc++/include/ext/memory b/contrib/libstdc++/include/ext/memory index 5626b70e6af5..1d93f90ac7ab 100644 --- a/contrib/libstdc++/include/ext/memory +++ b/contrib/libstdc++/include/ext/memory @@ -60,9 +60,10 @@ */ #ifndef _EXT_MEMORY -#define _EXT_MEMORY +#define _EXT_MEMORY 1 #pragma GCC system_header + #include <memory> #include <bits/stl_tempbuf.h> @@ -72,24 +73,23 @@ namespace __gnu_cxx using std::pair; using std::__iterator_category; using std::_Temporary_buffer; - template<typename _InputIter, typename _Size, typename _ForwardIter> pair<_InputIter, _ForwardIter> __uninitialized_copy_n(_InputIter __first, _Size __count, - _ForwardIter __result, - std::input_iterator_tag) + _ForwardIter __result, std::input_iterator_tag) { _ForwardIter __cur = __result; - try { - for ( ; __count > 0 ; --__count, ++__first, ++__cur) - std::_Construct(&*__cur, *__first); - return pair<_InputIter, _ForwardIter>(__first, __cur); - } + try + { + for ( ; __count > 0 ; --__count, ++__first, ++__cur) + std::_Construct(&*__cur, *__first); + return pair<_InputIter, _ForwardIter>(__first, __cur); + } catch(...) { std::_Destroy(__result, __cur); - __throw_exception_again; + __throw_exception_again; } } @@ -108,7 +108,8 @@ namespace __gnu_cxx template<typename _InputIter, typename _Size, typename _ForwardIter> inline pair<_InputIter, _ForwardIter> __uninitialized_copy_n(_InputIter __first, _Size __count, - _ForwardIter __result) { + _ForwardIter __result) + { return __uninitialized_copy_n(__first, __count, __result, __iterator_category(__first)); } @@ -126,7 +127,8 @@ namespace __gnu_cxx template<typename _InputIter, typename _Size, typename _ForwardIter> inline pair<_InputIter, _ForwardIter> uninitialized_copy_n(_InputIter __first, _Size __count, - _ForwardIter __result) { + _ForwardIter __result) + { return __uninitialized_copy_n(__first, __count, __result, __iterator_category(__first)); } @@ -152,19 +154,18 @@ namespace __gnu_cxx * * @ingroup SGIextensions */ - template <class _ForwardIterator, - class _Tp + template <class _ForwardIterator, class _Tp = typename std::iterator_traits<_ForwardIterator>::value_type > struct temporary_buffer : public _Temporary_buffer<_ForwardIterator, _Tp> { /// Requests storage large enough to hold a copy of [first,last). temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) - : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) {} + : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) { } + /// Destroys objects and frees storage. - ~temporary_buffer() {} + ~temporary_buffer() { } }; - } // namespace __gnu_cxx -#endif /* _EXT_MEMORY */ +#endif diff --git a/contrib/libstdc++/include/ext/mt_allocator.h b/contrib/libstdc++/include/ext/mt_allocator.h new file mode 100644 index 000000000000..f0ee2ebd26db --- /dev/null +++ b/contrib/libstdc++/include/ext/mt_allocator.h @@ -0,0 +1,718 @@ +// MT-optimized allocator -*- C++ -*- + +// Copyright (C) 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file ext/mt_allocator.h + * This file is a GNU extension to the Standard C++ Library. + * You should only include this header if you are using GCC 3 or later. + */ + +#ifndef _MT_ALLOCATOR_H +#define _MT_ALLOCATOR_H 1 + +#include <new> +#include <cstdlib> +#include <bits/functexcept.h> +#include <bits/gthr.h> +#include <bits/atomicity.h> + +namespace __gnu_cxx +{ + /** + * This is a fixed size (power of 2) allocator which - when + * compiled with thread support - will maintain one freelist per + * size per thread plus a "global" one. Steps are taken to limit + * the per thread freelist sizes (by returning excess back to + * "global"). + * + * Further details: + * http://gcc.gnu.org/onlinedocs/libstdc++/ext/mt_allocator.html + */ + template<typename _Tp> + class __mt_alloc + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template<typename _Tp1> + struct rebind + { typedef __mt_alloc<_Tp1> other; }; + + __mt_alloc() throw() + { + // XXX + } + + __mt_alloc(const __mt_alloc&) throw() + { + // XXX + } + + template<typename _Tp1> + __mt_alloc(const __mt_alloc<_Tp1>& obj) throw() + { + // XXX + } + + ~__mt_alloc() throw() { } + + pointer + address(reference __x) const + { return &__x; } + + const_pointer + address(const_reference __x) const + { return &__x; } + + size_type + max_size() const throw() + { return size_t(-1) / sizeof(_Tp); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_] allocator::construct + void + construct(pointer __p, const _Tp& __val) + { ::new(__p) _Tp(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } + + pointer + allocate(size_type __n, const void* = 0); + + void + deallocate(pointer __p, size_type __n); + + // Variables used to configure the behavior of the allocator, + // assigned and explained in detail below. + struct _Tune + { + // Alignment needed. + // NB: In any case must be >= sizeof(_Block_record), that + // is 4 on 32 bit machines and 8 on 64 bit machines. + size_t _M_align; + + // Allocation requests (after round-up to power of 2) below + // this value will be handled by the allocator. A raw new/ + // call will be used for requests larger than this value. + size_t _M_max_bytes; + + // Size in bytes of the smallest bin. + // NB: Must be a power of 2 and >= _M_align. + size_t _M_min_bin; + + // In order to avoid fragmenting and minimize the number of + // new() calls we always request new memory using this + // value. Based on previous discussions on the libstdc++ + // mailing list we have choosen the value below. + // See http://gcc.gnu.org/ml/libstdc++/2001-07/msg00077.html + size_t _M_chunk_size; + + // The maximum number of supported threads. Our Linux 2.4.18 + // reports 4070 in /proc/sys/kernel/threads-max + size_t _M_max_threads; + + // Each time a deallocation occurs in a threaded application + // we make sure that there are no more than + // _M_freelist_headroom % of used memory on the freelist. If + // the number of additional records is more than + // _M_freelist_headroom % of the freelist, we move these + // records back to the global pool. + size_t _M_freelist_headroom; + + // Set to true forces all allocations to use new(). + bool _M_force_new; + + explicit + _Tune() + : _M_align(8), _M_max_bytes(128), _M_min_bin(8), + _M_chunk_size(4096 - 4 * sizeof(void*)), + _M_max_threads(4096), _M_freelist_headroom(10), + _M_force_new(getenv("GLIBCXX_FORCE_NEW") ? true : false) + { } + + explicit + _Tune(size_t __align, size_t __maxb, size_t __minbin, + size_t __chunk, size_t __maxthreads, size_t __headroom, + bool __force) + : _M_align(__align), _M_max_bytes(__maxb), _M_min_bin(__minbin), + _M_chunk_size(__chunk), _M_max_threads(__maxthreads), + _M_freelist_headroom(__headroom), _M_force_new(__force) + { } + }; + + private: + // We need to create the initial lists and set up some variables + // before we can answer to the first request for memory. +#ifdef __GTHREADS + static __gthread_once_t _S_once; +#endif + static bool _S_init; + + static void + _S_initialize(); + + // Configuration options. + static _Tune _S_options; + + static const _Tune + _S_get_options() + { return _S_options; } + + static void + _S_set_options(_Tune __t) + { + if (!_S_init) + _S_options = __t; + } + + // Using short int as type for the binmap implies we are never + // caching blocks larger than 65535 with this allocator + typedef unsigned short int _Binmap_type; + static _Binmap_type* _S_binmap; + + // Each requesting thread is assigned an id ranging from 1 to + // _S_max_threads. Thread id 0 is used as a global memory pool. + // In order to get constant performance on the thread assignment + // routine, we keep a list of free ids. When a thread first + // requests memory we remove the first record in this list and + // stores the address in a __gthread_key. When initializing the + // __gthread_key we specify a destructor. When this destructor + // (i.e. the thread dies) is called, we return the thread id to + // the front of this list. +#ifdef __GTHREADS + struct _Thread_record + { + // Points to next free thread id record. NULL if last record in list. + _Thread_record* volatile _M_next; + + // Thread id ranging from 1 to _S_max_threads. + size_t _M_id; + }; + + static _Thread_record* volatile _S_thread_freelist_first; + static __gthread_mutex_t _S_thread_freelist_mutex; + static __gthread_key_t _S_thread_key; + + static void + _S_destroy_thread_key(void* __freelist_pos); +#endif + + static size_t + _S_get_thread_id(); + + union _Block_record + { + // Points to the block_record of the next free block. + _Block_record* volatile _M_next; + +#ifdef __GTHREADS + // The thread id of the thread which has requested this block. + size_t _M_thread_id; +#endif + }; + + struct _Bin_record + { + // An "array" of pointers to the first free block for each + // thread id. Memory to this "array" is allocated in _S_initialize() + // for _S_max_threads + global pool 0. + _Block_record** volatile _M_first; + +#ifdef __GTHREADS + // An "array" of counters used to keep track of the amount of + // blocks that are on the freelist/used for each thread id. + // Memory to these "arrays" is allocated in _S_initialize() for + // _S_max_threads + global pool 0. + size_t* volatile _M_free; + size_t* volatile _M_used; + + // Each bin has its own mutex which is used to ensure data + // integrity while changing "ownership" on a block. The mutex + // is initialized in _S_initialize(). + __gthread_mutex_t* _M_mutex; +#endif + }; + + // An "array" of bin_records each of which represents a specific + // power of 2 size. Memory to this "array" is allocated in + // _S_initialize(). + static _Bin_record* volatile _S_bin; + + // Actual value calculated in _S_initialize(). + static size_t _S_bin_size; + }; + + template<typename _Tp> + typename __mt_alloc<_Tp>::pointer + __mt_alloc<_Tp>:: + allocate(size_type __n, const void*) + { + // Although the test in __gthread_once() would suffice, we wrap + // test of the once condition in our own unlocked check. This + // saves one function call to pthread_once() (which itself only + // tests for the once value unlocked anyway and immediately + // returns if set) + if (!_S_init) + { +#ifdef __GTHREADS + if (__gthread_active_p()) + __gthread_once(&_S_once, _S_initialize); +#endif + if (!_S_init) + _S_initialize(); + } + + // Requests larger than _M_max_bytes are handled by new/delete + // directly. + const size_t __bytes = __n * sizeof(_Tp); + if (__bytes > _S_options._M_max_bytes || _S_options._M_force_new) + { + void* __ret = ::operator new(__bytes); + return static_cast<_Tp*>(__ret); + } + + // Round up to power of 2 and figure out which bin to use. + const size_t __which = _S_binmap[__bytes]; + const size_t __thread_id = _S_get_thread_id(); + + // Find out if we have blocks on our freelist. If so, go ahead + // and use them directly without having to lock anything. + const _Bin_record& __bin = _S_bin[__which]; + _Block_record* __block = NULL; + if (__bin._M_first[__thread_id] == NULL) + { + // NB: For alignment reasons, we can't use the first _M_align + // bytes, even when sizeof(_Block_record) < _M_align. + const size_t __bin_size = ((_S_options._M_min_bin << __which) + + _S_options._M_align); + size_t __block_count = _S_options._M_chunk_size / __bin_size; + + // Are we using threads? + // - Yes, check if there are free blocks on the global + // list. If so, grab up to __block_count blocks in one + // lock and change ownership. If the global list is + // empty, we allocate a new chunk and add those blocks + // directly to our own freelist (with us as owner). + // - No, all operations are made directly to global pool 0 + // no need to lock or change ownership but check for free + // blocks on global list (and if not add new ones) and + // get the first one. +#ifdef __GTHREADS + if (__gthread_active_p()) + { + __gthread_mutex_lock(__bin._M_mutex); + if (__bin._M_first[0] == NULL) + { + // No need to hold the lock when we are adding a + // whole chunk to our own list. + __gthread_mutex_unlock(__bin._M_mutex); + + void* __v = ::operator new(_S_options._M_chunk_size); + __bin._M_first[__thread_id] = static_cast<_Block_record*>(__v); + __bin._M_free[__thread_id] = __block_count; + + --__block_count; + __block = __bin._M_first[__thread_id]; + while (__block_count-- > 0) + { + char* __c = reinterpret_cast<char*>(__block) + __bin_size; + __block->_M_next = reinterpret_cast<_Block_record*>(__c); + __block = __block->_M_next; + } + __block->_M_next = NULL; + } + else + { + // Is the number of required blocks greater than or + // equal to the number that can be provided by the + // global free list? + __bin._M_first[__thread_id] = __bin._M_first[0]; + if (__block_count >= __bin._M_free[0]) + { + __bin._M_free[__thread_id] = __bin._M_free[0]; + __bin._M_free[0] = 0; + __bin._M_first[0] = NULL; + } + else + { + __bin._M_free[__thread_id] = __block_count; + __bin._M_free[0] -= __block_count; + --__block_count; + __block = __bin._M_first[0]; + while (__block_count-- > 0) + __block = __block->_M_next; + __bin._M_first[0] = __block->_M_next; + __block->_M_next = NULL; + } + __gthread_mutex_unlock(__bin._M_mutex); + } + } + else +#endif + { + void* __v = ::operator new(_S_options._M_chunk_size); + __bin._M_first[0] = static_cast<_Block_record*>(__v); + + --__block_count; + __block = __bin._M_first[0]; + while (__block_count-- > 0) + { + char* __c = reinterpret_cast<char*>(__block) + __bin_size; + __block->_M_next = reinterpret_cast<_Block_record*>(__c); + __block = __block->_M_next; + } + __block->_M_next = NULL; + } + } + + __block = __bin._M_first[__thread_id]; + __bin._M_first[__thread_id] = __bin._M_first[__thread_id]->_M_next; +#ifdef __GTHREADS + if (__gthread_active_p()) + { + __block->_M_thread_id = __thread_id; + --__bin._M_free[__thread_id]; + ++__bin._M_used[__thread_id]; + } +#endif + + char* __c = reinterpret_cast<char*>(__block) + _S_options._M_align; + return static_cast<_Tp*>(static_cast<void*>(__c)); + } + + template<typename _Tp> + void + __mt_alloc<_Tp>:: + deallocate(pointer __p, size_type __n) + { + // Requests larger than _M_max_bytes are handled by operators + // new/delete directly. + const size_t __bytes = __n * sizeof(_Tp); + if (__bytes > _S_options._M_max_bytes || _S_options._M_force_new) + { + ::operator delete(__p); + return; + } + + // Round up to power of 2 and figure out which bin to use. + const size_t __which = _S_binmap[__bytes]; + const _Bin_record& __bin = _S_bin[__which]; + + char* __c = reinterpret_cast<char*>(__p) - _S_options._M_align; + _Block_record* __block = reinterpret_cast<_Block_record*>(__c); + +#ifdef __GTHREADS + if (__gthread_active_p()) + { + // Calculate the number of records to remove from our freelist: + // in order to avoid too much contention we wait until the + // number of records is "high enough". + const size_t __thread_id = _S_get_thread_id(); + + long __remove = ((__bin._M_free[__thread_id] + * _S_options._M_freelist_headroom) + - __bin._M_used[__thread_id]); + if (__remove > static_cast<long>(100 * (_S_bin_size - __which) + * _S_options._M_freelist_headroom) + && __remove > static_cast<long>(__bin._M_free[__thread_id])) + { + _Block_record* __tmp = __bin._M_first[__thread_id]; + _Block_record* __first = __tmp; + __remove /= _S_options._M_freelist_headroom; + const long __removed = __remove; + --__remove; + while (__remove-- > 0) + __tmp = __tmp->_M_next; + __bin._M_first[__thread_id] = __tmp->_M_next; + __bin._M_free[__thread_id] -= __removed; + + __gthread_mutex_lock(__bin._M_mutex); + __tmp->_M_next = __bin._M_first[0]; + __bin._M_first[0] = __first; + __bin._M_free[0] += __removed; + __gthread_mutex_unlock(__bin._M_mutex); + } + + // Return this block to our list and update counters and + // owner id as needed. + --__bin._M_used[__block->_M_thread_id]; + + __block->_M_next = __bin._M_first[__thread_id]; + __bin._M_first[__thread_id] = __block; + + ++__bin._M_free[__thread_id]; + } + else +#endif + { + // Single threaded application - return to global pool. + __block->_M_next = __bin._M_first[0]; + __bin._M_first[0] = __block; + } + } + + template<typename _Tp> + void + __mt_alloc<_Tp>:: + _S_initialize() + { + // This method is called on the first allocation (when _S_init is still + // false) to create the bins. + + // Ensure that the static initialization of _S_options has + // happened. This depends on (a) _M_align == 0 being an invalid + // value that is only present at startup, and (b) the real + // static initialization that happens later not actually + // changing anything. + if (_S_options._M_align == 0) + new (&_S_options) _Tune; + + // _M_force_new must not change after the first allocate(), + // which in turn calls this method, so if it's false, it's false + // forever and we don't need to return here ever again. + if (_S_options._M_force_new) + { + _S_init = true; + return; + } + + // Calculate the number of bins required based on _M_max_bytes. + // _S_bin_size is statically-initialized to one. + size_t __bin_size = _S_options._M_min_bin; + while (_S_options._M_max_bytes > __bin_size) + { + __bin_size <<= 1; + ++_S_bin_size; + } + + // Setup the bin map for quick lookup of the relevant bin. + const size_t __j = (_S_options._M_max_bytes + 1) * sizeof(_Binmap_type); + _S_binmap = static_cast<_Binmap_type*>(::operator new(__j)); + + _Binmap_type* __bp = _S_binmap; + _Binmap_type __bin_max = _S_options._M_min_bin; + _Binmap_type __bint = 0; + for (_Binmap_type __ct = 0; __ct <= _S_options._M_max_bytes; ++__ct) + { + if (__ct > __bin_max) + { + __bin_max <<= 1; + ++__bint; + } + *__bp++ = __bint; + } + + // Initialize _S_bin and its members. + void* __v = ::operator new(sizeof(_Bin_record) * _S_bin_size); + _S_bin = static_cast<_Bin_record*>(__v); + + // If __gthread_active_p() create and initialize the list of + // free thread ids. Single threaded applications use thread id 0 + // directly and have no need for this. +#ifdef __GTHREADS + if (__gthread_active_p()) + { + const size_t __k = sizeof(_Thread_record) * _S_options._M_max_threads; + __v = ::operator new(__k); + _S_thread_freelist_first = static_cast<_Thread_record*>(__v); + + // NOTE! The first assignable thread id is 1 since the + // global pool uses id 0 + size_t __i; + for (__i = 1; __i < _S_options._M_max_threads; ++__i) + { + _Thread_record& __tr = _S_thread_freelist_first[__i - 1]; + __tr._M_next = &_S_thread_freelist_first[__i]; + __tr._M_id = __i; + } + + // Set last record. + _S_thread_freelist_first[__i - 1]._M_next = NULL; + _S_thread_freelist_first[__i - 1]._M_id = __i; + + // Make sure this is initialized. +#ifndef __GTHREAD_MUTEX_INIT + __GTHREAD_MUTEX_INIT_FUNCTION(&_S_thread_freelist_mutex); +#endif + // Initialize per thread key to hold pointer to + // _S_thread_freelist. + __gthread_key_create(&_S_thread_key, _S_destroy_thread_key); + + const size_t __max_threads = _S_options._M_max_threads + 1; + for (size_t __n = 0; __n < _S_bin_size; ++__n) + { + _Bin_record& __bin = _S_bin[__n]; + __v = ::operator new(sizeof(_Block_record*) * __max_threads); + __bin._M_first = static_cast<_Block_record**>(__v); + + __v = ::operator new(sizeof(size_t) * __max_threads); + __bin._M_free = static_cast<size_t*>(__v); + + __v = ::operator new(sizeof(size_t) * __max_threads); + __bin._M_used = static_cast<size_t*>(__v); + + __v = ::operator new(sizeof(__gthread_mutex_t)); + __bin._M_mutex = static_cast<__gthread_mutex_t*>(__v); + +#ifdef __GTHREAD_MUTEX_INIT + { + // Do not copy a POSIX/gthr mutex once in use. + __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; + *__bin._M_mutex = __tmp; + } +#else + { __GTHREAD_MUTEX_INIT_FUNCTION(__bin._M_mutex); } +#endif + + for (size_t __threadn = 0; __threadn < __max_threads; + ++__threadn) + { + __bin._M_first[__threadn] = NULL; + __bin._M_free[__threadn] = 0; + __bin._M_used[__threadn] = 0; + } + } + } + else +#endif + for (size_t __n = 0; __n < _S_bin_size; ++__n) + { + _Bin_record& __bin = _S_bin[__n]; + __v = ::operator new(sizeof(_Block_record*)); + __bin._M_first = static_cast<_Block_record**>(__v); + __bin._M_first[0] = NULL; + } + + _S_init = true; + } + + template<typename _Tp> + size_t + __mt_alloc<_Tp>:: + _S_get_thread_id() + { +#ifdef __GTHREADS + // If we have thread support and it's active we check the thread + // key value and return its id or if it's not set we take the + // first record from _S_thread_freelist and sets the key and + // returns it's id. + if (__gthread_active_p()) + { + _Thread_record* __freelist_pos = + static_cast<_Thread_record*>(__gthread_getspecific(_S_thread_key)); + if (__freelist_pos == NULL) + { + // Since _S_options._M_max_threads must be larger than + // the theoretical max number of threads of the OS the + // list can never be empty. + __gthread_mutex_lock(&_S_thread_freelist_mutex); + __freelist_pos = _S_thread_freelist_first; + _S_thread_freelist_first = _S_thread_freelist_first->_M_next; + __gthread_mutex_unlock(&_S_thread_freelist_mutex); + + __gthread_setspecific(_S_thread_key, + static_cast<void*>(__freelist_pos)); + } + return __freelist_pos->_M_id; + } +#endif + // Otherwise (no thread support or inactive) all requests are + // served from the global pool 0. + return 0; + } + +#ifdef __GTHREADS + template<typename _Tp> + void + __mt_alloc<_Tp>:: + _S_destroy_thread_key(void* __freelist_pos) + { + // Return this thread id record to front of thread_freelist. + __gthread_mutex_lock(&_S_thread_freelist_mutex); + _Thread_record* __tr = static_cast<_Thread_record*>(__freelist_pos); + __tr->_M_next = _S_thread_freelist_first; + _S_thread_freelist_first = __tr; + __gthread_mutex_unlock(&_S_thread_freelist_mutex); + } +#endif + + template<typename _Tp> + inline bool + operator==(const __mt_alloc<_Tp>&, const __mt_alloc<_Tp>&) + { return true; } + + template<typename _Tp> + inline bool + operator!=(const __mt_alloc<_Tp>&, const __mt_alloc<_Tp>&) + { return false; } + + template<typename _Tp> + bool __mt_alloc<_Tp>::_S_init = false; + + template<typename _Tp> + typename __mt_alloc<_Tp>::_Tune __mt_alloc<_Tp>::_S_options; + + template<typename _Tp> + typename __mt_alloc<_Tp>::_Binmap_type* __mt_alloc<_Tp>::_S_binmap; + + template<typename _Tp> + typename __mt_alloc<_Tp>::_Bin_record* volatile __mt_alloc<_Tp>::_S_bin; + + template<typename _Tp> + size_t __mt_alloc<_Tp>::_S_bin_size = 1; + + // Actual initialization in _S_initialize(). +#ifdef __GTHREADS + template<typename _Tp> + __gthread_once_t __mt_alloc<_Tp>::_S_once = __GTHREAD_ONCE_INIT; + + template<typename _Tp> + typename __mt_alloc<_Tp>::_Thread_record* + volatile __mt_alloc<_Tp>::_S_thread_freelist_first = NULL; + + template<typename _Tp> + __gthread_key_t __mt_alloc<_Tp>::_S_thread_key; + + template<typename _Tp> + __gthread_mutex_t +#ifdef __GTHREAD_MUTEX_INIT + __mt_alloc<_Tp>::_S_thread_freelist_mutex = __GTHREAD_MUTEX_INIT; +#else + __mt_alloc<_Tp>::_S_thread_freelist_mutex; +#endif +#endif +} // namespace __gnu_cxx + +#endif diff --git a/contrib/libstdc++/include/ext/new_allocator.h b/contrib/libstdc++/include/ext/new_allocator.h new file mode 100644 index 000000000000..1b0b4f610796 --- /dev/null +++ b/contrib/libstdc++/include/ext/new_allocator.h @@ -0,0 +1,113 @@ +// Allocator that wraps operator new -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _NEW_ALLOCATOR_H +#define _NEW_ALLOCATOR_H 1 + +#include <new> + +namespace __gnu_cxx +{ + /** + * @brief An allocator that uses global new, as per [20.4]. + * + * This is precisely the allocator defined in the C++ Standard. + * - all allocation calls operator new + * - all deallocation calls operator delete + * + * (See @link Allocators allocators info @endlink for more.) + */ + template<typename _Tp> + class new_allocator + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template<typename _Tp1> + struct rebind + { typedef new_allocator<_Tp1> other; }; + + new_allocator() throw() { } + + new_allocator(const new_allocator&) throw() { } + + template<typename _Tp1> + new_allocator(const new_allocator<_Tp1>&) throw() { } + + ~new_allocator() throw() { } + + pointer + address(reference __x) const { return &__x; } + + const_pointer + address(const_reference __x) const { return &__x; } + + // NB: __n is permitted to be 0. The C++ standard says nothing + // about what the return value is when __n == 0. + pointer + allocate(size_type __n, const void* = 0) + { return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); } + + // __p is not permitted to be a null pointer. + void + deallocate(pointer __p, size_type) + { ::operator delete(__p); } + + size_type + max_size() const throw() + { return size_t(-1) / sizeof(_Tp); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_] allocator::construct + void + construct(pointer __p, const _Tp& __val) + { ::new(__p) _Tp(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } + }; + + template<typename _Tp> + inline bool + operator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&) + { return true; } + + template<typename _Tp> + inline bool + operator!=(const new_allocator<_Tp>&, const new_allocator<_Tp>&) + { return false; } +} // namespace __gnu_cxx + +#endif diff --git a/contrib/libstdc++/include/ext/numeric b/contrib/libstdc++/include/ext/numeric index 6770461b5c6c..40edf07fe3da 100644 --- a/contrib/libstdc++/include/ext/numeric +++ b/contrib/libstdc++/include/ext/numeric @@ -60,9 +60,10 @@ */ #ifndef _EXT_NUMERIC -#define _EXT_NUMERIC +#define _EXT_NUMERIC 1 #pragma GCC system_header + #include <bits/concept_check.h> #include <numeric> @@ -72,7 +73,6 @@ namespace __gnu_cxx { // Returns __x ** __n, where __n >= 0. _Note that "multiplication" // is required to be associative, but not necessarily commutative. - template<typename _Tp, typename _Integer, typename _MonoidOperation> _Tp __power(_Tp __x, _Integer __n, _MonoidOperation __monoid_op) @@ -102,14 +102,13 @@ namespace __gnu_cxx __power(_Tp __x, _Integer __n) { return __power(__x, __n, std::multiplies<_Tp>()); } - // Alias for the internal name __power. Note that power is an extension, - // not part of the C++ standard. - /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ + // Alias for the internal name __power. Note that power is an extension, + // not part of the C++ standard. template<typename _Tp, typename _Integer, typename _MonoidOperation> inline _Tp power(_Tp __x, _Integer __n, _MonoidOperation __monoid_op) @@ -125,27 +124,25 @@ namespace __gnu_cxx power(_Tp __x, _Integer __n) { return __power(__x, __n); } - // iota is not part of the C++ standard. It is an extension. - /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ + // iota is not part of the C++ standard. It is an extension. template<typename _ForwardIter, typename _Tp> - void + void iota(_ForwardIter __first, _ForwardIter __last, _Tp __value) { // concept requirements - __glibcpp_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>) - __glibcpp_function_requires(_ConvertibleConcept<_Tp, + __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>) + __glibcxx_function_requires(_ConvertibleConcept<_Tp, typename std::iterator_traits<_ForwardIter>::value_type>) while (__first != __last) *__first++ = __value++; } - } // namespace __gnu_cxx -#endif /* _EXT_NUMERIC */ +#endif diff --git a/contrib/libstdc++/include/ext/pod_char_traits.h b/contrib/libstdc++/include/ext/pod_char_traits.h new file mode 100644 index 000000000000..c69025e005d2 --- /dev/null +++ b/contrib/libstdc++/include/ext/pod_char_traits.h @@ -0,0 +1,158 @@ +// POD character, std::char_traits specialization -*- C++ -*- + +// Copyright (C) 2002, 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// Gabriel Dos Reis <gdr@integrable-solutions.net> +// Benjamin Kosnik <bkoz@redhat.com> + +#ifndef _POD_CHAR_TRAITS_H +#define _POD_CHAR_TRAITS_H 1 + +#include <string> + +namespace __gnu_cxx +{ + template<typename V, typename I, typename S = mbstate_t> + struct character + { + typedef V value_type; + typedef I int_type; + typedef S state_type; + value_type value; + }; + + template<typename V, typename I> + inline bool + operator==(const character<V, I>& lhs, const character<V, I>& rhs) + { return lhs.value == rhs.value; } + + template<typename V, typename I> + inline bool + operator<(const character<V, I>& lhs, const character<V, I>& rhs) + { return lhs.value < rhs.value; } +} // namespace __gnu_cxx + +namespace std +{ + // Provide std::char_traits specialization. + template<typename V, typename I, typename S> + struct char_traits<__gnu_cxx::character<V, I, S> > + { + typedef __gnu_cxx::character<V, I, S> char_type; + + // NB: This type should be bigger than char_type, so as to + // properly hold EOF values in addition to the full range of + // char_type values. + // Also, assumes + // int_type(value_type) is valid. + // int_type(-1) is possible. + typedef typename char_type::int_type int_type; + typedef typename char_type::state_type state_type; + typedef fpos<state_type> pos_type; + typedef streamoff off_type; + + static void + assign(char_type& __c1, const char_type& __c2) + { __c1 = __c2; } + + static bool + eq(const char_type& __c1, const char_type& __c2) + { return __c1 == __c2; } + + static bool + lt(const char_type& __c1, const char_type& __c2) + { return __c1 < __c2; } + + static int + compare(const char_type* __s1, const char_type* __s2, size_t __n) + { + for (size_t __i = 0; __i < __n; ++__i) + if (!eq(__s1[__i], __s2[__i])) + return lt(__s1[__i], __s2[__i]) ? -1 : 1; + return 0; + } + + static size_t + length(const char_type* __s) + { + const char_type* __p = __s; + while (__p->value) + ++__p; + return (__p - __s); + } + + static const char_type* + find(const char_type* __s, size_t __n, const char_type& __a) + { + for (const char_type* __p = __s; size_t(__p - __s) < __n; ++__p) + if (*__p == __a) + return __p; + return 0; + } + + static char_type* + move(char_type* __s1, const char_type* __s2, size_t __n) + { return (char_type*) memmove(__s1, __s2, __n * sizeof(char_type)); } + + static char_type* + copy(char_type* __s1, const char_type* __s2, size_t __n) + { return (char_type*) memcpy(__s1, __s2, __n * sizeof(char_type)); } + + static char_type* + assign(char_type* __s, size_t __n, char_type __a) + { + for (char_type* __p = __s; __p < __s + __n; ++__p) + assign(*__p, __a); + return __s; + } + + static char_type + to_char_type(const int_type& __c) + { + char_type __r = { __c }; + return __r; + } + + static int_type + to_int_type(const char_type& __c) + { return int_type(__c.value); } + + static bool + eq_int_type(const int_type& __c1, const int_type& __c2) + { return __c1 == __c2; } + + static int_type + eof() { return static_cast<int_type>(-1); } + + static int_type + not_eof(const int_type& __c) + { return eq_int_type(__c, eof()) ? int_type(0) : __c; } + }; +} + +#endif diff --git a/contrib/libstdc++/include/ext/pool_allocator.h b/contrib/libstdc++/include/ext/pool_allocator.h new file mode 100644 index 000000000000..eec79e7070a0 --- /dev/null +++ b/contrib/libstdc++/include/ext/pool_allocator.h @@ -0,0 +1,254 @@ +// Allocators -*- C++ -*- + +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/* + * Copyright (c) 1996-1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/** @file ext/pool_allocator.h + * This file is a GNU extension to the Standard C++ Library. + * You should only include this header if you are using GCC 3 or later. + */ +#ifndef _POOL_ALLOCATOR_H +#define _POOL_ALLOCATOR_H 1 + +#include <bits/c++config.h> +#include <new> +#include <bits/functexcept.h> +#include <bits/atomicity.h> +#include <bits/concurrence.h> + +namespace __gnu_cxx +{ + /** + * @if maint + * Uses various allocators to fulfill underlying requests (and makes as + * few requests as possible when in default high-speed pool mode). + * + * Important implementation properties: + * 0. If globally mandated, then allocate objects from new + * 1. If the clients request an object of size > _S_max_bytes, the resulting + * object will be obtained directly from new + * 2. In all other cases, we allocate an object of size exactly + * _S_round_up(requested_size). Thus the client has enough size + * information that we can return the object to the proper free list + * without permanently losing part of the object. + * + * @endif + * (See @link Allocators allocators info @endlink for more.) + */ + class __pool_base + { + protected: + + enum { _S_align = 8 }; + enum { _S_max_bytes = 128 }; + enum { _S_free_list_size = _S_max_bytes / _S_align }; + + union _Obj + { + union _Obj* _M_free_list_link; + char _M_client_data[1]; // The client sees this. + }; + + static _Obj* volatile _S_free_list[_S_free_list_size]; + + // Chunk allocation state. + static char* _S_start_free; + static char* _S_end_free; + static size_t _S_heap_size; + + size_t + _M_round_up(size_t __bytes) + { return ((__bytes + (size_t)_S_align - 1) & ~((size_t)_S_align - 1)); } + + _Obj* volatile* + _M_get_free_list(size_t __bytes); + + mutex_type& + _M_get_mutex(); + + // Returns an object of size __n, and optionally adds to size __n + // free list. + void* + _M_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. + char* + _M_allocate_chunk(size_t __n, int& __nobjs); + }; + + + template<typename _Tp> + class __pool_alloc : private __pool_base + { + private: + static _Atomic_word _S_force_new; + + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template<typename _Tp1> + struct rebind + { typedef __pool_alloc<_Tp1> other; }; + + __pool_alloc() throw() { } + + __pool_alloc(const __pool_alloc&) throw() { } + + template<typename _Tp1> + __pool_alloc(const __pool_alloc<_Tp1>&) throw() { } + + ~__pool_alloc() throw() { } + + pointer + address(reference __x) const { return &__x; } + + const_pointer + address(const_reference __x) const { return &__x; } + + size_type + max_size() const throw() + { return size_t(-1) / sizeof(_Tp); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 402. wrong new expression in [some_] allocator::construct + void + construct(pointer __p, const _Tp& __val) + { ::new(__p) _Tp(__val); } + + void + destroy(pointer __p) { __p->~_Tp(); } + + pointer + allocate(size_type __n, const void* = 0); + + void + deallocate(pointer __p, size_type __n); + }; + + template<typename _Tp> + inline bool + operator==(const __pool_alloc<_Tp>&, const __pool_alloc<_Tp>&) + { return true; } + + template<typename _Tp> + inline bool + operator!=(const __pool_alloc<_Tp>&, const __pool_alloc<_Tp>&) + { return false; } + + template<typename _Tp> + _Atomic_word + __pool_alloc<_Tp>::_S_force_new; + + template<typename _Tp> + _Tp* + __pool_alloc<_Tp>::allocate(size_type __n, const void*) + { + pointer __ret = 0; + if (__n) + { + if (__n <= max_size()) + { + // If there is a race through here, assume answer from getenv + // will resolve in same direction. Inspired by techniques + // to efficiently support threading found in basic_string.h. + if (_S_force_new == 0) + { + if (getenv("GLIBCXX_FORCE_NEW")) + __atomic_add(&_S_force_new, 1); + else + __atomic_add(&_S_force_new, -1); + } + + const size_t __bytes = __n * sizeof(_Tp); + if (__bytes > size_t(_S_max_bytes) || _S_force_new == 1) + __ret = static_cast<_Tp*>(::operator new(__bytes)); + else + { + _Obj* volatile* __free_list = _M_get_free_list(__bytes); + + lock sentry(_M_get_mutex()); + _Obj* __restrict__ __result = *__free_list; + if (__builtin_expect(__result == 0, 0)) + __ret = static_cast<_Tp*>(_M_refill(_M_round_up(__bytes))); + else + { + *__free_list = __result->_M_free_list_link; + __ret = reinterpret_cast<_Tp*>(__result); + } + if (__builtin_expect(__ret == 0, 0)) + std::__throw_bad_alloc(); + } + } + else + std::__throw_bad_alloc(); + } + return __ret; + } + + template<typename _Tp> + void + __pool_alloc<_Tp>::deallocate(pointer __p, size_type __n) + { + if (__n) + { + const size_t __bytes = __n * sizeof(_Tp); + if (__bytes > static_cast<size_t>(_S_max_bytes) || _S_force_new == 1) + ::operator delete(__p); + else + { + _Obj* volatile* __free_list = _M_get_free_list(__bytes); + _Obj* __q = reinterpret_cast<_Obj*>(__p); + + lock sentry(_M_get_mutex()); + __q ->_M_free_list_link = *__free_list; + *__free_list = __q; + } + } + } +} // namespace __gnu_cxx + +#endif diff --git a/contrib/libstdc++/include/ext/rb_tree b/contrib/libstdc++/include/ext/rb_tree index 394124383828..2c38b39706e2 100644 --- a/contrib/libstdc++/include/ext/rb_tree +++ b/contrib/libstdc++/include/ext/rb_tree @@ -59,39 +59,39 @@ * include this header if you are using GCC 3 or later. */ -#ifndef _EXT_RB_TREE -#define _EXT_RB_TREE +#ifndef _RB_TREE +#define _RB_TREE 1 #pragma GCC system_header + #include <bits/stl_tree.h> namespace __gnu_cxx { -using std::_Rb_tree; -using std::allocator; + using std::_Rb_tree; + using std::allocator; -// Class rb_tree is not part of the C++ standard. It is provided for -// compatibility with the HP STL. + // Class rb_tree is not part of the C++ standard. It is provided for + // compatibility with the HP STL. -/** - * This is an SGI extension. - * @ingroup SGIextensions - * @doctodo -*/ -template <class _Key, class _Value, class _KeyOfValue, class _Compare, - class _Alloc = allocator<_Value> > -struct rb_tree : public _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> -{ - typedef _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> _Base; - typedef typename _Base::allocator_type allocator_type; + /** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo + */ + template <class _Key, class _Value, class _KeyOfValue, class _Compare, + class _Alloc = allocator<_Value> > + struct rb_tree : public _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> + { + typedef _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> _Base; + typedef typename _Base::allocator_type allocator_type; - rb_tree(const _Compare& __comp = _Compare(), - const allocator_type& __a = allocator_type()) - : _Base(__comp, __a) {} - - ~rb_tree() {} -}; + rb_tree(const _Compare& __comp = _Compare(), + const allocator_type& __a = allocator_type()) + : _Base(__comp, __a) { } + ~rb_tree() { } + }; } // namespace __gnu_cxx -#endif /* _EXT_RB_TREE */ +#endif diff --git a/contrib/libstdc++/include/ext/rope b/contrib/libstdc++/include/ext/rope index 1441df15a627..95afd82e0b55 100644 --- a/contrib/libstdc++/include/ext/rope +++ b/contrib/libstdc++/include/ext/rope @@ -1,6 +1,6 @@ // SGI's rope class -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -46,21 +46,2449 @@ * include this header if you are using GCC 3 or later. */ -#ifndef __SGI_STL_ROPE -#define __SGI_STL_ROPE +#ifndef _ROPE +#define _ROPE 1 #include <bits/stl_algobase.h> +#include <bits/stl_construct.h> +#include <bits/stl_uninitialized.h> #include <bits/stl_algo.h> #include <bits/stl_function.h> #include <bits/stl_numeric.h> -#include <bits/stl_alloc.h> -#include <bits/stl_construct.h> -#include <bits/stl_uninitialized.h> -#include <ext/stl_hash_fun.h> -#include <ext/stl_rope.h> +#include <bits/allocator.h> +#include <ext/hash_fun.h> + +# ifdef __GC +# define __GC_CONST const +# else +# include <bits/gthr.h> +# define __GC_CONST // constant except for deallocation +# endif + +#include <ext/memory> // For uninitialized_copy_n + +namespace __gnu_cxx +{ +using std::size_t; +using std::ptrdiff_t; +using std::allocator; +using std::iterator; +using std::reverse_iterator; +using std::_Destroy; + +// The _S_eos function is used for those functions that +// convert to/from C-like strings to detect the end of the string. + +// The end-of-C-string character. +// This is what the draft standard says it should be. +template <class _CharT> +inline _CharT _S_eos(_CharT*) { return _CharT(); } + +// Test for basic character types. +// For basic character types leaves having a trailing eos. +template <class _CharT> +inline bool _S_is_basic_char_type(_CharT*) { return false; } +template <class _CharT> +inline bool _S_is_one_byte_char_type(_CharT*) { return false; } + +inline bool _S_is_basic_char_type(char*) { return true; } +inline bool _S_is_one_byte_char_type(char*) { return true; } +inline bool _S_is_basic_char_type(wchar_t*) { return true; } + +// Store an eos iff _CharT is a basic character type. +// Do not reference _S_eos if it isn't. +template <class _CharT> +inline void _S_cond_store_eos(_CharT&) {} + +inline void _S_cond_store_eos(char& __c) { __c = 0; } +inline void _S_cond_store_eos(wchar_t& __c) { __c = 0; } + +// char_producers are logically functions that generate a section of +// a string. These can be convereted to ropes. The resulting rope +// invokes the char_producer on demand. This allows, for example, +// files to be viewed as ropes without reading the entire file. +template <class _CharT> +class char_producer { + public: + virtual ~char_producer() {}; + virtual void operator()(size_t __start_pos, size_t __len, + _CharT* __buffer) = 0; + // Buffer should really be an arbitrary output iterator. + // That way we could flatten directly into an ostream, etc. + // This is thoroughly impossible, since iterator types don't + // have runtime descriptions. +}; + +// Sequence buffers: +// +// Sequence must provide an append operation that appends an +// array to the sequence. Sequence buffers are useful only if +// appending an entire array is cheaper than appending element by element. +// This is true for many string representations. +// This should perhaps inherit from ostream<sequence::value_type> +// and be implemented correspondingly, so that they can be used +// for formatted. For the sake of portability, we don't do this yet. +// +// For now, sequence buffers behave as output iterators. But they also +// behave a little like basic_ostringstream<sequence::value_type> and a +// little like containers. + +template<class _Sequence, size_t _Buf_sz = 100> +class sequence_buffer : public iterator<std::output_iterator_tag,void,void,void,void> +{ + public: + typedef typename _Sequence::value_type value_type; + protected: + _Sequence* _M_prefix; + value_type _M_buffer[_Buf_sz]; + size_t _M_buf_count; + public: + void flush() { + _M_prefix->append(_M_buffer, _M_buffer + _M_buf_count); + _M_buf_count = 0; + } + ~sequence_buffer() { flush(); } + sequence_buffer() : _M_prefix(0), _M_buf_count(0) {} + sequence_buffer(const sequence_buffer& __x) { + _M_prefix = __x._M_prefix; + _M_buf_count = __x._M_buf_count; + copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); + } + sequence_buffer(sequence_buffer& __x) { + __x.flush(); + _M_prefix = __x._M_prefix; + _M_buf_count = 0; + } + sequence_buffer(_Sequence& __s) : _M_prefix(&__s), _M_buf_count(0) {} + sequence_buffer& operator= (sequence_buffer& __x) { + __x.flush(); + _M_prefix = __x._M_prefix; + _M_buf_count = 0; + return *this; + } + sequence_buffer& operator= (const sequence_buffer& __x) { + _M_prefix = __x._M_prefix; + _M_buf_count = __x._M_buf_count; + copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); + return *this; + } + void push_back(value_type __x) + { + if (_M_buf_count < _Buf_sz) { + _M_buffer[_M_buf_count] = __x; + ++_M_buf_count; + } else { + flush(); + _M_buffer[0] = __x; + _M_buf_count = 1; + } + } + void append(value_type* __s, size_t __len) + { + if (__len + _M_buf_count <= _Buf_sz) { + size_t __i = _M_buf_count; + for (size_t __j = 0; __j < __len; __i++, __j++) { + _M_buffer[__i] = __s[__j]; + } + _M_buf_count += __len; + } else if (0 == _M_buf_count) { + _M_prefix->append(__s, __s + __len); + } else { + flush(); + append(__s, __len); + } + } + sequence_buffer& write(value_type* __s, size_t __len) + { + append(__s, __len); + return *this; + } + sequence_buffer& put(value_type __x) + { + push_back(__x); + return *this; + } + sequence_buffer& operator=(const value_type& __rhs) + { + push_back(__rhs); + return *this; + } + sequence_buffer& operator*() { return *this; } + sequence_buffer& operator++() { return *this; } + sequence_buffer operator++(int) { return *this; } +}; + +// The following should be treated as private, at least for now. +template<class _CharT> +class _Rope_char_consumer { + public: + // If we had member templates, these should not be virtual. + // For now we need to use run-time parametrization where + // compile-time would do. Hence this should all be private + // for now. + // The symmetry with char_producer is accidental and temporary. + virtual ~_Rope_char_consumer() {}; + virtual bool operator()(const _CharT* __buffer, size_t __len) = 0; +}; + +// First a lot of forward declarations. The standard seems to require +// much stricter "declaration before use" than many of the implementations +// that preceded it. +template<class _CharT, class _Alloc = allocator<_CharT> > class rope; +template<class _CharT, class _Alloc> struct _Rope_RopeConcatenation; +template<class _CharT, class _Alloc> struct _Rope_RopeLeaf; +template<class _CharT, class _Alloc> struct _Rope_RopeFunction; +template<class _CharT, class _Alloc> struct _Rope_RopeSubstring; +template<class _CharT, class _Alloc> class _Rope_iterator; +template<class _CharT, class _Alloc> class _Rope_const_iterator; +template<class _CharT, class _Alloc> class _Rope_char_ref_proxy; +template<class _CharT, class _Alloc> class _Rope_char_ptr_proxy; + +template<class _CharT, class _Alloc> +bool operator== (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y); + +template<class _CharT, class _Alloc> +_Rope_const_iterator<_CharT,_Alloc> operator- + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + +template<class _CharT, class _Alloc> +_Rope_const_iterator<_CharT,_Alloc> operator+ + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + +template<class _CharT, class _Alloc> +_Rope_const_iterator<_CharT,_Alloc> operator+ + (ptrdiff_t __n, + const _Rope_const_iterator<_CharT,_Alloc>& __x); + +template<class _CharT, class _Alloc> +bool operator== + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); + +template<class _CharT, class _Alloc> +bool operator< + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); + +template<class _CharT, class _Alloc> +ptrdiff_t operator- + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); + +template<class _CharT, class _Alloc> +_Rope_iterator<_CharT,_Alloc> operator- + (const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + +template<class _CharT, class _Alloc> +_Rope_iterator<_CharT,_Alloc> operator+ + (const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + +template<class _CharT, class _Alloc> +_Rope_iterator<_CharT,_Alloc> operator+ + (ptrdiff_t __n, + const _Rope_iterator<_CharT,_Alloc>& __x); + +template<class _CharT, class _Alloc> +bool operator== + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + +template<class _CharT, class _Alloc> +bool operator< + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + +template<class _CharT, class _Alloc> +ptrdiff_t operator- + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + +template<class _CharT, class _Alloc> +rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right); + +template<class _CharT, class _Alloc> +rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, + const _CharT* __right); + +template<class _CharT, class _Alloc> +rope<_CharT,_Alloc> operator+ (const rope<_CharT,_Alloc>& __left, + _CharT __right); + +// Some helpers, so we can use power on ropes. +// See below for why this isn't local to the implementation. + +// This uses a nonstandard refcount convention. +// The result has refcount 0. +template<class _CharT, class _Alloc> +struct _Rope_Concat_fn + : public std::binary_function<rope<_CharT,_Alloc>, rope<_CharT,_Alloc>, + rope<_CharT,_Alloc> > { + rope<_CharT,_Alloc> operator() (const rope<_CharT,_Alloc>& __x, + const rope<_CharT,_Alloc>& __y) { + return __x + __y; + } +}; + +template <class _CharT, class _Alloc> +inline +rope<_CharT,_Alloc> +identity_element(_Rope_Concat_fn<_CharT, _Alloc>) +{ + return rope<_CharT,_Alloc>(); +} + + + // Class _Refcount_Base provides a type, _RC_t, a data member, + // _M_ref_count, and member functions _M_incr and _M_decr, which perform + // atomic preincrement/predecrement. The constructor initializes + // _M_ref_count. + struct _Refcount_Base + { + // The type _RC_t + typedef size_t _RC_t; + + // The data member _M_ref_count + volatile _RC_t _M_ref_count; + + // Constructor + __gthread_mutex_t _M_ref_count_lock; + + _Refcount_Base(_RC_t __n) : _M_ref_count(__n), _M_ref_count_lock() + { +#ifdef __GTHREAD_MUTEX_INIT + __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; + _M_ref_count_lock = __tmp; +#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION) + __GTHREAD_MUTEX_INIT_FUNCTION (&_M_ref_count_lock); +#else +#error __GTHREAD_MUTEX_INIT or __GTHREAD_MUTEX_INIT_FUNCTION should be defined by gthr.h abstraction layer, report problem to libstdc++@gcc.gnu.org. +#endif + } + + void + _M_incr() + { + __gthread_mutex_lock(&_M_ref_count_lock); + ++_M_ref_count; + __gthread_mutex_unlock(&_M_ref_count_lock); + } + + _RC_t + _M_decr() + { + __gthread_mutex_lock(&_M_ref_count_lock); + volatile _RC_t __tmp = --_M_ref_count; + __gthread_mutex_unlock(&_M_ref_count_lock); + return __tmp; + } + }; + +// +// What follows should really be local to rope. Unfortunately, +// that doesn't work, since it makes it impossible to define generic +// equality on rope iterators. According to the draft standard, the +// template parameters for such an equality operator cannot be inferred +// from the occurrence of a member class as a parameter. +// (SGI compilers in fact allow this, but the __result wouldn't be +// portable.) +// Similarly, some of the static member functions are member functions +// only to avoid polluting the global namespace, and to circumvent +// restrictions on type inference for template functions. +// + +// +// The internal data structure for representing a rope. This is +// private to the implementation. A rope is really just a pointer +// to one of these. +// +// A few basic functions for manipulating this data structure +// are members of _RopeRep. Most of the more complex algorithms +// are implemented as rope members. +// +// Some of the static member functions of _RopeRep have identically +// named functions in rope that simply invoke the _RopeRep versions. + +#define __ROPE_DEFINE_ALLOCS(__a) \ + __ROPE_DEFINE_ALLOC(_CharT,_Data) /* character data */ \ + 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. + +#define __STATIC_IF_SGI_ALLOC /* not static */ + +template <class _CharT, class _Alloc> +struct _Rope_rep_base +: public _Alloc +{ + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const { return *static_cast<const _Alloc*>(this); } + + _Rope_rep_base(size_t __size, const allocator_type&) + : _M_size(__size) {} + + size_t _M_size; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc::template rebind<_Tp>::other __name##Alloc; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc().allocate(__n); } \ + static void __name##_deallocate(_Tp *__p, size_t __n) \ + { __name##Alloc().deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Alloc) +# undef __ROPE_DEFINE_ALLOC +}; + +namespace _Rope_constants +{ + enum { _S_max_rope_depth = 45 }; + enum _Tag {_S_leaf, _S_concat, _S_substringfn, _S_function}; +} + +template<class _CharT, class _Alloc> +struct _Rope_RopeRep : public _Rope_rep_base<_CharT,_Alloc> +# ifndef __GC + , _Refcount_Base +# endif +{ + public: + _Rope_constants::_Tag _M_tag:8; + bool _M_is_balanced:8; + unsigned char _M_depth; + __GC_CONST _CharT* _M_c_string; + __gthread_mutex_t _M_c_string_lock; + /* Flattened version of string, if needed. */ + /* typically 0. */ + /* If it's not 0, then the memory is owned */ + /* by this node. */ + /* In the case of a leaf, this may point to */ + /* the same memory as the data field. */ + typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; + using _Rope_rep_base<_CharT,_Alloc>::get_allocator; + _Rope_RopeRep(_Rope_constants::_Tag __t, int __d, bool __b, size_t __size, + allocator_type __a) + : _Rope_rep_base<_CharT,_Alloc>(__size, __a), +# ifndef __GC + _Refcount_Base(1), +# endif + _M_tag(__t), _M_is_balanced(__b), _M_depth(__d), _M_c_string(0) +#ifdef __GTHREAD_MUTEX_INIT + { + // Do not copy a POSIX/gthr mutex once in use. However, bits are bits. + __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; + _M_c_string_lock = __tmp; + } +#else + { __GTHREAD_MUTEX_INIT_FUNCTION (&_M_c_string_lock); } +#endif +# ifdef __GC + void _M_incr () {} +# endif + static void _S_free_string(__GC_CONST _CharT*, size_t __len, + allocator_type __a); +# define __STL_FREE_STRING(__s, __l, __a) _S_free_string(__s, __l, __a); + // Deallocate data section of a leaf. + // This shouldn't be a member function. + // But its hard to do anything else at the + // moment, because it's templatized w.r.t. + // an allocator. + // Does nothing if __GC is defined. +# ifndef __GC + void _M_free_c_string(); + void _M_free_tree(); + // Deallocate t. Assumes t is not 0. + void _M_unref_nonnil() + { + if (0 == _M_decr()) _M_free_tree(); + } + void _M_ref_nonnil() + { + _M_incr(); + } + static void _S_unref(_Rope_RopeRep* __t) + { + if (0 != __t) { + __t->_M_unref_nonnil(); + } + } + static void _S_ref(_Rope_RopeRep* __t) + { + if (0 != __t) __t->_M_incr(); + } + static void _S_free_if_unref(_Rope_RopeRep* __t) + { + if (0 != __t && 0 == __t->_M_ref_count) __t->_M_free_tree(); + } +# else /* __GC */ + void _M_unref_nonnil() {} + void _M_ref_nonnil() {} + static void _S_unref(_Rope_RopeRep*) {} + static void _S_ref(_Rope_RopeRep*) {} + static void _S_free_if_unref(_Rope_RopeRep*) {} +# endif +protected: + _Rope_RopeRep& + operator=(const _Rope_RopeRep&); + + _Rope_RopeRep(const _Rope_RopeRep&); +}; + +template<class _CharT, class _Alloc> +struct _Rope_RopeLeaf : public _Rope_RopeRep<_CharT,_Alloc> { + public: + // Apparently needed by VC++ + // The data fields of leaves are allocated with some + // extra space, to accommodate future growth and for basic + // character types, to hold a trailing eos character. + enum { _S_alloc_granularity = 8 }; + static size_t _S_rounded_up_size(size_t __n) { + size_t __size_with_eos; + + if (_S_is_basic_char_type((_CharT*)0)) { + __size_with_eos = __n + 1; + } else { + __size_with_eos = __n; + } +# ifdef __GC + return __size_with_eos; +# else + // Allow slop for in-place expansion. + return (__size_with_eos + _S_alloc_granularity-1) + &~ (_S_alloc_granularity-1); +# endif + } + __GC_CONST _CharT* _M_data; /* Not necessarily 0 terminated. */ + /* The allocated size is */ + /* _S_rounded_up_size(size), except */ + /* in the GC case, in which it */ + /* doesn't matter. */ + typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; + _Rope_RopeLeaf(__GC_CONST _CharT* __d, size_t __size, allocator_type __a) + : _Rope_RopeRep<_CharT,_Alloc>(_Rope_constants::_S_leaf, 0, true, __size, __a), _M_data(__d) + { + if (_S_is_basic_char_type((_CharT *)0)) { + // already eos terminated. + this->_M_c_string = __d; + } + } + // The constructor assumes that d has been allocated with + // the proper allocator and the properly padded size. + // In contrast, the destructor deallocates the data: +# ifndef __GC + ~_Rope_RopeLeaf() throw() { + if (_M_data != this->_M_c_string) { + this->_M_free_c_string(); + } + __STL_FREE_STRING(_M_data, this->_M_size, this->get_allocator()); + } +# endif +protected: + _Rope_RopeLeaf& + operator=(const _Rope_RopeLeaf&); + + _Rope_RopeLeaf(const _Rope_RopeLeaf&); +}; + +template<class _CharT, class _Alloc> +struct _Rope_RopeConcatenation : public _Rope_RopeRep<_CharT,_Alloc> { + public: + _Rope_RopeRep<_CharT,_Alloc>* _M_left; + _Rope_RopeRep<_CharT,_Alloc>* _M_right; + typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; + _Rope_RopeConcatenation(_Rope_RopeRep<_CharT,_Alloc>* __l, + _Rope_RopeRep<_CharT,_Alloc>* __r, + allocator_type __a) + + : _Rope_RopeRep<_CharT,_Alloc>(_Rope_constants::_S_concat, + std::max(__l->_M_depth, __r->_M_depth) + 1, + false, + __l->_M_size + __r->_M_size, __a), + _M_left(__l), _M_right(__r) + {} +# ifndef __GC + ~_Rope_RopeConcatenation() throw() { + this->_M_free_c_string(); + _M_left->_M_unref_nonnil(); + _M_right->_M_unref_nonnil(); + } +# endif +protected: + _Rope_RopeConcatenation& + operator=(const _Rope_RopeConcatenation&); + + _Rope_RopeConcatenation(const _Rope_RopeConcatenation&); +}; + +template<class _CharT, class _Alloc> +struct _Rope_RopeFunction : public _Rope_RopeRep<_CharT,_Alloc> { + public: + char_producer<_CharT>* _M_fn; +# ifndef __GC + 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 typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; + _Rope_RopeFunction(char_producer<_CharT>* __f, size_t __size, + bool __d, allocator_type __a) + : _Rope_RopeRep<_CharT,_Alloc>(_Rope_constants::_S_function, + 0, true, __size, __a) + , _M_fn(__f) +# ifndef __GC + , _M_delete_when_done(__d) +# endif + { +# ifdef __GC + if (__d) { + GC_REGISTER_FINALIZER( + this, _Rope_RopeFunction::_S_fn_finalization_proc, 0, 0, 0); + } +# endif + } +# ifndef __GC + ~_Rope_RopeFunction() throw() { + this->_M_free_c_string(); + if (_M_delete_when_done) { + delete _M_fn; + } + } +# endif +protected: + _Rope_RopeFunction& + operator=(const _Rope_RopeFunction&); + + _Rope_RopeFunction(const _Rope_RopeFunction&); +}; +// Substring results are usually represented using just +// concatenation nodes. But in the case of very long flat ropes +// or ropes with a functional representation that isn't practical. +// In that case, we represent the __result as a special case of +// RopeFunction, whose char_producer points back to the rope itself. +// In all cases except repeated substring operations and +// deallocation, we treat the __result as a RopeFunction. +template<class _CharT, class _Alloc> +struct _Rope_RopeSubstring : public _Rope_RopeFunction<_CharT,_Alloc>, + public char_producer<_CharT> { + public: + // XXX this whole class should be rewritten. + _Rope_RopeRep<_CharT,_Alloc>* _M_base; // not 0 + size_t _M_start; + virtual void operator()(size_t __start_pos, size_t __req_len, + _CharT* __buffer) { + switch(_M_base->_M_tag) { + case _Rope_constants::_S_function: + case _Rope_constants::_S_substringfn: + { + char_producer<_CharT>* __fn = + ((_Rope_RopeFunction<_CharT,_Alloc>*)_M_base)->_M_fn; + (*__fn)(__start_pos + _M_start, __req_len, __buffer); + } + break; + case _Rope_constants::_S_leaf: + { + __GC_CONST _CharT* __s = + ((_Rope_RopeLeaf<_CharT,_Alloc>*)_M_base)->_M_data; + uninitialized_copy_n(__s + __start_pos + _M_start, __req_len, + __buffer); + } + break; + default: + break; + } + } + typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type + allocator_type; + _Rope_RopeSubstring(_Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s, + size_t __l, allocator_type __a) + : _Rope_RopeFunction<_CharT,_Alloc>(this, __l, false, __a), + char_producer<_CharT>(), + _M_base(__b), + _M_start(__s) + { +# ifndef __GC + _M_base->_M_ref_nonnil(); +# endif + this->_M_tag = _Rope_constants::_S_substringfn; + } + virtual ~_Rope_RopeSubstring() throw() + { +# ifndef __GC + _M_base->_M_unref_nonnil(); + // _M_free_c_string(); -- done by parent class +# endif + } +}; + + +// Self-destructing pointers to Rope_rep. +// These are not conventional smart pointers. Their +// only purpose in life is to ensure that unref is called +// on the pointer either at normal exit or if an exception +// is raised. It is the caller's responsibility to +// adjust reference counts when these pointers are initialized +// or assigned to. (This convention significantly reduces +// the number of potentially expensive reference count +// updates.) +#ifndef __GC + template<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 __EXCEPTIONS + _Rope_self_destruct_ptr() : _M_ptr(0) {}; +#else + _Rope_self_destruct_ptr() {}; +#endif + _Rope_self_destruct_ptr(_Rope_RopeRep<_CharT,_Alloc>* __p) : _M_ptr(__p) {} + _Rope_RopeRep<_CharT,_Alloc>& operator*() { return *_M_ptr; } + _Rope_RopeRep<_CharT,_Alloc>* operator->() { return _M_ptr; } + operator _Rope_RopeRep<_CharT,_Alloc>*() { return _M_ptr; } + _Rope_self_destruct_ptr& operator= (_Rope_RopeRep<_CharT,_Alloc>* __x) + { _M_ptr = __x; return *this; } + }; +#endif + +// Dereferencing a nonconst iterator has to return something +// that behaves almost like a reference. It's not possible to +// return an actual reference since assignment requires extra +// work. And we would get into the same problems as with the +// CD2 version of basic_string. +template<class _CharT, class _Alloc> +class _Rope_char_ref_proxy { + friend class rope<_CharT,_Alloc>; + friend class _Rope_iterator<_CharT,_Alloc>; + friend class _Rope_char_ptr_proxy<_CharT,_Alloc>; +# ifdef __GC + typedef _Rope_RopeRep<_CharT,_Alloc>* _Self_destruct_ptr; +# else + typedef _Rope_self_destruct_ptr<_CharT,_Alloc> _Self_destruct_ptr; +# endif + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + typedef rope<_CharT,_Alloc> _My_rope; + size_t _M_pos; + _CharT _M_current; + bool _M_current_valid; + _My_rope* _M_root; // The whole rope. + public: + _Rope_char_ref_proxy(_My_rope* __r, size_t __p) + : _M_pos(__p), _M_current(), _M_current_valid(false), _M_root(__r) {} + + _Rope_char_ref_proxy(const _Rope_char_ref_proxy& __x) + : _M_pos(__x._M_pos), _M_current(__x._M_current), _M_current_valid(false), + _M_root(__x._M_root) {} + + // Don't preserve cache if the reference can outlive the + // expression. We claim that's not possible without calling + // a copy constructor or generating reference to a proxy + // reference. We declare the latter to have undefined semantics. + _Rope_char_ref_proxy(_My_rope* __r, size_t __p, _CharT __c) + : _M_pos(__p), _M_current(__c), _M_current_valid(true), _M_root(__r) {} + inline operator _CharT () const; + _Rope_char_ref_proxy& operator= (_CharT __c); + _Rope_char_ptr_proxy<_CharT,_Alloc> operator& () const; + _Rope_char_ref_proxy& operator= (const _Rope_char_ref_proxy& __c) { + return operator=((_CharT)__c); + } +}; + +template<class _CharT, class __Alloc> +inline void swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a, + _Rope_char_ref_proxy <_CharT, __Alloc > __b) { + _CharT __tmp = __a; + __a = __b; + __b = __tmp; +} + +template<class _CharT, class _Alloc> +class _Rope_char_ptr_proxy { + // XXX this class should be rewritten. + friend class _Rope_char_ref_proxy<_CharT,_Alloc>; + size_t _M_pos; + rope<_CharT,_Alloc>* _M_root; // The whole rope. + public: + _Rope_char_ptr_proxy(const _Rope_char_ref_proxy<_CharT,_Alloc>& __x) + : _M_pos(__x._M_pos), _M_root(__x._M_root) {} + _Rope_char_ptr_proxy(const _Rope_char_ptr_proxy& __x) + : _M_pos(__x._M_pos), _M_root(__x._M_root) {} + _Rope_char_ptr_proxy() {} + _Rope_char_ptr_proxy(_CharT* __x) : _M_root(0), _M_pos(0) { + } + _Rope_char_ptr_proxy& + operator= (const _Rope_char_ptr_proxy& __x) { + _M_pos = __x._M_pos; + _M_root = __x._M_root; + return *this; + } + template<class _CharT2, class _Alloc2> + friend bool operator== (const _Rope_char_ptr_proxy<_CharT2,_Alloc2>& __x, + const _Rope_char_ptr_proxy<_CharT2,_Alloc2>& __y); + _Rope_char_ref_proxy<_CharT,_Alloc> operator*() const { + return _Rope_char_ref_proxy<_CharT,_Alloc>(_M_root, _M_pos); + } +}; + + +// Rope iterators: +// Unlike in the C version, we cache only part of the stack +// for rope iterators, since they must be efficiently copyable. +// When we run out of cache, we have to reconstruct the iterator +// value. +// Pointers from iterators are not included in reference counts. +// Iterators are assumed to be thread private. Ropes can +// be shared. + +template<class _CharT, class _Alloc> +class _Rope_iterator_base + : public iterator<std::random_access_iterator_tag, _CharT> +{ + friend class rope<_CharT,_Alloc>; + public: + typedef _Alloc _allocator_type; // used in _Rope_rotate, VC++ workaround + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + // Borland doesn't want this to be protected. + protected: + enum { _S_path_cache_len = 4 }; // Must be <= 9. + enum { _S_iterator_buf_len = 15 }; + size_t _M_current_pos; + _RopeRep* _M_root; // The whole rope. + size_t _M_leaf_pos; // Starting position for current leaf + __GC_CONST _CharT* _M_buf_start; + // Buffer possibly + // containing current char. + __GC_CONST _CharT* _M_buf_ptr; + // Pointer to current char in buffer. + // != 0 ==> buffer valid. + __GC_CONST _CharT* _M_buf_end; + // One past __last valid char in buffer. + // What follows is the path cache. We go out of our + // way to make this compact. + // Path_end contains the bottom section of the path from + // the root to the current leaf. + const _RopeRep* _M_path_end[_S_path_cache_len]; + int _M_leaf_index; // Last valid __pos in path_end; + // _M_path_end[0] ... _M_path_end[leaf_index-1] + // point to concatenation nodes. + unsigned char _M_path_directions; + // (path_directions >> __i) & 1 is 1 + // iff we got from _M_path_end[leaf_index - __i - 1] + // to _M_path_end[leaf_index - __i] by going to the + // __right. Assumes path_cache_len <= 9. + _CharT _M_tmp_buf[_S_iterator_buf_len]; + // Short buffer for surrounding chars. + // This is useful primarily for + // RopeFunctions. We put the buffer + // here to avoid locking in the + // multithreaded case. + // The cached path is generally assumed to be valid + // only if the buffer is valid. + static void _S_setbuf(_Rope_iterator_base& __x); + // Set buffer contents given + // path cache. + static void _S_setcache(_Rope_iterator_base& __x); + // Set buffer contents and + // path cache. + static void _S_setcache_for_incr(_Rope_iterator_base& __x); + // As above, but assumes path + // cache is valid for previous posn. + _Rope_iterator_base() {} + _Rope_iterator_base(_RopeRep* __root, size_t __pos) + : _M_current_pos(__pos), _M_root(__root), _M_buf_ptr(0) {} + void _M_incr(size_t __n); + void _M_decr(size_t __n); + public: + size_t index() const { return _M_current_pos; } + _Rope_iterator_base(const _Rope_iterator_base& __x) { + if (0 != __x._M_buf_ptr) { + *this = __x; + } else { + _M_current_pos = __x._M_current_pos; + _M_root = __x._M_root; + _M_buf_ptr = 0; + } + } +}; + +template<class _CharT, class _Alloc> class _Rope_iterator; + +template<class _CharT, class _Alloc> +class _Rope_const_iterator : public _Rope_iterator_base<_CharT,_Alloc> { + friend class rope<_CharT,_Alloc>; + protected: + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + // The one from the base class may not be directly visible. + _Rope_const_iterator(const _RopeRep* __root, size_t __pos): + _Rope_iterator_base<_CharT,_Alloc>( + const_cast<_RopeRep*>(__root), __pos) + // Only nonconst iterators modify root ref count + {} + public: + typedef _CharT reference; // Really a value. Returning a reference + // Would be a mess, since it would have + // to be included in refcount. + typedef const _CharT* pointer; + + public: + _Rope_const_iterator() {}; + _Rope_const_iterator(const _Rope_const_iterator& __x) : + _Rope_iterator_base<_CharT,_Alloc>(__x) { } + _Rope_const_iterator(const _Rope_iterator<_CharT,_Alloc>& __x); + _Rope_const_iterator(const rope<_CharT,_Alloc>& __r, size_t __pos) : + _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos) {} + _Rope_const_iterator& operator= (const _Rope_const_iterator& __x) { + if (0 != __x._M_buf_ptr) { + *(static_cast<_Rope_iterator_base<_CharT,_Alloc>*>(this)) = __x; + } else { + this->_M_current_pos = __x._M_current_pos; + this->_M_root = __x._M_root; + this->_M_buf_ptr = 0; + } + return(*this); + } + reference operator*() { + if (0 == this->_M_buf_ptr) _S_setcache(*this); + return *this->_M_buf_ptr; + } + _Rope_const_iterator& operator++() { + __GC_CONST _CharT* __next; + if (0 != this->_M_buf_ptr + && (__next = this->_M_buf_ptr + 1) < this->_M_buf_end) { + this->_M_buf_ptr = __next; + ++this->_M_current_pos; + } else { + this->_M_incr(1); + } + return *this; + } + _Rope_const_iterator& operator+=(ptrdiff_t __n) { + if (__n >= 0) { + this->_M_incr(__n); + } else { + this->_M_decr(-__n); + } + return *this; + } + _Rope_const_iterator& operator--() { + this->_M_decr(1); + return *this; + } + _Rope_const_iterator& operator-=(ptrdiff_t __n) { + if (__n >= 0) { + this->_M_decr(__n); + } else { + this->_M_incr(-__n); + } + return *this; + } + _Rope_const_iterator operator++(int) { + size_t __old_pos = this->_M_current_pos; + this->_M_incr(1); + return _Rope_const_iterator<_CharT,_Alloc>(this->_M_root, __old_pos); + // This makes a subsequent dereference expensive. + // Perhaps we should instead copy the iterator + // if it has a valid cache? + } + _Rope_const_iterator operator--(int) { + size_t __old_pos = this->_M_current_pos; + this->_M_decr(1); + return _Rope_const_iterator<_CharT,_Alloc>(this->_M_root, __old_pos); + } + template<class _CharT2, class _Alloc2> + friend _Rope_const_iterator<_CharT2,_Alloc2> operator- + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + ptrdiff_t __n); + template<class _CharT2, class _Alloc2> + friend _Rope_const_iterator<_CharT2,_Alloc2> operator+ + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + ptrdiff_t __n); + template<class _CharT2, class _Alloc2> + friend _Rope_const_iterator<_CharT2,_Alloc2> operator+ + (ptrdiff_t __n, + const _Rope_const_iterator<_CharT2,_Alloc2>& __x); + reference operator[](size_t __n) { + return rope<_CharT,_Alloc>::_S_fetch(this->_M_root, + this->_M_current_pos + __n); + } + + template<class _CharT2, class _Alloc2> + friend bool operator== + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + const _Rope_const_iterator<_CharT2,_Alloc2>& __y); + template<class _CharT2, class _Alloc2> + friend bool operator< + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + const _Rope_const_iterator<_CharT2,_Alloc2>& __y); + template<class _CharT2, class _Alloc2> + friend ptrdiff_t operator- + (const _Rope_const_iterator<_CharT2,_Alloc2>& __x, + const _Rope_const_iterator<_CharT2,_Alloc2>& __y); +}; + +template<class _CharT, class _Alloc> +class _Rope_iterator : public _Rope_iterator_base<_CharT,_Alloc> { + friend class rope<_CharT,_Alloc>; + protected: + typedef typename _Rope_iterator_base<_CharT,_Alloc>::_RopeRep _RopeRep; + rope<_CharT,_Alloc>* _M_root_rope; + // root is treated as a cached version of this, + // and is used to detect changes to the underlying + // rope. + // Root is included in the reference count. + // This is necessary so that we can detect changes reliably. + // Unfortunately, it requires careful bookkeeping for the + // nonGC case. + _Rope_iterator(rope<_CharT,_Alloc>* __r, size_t __pos) + : _Rope_iterator_base<_CharT,_Alloc>(__r->_M_tree_ptr, __pos), + _M_root_rope(__r) + { _RopeRep::_S_ref(this->_M_root); + if (!(__r -> empty()))_S_setcache(*this); } + + void _M_check(); + public: + typedef _Rope_char_ref_proxy<_CharT,_Alloc> reference; + typedef _Rope_char_ref_proxy<_CharT,_Alloc>* pointer; + + public: + rope<_CharT,_Alloc>& container() { return *_M_root_rope; } + _Rope_iterator() { + this->_M_root = 0; // Needed for reference counting. + }; + _Rope_iterator(const _Rope_iterator& __x) : + _Rope_iterator_base<_CharT,_Alloc>(__x) { + _M_root_rope = __x._M_root_rope; + _RopeRep::_S_ref(this->_M_root); + } + _Rope_iterator(rope<_CharT,_Alloc>& __r, size_t __pos); + ~_Rope_iterator() { + _RopeRep::_S_unref(this->_M_root); + } + _Rope_iterator& operator= (const _Rope_iterator& __x) { + _RopeRep* __old = this->_M_root; + + _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 { + this->_M_current_pos = __x._M_current_pos; + this->_M_root = __x._M_root; + _M_root_rope = __x._M_root_rope; + this->_M_buf_ptr = 0; + } + _RopeRep::_S_unref(__old); + return(*this); + } + reference operator*() { + _M_check(); + if (0 == this->_M_buf_ptr) { + return _Rope_char_ref_proxy<_CharT,_Alloc>( + _M_root_rope, this->_M_current_pos); + } else { + return _Rope_char_ref_proxy<_CharT,_Alloc>( + _M_root_rope, this->_M_current_pos, *this->_M_buf_ptr); + } + } + _Rope_iterator& operator++() { + this->_M_incr(1); + return *this; + } + _Rope_iterator& operator+=(ptrdiff_t __n) { + if (__n >= 0) { + this->_M_incr(__n); + } else { + this->_M_decr(-__n); + } + return *this; + } + _Rope_iterator& operator--() { + this->_M_decr(1); + return *this; + } + _Rope_iterator& operator-=(ptrdiff_t __n) { + if (__n >= 0) { + this->_M_decr(__n); + } else { + this->_M_incr(-__n); + } + return *this; + } + _Rope_iterator operator++(int) { + size_t __old_pos = this->_M_current_pos; + this->_M_incr(1); + return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); + } + _Rope_iterator operator--(int) { + size_t __old_pos = this->_M_current_pos; + this->_M_decr(1); + return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); + } + reference operator[](ptrdiff_t __n) { + return _Rope_char_ref_proxy<_CharT,_Alloc>( + _M_root_rope, this->_M_current_pos + __n); + } + + template<class _CharT2, class _Alloc2> + friend bool operator== + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + const _Rope_iterator<_CharT2,_Alloc2>& __y); + template<class _CharT2, class _Alloc2> + friend bool operator< + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + const _Rope_iterator<_CharT2,_Alloc2>& __y); + template<class _CharT2, class _Alloc2> + friend ptrdiff_t operator- + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + const _Rope_iterator<_CharT2,_Alloc2>& __y); + template<class _CharT2, class _Alloc2> + friend _Rope_iterator<_CharT2,_Alloc2> operator- + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + ptrdiff_t __n); + template<class _CharT2, class _Alloc2> + friend _Rope_iterator<_CharT2,_Alloc2> operator+ + (const _Rope_iterator<_CharT2,_Alloc2>& __x, + ptrdiff_t __n); + template<class _CharT2, class _Alloc2> + friend _Rope_iterator<_CharT2,_Alloc2> operator+ + (ptrdiff_t __n, + const _Rope_iterator<_CharT2,_Alloc2>& __x); +}; + + +template <class _CharT, class _Alloc> +struct _Rope_base +: public _Alloc +{ + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const { return *static_cast<const _Alloc*>(this); } + + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + // The one in _Base may not be visible due to template rules. + + _Rope_base(_RopeRep* __t, const allocator_type&) + : _M_tree_ptr(__t) {} + _Rope_base(const allocator_type&) {} + + // The only data member of a rope: + _RopeRep *_M_tree_ptr; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc::template rebind<_Tp>::other __name##Alloc; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc().allocate(__n); } \ + static void __name##_deallocate(_Tp *__p, size_t __n) \ + { __name##Alloc().deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Alloc) +# undef __ROPE_DEFINE_ALLOC + +protected: + _Rope_base& + operator=(const _Rope_base&); + + _Rope_base(const _Rope_base&); +}; + + +/** + * This is an SGI extension. + * @ingroup SGIextensions + * @doctodo +*/ +template <class _CharT, class _Alloc> +class rope : public _Rope_base<_CharT,_Alloc> { + public: + typedef _CharT value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef _CharT const_reference; + typedef const _CharT* const_pointer; + typedef _Rope_iterator<_CharT,_Alloc> iterator; + typedef _Rope_const_iterator<_CharT,_Alloc> const_iterator; + typedef _Rope_char_ref_proxy<_CharT,_Alloc> reference; + typedef _Rope_char_ptr_proxy<_CharT,_Alloc> pointer; + + friend class _Rope_iterator<_CharT,_Alloc>; + friend class _Rope_const_iterator<_CharT,_Alloc>; + friend struct _Rope_RopeRep<_CharT,_Alloc>; + friend class _Rope_iterator_base<_CharT,_Alloc>; + friend class _Rope_char_ptr_proxy<_CharT,_Alloc>; + friend class _Rope_char_ref_proxy<_CharT,_Alloc>; + friend struct _Rope_RopeSubstring<_CharT,_Alloc>; + + protected: + typedef _Rope_base<_CharT,_Alloc> _Base; + typedef typename _Base::allocator_type allocator_type; + using _Base::_M_tree_ptr; + using _Base::get_allocator; + typedef __GC_CONST _CharT* _Cstrptr; + + static _CharT _S_empty_c_str[1]; + + static bool _S_is0(_CharT __c) { return __c == _S_eos((_CharT*)0); } + enum { _S_copy_max = 23 }; + // For strings shorter than _S_copy_max, we copy to + // concatenate. + + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + typedef _Rope_RopeConcatenation<_CharT,_Alloc> _RopeConcatenation; + typedef _Rope_RopeLeaf<_CharT,_Alloc> _RopeLeaf; + typedef _Rope_RopeFunction<_CharT,_Alloc> _RopeFunction; + typedef _Rope_RopeSubstring<_CharT,_Alloc> _RopeSubstring; + + // Retrieve a character at the indicated position. + static _CharT _S_fetch(_RopeRep* __r, size_type __pos); + +# ifndef __GC + // Obtain a pointer to the character at the indicated position. + // The pointer can be used to change the character. + // If such a pointer cannot be produced, as is frequently the + // case, 0 is returned instead. + // (Returns nonzero only if all nodes in the path have a refcount + // of 1.) + static _CharT* _S_fetch_ptr(_RopeRep* __r, size_type __pos); +# endif + + static bool _S_apply_to_pieces( + // should be template parameter + _Rope_char_consumer<_CharT>& __c, + const _RopeRep* __r, + size_t __begin, size_t __end); + // begin and end are assumed to be in range. + +# ifndef __GC + static void _S_unref(_RopeRep* __t) + { + _RopeRep::_S_unref(__t); + } + static void _S_ref(_RopeRep* __t) + { + _RopeRep::_S_ref(__t); + } +# else /* __GC */ + static void _S_unref(_RopeRep*) {} + static void _S_ref(_RopeRep*) {} +# endif + + +# ifdef __GC + typedef _Rope_RopeRep<_CharT,_Alloc>* _Self_destruct_ptr; +# else + typedef _Rope_self_destruct_ptr<_CharT,_Alloc> _Self_destruct_ptr; +# endif + + // _Result is counted in refcount. + static _RopeRep* _S_substring(_RopeRep* __base, + size_t __start, size_t __endp1); + + static _RopeRep* _S_concat_char_iter(_RopeRep* __r, + const _CharT* __iter, size_t __slen); + // Concatenate rope and char ptr, copying __s. + // Should really take an arbitrary iterator. + // Result is counted in refcount. + static _RopeRep* _S_destr_concat_char_iter(_RopeRep* __r, + const _CharT* __iter, size_t __slen) + // As above, but one reference to __r is about to be + // destroyed. Thus the pieces may be recycled if all + // relevant reference counts are 1. +# ifdef __GC + // We can't really do anything since refcounts are unavailable. + { return _S_concat_char_iter(__r, __iter, __slen); } +# else + ; +# endif + + static _RopeRep* _S_concat(_RopeRep* __left, _RopeRep* __right); + // General concatenation on _RopeRep. _Result + // has refcount of 1. Adjusts argument refcounts. + + public: + void apply_to_pieces( size_t __begin, size_t __end, + _Rope_char_consumer<_CharT>& __c) const { + _S_apply_to_pieces(__c, this->_M_tree_ptr, __begin, __end); + } + + + protected: + + static size_t _S_rounded_up_size(size_t __n) { + return _RopeLeaf::_S_rounded_up_size(__n); + } + + static size_t _S_allocated_capacity(size_t __n) { + if (_S_is_basic_char_type((_CharT*)0)) { + return _S_rounded_up_size(__n) - 1; + } else { + return _S_rounded_up_size(__n); + } + } + + // Allocate and construct a RopeLeaf using the supplied allocator + // Takes ownership of s instead of copying. + static _RopeLeaf* _S_new_RopeLeaf(__GC_CONST _CharT *__s, + size_t __size, allocator_type __a) + { + _RopeLeaf* __space = typename _Base::_LAlloc(__a).allocate(1); + return new(__space) _RopeLeaf(__s, __size, __a); + } + + static _RopeConcatenation* _S_new_RopeConcatenation( + _RopeRep* __left, _RopeRep* __right, + allocator_type __a) + { + _RopeConcatenation* __space = typename _Base::_CAlloc(__a).allocate(1); + return new(__space) _RopeConcatenation(__left, __right, __a); + } + + static _RopeFunction* _S_new_RopeFunction(char_producer<_CharT>* __f, + size_t __size, bool __d, allocator_type __a) + { + _RopeFunction* __space = typename _Base::_FAlloc(__a).allocate(1); + return new(__space) _RopeFunction(__f, __size, __d, __a); + } + + static _RopeSubstring* _S_new_RopeSubstring( + _Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s, + size_t __l, allocator_type __a) + { + _RopeSubstring* __space = typename _Base::_SAlloc(__a).allocate(1); + return new(__space) _RopeSubstring(__b, __s, __l, __a); + } + + static + _RopeLeaf* _S_RopeLeaf_from_unowned_char_ptr(const _CharT *__s, + size_t __size, allocator_type __a) +# define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) \ + _S_RopeLeaf_from_unowned_char_ptr(__s, __size, __a) + { + if (0 == __size) return 0; + _CharT* __buf = __a.allocate(_S_rounded_up_size(__size)); + + uninitialized_copy_n(__s, __size, __buf); + _S_cond_store_eos(__buf[__size]); + try { + return _S_new_RopeLeaf(__buf, __size, __a); + } + catch(...) + { + _RopeRep::__STL_FREE_STRING(__buf, __size, __a); + __throw_exception_again; + } + } + + + // Concatenation of nonempty strings. + // Always builds a concatenation node. + // Rebalances if the result is too deep. + // Result has refcount 1. + // Does not increment left and right ref counts even though + // they are referenced. + static _RopeRep* + _S_tree_concat(_RopeRep* __left, _RopeRep* __right); + + // Concatenation helper functions + static _RopeLeaf* + _S_leaf_concat_char_iter(_RopeLeaf* __r, + const _CharT* __iter, size_t __slen); + // Concatenate by copying leaf. + // should take an arbitrary iterator + // result has refcount 1. +# ifndef __GC + static _RopeLeaf* _S_destr_leaf_concat_char_iter + (_RopeLeaf* __r, const _CharT* __iter, size_t __slen); + // A version that potentially clobbers __r if __r->_M_ref_count == 1. +# endif + + private: + + static size_t _S_char_ptr_len(const _CharT* __s); + // slightly generalized strlen + + rope(_RopeRep* __t, const allocator_type& __a = allocator_type()) + : _Base(__t,__a) { } + + + // Copy __r to the _CharT buffer. + // Returns __buffer + __r->_M_size. + // Assumes that buffer is uninitialized. + static _CharT* _S_flatten(_RopeRep* __r, _CharT* __buffer); + + // Again, with explicit starting position and length. + // Assumes that buffer is uninitialized. + static _CharT* _S_flatten(_RopeRep* __r, + size_t __start, size_t __len, + _CharT* __buffer); + + static const unsigned long + _S_min_len[_Rope_constants::_S_max_rope_depth + 1]; + + static bool _S_is_balanced(_RopeRep* __r) + { return (__r->_M_size >= _S_min_len[__r->_M_depth]); } + + static bool _S_is_almost_balanced(_RopeRep* __r) + { return (__r->_M_depth == 0 || + __r->_M_size >= _S_min_len[__r->_M_depth - 1]); } + + static bool _S_is_roughly_balanced(_RopeRep* __r) + { return (__r->_M_depth <= 1 || + __r->_M_size >= _S_min_len[__r->_M_depth - 2]); } + + // Assumes the result is not empty. + static _RopeRep* _S_concat_and_set_balanced(_RopeRep* __left, + _RopeRep* __right) + { + _RopeRep* __result = _S_concat(__left, __right); + if (_S_is_balanced(__result)) __result->_M_is_balanced = true; + return __result; + } + + // The basic rebalancing operation. Logically copies the + // rope. The result has refcount of 1. The client will + // usually decrement the reference count of __r. + // The result is within height 2 of balanced by the above + // definition. + static _RopeRep* _S_balance(_RopeRep* __r); + + // Add all unbalanced subtrees to the forest of balanceed trees. + // Used only by balance. + static void _S_add_to_forest(_RopeRep*__r, _RopeRep** __forest); + + // Add __r to forest, assuming __r is already balanced. + static void _S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest); + + // Print to stdout, exposing structure + static void _S_dump(_RopeRep* __r, int __indent = 0); + + // Return -1, 0, or 1 if __x < __y, __x == __y, or __x > __y resp. + static int _S_compare(const _RopeRep* __x, const _RopeRep* __y); + + public: + bool empty() const { return 0 == this->_M_tree_ptr; } + + // Comparison member function. This is public only for those + // clients that need a ternary comparison. Others + // should use the comparison operators below. + int compare(const rope& __y) const { + return _S_compare(this->_M_tree_ptr, __y._M_tree_ptr); + } + + rope(const _CharT* __s, const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, _S_char_ptr_len(__s), + __a),__a) + { } + + rope(const _CharT* __s, size_t __len, + const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __len, __a), __a) + { } + + // Should perhaps be templatized with respect to the iterator type + // and use Sequence_buffer. (It should perhaps use sequence_buffer + // even now.) + rope(const _CharT *__s, const _CharT *__e, + const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __e - __s, __a), __a) + { } + + rope(const const_iterator& __s, const const_iterator& __e, + const allocator_type& __a = allocator_type()) + : _Base(_S_substring(__s._M_root, __s._M_current_pos, + __e._M_current_pos), __a) + { } + + rope(const iterator& __s, const iterator& __e, + const allocator_type& __a = allocator_type()) + : _Base(_S_substring(__s._M_root, __s._M_current_pos, + __e._M_current_pos), __a) + { } + + rope(_CharT __c, const allocator_type& __a = allocator_type()) + : _Base(__a) + { + _CharT* __buf = this->_Data_allocate(_S_rounded_up_size(1)); + + std::_Construct(__buf, __c); + try { + this->_M_tree_ptr = _S_new_RopeLeaf(__buf, 1, __a); + } + catch(...) + { + _RopeRep::__STL_FREE_STRING(__buf, 1, __a); + __throw_exception_again; + } + } + + rope(size_t __n, _CharT __c, + const allocator_type& __a = allocator_type()); + + rope(const allocator_type& __a = allocator_type()) + : _Base(0, __a) {} + + // Construct a rope from a function that can compute its members + rope(char_producer<_CharT> *__fn, size_t __len, bool __delete_fn, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + this->_M_tree_ptr = (0 == __len) ? + 0 : _S_new_RopeFunction(__fn, __len, __delete_fn, __a); + } + + rope(const rope& __x, const allocator_type& __a = allocator_type()) + : _Base(__x._M_tree_ptr, __a) + { + _S_ref(this->_M_tree_ptr); + } + + ~rope() throw() + { _S_unref(this->_M_tree_ptr); } + + rope& operator=(const rope& __x) + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr = __x._M_tree_ptr; + _S_ref(this->_M_tree_ptr); + _S_unref(__old); + return *this; + } + + void clear() + { + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = 0; + } + + void push_back(_CharT __x) + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr + = _S_destr_concat_char_iter(this->_M_tree_ptr, &__x, 1); + _S_unref(__old); + } + + void pop_back() + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr = + _S_substring(this->_M_tree_ptr, + 0, + this->_M_tree_ptr->_M_size - 1); + _S_unref(__old); + } + + _CharT back() const + { + return _S_fetch(this->_M_tree_ptr, this->_M_tree_ptr->_M_size - 1); + } + + void push_front(_CharT __x) + { + _RopeRep* __old = this->_M_tree_ptr; + _RopeRep* __left = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(&__x, 1, this->get_allocator()); + try { + this->_M_tree_ptr = _S_concat(__left, this->_M_tree_ptr); + _S_unref(__old); + _S_unref(__left); + } + catch(...) + { + _S_unref(__left); + __throw_exception_again; + } + } + + void pop_front() + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr + = _S_substring(this->_M_tree_ptr, 1, this->_M_tree_ptr->_M_size); + _S_unref(__old); + } + + _CharT front() const + { + return _S_fetch(this->_M_tree_ptr, 0); + } + + void balance() + { + _RopeRep* __old = this->_M_tree_ptr; + this->_M_tree_ptr = _S_balance(this->_M_tree_ptr); + _S_unref(__old); + } + + void copy(_CharT* __buffer) const { + _Destroy(__buffer, __buffer + size()); + _S_flatten(this->_M_tree_ptr, __buffer); + } + + // This is the copy function from the standard, but + // with the arguments reordered to make it consistent with the + // rest of the interface. + // Note that this guaranteed not to compile if the draft standard + // order is assumed. + size_type copy(size_type __pos, size_type __n, _CharT* __buffer) const + { + size_t __size = size(); + size_t __len = (__pos + __n > __size? __size - __pos : __n); + + _Destroy(__buffer, __buffer + __len); + _S_flatten(this->_M_tree_ptr, __pos, __len, __buffer); + return __len; + } + + // Print to stdout, exposing structure. May be useful for + // performance debugging. + void dump() { + _S_dump(this->_M_tree_ptr); + } + + // Convert to 0 terminated string in new allocated memory. + // Embedded 0s in the input do not terminate the copy. + const _CharT* c_str() const; + + // As above, but lso use the flattened representation as the + // the new rope representation. + const _CharT* replace_with_c_str(); + + // Reclaim memory for the c_str generated flattened string. + // Intentionally undocumented, since it's hard to say when this + // is safe for multiple threads. + void delete_c_str () { + if (0 == this->_M_tree_ptr) return; + if (_Rope_constants::_S_leaf == this->_M_tree_ptr->_M_tag && + ((_RopeLeaf*)this->_M_tree_ptr)->_M_data == + this->_M_tree_ptr->_M_c_string) { + // Representation shared + return; + } +# ifndef __GC + this->_M_tree_ptr->_M_free_c_string(); +# endif + this->_M_tree_ptr->_M_c_string = 0; + } + + _CharT operator[] (size_type __pos) const { + return _S_fetch(this->_M_tree_ptr, __pos); + } + + _CharT at(size_type __pos) const { + // if (__pos >= size()) throw out_of_range; // XXX + return (*this)[__pos]; + } + + const_iterator begin() const { + return(const_iterator(this->_M_tree_ptr, 0)); + } + + // An easy way to get a const iterator from a non-const container. + const_iterator const_begin() const { + return(const_iterator(this->_M_tree_ptr, 0)); + } + + const_iterator end() const { + return(const_iterator(this->_M_tree_ptr, size())); + } + + const_iterator const_end() const { + return(const_iterator(this->_M_tree_ptr, size())); + } + + size_type size() const { + return(0 == this->_M_tree_ptr? 0 : this->_M_tree_ptr->_M_size); + } + + size_type length() const { + return size(); + } + + size_type max_size() const { + return _S_min_len[_Rope_constants::_S_max_rope_depth - 1] - 1; + // Guarantees that the result can be sufficirntly + // balanced. Longer ropes will probably still work, + // but it's harder to make guarantees. + } + + typedef reverse_iterator<const_iterator> const_reverse_iterator; + + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + + const_reverse_iterator const_rbegin() const { + return const_reverse_iterator(end()); + } + + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + const_reverse_iterator const_rend() const { + return const_reverse_iterator(begin()); + } + + template<class _CharT2, class _Alloc2> + friend rope<_CharT2,_Alloc2> + operator+ (const rope<_CharT2,_Alloc2>& __left, + const rope<_CharT2,_Alloc2>& __right); + + template<class _CharT2, class _Alloc2> + friend rope<_CharT2,_Alloc2> + operator+ (const rope<_CharT2,_Alloc2>& __left, + const _CharT2* __right); + + template<class _CharT2, class _Alloc2> + friend rope<_CharT2,_Alloc2> + operator+ (const rope<_CharT2,_Alloc2>& __left, _CharT2 __right); + // The symmetric cases are intentionally omitted, since they're presumed + // to be less common, and we don't handle them as well. + + // The following should really be templatized. + // The first argument should be an input iterator or + // forward iterator with value_type _CharT. + rope& append(const _CharT* __iter, size_t __n) { + _RopeRep* __result = + _S_destr_concat_char_iter(this->_M_tree_ptr, __iter, __n); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + return *this; + } + + rope& append(const _CharT* __c_string) { + size_t __len = _S_char_ptr_len(__c_string); + append(__c_string, __len); + return(*this); + } + + rope& append(const _CharT* __s, const _CharT* __e) { + _RopeRep* __result = + _S_destr_concat_char_iter(this->_M_tree_ptr, __s, __e - __s); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + return *this; + } + + rope& append(const_iterator __s, const_iterator __e) { + _Self_destruct_ptr __appendee(_S_substring( + __s._M_root, __s._M_current_pos, __e._M_current_pos)); + _RopeRep* __result = + _S_concat(this->_M_tree_ptr, (_RopeRep*)__appendee); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + return *this; + } + + rope& append(_CharT __c) { + _RopeRep* __result = + _S_destr_concat_char_iter(this->_M_tree_ptr, &__c, 1); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + return *this; + } + + rope& append() { return append(_CharT()); } // XXX why? + + rope& append(const rope& __y) { + _RopeRep* __result = _S_concat(this->_M_tree_ptr, __y._M_tree_ptr); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + return *this; + } + + rope& append(size_t __n, _CharT __c) { + rope<_CharT,_Alloc> __last(__n, __c); + return append(__last); + } + + void swap(rope& __b) { + _RopeRep* __tmp = this->_M_tree_ptr; + this->_M_tree_ptr = __b._M_tree_ptr; + __b._M_tree_ptr = __tmp; + } + + + protected: + // Result is included in refcount. + static _RopeRep* replace(_RopeRep* __old, size_t __pos1, + size_t __pos2, _RopeRep* __r) { + if (0 == __old) { _S_ref(__r); return __r; } + _Self_destruct_ptr __left( + _S_substring(__old, 0, __pos1)); + _Self_destruct_ptr __right( + _S_substring(__old, __pos2, __old->_M_size)); + _RopeRep* __result; + + if (0 == __r) { + __result = _S_concat(__left, __right); + } else { + _Self_destruct_ptr __left_result(_S_concat(__left, __r)); + __result = _S_concat(__left_result, __right); + } + return __result; + } + + public: + void insert(size_t __p, const rope& __r) { + _RopeRep* __result = + replace(this->_M_tree_ptr, __p, __p, __r._M_tree_ptr); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + } + + void insert(size_t __p, size_t __n, _CharT __c) { + rope<_CharT,_Alloc> __r(__n,__c); + insert(__p, __r); + } + + void insert(size_t __p, const _CharT* __i, size_t __n) { + _Self_destruct_ptr __left(_S_substring(this->_M_tree_ptr, 0, __p)); + _Self_destruct_ptr __right(_S_substring(this->_M_tree_ptr, + __p, size())); + _Self_destruct_ptr __left_result( + _S_concat_char_iter(__left, __i, __n)); + // _S_ destr_concat_char_iter should be safe here. + // But as it stands it's probably not a win, since __left + // is likely to have additional references. + _RopeRep* __result = _S_concat(__left_result, __right); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + } + + void insert(size_t __p, const _CharT* __c_string) { + insert(__p, __c_string, _S_char_ptr_len(__c_string)); + } + + void insert(size_t __p, _CharT __c) { + insert(__p, &__c, 1); + } + + void insert(size_t __p) { + _CharT __c = _CharT(); + insert(__p, &__c, 1); + } + + void insert(size_t __p, const _CharT* __i, const _CharT* __j) { + rope __r(__i, __j); + insert(__p, __r); + } + + void insert(size_t __p, const const_iterator& __i, + const const_iterator& __j) { + rope __r(__i, __j); + insert(__p, __r); + } + + void insert(size_t __p, const iterator& __i, + const iterator& __j) { + rope __r(__i, __j); + insert(__p, __r); + } + + // (position, length) versions of replace operations: + + void replace(size_t __p, size_t __n, const rope& __r) { + _RopeRep* __result = + replace(this->_M_tree_ptr, __p, __p + __n, __r._M_tree_ptr); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + } + + void replace(size_t __p, size_t __n, + const _CharT* __i, size_t __i_len) { + rope __r(__i, __i_len); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, _CharT __c) { + rope __r(__c); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, const _CharT* __c_string) { + rope __r(__c_string); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, + const _CharT* __i, const _CharT* __j) { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, + const const_iterator& __i, const const_iterator& __j) { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, + const iterator& __i, const iterator& __j) { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + // Single character variants: + void replace(size_t __p, _CharT __c) { + iterator __i(this, __p); + *__i = __c; + } + + void replace(size_t __p, const rope& __r) { + replace(__p, 1, __r); + } + + void replace(size_t __p, const _CharT* __i, size_t __i_len) { + replace(__p, 1, __i, __i_len); + } + + void replace(size_t __p, const _CharT* __c_string) { + replace(__p, 1, __c_string); + } + + void replace(size_t __p, const _CharT* __i, const _CharT* __j) { + replace(__p, 1, __i, __j); + } + + void replace(size_t __p, const const_iterator& __i, + const const_iterator& __j) { + replace(__p, 1, __i, __j); + } + + void replace(size_t __p, const iterator& __i, + const iterator& __j) { + replace(__p, 1, __i, __j); + } + + // Erase, (position, size) variant. + void erase(size_t __p, size_t __n) { + _RopeRep* __result = replace(this->_M_tree_ptr, __p, __p + __n, 0); + _S_unref(this->_M_tree_ptr); + this->_M_tree_ptr = __result; + } + + // Erase, single character + void erase(size_t __p) { + erase(__p, __p + 1); + } + + // Insert, iterator variants. + iterator insert(const iterator& __p, const rope& __r) + { insert(__p.index(), __r); return __p; } + iterator insert(const iterator& __p, size_t __n, _CharT __c) + { insert(__p.index(), __n, __c); return __p; } + iterator insert(const iterator& __p, _CharT __c) + { insert(__p.index(), __c); return __p; } + iterator insert(const iterator& __p ) + { insert(__p.index()); return __p; } + iterator insert(const iterator& __p, const _CharT* c_string) + { insert(__p.index(), c_string); return __p; } + iterator insert(const iterator& __p, const _CharT* __i, size_t __n) + { insert(__p.index(), __i, __n); return __p; } + iterator insert(const iterator& __p, const _CharT* __i, + const _CharT* __j) + { insert(__p.index(), __i, __j); return __p; } + iterator insert(const iterator& __p, + const const_iterator& __i, const const_iterator& __j) + { insert(__p.index(), __i, __j); return __p; } + iterator insert(const iterator& __p, + const iterator& __i, const iterator& __j) + { insert(__p.index(), __i, __j); return __p; } + + // Replace, range variants. + void replace(const iterator& __p, const iterator& __q, + const rope& __r) + { replace(__p.index(), __q.index() - __p.index(), __r); } + void replace(const iterator& __p, const iterator& __q, _CharT __c) + { replace(__p.index(), __q.index() - __p.index(), __c); } + void replace(const iterator& __p, const iterator& __q, + const _CharT* __c_string) + { replace(__p.index(), __q.index() - __p.index(), __c_string); } + void replace(const iterator& __p, const iterator& __q, + const _CharT* __i, size_t __n) + { replace(__p.index(), __q.index() - __p.index(), __i, __n); } + void replace(const iterator& __p, const iterator& __q, + const _CharT* __i, const _CharT* __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + void replace(const iterator& __p, const iterator& __q, + const const_iterator& __i, const const_iterator& __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + void replace(const iterator& __p, const iterator& __q, + const iterator& __i, const iterator& __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + + // Replace, iterator variants. + void replace(const iterator& __p, const rope& __r) + { replace(__p.index(), __r); } + void replace(const iterator& __p, _CharT __c) + { replace(__p.index(), __c); } + void replace(const iterator& __p, const _CharT* __c_string) + { replace(__p.index(), __c_string); } + void replace(const iterator& __p, const _CharT* __i, size_t __n) + { replace(__p.index(), __i, __n); } + void replace(const iterator& __p, const _CharT* __i, const _CharT* __j) + { replace(__p.index(), __i, __j); } + void replace(const iterator& __p, const_iterator __i, + const_iterator __j) + { replace(__p.index(), __i, __j); } + void replace(const iterator& __p, iterator __i, iterator __j) + { replace(__p.index(), __i, __j); } + + // Iterator and range variants of erase + iterator erase(const iterator& __p, const iterator& __q) { + size_t __p_index = __p.index(); + erase(__p_index, __q.index() - __p_index); + return iterator(this, __p_index); + } + iterator erase(const iterator& __p) { + size_t __p_index = __p.index(); + erase(__p_index, 1); + return iterator(this, __p_index); + } + + rope substr(size_t __start, size_t __len = 1) const { + return rope<_CharT,_Alloc>( + _S_substring(this->_M_tree_ptr, + __start, + __start + __len)); + } + + rope substr(iterator __start, iterator __end) const { + return rope<_CharT,_Alloc>( + _S_substring(this->_M_tree_ptr, + __start.index(), + __end.index())); + } + + rope substr(iterator __start) const { + size_t __pos = __start.index(); + return rope<_CharT,_Alloc>( + _S_substring(this->_M_tree_ptr, __pos, __pos + 1)); + } + + rope substr(const_iterator __start, const_iterator __end) const { + // This might eventually take advantage of the cache in the + // iterator. + return rope<_CharT,_Alloc>( + _S_substring(this->_M_tree_ptr, __start.index(), __end.index())); + } + + rope<_CharT,_Alloc> substr(const_iterator __start) { + size_t __pos = __start.index(); + return rope<_CharT,_Alloc>( + _S_substring(this->_M_tree_ptr, __pos, __pos + 1)); + } + + static const size_type npos; + + size_type find(_CharT __c, size_type __pos = 0) const; + size_type find(const _CharT* __s, size_type __pos = 0) const { + size_type __result_pos; + const_iterator __result = + std::search(const_begin() + __pos, const_end(), + __s, __s + _S_char_ptr_len(__s)); + __result_pos = __result.index(); +# ifndef __STL_OLD_ROPE_SEMANTICS + if (__result_pos == size()) __result_pos = npos; +# endif + return __result_pos; + } + + iterator mutable_begin() { + return(iterator(this, 0)); + } + + iterator mutable_end() { + return(iterator(this, size())); + } + + typedef reverse_iterator<iterator> reverse_iterator; + + reverse_iterator mutable_rbegin() { + return reverse_iterator(mutable_end()); + } + + reverse_iterator mutable_rend() { + return reverse_iterator(mutable_begin()); + } + + reference mutable_reference_at(size_type __pos) { + return reference(this, __pos); + } + +# ifdef __STD_STUFF + reference operator[] (size_type __pos) { + return _char_ref_proxy(this, __pos); + } + + reference at(size_type __pos) { + // if (__pos >= size()) throw out_of_range; // XXX + return (*this)[__pos]; + } + + void resize(size_type __n, _CharT __c) {} + void resize(size_type __n) {} + void reserve(size_type __res_arg = 0) {} + size_type capacity() const { + return max_size(); + } + + // Stuff below this line is dangerous because it's error prone. + // I would really like to get rid of it. + // copy function with funny arg ordering. + size_type copy(_CharT* __buffer, size_type __n, + size_type __pos = 0) const { + return copy(__pos, __n, __buffer); + } + + iterator end() { return mutable_end(); } + + iterator begin() { return mutable_begin(); } + + reverse_iterator rend() { return mutable_rend(); } + + reverse_iterator rbegin() { return mutable_rbegin(); } + +# else + + const_iterator end() { return const_end(); } + + const_iterator begin() { return const_begin(); } + + const_reverse_iterator rend() { return const_rend(); } + + const_reverse_iterator rbegin() { return const_rbegin(); } + +# endif + +}; + +template <class _CharT, class _Alloc> +const typename rope<_CharT, _Alloc>::size_type rope<_CharT, _Alloc>::npos = + (size_type)(-1); + +template <class _CharT, class _Alloc> +inline bool operator== (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos == __y._M_current_pos && + __x._M_root == __y._M_root); +} + +template <class _CharT, class _Alloc> +inline bool operator< (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos < __y._M_current_pos); +} + +template <class _CharT, class _Alloc> +inline bool operator!= (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return !(__x == __y); +} + +template <class _CharT, class _Alloc> +inline bool operator> (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return __y < __x; +} + +template <class _CharT, class _Alloc> +inline bool operator<= (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return !(__y < __x); +} + +template <class _CharT, class _Alloc> +inline bool operator>= (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return !(__x < __y); +} + +template <class _CharT, class _Alloc> +inline ptrdiff_t operator-(const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos; +} + +template <class _CharT, class _Alloc> +inline _Rope_const_iterator<_CharT,_Alloc> +operator-(const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n) { + return _Rope_const_iterator<_CharT,_Alloc>( + __x._M_root, __x._M_current_pos - __n); +} + +template <class _CharT, class _Alloc> +inline _Rope_const_iterator<_CharT,_Alloc> +operator+(const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n) { + return _Rope_const_iterator<_CharT,_Alloc>( + __x._M_root, __x._M_current_pos + __n); +} + +template <class _CharT, class _Alloc> +inline _Rope_const_iterator<_CharT,_Alloc> +operator+(ptrdiff_t __n, const _Rope_const_iterator<_CharT,_Alloc>& __x) { + return _Rope_const_iterator<_CharT,_Alloc>( + __x._M_root, __x._M_current_pos + __n); +} + +template <class _CharT, class _Alloc> +inline bool operator== (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos == __y._M_current_pos && + __x._M_root_rope == __y._M_root_rope); +} + +template <class _CharT, class _Alloc> +inline bool operator< (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos < __y._M_current_pos); +} + +template <class _CharT, class _Alloc> +inline bool operator!= (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return !(__x == __y); +} + +template <class _CharT, class _Alloc> +inline bool operator> (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return __y < __x; +} + +template <class _CharT, class _Alloc> +inline bool operator<= (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return !(__y < __x); +} + +template <class _CharT, class _Alloc> +inline bool operator>= (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return !(__x < __y); +} + +template <class _CharT, class _Alloc> +inline ptrdiff_t operator-(const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos; +} + +template <class _CharT, class _Alloc> +inline _Rope_iterator<_CharT,_Alloc> +operator-(const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n) { + return _Rope_iterator<_CharT,_Alloc>( + __x._M_root_rope, __x._M_current_pos - __n); +} + +template <class _CharT, class _Alloc> +inline _Rope_iterator<_CharT,_Alloc> +operator+(const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n) { + return _Rope_iterator<_CharT,_Alloc>( + __x._M_root_rope, __x._M_current_pos + __n); +} + +template <class _CharT, class _Alloc> +inline _Rope_iterator<_CharT,_Alloc> +operator+(ptrdiff_t __n, const _Rope_iterator<_CharT,_Alloc>& __x) { + return _Rope_iterator<_CharT,_Alloc>( + __x._M_root_rope, __x._M_current_pos + __n); +} + +template <class _CharT, class _Alloc> +inline +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) +{ + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat(__left._M_tree_ptr, __right._M_tree_ptr)); + // Inlining this should make it possible to keep __left and + // __right in registers. +} + +template <class _CharT, class _Alloc> +inline +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) +{ + __left.append(__right); + return __left; +} + +template <class _CharT, class _Alloc> +inline +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, + const _CharT* __right) { + size_t __rlen = rope<_CharT,_Alloc>::_S_char_ptr_len(__right); + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat_char_iter( + __left._M_tree_ptr, __right, __rlen)); +} + +template <class _CharT, class _Alloc> +inline +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, + const _CharT* __right) { + __left.append(__right); + return __left; +} + +template <class _CharT, class _Alloc> +inline +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, _CharT __right) { + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat_char_iter( + __left._M_tree_ptr, &__right, 1)); +} + +template <class _CharT, class _Alloc> +inline +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, _CharT __right) { + __left.append(__right); + return __left; +} + +template <class _CharT, class _Alloc> +bool +operator< (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) { + return __left.compare(__right) < 0; +} + +template <class _CharT, class _Alloc> +bool +operator== (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) { + return __left.compare(__right) == 0; +} + +template <class _CharT, class _Alloc> +inline bool operator== (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y) { + return (__x._M_pos == __y._M_pos && __x._M_root == __y._M_root); +} + +template <class _CharT, class _Alloc> +inline bool +operator!= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { + return !(__x == __y); +} + +template <class _CharT, class _Alloc> +inline bool +operator> (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { + return __y < __x; +} + +template <class _CharT, class _Alloc> +inline bool +operator<= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { + return !(__y < __x); +} + +template <class _CharT, class _Alloc> +inline bool +operator>= (const rope<_CharT,_Alloc>& __x, const rope<_CharT,_Alloc>& __y) { + return !(__x < __y); +} + +template <class _CharT, class _Alloc> +inline bool operator!= (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y) { + return !(__x == __y); +} + +template<class _CharT, class _Traits, class _Alloc> +std::basic_ostream<_CharT, _Traits>& operator<< + (std::basic_ostream<_CharT, _Traits>& __o, + const rope<_CharT, _Alloc>& __r); + +typedef rope<char> crope; +typedef rope<wchar_t> wrope; + +inline crope::reference __mutable_reference_at(crope& __c, size_t __i) +{ + return __c.mutable_reference_at(__i); +} + +inline wrope::reference __mutable_reference_at(wrope& __c, size_t __i) +{ + return __c.mutable_reference_at(__i); +} + +template <class _CharT, class _Alloc> +inline void swap(rope<_CharT,_Alloc>& __x, rope<_CharT,_Alloc>& __y) { + __x.swap(__y); +} + +// Hash functions should probably be revisited later: +template<> struct hash<crope> +{ + size_t operator()(const crope& __str) const + { + size_t __size = __str.size(); + + if (0 == __size) return 0; + return 13*__str[0] + 5*__str[__size - 1] + __size; + } +}; + + +template<> struct hash<wrope> +{ + size_t operator()(const wrope& __str) const + { + size_t __size = __str.size(); + + if (0 == __size) return 0; + return 13*__str[0] + 5*__str[__size - 1] + __size; + } +}; + +} // namespace __gnu_cxx -#endif /* __SGI_STL_ROPE */ +# include <ext/ropeimpl.h> -// Local Variables: -// mode:C++ -// End: +#endif diff --git a/contrib/libstdc++/include/ext/ropeimpl.h b/contrib/libstdc++/include/ext/ropeimpl.h index f3f09f5c468c..5eba107bc9d8 100644 --- a/contrib/libstdc++/include/ext/ropeimpl.h +++ b/contrib/libstdc++/include/ext/ropeimpl.h @@ -1,6 +1,6 @@ // SGI's rope class implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -45,8 +45,8 @@ * You should not attempt to use it directly. */ -#include <cstdio> -#include <iostream> +#include <cstdio> +#include <ostream> #include <bits/functexcept.h> #include <ext/algorithm> // For copy_n and lexicographical_compare_3way @@ -55,20 +55,19 @@ namespace __gnu_cxx { -using std::size_t; -using std::printf; -using std::basic_ostream; -using std::__throw_length_error; -using std::__alloc; -using std::_Destroy; -using std::uninitialized_fill_n; + using std::size_t; + using std::printf; + using std::basic_ostream; + using std::__throw_length_error; + using std::_Destroy; + using std::uninitialized_fill_n; // Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf // if necessary. Assumes _M_path_end[leaf_index] and leaf_pos are correct. // Results in a valid buf_ptr if the iterator can be legitimately // dereferenced. template <class _CharT, class _Alloc> -void _Rope_iterator_base<_CharT,_Alloc>::_S_setbuf( +void _Rope_iterator_base<_CharT,_Alloc>::_S_setbuf( _Rope_iterator_base<_CharT,_Alloc>& __x) { const _RopeRep* __leaf = __x._M_path_end[__x._M_leaf_index]; @@ -76,14 +75,14 @@ void _Rope_iterator_base<_CharT,_Alloc>::_S_setbuf( size_t __pos = __x._M_current_pos; switch(__leaf->_M_tag) { - case _RopeRep::_S_leaf: - __x._M_buf_start = + case _Rope_constants::_S_leaf: + __x._M_buf_start = ((_Rope_RopeLeaf<_CharT,_Alloc>*)__leaf)->_M_data; __x._M_buf_ptr = __x._M_buf_start + (__pos - __leaf_pos); __x._M_buf_end = __x._M_buf_start + __leaf->_M_size; break; - case _RopeRep::_S_function: - case _RopeRep::_S_substringfn: + case _Rope_constants::_S_function: + case _Rope_constants::_S_substringfn: { size_t __len = _S_iterator_buf_len; size_t __buf_start_pos = __leaf_pos; @@ -111,13 +110,13 @@ void _Rope_iterator_base<_CharT,_Alloc>::_S_setbuf( } } -// Set path and buffer inside a rope iterator. We assume that +// Set path and buffer inside a rope iterator. We assume that // pos and root are already set. template <class _CharT, class _Alloc> void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache (_Rope_iterator_base<_CharT,_Alloc>& __x) { - const _RopeRep* __path[_RopeRep::_S_max_rope_depth+1]; + const _RopeRep* __path[_Rope_constants::_S_max_rope_depth + 1]; const _RopeRep* __curr_rope; int __curr_depth = -1; /* index into path */ size_t __curr_start_pos = 0; @@ -143,18 +142,18 @@ void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache ++__curr_depth; __path[__curr_depth] = __curr_rope; switch(__curr_rope->_M_tag) { - case _RopeRep::_S_leaf: - case _RopeRep::_S_function: - case _RopeRep::_S_substringfn: + case _Rope_constants::_S_leaf: + case _Rope_constants::_S_function: + case _Rope_constants::_S_substringfn: __x._M_leaf_pos = __curr_start_pos; goto done; - case _RopeRep::_S_concat: + case _Rope_constants::_S_concat: { _Rope_RopeConcatenation<_CharT,_Alloc>* __c = (_Rope_RopeConcatenation<_CharT,_Alloc>*)__curr_rope; _RopeRep* __left = __c->_M_left; size_t __left_len = __left->_M_size; - + __dirns <<= 1; if (__pos >= __curr_start_pos + __left_len) { __dirns |= 1; @@ -203,7 +202,7 @@ void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache_for_incr } // node_start_pos is starting position of last_node. while (--__current_index >= 0) { - if (!(__dirns & 1) /* Path turned left */) + if (!(__dirns & 1) /* Path turned left */) break; __current_node = __x._M_path_end[__current_index]; __c = (_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node; @@ -226,7 +225,7 @@ void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache_for_incr __current_node = __c->_M_right; __x._M_path_end[++__current_index] = __current_node; __dirns |= 1; - while (_RopeRep::_S_concat == __current_node->_M_tag) { + while (_Rope_constants::_S_concat == __current_node->_M_tag) { ++__current_index; if (_S_path_cache_len == __current_index) { int __i; @@ -278,33 +277,33 @@ void _Rope_iterator_base<_CharT,_Alloc>::_M_decr(size_t __n) { template <class _CharT, class _Alloc> void _Rope_iterator<_CharT,_Alloc>::_M_check() { - if (_M_root_rope->_M_tree_ptr != _M_root) { + if (_M_root_rope->_M_tree_ptr != this->_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; + _RopeRep::_S_unref(this->_M_root); + this->_M_root = _M_root_rope->_M_tree_ptr; + _RopeRep::_S_ref(this->_M_root); + this->_M_buf_ptr = 0; } } template <class _CharT, class _Alloc> -inline +inline _Rope_const_iterator<_CharT, _Alloc>::_Rope_const_iterator( const _Rope_iterator<_CharT,_Alloc>& __x) -: _Rope_iterator_base<_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), +: _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos), _M_root_rope(&__r) { - _RopeRep::_S_ref(_M_root); + _RopeRep::_S_ref(this->_M_root); } template <class _CharT, class _Alloc> -inline size_t +inline size_t rope<_CharT,_Alloc>::_S_char_ptr_len(const _CharT* __s) { const _CharT* __p = __s; @@ -321,9 +320,9 @@ inline void _Rope_RopeRep<_CharT,_Alloc>::_M_free_c_string() { _CharT* __cstr = _M_c_string; if (0 != __cstr) { - size_t __size = _M_size + 1; + size_t __size = this->_M_size + 1; _Destroy(__cstr, __cstr + __size); - _Data_deallocate(__cstr, __size); + this->_Data_deallocate(__cstr, __size); } } @@ -352,7 +351,7 @@ template <class _CharT, class _Alloc> void _Rope_RopeRep<_CharT,_Alloc>::_M_free_tree() { switch(_M_tag) { - case _S_leaf: + case _Rope_constants::_S_leaf: { _Rope_RopeLeaf<_CharT,_Alloc>* __l = (_Rope_RopeLeaf<_CharT,_Alloc>*)this; @@ -360,7 +359,7 @@ void _Rope_RopeRep<_CharT,_Alloc>::_M_free_tree() _L_deallocate(__l, 1); break; } - case _S_concat: + case _Rope_constants::_S_concat: { _Rope_RopeConcatenation<_CharT,_Alloc>* __c = (_Rope_RopeConcatenation<_CharT,_Alloc>*)this; @@ -369,7 +368,7 @@ void _Rope_RopeRep<_CharT,_Alloc>::_M_free_tree() _C_deallocate(__c, 1); break; } - case _S_function: + case _Rope_constants::_S_function: { _Rope_RopeFunction<_CharT,_Alloc>* __f = (_Rope_RopeFunction<_CharT,_Alloc>*)this; @@ -377,7 +376,7 @@ void _Rope_RopeRep<_CharT,_Alloc>::_M_free_tree() _F_deallocate(__f, 1); break; } - case _S_substringfn: + case _Rope_constants::_S_substringfn: { _Rope_RopeSubstring<_CharT,_Alloc>* __ss = (_Rope_RopeSubstring<_CharT,_Alloc>*)this; @@ -407,9 +406,9 @@ rope<_CharT,_Alloc>::_S_leaf_concat_char_iter { size_t __old_len = __r->_M_size; _CharT* __new_data = (_CharT*) - _Data_allocate(_S_rounded_up_size(__old_len + __len)); + _Data_allocate(_S_rounded_up_size(__old_len + __len)); _RopeLeaf* __result; - + uninitialized_copy_n(__r->_M_data, __old_len, __new_data); uninitialized_copy_n(__iter, __len, __new_data + __old_len); _S_cond_store_eos(__new_data[__old_len + __len]); @@ -463,22 +462,22 @@ template <class _CharT, class _Alloc> typename rope<_CharT,_Alloc>::_RopeRep* rope<_CharT,_Alloc>::_S_tree_concat (_RopeRep* __left, _RopeRep* __right) { - _RopeConcatenation* __result = _S_new_RopeConcatenation(__left, __right, + _RopeConcatenation* __result = _S_new_RopeConcatenation(__left, __right, __left->get_allocator()); size_t __depth = __result->_M_depth; - + if (__depth > 20 && (__result->_M_size < 1000 || - __depth > _RopeRep::_S_max_rope_depth)) + __depth > _Rope_constants::_S_max_rope_depth)) { _RopeRep* __balanced; - - try + + try { __balanced = _S_balance(__result); __result->_M_unref_nonnil(); } catch(...) - { + { _C_deallocate(__result,1); __throw_exception_again; } @@ -487,8 +486,8 @@ rope<_CharT,_Alloc>::_S_tree_concat (_RopeRep* __left, _RopeRep* __right) // still owns its children. Thus unref is // inappropriate. return __balanced; - } - else + } + else return __result; } @@ -505,18 +504,18 @@ rope<_CharT,_Alloc>::_RopeRep* rope<_CharT,_Alloc>::_S_concat_char_iter if (0 == __r) return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator()); - if (_RopeRep::_S_leaf == __r->_M_tag && + if (_Rope_constants::_S_leaf == __r->_M_tag && __r->_M_size + __slen <= _S_copy_max) { __result = _S_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); return __result; } - if (_RopeRep::_S_concat == __r->_M_tag - && _RopeRep::_S_leaf == ((_RopeConcatenation*)__r)->_M_right->_M_tag) { - _RopeLeaf* __right = + if (_Rope_constants::_S_concat == __r->_M_tag + && _Rope_constants::_S_leaf == ((_RopeConcatenation*)__r)->_M_right->_M_tag) { + _RopeLeaf* __right = (_RopeLeaf* )(((_RopeConcatenation* )__r)->_M_right); if (__right->_M_size + __slen <= _S_copy_max) { _RopeRep* __left = ((_RopeConcatenation*)__r)->_M_left; - _RopeRep* __nright = + _RopeRep* __nright = _S_leaf_concat_char_iter((_RopeLeaf*)__right, __s, __slen); __left->_M_ref_nonnil(); try { @@ -524,7 +523,7 @@ rope<_CharT,_Alloc>::_RopeRep* rope<_CharT,_Alloc>::_S_concat_char_iter } catch(...) { - _S_unref(__left); + _S_unref(__left); _S_unref(__nright); __throw_exception_again; } @@ -539,7 +538,7 @@ rope<_CharT,_Alloc>::_RopeRep* rope<_CharT,_Alloc>::_S_concat_char_iter } catch(...) { - _S_unref(__r); + _S_unref(__r); _S_unref(__nright); __throw_exception_again; } @@ -548,7 +547,7 @@ rope<_CharT,_Alloc>::_RopeRep* rope<_CharT,_Alloc>::_S_concat_char_iter #ifndef __GC template <class _CharT, class _Alloc> -typename rope<_CharT,_Alloc>::_RopeRep* +typename rope<_CharT,_Alloc>::_RopeRep* rope<_CharT,_Alloc>::_S_destr_concat_char_iter( _RopeRep* __r, const _CharT* __s, size_t __slen) { @@ -563,20 +562,20 @@ rope<_CharT,_Alloc>::_S_destr_concat_char_iter( __r->_M_ref_count = 2; // One more than before return __r; } - if (__orig_size + __slen <= _S_copy_max && - _RopeRep::_S_leaf == __r->_M_tag) { + if (__orig_size + __slen <= _S_copy_max && + _Rope_constants::_S_leaf == __r->_M_tag) { __result = _S_destr_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); return __result; } - if (_RopeRep::_S_concat == __r->_M_tag) { + if (_Rope_constants::_S_concat == __r->_M_tag) { _RopeLeaf* __right = (_RopeLeaf*)(((_RopeConcatenation*)__r)->_M_right); - if (_RopeRep::_S_leaf == __right->_M_tag + if (_Rope_constants::_S_leaf == __right->_M_tag && __right->_M_size + __slen <= _S_copy_max) { - _RopeRep* __new_right = + _RopeRep* __new_right = _S_destr_leaf_concat_char_iter(__right, __s, __slen); - if (__right == __new_right) + if (__right == __new_right) __new_right->_M_ref_count = 1; - else + else __right->_M_unref_nonnil(); __r->_M_ref_count = 2; // One more than before. ((_RopeConcatenation*)__r)->_M_right = __new_right; @@ -596,7 +595,7 @@ rope<_CharT,_Alloc>::_S_destr_concat_char_iter( } catch(...) { - _S_unref(__r); + _S_unref(__r); _S_unref(__right); __throw_exception_again; } @@ -616,18 +615,18 @@ rope<_CharT,_Alloc>::_S_concat(_RopeRep* __left, _RopeRep* __right) __left->_M_ref_nonnil(); return __left; } - if (_RopeRep::_S_leaf == __right->_M_tag) { - if (_RopeRep::_S_leaf == __left->_M_tag) { + if (_Rope_constants::_S_leaf == __right->_M_tag) { + if (_Rope_constants::_S_leaf == __left->_M_tag) { if (__right->_M_size + __left->_M_size <= _S_copy_max) { return _S_leaf_concat_char_iter((_RopeLeaf*)__left, ((_RopeLeaf*)__right)->_M_data, __right->_M_size); } - } else if (_RopeRep::_S_concat == __left->_M_tag - && _RopeRep::_S_leaf == + } else if (_Rope_constants::_S_concat == __left->_M_tag + && _Rope_constants::_S_leaf == ((_RopeConcatenation*)__left)->_M_right->_M_tag) { _RopeLeaf* __leftright = - (_RopeLeaf*)(((_RopeConcatenation*)__left)->_M_right); + (_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, @@ -639,7 +638,7 @@ rope<_CharT,_Alloc>::_S_concat(_RopeRep* __left, _RopeRep* __right) } catch(...) { - _S_unref(__leftleft); + _S_unref(__leftleft); _S_unref(__rest); __throw_exception_again; } @@ -653,7 +652,7 @@ rope<_CharT,_Alloc>::_S_concat(_RopeRep* __left, _RopeRep* __right) } catch(...) { - _S_unref(__left); + _S_unref(__left); _S_unref(__right); __throw_exception_again; } @@ -661,14 +660,14 @@ rope<_CharT,_Alloc>::_S_concat(_RopeRep* __left, _RopeRep* __right) template <class _CharT, class _Alloc> typename rope<_CharT,_Alloc>::_RopeRep* -rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base, +rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base, size_t __start, size_t __endp1) { if (0 == __base) return 0; size_t __len = __base->_M_size; size_t __adj_endp1; const size_t __lazy_threshold = 128; - + if (__endp1 >= __len) { if (0 == __start) { __base->_M_ref_nonnil(); @@ -680,7 +679,7 @@ rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base, __adj_endp1 = __endp1; } switch(__base->_M_tag) { - case _RopeRep::_S_concat: + case _Rope_constants::_S_concat: { _RopeConcatenation* __c = (_RopeConcatenation*)__base; _RopeRep* __left = __c->_M_left; @@ -701,7 +700,7 @@ rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base, __result = _S_concat(__left_result, __right_result); return __result; } - case _RopeRep::_S_leaf: + case _Rope_constants::_S_leaf: { _RopeLeaf* __l = (_RopeLeaf*)__base; _RopeLeaf* __result; @@ -722,7 +721,7 @@ rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base, # endif return __result; } - case _RopeRep::_S_substringfn: + case _Rope_constants::_S_substringfn: // Avoid introducing multiple layers of substring nodes. { _RopeSubstring* __old = (_RopeSubstring*)__base; @@ -739,7 +738,7 @@ rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base, } // *** else fall through: *** } - case _RopeRep::_S_function: + case _Rope_constants::_S_function: { _RopeFunction* __f = (_RopeFunction*)__base; _CharT* __section; @@ -749,7 +748,7 @@ rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base, if (__result_len > __lazy_threshold) goto lazy; __section = (_CharT*) - _Data_allocate(_S_rounded_up_size(__result_len)); + _Data_allocate(_S_rounded_up_size(__result_len)); try { (*(__f->_M_fn))(__start, __result_len, __section); } @@ -788,14 +787,14 @@ class _Rope_flatten_char_consumer : public _Rope_char_consumer<_CharT> { return true; } }; - + template<class _CharT> class _Rope_find_char_char_consumer : public _Rope_char_consumer<_CharT> { private: _CharT _M_pattern; public: size_t _M_count; // Number of nonmatching characters - _Rope_find_char_char_consumer(_CharT __p) + _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) { @@ -808,7 +807,7 @@ class _Rope_find_char_char_consumer : public _Rope_char_consumer<_CharT> { _M_count += __n; return true; } }; - + template<class _CharT, class _Traits> // Here _CharT is both the stream and rope character type. class _Rope_insert_char_consumer : public _Rope_char_consumer<_CharT> { @@ -816,14 +815,14 @@ class _Rope_insert_char_consumer : public _Rope_char_consumer<_CharT> { typedef basic_ostream<_CharT,_Traits> _Insert_ostream; _Insert_ostream& _M_o; public: - _Rope_insert_char_consumer(_Insert_ostream& __writer) + _Rope_insert_char_consumer(_Insert_ostream& __writer) : _M_o(__writer) {}; ~_Rope_insert_char_consumer() { }; // Caller is presumed to own the ostream bool operator() (const _CharT* __leaf, size_t __n); // Returns true to continue traversal. }; - + template<class _CharT, class _Traits> bool _Rope_insert_char_consumer<_CharT, _Traits>::operator() (const _CharT* __leaf, size_t __n) @@ -842,7 +841,7 @@ bool rope<_CharT, _Alloc>::_S_apply_to_pieces( { if (0 == __r) return true; switch(__r->_M_tag) { - case _RopeRep::_S_concat: + case _Rope_constants::_S_concat: { _RopeConcatenation* __conc = (_RopeConcatenation*)__r; _RopeRep* __left = __conc->_M_left; @@ -863,27 +862,27 @@ bool rope<_CharT, _Alloc>::_S_apply_to_pieces( } } return true; - case _RopeRep::_S_leaf: + case _Rope_constants::_S_leaf: { _RopeLeaf* __l = (_RopeLeaf*)__r; return __c(__l->_M_data + __begin, __end - __begin); } - case _RopeRep::_S_function: - case _RopeRep::_S_substringfn: + case _Rope_constants::_S_function: + case _Rope_constants::_S_substringfn: { _RopeFunction* __f = (_RopeFunction*)__r; size_t __len = __end - __begin; bool __result; _CharT* __buffer = - (_CharT*)__alloc::allocate(__len * sizeof(_CharT)); + (_CharT*)_Alloc().allocate(__len * sizeof(_CharT)); try { (*(__f->_M_fn))(__begin, __len, __buffer); __result = __c(__buffer, __len); - __alloc::deallocate(__buffer, __len * sizeof(_CharT)); + _Alloc().deallocate(__buffer, __len * sizeof(_CharT)); } catch(...) { - __alloc::deallocate(__buffer, __len * sizeof(_CharT)); + _Alloc().deallocate(__buffer, __len * sizeof(_CharT)); __throw_exception_again; } return __result; @@ -901,7 +900,7 @@ bool rope<_CharT, _Alloc>::_S_apply_to_pieces( 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; } @@ -917,7 +916,7 @@ basic_ostream<_CharT, _Traits>& operator<< (basic_ostream<_CharT, _Traits>& __o, size_t __rope_len = __r.size(); _Rope_insert_char_consumer<_CharT, _Traits> __c(__o); bool __is_simple = _Rope_is_simple((_CharT*)0); - + if (__rope_len < __w) { __pad_len = __w - __rope_len; } else { @@ -937,7 +936,7 @@ basic_ostream<_CharT, _Traits>& operator<< (basic_ostream<_CharT, _Traits>& __o, } catch(...) { - if (!__is_simple) + if (!__is_simple) __o.width(__w); __throw_exception_again; } @@ -960,7 +959,7 @@ size_t rope<_CharT,_Alloc>::find(_CharT __pattern, size_t __start) const { _Rope_find_char_char_consumer<_CharT> __c(__pattern); - _S_apply_to_pieces(__c, _M_tree_ptr, __start, size()); + _S_apply_to_pieces(__c, this->_M_tree_ptr, __start, size()); size_type __result_pos = __start + __c._M_count; # ifndef __STL_OLD_ROPE_SEMANTICS if (__result_pos == size()) __result_pos = npos; @@ -974,7 +973,7 @@ rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r, _CharT* __buffer) { if (0 == __r) return __buffer; switch(__r->_M_tag) { - case _RopeRep::_S_concat: + case _Rope_constants::_S_concat: { _RopeConcatenation* __c = (_RopeConcatenation*)__r; _RopeRep* __left = __c->_M_left; @@ -982,13 +981,13 @@ rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r, _CharT* __buffer) _CharT* __rest = _S_flatten(__left, __buffer); return _S_flatten(__right, __rest); } - case _RopeRep::_S_leaf: + case _Rope_constants::_S_leaf: { _RopeLeaf* __l = (_RopeLeaf*)__r; return copy_n(__l->_M_data, __l->_M_size, __buffer).second; } - case _RopeRep::_S_function: - case _RopeRep::_S_substringfn: + case _Rope_constants::_S_function: + case _Rope_constants::_S_substringfn: // We don't yet do anything with substring nodes. // This needs to be fixed before ropefiles will work well. { @@ -1011,7 +1010,7 @@ rope<_CharT,_Alloc>::_S_dump(_RopeRep* __r, int __indent) if (0 == __r) { printf("NULL\n"); return; } - if (_RopeRep::_S_concat == __r->_M_tag) { + if (_Rope_constants::_S_concat == __r->_M_tag) { _RopeConcatenation* __c = (_RopeConcatenation*)__r; _RopeRep* __left = __c->_M_left; _RopeRep* __right = __c->_M_right; @@ -1032,13 +1031,13 @@ rope<_CharT,_Alloc>::_S_dump(_RopeRep* __r, int __indent) char* __kind; switch (__r->_M_tag) { - case _RopeRep::_S_leaf: + case _Rope_constants::_S_leaf: __kind = "Leaf"; break; - case _RopeRep::_S_function: + case _Rope_constants::_S_function: __kind = "Function"; break; - case _RopeRep::_S_substringfn: + case _Rope_constants::_S_substringfn: __kind = "Function representing substring"; break; default: @@ -1058,8 +1057,8 @@ rope<_CharT,_Alloc>::_S_dump(_RopeRep* __r, int __indent) 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", + __buffer[__prefix->_M_size] = _S_eos((_CharT*)0); + printf("%s%s\n", (char*)__buffer, __too_big? "...\n" : "\n"); } else { printf("\n"); @@ -1069,8 +1068,7 @@ rope<_CharT,_Alloc>::_S_dump(_RopeRep* __r, int __indent) template <class _CharT, class _Alloc> const unsigned long -rope<_CharT,_Alloc>::_S_min_len[ - _Rope_RopeRep<_CharT,_Alloc>::_S_max_rope_depth + 1] = { +rope<_CharT,_Alloc>::_S_min_len[_Rope_constants::_S_max_rope_depth + 1] = { /* 0 */1, /* 1 */2, /* 2 */3, /* 3 */5, /* 4 */8, /* 5 */13, /* 6 */21, /* 7 */34, /* 8 */55, /* 9 */89, /* 10 */144, /* 11 */233, /* 12 */377, /* 13 */610, /* 14 */987, /* 15 */1597, /* 16 */2584, /* 17 */4181, @@ -1088,7 +1086,7 @@ template <class _CharT, class _Alloc> typename rope<_CharT,_Alloc>::_RopeRep* rope<_CharT,_Alloc>::_S_balance(_RopeRep* __r) { - _RopeRep* __forest[_RopeRep::_S_max_rope_depth + 1]; + _RopeRep* __forest[_Rope_constants::_S_max_rope_depth + 1]; _RopeRep* __result = 0; int __i; // Invariant: @@ -1097,11 +1095,11 @@ rope<_CharT,_Alloc>::_S_balance(_RopeRep* __r) // __forest[__i]._M_depth = __i // References from forest are included in refcount. - for (__i = 0; __i <= _RopeRep::_S_max_rope_depth; ++__i) + for (__i = 0; __i <= _Rope_constants::_S_max_rope_depth; ++__i) __forest[__i] = 0; try { _S_add_to_forest(__r, __forest); - for (__i = 0; __i <= _RopeRep::_S_max_rope_depth; ++__i) + for (__i = 0; __i <= _Rope_constants::_S_max_rope_depth; ++__i) if (0 != __forest[__i]) { # ifndef __GC _Self_destruct_ptr __old(__result); @@ -1115,13 +1113,13 @@ rope<_CharT,_Alloc>::_S_balance(_RopeRep* __r) } catch(...) { - for(__i = 0; __i <= _RopeRep::_S_max_rope_depth; __i++) + for(__i = 0; __i <= _Rope_constants::_S_max_rope_depth; __i++) _S_unref(__forest[__i]); __throw_exception_again; } - if (__result->_M_depth > _RopeRep::_S_max_rope_depth) - __throw_length_error("rope too long"); + if (__result->_M_depth > _Rope_constants::_S_max_rope_depth) + __throw_length_error(__N("rope::_S_balance")); return(__result); } @@ -1148,9 +1146,9 @@ template <class _CharT, class _Alloc> void rope<_CharT,_Alloc>::_S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest) { - _RopeRep* __insertee; // included in refcount - _RopeRep* __too_tiny = 0; // included in refcount - int __i; // forest[0..__i-1] is empty + _RopeRep* __insertee; // included in refcount + _RopeRep* __too_tiny = 0; // included in refcount + int __i; // forest[0..__i-1] is empty size_t __s = __r->_M_size; for (__i = 0; __s >= _S_min_len[__i+1]/* not this bucket */; ++__i) { @@ -1180,7 +1178,7 @@ rope<_CharT,_Alloc>::_S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest) __forest[__i]->_M_unref_nonnil(); __forest[__i] = 0; } - if (__i == _RopeRep::_S_max_rope_depth || + if (__i == _Rope_constants::_S_max_rope_depth || __insertee->_M_size < _S_min_len[__i+1]) { __forest[__i] = __insertee; // refcount is OK since __insertee is now dead. @@ -1195,10 +1193,10 @@ rope<_CharT,_Alloc>::_S_fetch(_RopeRep* __r, size_type __i) { __GC_CONST _CharT* __cstr = __r->_M_c_string; - if (0 != __cstr) return __cstr[__i]; + if (0 != __cstr) return __cstr[__i]; for(;;) { switch(__r->_M_tag) { - case _RopeRep::_S_concat: + case _Rope_constants::_S_concat: { _RopeConcatenation* __c = (_RopeConcatenation*)__r; _RopeRep* __left = __c->_M_left; @@ -1212,13 +1210,13 @@ rope<_CharT,_Alloc>::_S_fetch(_RopeRep* __r, size_type __i) } } break; - case _RopeRep::_S_leaf: + case _Rope_constants::_S_leaf: { _RopeLeaf* __l = (_RopeLeaf*)__r; return __l->_M_data[__i]; } - case _RopeRep::_S_function: - case _RopeRep::_S_substringfn: + case _Rope_constants::_S_function: + case _Rope_constants::_S_substringfn: { _RopeFunction* __f = (_RopeFunction*)__r; _CharT __result; @@ -1237,13 +1235,13 @@ template <class _CharT, class _Alloc> _CharT* rope<_CharT,_Alloc>::_S_fetch_ptr(_RopeRep* __r, size_type __i) { - _RopeRep* __clrstack[_RopeRep::_S_max_rope_depth]; + _RopeRep* __clrstack[_Rope_constants::_S_max_rope_depth]; size_t __csptr = 0; for(;;) { if (__r->_M_ref_count > 1) return 0; switch(__r->_M_tag) { - case _RopeRep::_S_concat: + case _Rope_constants::_S_concat: { _RopeConcatenation* __c = (_RopeConcatenation*)__r; _RopeRep* __left = __c->_M_left; @@ -1258,7 +1256,7 @@ rope<_CharT,_Alloc>::_S_fetch_ptr(_RopeRep* __r, size_type __i) } } break; - case _RopeRep::_S_leaf: + case _Rope_constants::_S_leaf: { _RopeLeaf* __l = (_RopeLeaf*)__r; if (__l->_M_c_string != __l->_M_data && __l->_M_c_string != 0) @@ -1271,8 +1269,8 @@ rope<_CharT,_Alloc>::_S_fetch_ptr(_RopeRep* __r, size_type __i) } return __l->_M_data + __i; } - case _RopeRep::_S_function: - case _RopeRep::_S_substringfn: + case _Rope_constants::_S_function: + case _Rope_constants::_S_substringfn: return 0; } } @@ -1285,7 +1283,7 @@ rope<_CharT,_Alloc>::_S_fetch_ptr(_RopeRep* __r, size_type __i) // flat strings. template <class _CharT, class _Alloc> int -rope<_CharT,_Alloc>::_S_compare (const _RopeRep* __left, +rope<_CharT,_Alloc>::_S_compare (const _RopeRep* __left, const _RopeRep* __right) { size_t __left_len; @@ -1295,7 +1293,7 @@ rope<_CharT,_Alloc>::_S_compare (const _RopeRep* __left, if (0 == __left) return -1; __left_len = __left->_M_size; __right_len = __right->_M_size; - if (_RopeRep::_S_leaf == __left->_M_tag) { + if (_Rope_constants::_S_leaf == __left->_M_tag) { _RopeLeaf* __l = (_RopeLeaf*) __left; if (_RopeRep::_S_leaf == __right->_M_tag) { _RopeLeaf* __r = (_RopeLeaf*) __right; @@ -1312,7 +1310,7 @@ rope<_CharT,_Alloc>::_S_compare (const _RopeRep* __left, } else { const_iterator __lstart(__left, 0); const_iterator __lend(__left, __left_len); - if (_RopeRep::_S_leaf == __right->_M_tag) { + if (_Rope_constants::_S_leaf == __right->_M_tag) { _RopeLeaf* __r = (_RopeLeaf*) __right; return lexicographical_compare_3way( __lstart, __lend, @@ -1387,13 +1385,13 @@ rope<_CharT, _Alloc>::rope(size_t __n, _CharT __c, if (0 == __n) return; - + __exponent = __n / __exponentiate_threshold; __rest = __n % __exponentiate_threshold; if (0 == __rest) { __remainder = 0; } else { - __rest_buffer = _Data_allocate(_S_rounded_up_size(__rest)); + __rest_buffer = this->_Data_allocate(_S_rounded_up_size(__rest)); uninitialized_fill_n(__rest_buffer, __rest, __c); _S_cond_store_eos(__rest_buffer[__rest]); try { @@ -1408,7 +1406,7 @@ rope<_CharT, _Alloc>::rope(size_t __n, _CharT __c, __remainder_rope._M_tree_ptr = __remainder; if (__exponent != 0) { _CharT* __base_buffer = - _Data_allocate(_S_rounded_up_size(__exponentiate_threshold)); + this->_Data_allocate(_S_rounded_up_size(__exponentiate_threshold)); _RopeLeaf* __base_leaf; rope __base_rope; uninitialized_fill_n(__base_buffer, __exponentiate_threshold, __c); @@ -1419,12 +1417,12 @@ rope<_CharT, _Alloc>::rope(size_t __n, _CharT __c, } catch(...) { - _RopeRep::__STL_FREE_STRING(__base_buffer, + _RopeRep::__STL_FREE_STRING(__base_buffer, __exponentiate_threshold, __a); __throw_exception_again; } __base_rope._M_tree_ptr = __base_leaf; - if (1 == __exponent) { + if (1 == __exponent) { __result = __base_rope; } else { __result = power(__base_rope, __exponent, @@ -1436,8 +1434,8 @@ rope<_CharT, _Alloc>::rope(size_t __n, _CharT __c, } else { __result = __remainder_rope; } - _M_tree_ptr = __result._M_tree_ptr; - _M_tree_ptr->_M_ref_nonnil(); + this->_M_tree_ptr = __result._M_tree_ptr; + this->_M_tree_ptr->_M_ref_nonnil(); } template<class _CharT, class _Alloc> @@ -1445,49 +1443,42 @@ template<class _CharT, class _Alloc> template<class _CharT, class _Alloc> const _CharT* rope<_CharT,_Alloc>::c_str() const { - if (0 == _M_tree_ptr) { + if (0 == this->_M_tree_ptr) { _S_empty_c_str[0] = _S_eos((_CharT*)0); // Possibly redundant, // but probably fast. return _S_empty_c_str; } - __GC_CONST _CharT* __old_c_string = _M_tree_ptr->_M_c_string; - if (0 != __old_c_string) return(__old_c_string); - size_t __s = size(); - _CharT* __result = _Data_allocate(__s + 1); - _S_flatten(_M_tree_ptr, __result); - __result[__s] = _S_eos((_CharT*)0); -# ifdef __GC - _M_tree_ptr->_M_c_string = __result; -# else - if ((__old_c_string = (__GC_CONST _CharT*) - std::_Atomic_swap((unsigned long *)(&(_M_tree_ptr->_M_c_string)), - (unsigned long)__result)) != 0) { - // It must have been added in the interim. Hence it had to have been - // separately allocated. Deallocate the old copy, since we just - // replaced it. - _Destroy(__old_c_string, __old_c_string + __s + 1); - _Data_deallocate(__old_c_string, __s + 1); + __gthread_mutex_lock (&this->_M_tree_ptr->_M_c_string_lock); + __GC_CONST _CharT* __result = this->_M_tree_ptr->_M_c_string; + if (0 == __result) + { + size_t __s = size(); + __result = this->_Data_allocate(__s + 1); + _S_flatten(this->_M_tree_ptr, __result); + __result[__s] = _S_eos((_CharT*)0); + this->_M_tree_ptr->_M_c_string = __result; } -# endif + __gthread_mutex_unlock (&this->_M_tree_ptr->_M_c_string_lock); return(__result); } template<class _CharT, class _Alloc> const _CharT* rope<_CharT,_Alloc>::replace_with_c_str() { - if (0 == _M_tree_ptr) { + if (0 == this->_M_tree_ptr) { _S_empty_c_str[0] = _S_eos((_CharT*)0); return _S_empty_c_str; } - __GC_CONST _CharT* __old_c_string = _M_tree_ptr->_M_c_string; - if (_RopeRep::_S_leaf == _M_tree_ptr->_M_tag && 0 != __old_c_string) { + __GC_CONST _CharT* __old_c_string = this->_M_tree_ptr->_M_c_string; + if (_Rope_constants::_S_leaf == this->_M_tree_ptr->_M_tag + && 0 != __old_c_string) { return(__old_c_string); } size_t __s = size(); - _CharT* __result = _Data_allocate(_S_rounded_up_size(__s)); - _S_flatten(_M_tree_ptr, __result); + _CharT* __result = this->_Data_allocate(_S_rounded_up_size(__s)); + _S_flatten(this->_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()); + this->_M_tree_ptr->_M_unref_nonnil(); + this->_M_tree_ptr = _S_new_RopeLeaf(__result, __s, this->get_allocator()); return(__result); } @@ -1501,14 +1492,14 @@ _Rope_rotate(_Rope_iterator __first, { typedef typename _Rope_iterator::value_type _CharT; typedef typename _Rope_iterator::_allocator_type _Alloc; - + rope<_CharT,_Alloc>& __r(__first.container()); rope<_CharT,_Alloc> __prefix = __r.substr(0, __first.index()); - rope<_CharT,_Alloc> __suffix = + rope<_CharT,_Alloc> __suffix = __r.substr(__last.index(), __r.size() - __last.index()); - rope<_CharT,_Alloc> __part1 = + rope<_CharT,_Alloc> __part1 = __r.substr(__middle.index(), __last.index() - __middle.index()); - rope<_CharT,_Alloc> __part2 = + rope<_CharT,_Alloc> __part2 = __r.substr(__first.index(), __middle.index() - __first.index()); __r = __prefix; __r += __part1; diff --git a/contrib/libstdc++/include/ext/slist b/contrib/libstdc++/include/ext/slist index 35e089af5306..4b5852030184 100644 --- a/contrib/libstdc++/include/ext/slist +++ b/contrib/libstdc++/include/ext/slist @@ -47,20 +47,19 @@ * include this header if you are using GCC 3 or later. */ -#ifndef __SGI_STL_INTERNAL_SLIST_H -#define __SGI_STL_INTERNAL_SLIST_H +#ifndef _SLIST +#define _SLIST 1 #include <bits/stl_algobase.h> -#include <bits/stl_alloc.h> +#include <bits/allocator.h> #include <bits/stl_construct.h> #include <bits/stl_uninitialized.h> #include <bits/concept_check.h> namespace __gnu_cxx -{ +{ using std::size_t; using std::ptrdiff_t; -using std::_Alloc_traits; using std::_Construct; using std::_Destroy; using std::allocator; @@ -79,7 +78,7 @@ __slist_make_link(_Slist_node_base* __prev_node, return __new_node; } -inline _Slist_node_base* +inline _Slist_node_base* __slist_previous(_Slist_node_base* __head, const _Slist_node_base* __node) { @@ -88,7 +87,7 @@ __slist_previous(_Slist_node_base* __head, return __head; } -inline const _Slist_node_base* +inline const _Slist_node_base* __slist_previous(const _Slist_node_base* __head, const _Slist_node_base* __node) { @@ -201,73 +200,27 @@ struct _Slist_iterator : public _Slist_iterator_base } }; - -// Base class that encapsulates details of allocators. Three cases: -// an ordinary standard-conforming allocator, a standard-conforming -// allocator with no non-static data, and an SGI-style allocator. -// This complexity is necessary only because we're worrying about backward -// compatibility and because we want to avoid wasting storage on an -// allocator instance if it isn't necessary. - -// Base for general standard-conforming allocators. -template <class _Tp, class _Allocator, bool _IsStatic> -class _Slist_alloc_base { -public: - typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type - allocator_type; - allocator_type get_allocator() const { return _M_node_allocator; } - - _Slist_alloc_base(const allocator_type& __a) : _M_node_allocator(__a) {} - -protected: - _Slist_node<_Tp>* _M_get_node() - { return _M_node_allocator.allocate(1); } - void _M_put_node(_Slist_node<_Tp>* __p) - { _M_node_allocator.deallocate(__p, 1); } - -protected: - typename _Alloc_traits<_Slist_node<_Tp>,_Allocator>::allocator_type - _M_node_allocator; - _Slist_node_base _M_head; -}; - -// Specialization for instanceless allocators. -template <class _Tp, class _Allocator> -class _Slist_alloc_base<_Tp,_Allocator, true> { -public: - typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type - allocator_type; - allocator_type get_allocator() const { return allocator_type(); } - - _Slist_alloc_base(const allocator_type&) {} - -protected: - typedef typename _Alloc_traits<_Slist_node<_Tp>, _Allocator>::_Alloc_type - _Alloc_type; - _Slist_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } - void _M_put_node(_Slist_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } - -protected: - _Slist_node_base _M_head; -}; - - template <class _Tp, class _Alloc> struct _Slist_base - : public _Slist_alloc_base<_Tp, _Alloc, - _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + : public _Alloc::template rebind<_Slist_node<_Tp> >::other { - typedef _Slist_alloc_base<_Tp, _Alloc, - _Alloc_traits<_Tp, _Alloc>::_S_instanceless> - _Base; - typedef typename _Base::allocator_type allocator_type; + typedef typename _Alloc::template rebind<_Slist_node<_Tp> >::other _Node_alloc; + typedef _Alloc allocator_type; + allocator_type get_allocator() const { + return *static_cast<const _Node_alloc*>(this); + } _Slist_base(const allocator_type& __a) - : _Base(__a) { this->_M_head._M_next = 0; } + : _Node_alloc(__a) { this->_M_head._M_next = 0; } ~_Slist_base() { _M_erase_after(&this->_M_head, 0); } protected: + _Slist_node_base _M_head; + + _Slist_node<_Tp>* _M_get_node() { return _Node_alloc::allocate(1); } + void _M_put_node(_Slist_node<_Tp>* __p) { _Node_alloc::deallocate(__p, 1); } +protected: _Slist_node_base* _M_erase_after(_Slist_node_base* __pos) { _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next); @@ -280,7 +233,7 @@ protected: _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*); }; -template <class _Tp, class _Alloc> +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) { @@ -304,7 +257,7 @@ template <class _Tp, class _Alloc = allocator<_Tp> > class slist : private _Slist_base<_Tp,_Alloc> { // concept requirements - __glibcpp_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) private: typedef _Slist_base<_Tp,_Alloc> _Base; @@ -341,7 +294,7 @@ private: } return __node; } - + _Node* _M_create_node() { _Node* __node = this->_M_get_node(); try { @@ -408,7 +361,7 @@ public: public: iterator begin() { return iterator((_Node*)this->_M_head._M_next); } - const_iterator begin() const + const_iterator begin() const { return const_iterator((_Node*)this->_M_head._M_next);} iterator end() { return iterator(0); } @@ -417,8 +370,8 @@ public: // Experimental new feature: before_begin() returns a // non-dereferenceable iterator that, when incremented, yields // begin(). This iterator may be used as the argument to - // insert_after, erase_after, etc. Note that even for an empty - // slist, before_begin() is not the same iterator as end(). It + // insert_after, erase_after, etc. Note that even for an empty + // slist, before_begin() is not the same iterator as end(). It // is always necessary to increment before_begin() at least once to // obtain end(). iterator before_begin() { return iterator((_Node*) &this->_M_head); } @@ -426,7 +379,7 @@ public: { return const_iterator((_Node*) &this->_M_head); } size_type size() const { return __slist_size(this->_M_head._M_next); } - + size_type max_size() const { return size_type(-1); } bool empty() const { return this->_M_head._M_next == 0; } @@ -437,7 +390,7 @@ public: public: reference front() { return ((_Node*) this->_M_head._M_next)->_M_data; } - const_reference front() const + const_reference front() const { return ((_Node*) this->_M_head._M_next)->_M_data; } void push_front(const value_type& __x) { __slist_make_link(&this->_M_head, _M_create_node(__x)); @@ -474,10 +427,10 @@ private: } // 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; + template <class _InIterator> + void _M_insert_after_range(_Node_base* __pos, + _InIterator __first, _InIterator __last) { + typedef typename _Is_integer<_InIterator>::_Integral _Integral; _M_insert_after_range(__pos, __first, __last, _Integral()); } @@ -487,9 +440,9 @@ private: _M_insert_after_fill(__pos, __n, __x); } - template <class _InIter> + template <class _InIterator> void _M_insert_after_range(_Node_base* __pos, - _InIter __first, _InIter __last, + _InIterator __first, _InIterator __last, __false_type) { while (__first != __last) { __pos = __slist_make_link(__pos, _M_create_node(*__first)); @@ -513,8 +466,8 @@ public: // 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) { + template <class _InIterator> + void insert_after(iterator __pos, _InIterator __first, _InIterator __last) { _M_insert_after_range(__pos._M_node, __first, __last); } @@ -533,13 +486,13 @@ public: void insert(iterator __pos, size_type __n, const value_type& __x) { _M_insert_after_fill(__slist_previous(&this->_M_head, __pos._M_node), __n, __x); - } - + } + // We don't need any dispatching tricks here, because _M_insert_after_range // already does them. - template <class _InIter> - void insert(iterator __pos, _InIter __first, _InIter __last) { - _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node), + template <class _InIterator> + void insert(iterator __pos, _InIterator __first, _InIterator __last) { + _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node), __first, __last); } @@ -548,12 +501,12 @@ public: return iterator((_Node*) this->_M_erase_after(__pos._M_node)); } iterator erase_after(iterator __before_first, iterator __last) { - return iterator((_Node*) this->_M_erase_after(__before_first._M_node, + return iterator((_Node*) this->_M_erase_after(__before_first._M_node, __last._M_node)); - } + } iterator erase(iterator __pos) { - return (_Node*) this->_M_erase_after(__slist_previous(&this->_M_head, + return (_Node*) this->_M_erase_after(__slist_previous(&this->_M_head, __pos._M_node)); } iterator erase(iterator __first, iterator __last) { @@ -568,11 +521,11 @@ public: 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, + void splice_after(iterator __pos, iterator __before_first, iterator __before_last) { - if (__before_first != __before_last) - __slist_splice_after(__pos._M_node, __before_first._M_node, + if (__before_first != __before_last) + __slist_splice_after(__pos._M_node, __before_first._M_node, __before_last._M_node); } @@ -618,27 +571,27 @@ public: } public: - void reverse() { + void reverse() { if (this->_M_head._M_next) this->_M_head._M_next = __slist_reverse(this->_M_head._M_next); } - void remove(const _Tp& __val); - void unique(); + void remove(const _Tp& __val); + void unique(); void merge(slist& __x); - void sort(); + void sort(); - template <class _Predicate> + template <class _Predicate> void remove_if(_Predicate __pred); - template <class _BinaryPredicate> - void unique(_BinaryPredicate __pred); + template <class _BinaryPredicate> + void unique(_BinaryPredicate __pred); - template <class _StrictWeakOrdering> + template <class _StrictWeakOrdering> void merge(slist&, _StrictWeakOrdering); - template <class _StrictWeakOrdering> - void sort(_StrictWeakOrdering __comp); + template <class _StrictWeakOrdering> + void sort(_StrictWeakOrdering __comp); }; template <class _Tp, class _Alloc> @@ -657,7 +610,7 @@ slist<_Tp,_Alloc>& slist<_Tp,_Alloc>::operator=(const slist<_Tp,_Alloc>& __x) if (__n2 == 0) this->_M_erase_after(__p1, 0); else - _M_insert_after_range(__p1, const_iterator((_Node*)__n2), + _M_insert_after_range(__p1, const_iterator((_Node*)__n2), const_iterator(0)); } return *this; @@ -678,9 +631,9 @@ void slist<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) { this->_M_erase_after(__prev, 0); } -template <class _Tp, class _Alloc> template <class _InputIter> +template <class _Tp, class _Alloc> template <class _InputIterator> void -slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first, _InputIter __last, +slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type) { _Node_base* __prev = &this->_M_head; @@ -698,7 +651,7 @@ slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first, _InputIter __last, } template <class _Tp, class _Alloc> -inline bool +inline bool operator==(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator; @@ -719,30 +672,30 @@ template <class _Tp, class _Alloc> inline bool operator<(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { - return std::lexicographical_compare(_SL1.begin(), _SL1.end(), + return std::lexicographical_compare(_SL1.begin(), _SL1.end(), _SL2.begin(), _SL2.end()); } template <class _Tp, class _Alloc> -inline bool +inline bool operator!=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { return !(_SL1 == _SL2); } template <class _Tp, class _Alloc> -inline bool +inline bool operator>(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { return _SL2 < _SL1; } template <class _Tp, class _Alloc> -inline bool +inline bool operator<=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { return !(_SL2 < _SL1); } template <class _Tp, class _Alloc> -inline bool +inline bool operator>=(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { return !(_SL1 < _SL2); } @@ -761,7 +714,7 @@ void slist<_Tp,_Alloc>::resize(size_type __len, const _Tp& __x) --__len; __cur = __cur->_M_next; } - if (__cur->_M_next) + if (__cur->_M_next) this->_M_erase_after(__cur, 0); else _M_insert_after_fill(__cur, __len, __x); @@ -779,13 +732,13 @@ void slist<_Tp,_Alloc>::remove(const _Tp& __val) } } -template <class _Tp, class _Alloc> +template <class _Tp, class _Alloc> void slist<_Tp,_Alloc>::unique() { _Node_base* __cur = this->_M_head._M_next; if (__cur) { while (__cur->_M_next) { - if (((_Node*)__cur)->_M_data == + if (((_Node*)__cur)->_M_data == ((_Node*)(__cur->_M_next))->_M_data) this->_M_erase_after(__cur); else @@ -799,8 +752,8 @@ void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x) { _Node_base* __n1 = &this->_M_head; while (__n1->_M_next && __x._M_head._M_next) { - if (((_Node*) __x._M_head._M_next)->_M_data < - ((_Node*) __n1->_M_next)->_M_data) + 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; } @@ -837,7 +790,7 @@ void slist<_Tp,_Alloc>::sort() } } -template <class _Tp, class _Alloc> +template <class _Tp, class _Alloc> template <class _Predicate> void slist<_Tp,_Alloc>::remove_if(_Predicate __pred) { @@ -850,13 +803,13 @@ void slist<_Tp,_Alloc>::remove_if(_Predicate __pred) } } -template <class _Tp, class _Alloc> template <class _BinaryPredicate> +template <class _Tp, class _Alloc> template <class _BinaryPredicate> void slist<_Tp,_Alloc>::unique(_BinaryPredicate __pred) { _Node* __cur = (_Node*) this->_M_head._M_next; if (__cur) { while (__cur->_M_next) { - if (__pred(((_Node*)__cur)->_M_data, + if (__pred(((_Node*)__cur)->_M_data, ((_Node*)(__cur->_M_next))->_M_data)) this->_M_erase_after(__cur); else @@ -882,7 +835,7 @@ void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x, } } -template <class _Tp, class _Alloc> template <class _StrictWeakOrdering> +template <class _Tp, class _Alloc> template <class _StrictWeakOrdering> void slist<_Tp,_Alloc>::sort(_StrictWeakOrdering __comp) { if (this->_M_head._M_next && this->_M_head._M_next->_M_next) { @@ -930,7 +883,7 @@ public: typedef void pointer; typedef void reference; - insert_iterator(_Container& __x, typename _Container::iterator __i) + insert_iterator(_Container& __x, typename _Container::iterator __i) : container(&__x) { if (__i == __x.begin()) iter = __x.before_begin(); @@ -939,7 +892,7 @@ public: } insert_iterator<_Container>& - operator=(const typename _Container::value_type& __value) { + operator=(const typename _Container::value_type& __value) { iter = container->insert_after(iter, __value); return *this; } @@ -950,8 +903,4 @@ public: } // namespace std -#endif /* __SGI_STL_INTERNAL_SLIST_H */ - -// Local Variables: -// mode:C++ -// End: +#endif diff --git a/contrib/libstdc++/include/ext/stdio_filebuf.h b/contrib/libstdc++/include/ext/stdio_filebuf.h index 4c6bf90a7c41..cc229728fa8a 100644 --- a/contrib/libstdc++/include/ext/stdio_filebuf.h +++ b/contrib/libstdc++/include/ext/stdio_filebuf.h @@ -1,6 +1,6 @@ // File descriptor layer for filebuf -*- C++ -*- -// Copyright (C) 2002 Free Software Foundation, Inc. +// Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -31,10 +31,11 @@ * This file is a GNU extension to the Standard C++ Library. */ -#ifndef _EXT_STDIO_FILEBUF -#define _EXT_STDIO_FILEBUF +#ifndef _STDIO_FILEBUF_H +#define _STDIO_FILEBUF_H 1 #pragma GCC system_header + #include <fstream> namespace __gnu_cxx @@ -53,47 +54,47 @@ namespace __gnu_cxx { public: // Types: - typedef _CharT char_type; - typedef _Traits traits_type; - typedef typename traits_type::int_type int_type; - typedef typename traits_type::pos_type pos_type; - typedef typename traits_type::off_type off_type; + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; typedef std::size_t size_t; - - protected: - // Stack-based buffer for unbuffered input. - char_type _M_unbuf[4]; - + public: /** + * deferred initialization + */ + stdio_filebuf() : std::basic_filebuf<_CharT, _Traits>() {} + + /** * @param fd An open file descriptor. * @param mode Same meaning as in a standard filebuf. - * @param del Whether to close the file on destruction. - * @param size Optimal or preferred size of internal buffer, in bytes. + * @param size Optimal or preferred size of internal buffer, in chars. * * This constructor associates a file stream buffer with an open - * POSIX file descriptor. Iff @a del is true, then the associated - * file will be closed when the stdio_filebuf is closed/destroyed. + * POSIX file descriptor. The file descriptor will be automatically + * closed when the stdio_filebuf is closed/destroyed. */ - stdio_filebuf(int __fd, std::ios_base::openmode __mode, bool __del, - size_t __size); + stdio_filebuf(int __fd, std::ios_base::openmode __mode, + size_t __size = static_cast<size_t>(BUFSIZ)); /** * @param f An open @c FILE*. * @param mode Same meaning as in a standard filebuf. - * @param size Optimal or preferred size of internal buffer, in bytes. + * @param size Optimal or preferred size of internal buffer, in chars. * Defaults to system's @c BUFSIZ. * * This constructor associates a file stream buffer with an open * C @c FILE*. The @c FILE* will not be automatically closed when the * stdio_filebuf is closed/destroyed. */ - stdio_filebuf(std::__c_file* __f, std::ios_base::openmode __mode, + stdio_filebuf(std::__c_file* __f, std::ios_base::openmode __mode, size_t __size = static_cast<size_t>(BUFSIZ)); /** - * Possibly closes the external data stream, in the case of the file - * descriptor constructor and @c del @c == @c true. + * Closes the external data stream if the file descriptor constructor + * was used. */ virtual ~stdio_filebuf(); @@ -107,8 +108,17 @@ namespace __gnu_cxx * descriptor, so be careful. */ int - fd() - { return _M_file.fd(); } + fd() { return this->_M_file.fd(); } + + /** + * @return The underlying FILE*. + * + * This function can be used to access the underlying "C" file pointer. + * Note that there is no way for the library to track what you do + * with the file, so be careful. + */ + std::__c_file* + file() { return this->_M_file.file(); } }; template<typename _CharT, typename _Traits> @@ -117,53 +127,36 @@ namespace __gnu_cxx template<typename _CharT, typename _Traits> stdio_filebuf<_CharT, _Traits>:: - stdio_filebuf(int __fd, std::ios_base::openmode __mode, bool __del, - size_t __size) + stdio_filebuf(int __fd, std::ios_base::openmode __mode, size_t __size) { - _M_file.sys_open(__fd, __mode, __del); + this->_M_file.sys_open(__fd, __mode); if (this->is_open()) { - _M_mode = __mode; - if (__size > 0 && __size < 4) - { - // Specify not to use an allocated buffer. - _M_buf = _M_unbuf; - _M_buf_size = __size; - _M_buf_size_opt = 0; - } - else - { - _M_buf_size_opt = __size; - _M_allocate_internal_buffer(); - } - _M_set_indeterminate(); + this->_M_mode = __mode; + this->_M_buf_size = __size; + this->_M_allocate_internal_buffer(); + this->_M_reading = false; + this->_M_writing = false; + this->_M_set_buffer(-1); } } template<typename _CharT, typename _Traits> stdio_filebuf<_CharT, _Traits>:: - stdio_filebuf(std::__c_file* __f, std::ios_base::openmode __mode, + stdio_filebuf(std::__c_file* __f, std::ios_base::openmode __mode, size_t __size) { - _M_file.sys_open(__f, __mode); + this->_M_file.sys_open(__f, __mode); if (this->is_open()) { - _M_mode = __mode; - if (__size > 0 && __size < 4) - { - // Specify not to use an allocated buffer. - _M_buf = _M_unbuf; - _M_buf_size = __size; - _M_buf_size_opt = 0; - } - else - { - _M_buf_size_opt = __size; - _M_allocate_internal_buffer(); - } - _M_set_indeterminate(); + this->_M_mode = __mode; + this->_M_buf_size = __size; + this->_M_allocate_internal_buffer(); + this->_M_reading = false; + this->_M_writing = false; + this->_M_set_buffer(-1); } } } // namespace __gnu_cxx -#endif /* _EXT_STDIO_FILEBUF */ +#endif diff --git a/contrib/libstdc++/include/ext/stdio_sync_filebuf.h b/contrib/libstdc++/include/ext/stdio_sync_filebuf.h new file mode 100644 index 000000000000..367d310b4b04 --- /dev/null +++ b/contrib/libstdc++/include/ext/stdio_sync_filebuf.h @@ -0,0 +1,281 @@ +// Iostreams wrapper for stdio FILE* -*- C++ -*- + +// Copyright (C) 2003, 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file ext/stdiostream.h + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _STDIO_SYNC_FILEBUF_H +#define _STDIO_SYNC_FILEBUF_H 1 + +#pragma GCC system_header + +#include <streambuf> +#include <unistd.h> +#include <cstdio> + +#ifdef _GLIBCXX_USE_WCHAR_T +#include <cwchar> +#endif + +namespace __gnu_cxx +{ + template<typename _CharT, typename _Traits = std::char_traits<_CharT> > + class stdio_sync_filebuf : public std::basic_streambuf<_CharT, _Traits> + { + public: + // Types: + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename traits_type::int_type int_type; + typedef typename traits_type::pos_type pos_type; + typedef typename traits_type::off_type off_type; + + private: + // Underlying stdio FILE + std::__c_file* const _M_file; + + // Last character gotten. This is used when pbackfail is + // called from basic_streambuf::sungetc() + int_type _M_unget_buf; + + public: + explicit + stdio_sync_filebuf(std::__c_file* __f) + : _M_file(__f), _M_unget_buf(traits_type::eof()) + { } + + /** + * @return The underlying FILE*. + * + * This function can be used to access the underlying "C" file pointer. + * Note that there is no way for the library to track what you do + * with the file, so be careful. + */ + std::__c_file* const + file() { return this->_M_file; } + + protected: + int_type + syncgetc(); + + int_type + syncungetc(int_type __c); + + int_type + syncputc(int_type __c); + + virtual int_type + underflow() + { + int_type __c = this->syncgetc(); + return this->syncungetc(__c); + } + + virtual int_type + uflow() + { + // Store the gotten character in case we need to unget it. + _M_unget_buf = this->syncgetc(); + return _M_unget_buf; + } + + virtual int_type + pbackfail(int_type __c = traits_type::eof()) + { + int_type __ret; + const int_type __eof = traits_type::eof(); + + // Check if the unget or putback was requested + if (traits_type::eq_int_type(__c, __eof)) // unget + { + if (!traits_type::eq_int_type(_M_unget_buf, __eof)) + __ret = this->syncungetc(_M_unget_buf); + else // buffer invalid, fail. + __ret = __eof; + } + else // putback + __ret = this->syncungetc(__c); + + // The buffered character is no longer valid, discard it. + _M_unget_buf = __eof; + return __ret; + } + + virtual std::streamsize + xsgetn(char_type* __s, std::streamsize __n); + + virtual int_type + overflow(int_type __c = traits_type::eof()) + { + int_type __ret; + if (traits_type::eq_int_type(__c, traits_type::eof())) + { + if (std::fflush(_M_file)) + __ret = traits_type::eof(); + else + __ret = traits_type::not_eof(__c); + } + else + __ret = this->syncputc(__c); + return __ret; + } + + virtual std::streamsize + xsputn(const char_type* __s, std::streamsize __n); + + virtual int + sync() + { return std::fflush(_M_file); } + + virtual std::streampos + seekoff(std::streamoff __off, std::ios_base::seekdir __dir, + std::ios_base::openmode = std::ios_base::in | std::ios_base::out) + { + std::streampos __ret(std::streamoff(-1)); + int __whence; + if (__dir == std::ios_base::beg) + __whence = SEEK_SET; + else if (__dir == std::ios_base::cur) + __whence = SEEK_CUR; + else + __whence = SEEK_END; +#ifdef _GLIBCXX_USE_LFS + if (!fseeko64(_M_file, __off, __whence)) + __ret = std::streampos(ftello64(_M_file)); +#else + if (!fseek(_M_file, __off, __whence)) + __ret = std::streampos(std::ftell(_M_file)); +#endif + return __ret; + } + + virtual std::streampos + seekpos(std::streampos __pos, + std::ios_base::openmode __mode = + std::ios_base::in | std::ios_base::out) + { return seekoff(std::streamoff(__pos), std::ios_base::beg, __mode); } + }; + + template<> + inline stdio_sync_filebuf<char>::int_type + stdio_sync_filebuf<char>::syncgetc() + { return std::getc(_M_file); } + + template<> + inline stdio_sync_filebuf<char>::int_type + stdio_sync_filebuf<char>::syncungetc(int_type __c) + { return std::ungetc(__c, _M_file); } + + template<> + inline stdio_sync_filebuf<char>::int_type + stdio_sync_filebuf<char>::syncputc(int_type __c) + { return std::putc(__c, _M_file); } + + template<> + inline std::streamsize + stdio_sync_filebuf<char>::xsgetn(char* __s, std::streamsize __n) + { + std::streamsize __ret = std::fread(__s, 1, __n, _M_file); + if (__ret > 0) + _M_unget_buf = traits_type::to_int_type(__s[__ret - 1]); + else + _M_unget_buf = traits_type::eof(); + return __ret; + } + + template<> + inline std::streamsize + stdio_sync_filebuf<char>::xsputn(const char* __s, std::streamsize __n) + { return std::fwrite(__s, 1, __n, _M_file); } + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + inline stdio_sync_filebuf<wchar_t>::int_type + stdio_sync_filebuf<wchar_t>::syncgetc() + { return std::getwc(_M_file); } + + template<> + inline stdio_sync_filebuf<wchar_t>::int_type + stdio_sync_filebuf<wchar_t>::syncungetc(int_type __c) + { return std::ungetwc(__c, _M_file); } + + template<> + inline stdio_sync_filebuf<wchar_t>::int_type + stdio_sync_filebuf<wchar_t>::syncputc(int_type __c) + { return std::putwc(__c, _M_file); } + + template<> + inline std::streamsize + stdio_sync_filebuf<wchar_t>::xsgetn(wchar_t* __s, std::streamsize __n) + { + std::streamsize __ret = 0; + const int_type __eof = traits_type::eof(); + while (__n--) + { + int_type __c = this->syncgetc(); + if (traits_type::eq_int_type(__c, __eof)) + break; + __s[__ret] = traits_type::to_char_type(__c); + ++__ret; + } + + if (__ret > 0) + _M_unget_buf = traits_type::to_int_type(__s[__ret - 1]); + else + _M_unget_buf = traits_type::eof(); + return __ret; + } + + template<> + inline std::streamsize + stdio_sync_filebuf<wchar_t>::xsputn(const wchar_t* __s, + std::streamsize __n) + { + std::streamsize __ret = 0; + const int_type __eof = traits_type::eof(); + while (__n--) + { + if (traits_type::eq_int_type(this->syncputc(*__s++), __eof)) + break; + ++__ret; + } + return __ret; + } +#endif + +#if _GLIBCXX_EXTERN_TEMPLATE + extern template class stdio_sync_filebuf<char>; +#ifdef _GLIBCXX_USE_WCHAR_T + extern template class stdio_sync_filebuf<wchar_t>; +#endif +#endif +} // namespace __gnu_cxx + +#endif diff --git a/contrib/libstdc++/include/std/std_algorithm.h b/contrib/libstdc++/include/std/std_algorithm.h index bcc0c8a70cda..40e6246ce7f9 100644 --- a/contrib/libstdc++/include/std/std_algorithm.h +++ b/contrib/libstdc++/include/std/std_algorithm.h @@ -58,8 +58,8 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_ALGORITHM -#define _CPP_ALGORITHM 1 +#ifndef _GLIBCXX_ALGORITHM +#define _GLIBCXX_ALGORITHM 1 #pragma GCC system_header @@ -68,8 +68,4 @@ #include <bits/stl_uninitialized.h> #include <bits/stl_algo.h> -#endif /* _CPP_ALGORITHM */ - -// Local Variables: -// mode:C++ -// End: +#endif /* _GLIBCXX_ALGORITHM */ diff --git a/contrib/libstdc++/include/std/std_bitset.h b/contrib/libstdc++/include/std/std_bitset.h index ebe16504d188..01e3f904e470 100644 --- a/contrib/libstdc++/include/std/std_bitset.h +++ b/contrib/libstdc++/include/std/std_bitset.h @@ -1,6 +1,6 @@ // <bitset> -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -45,29 +45,26 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _GLIBCPP_BITSET_H -#define _GLIBCPP_BITSET_H +#ifndef _GLIBCXX_BITSET +#define _GLIBCXX_BITSET 1 #pragma GCC system_header -#include <cstddef> // for size_t -#include <cstring> // for memset +#include <cstddef> // For size_t +#include <cstring> // For memset +#include <limits> // For numeric_limits #include <string> -#include <bits/functexcept.h> // for invalid_argument, out_of_range, +#include <bits/functexcept.h> // For invalid_argument, out_of_range, // overflow_error -#include <ostream> // for ostream (operator<<) -#include <istream> // for istream (operator>>) +#include <ostream> // For ostream (operator<<) +#include <istream> // For istream (operator>>) +#define _GLIBCXX_BITSET_BITS_PER_WORD numeric_limits<unsigned long>::digits +#define _GLIBCXX_BITSET_WORDS(__n) \ + ((__n) < 1 ? 0 : ((__n) + _GLIBCXX_BITSET_BITS_PER_WORD - 1)/_GLIBCXX_BITSET_BITS_PER_WORD) -#define _GLIBCPP_BITSET_BITS_PER_WORD (CHAR_BIT*sizeof(unsigned long)) -#define _GLIBCPP_BITSET_WORDS(__n) \ - ((__n) < 1 ? 0 : ((__n) + _GLIBCPP_BITSET_BITS_PER_WORD - 1)/_GLIBCPP_BITSET_BITS_PER_WORD) - -namespace std +namespace _GLIBCXX_STD { - extern unsigned char _S_bit_count[256]; - extern unsigned char _S_first_one[256]; - /** * @if maint * Base class, general case. It is a class inveriant that _Nw will be @@ -93,15 +90,15 @@ namespace std static size_t _S_whichword(size_t __pos ) - { return __pos / _GLIBCPP_BITSET_BITS_PER_WORD; } + { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } static size_t _S_whichbyte(size_t __pos ) - { return (__pos % _GLIBCPP_BITSET_BITS_PER_WORD) / CHAR_BIT; } + { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } static size_t _S_whichbit(size_t __pos ) - { return __pos % _GLIBCPP_BITSET_BITS_PER_WORD; } + { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } static _WordT _S_maskbit(size_t __pos ) @@ -191,14 +188,8 @@ namespace std _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 += _S_bit_count[*__byte_ptr]; - __byte_ptr++; - } + for (size_t __i = 0; __i < _Nw; __i++) + __result += __builtin_popcountl(_M_w[__i]); return __result; } @@ -221,22 +212,22 @@ namespace std { if (__builtin_expect(__shift != 0, 1)) { - const size_t __wshift = __shift / _GLIBCPP_BITSET_BITS_PER_WORD; - const size_t __offset = __shift % _GLIBCPP_BITSET_BITS_PER_WORD; + const size_t __wshift = __shift / _GLIBCXX_BITSET_BITS_PER_WORD; + const size_t __offset = __shift % _GLIBCXX_BITSET_BITS_PER_WORD; if (__offset == 0) for (size_t __n = _Nw - 1; __n >= __wshift; --__n) _M_w[__n] = _M_w[__n - __wshift]; else { - const size_t __sub_offset = _GLIBCPP_BITSET_BITS_PER_WORD - __offset; + const size_t __sub_offset = _GLIBCXX_BITSET_BITS_PER_WORD - __offset; for (size_t __n = _Nw - 1; __n > __wshift; --__n) _M_w[__n] = (_M_w[__n - __wshift] << __offset) | (_M_w[__n - __wshift - 1] >> __sub_offset); _M_w[__wshift] = _M_w[0] << __offset; } - fill(_M_w + 0, _M_w + __wshift, static_cast<_WordT>(0)); + std::fill(_M_w + 0, _M_w + __wshift, static_cast<_WordT>(0)); } } @@ -246,8 +237,8 @@ namespace std { if (__builtin_expect(__shift != 0, 1)) { - const size_t __wshift = __shift / _GLIBCPP_BITSET_BITS_PER_WORD; - const size_t __offset = __shift % _GLIBCPP_BITSET_BITS_PER_WORD; + const size_t __wshift = __shift / _GLIBCXX_BITSET_BITS_PER_WORD; + const size_t __offset = __shift % _GLIBCXX_BITSET_BITS_PER_WORD; const size_t __limit = _Nw - __wshift - 1; if (__offset == 0) @@ -255,14 +246,14 @@ namespace std _M_w[__n] = _M_w[__n + __wshift]; else { - const size_t __sub_offset = _GLIBCPP_BITSET_BITS_PER_WORD - __offset; + const size_t __sub_offset = _GLIBCXX_BITSET_BITS_PER_WORD - __offset; for (size_t __n = 0; __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; } - - fill(_M_w + __limit + 1, _M_w + _Nw, static_cast<_WordT>(0)); + + std::fill(_M_w + __limit + 1, _M_w + _Nw, static_cast<_WordT>(0)); } } @@ -272,7 +263,7 @@ namespace std { for (size_t __i = 1; __i < _Nw; ++__i) if (_M_w[__i]) - __throw_overflow_error("bitset -- too large to fit in unsigned long"); + __throw_overflow_error(__N("_Base_bitset::_M_do_to_ulong")); return _M_w[0]; } @@ -280,23 +271,12 @@ namespace std size_t _Base_bitset<_Nw>::_M_do_find_first(size_t __not_found) const { - for (size_t __i = 0; __i < _Nw; __i++ ) + 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*_GLIBCPP_BITSET_BITS_PER_WORD + __j*CHAR_BIT + - _S_first_one[__this_byte]; - - __thisword >>= CHAR_BIT; - } - } + if (__thisword != static_cast<_WordT>(0)) + return __i * _GLIBCXX_BITSET_BITS_PER_WORD + + __builtin_ctzl(__thisword); } // not found, so return an indication of failure. return __not_found; @@ -310,7 +290,7 @@ namespace std ++__prev; // check out of bounds - if ( __prev >= _Nw * _GLIBCPP_BITSET_BITS_PER_WORD ) + if (__prev >= _Nw * _GLIBCXX_BITSET_BITS_PER_WORD) return __not_found; // search first word @@ -320,42 +300,18 @@ namespace std // 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*_GLIBCPP_BITSET_BITS_PER_WORD + __j*CHAR_BIT + - _S_first_one[__this_byte]; - - __thisword >>= CHAR_BIT; - } - } + if (__thisword != static_cast<_WordT>(0)) + return __i * _GLIBCXX_BITSET_BITS_PER_WORD + + __builtin_ctzl(__thisword); // check subsequent words __i++; for ( ; __i < _Nw; __i++ ) { __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*_GLIBCPP_BITSET_BITS_PER_WORD + __j*CHAR_BIT + - _S_first_one[__this_byte]; - - __thisword >>= CHAR_BIT; - } - } + if (__thisword != static_cast<_WordT>(0)) + return __i * _GLIBCXX_BITSET_BITS_PER_WORD + + __builtin_ctzl(__thisword); } // not found, so return an indication of failure. return __not_found; @@ -380,15 +336,15 @@ namespace std static size_t _S_whichword(size_t __pos ) - { return __pos / _GLIBCPP_BITSET_BITS_PER_WORD; } + { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } static size_t _S_whichbyte(size_t __pos ) - { return (__pos % _GLIBCPP_BITSET_BITS_PER_WORD) / CHAR_BIT; } + { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } static size_t _S_whichbit(size_t __pos ) - { return __pos % _GLIBCPP_BITSET_BITS_PER_WORD; } + { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } static _WordT _S_maskbit(size_t __pos ) @@ -438,29 +394,34 @@ namespace std _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 += _S_bit_count[*__byte_ptr]; - __byte_ptr++; - } - return __result; - } + _M_do_count() const { return __builtin_popcountl(_M_w); } unsigned long _M_do_to_ulong() const { return _M_w; } size_t - _M_do_find_first(size_t __not_found) const; + _M_do_find_first(size_t __not_found) const + { + if (_M_w != 0) + return __builtin_ctzl(_M_w); + else + return __not_found; + } // find the next "on" bit that follows "prev" size_t - _M_do_find_next(size_t __prev, size_t __not_found) const; + _M_do_find_next(size_t __prev, size_t __not_found) const + { + ++__prev; + if (__prev >= ((size_t) _GLIBCXX_BITSET_BITS_PER_WORD)) + return __not_found; + + _WordT __x = _M_w >> __prev; + if (__x != 0) + return __builtin_ctzl(__x) + __prev; + else + return __not_found; + } }; @@ -481,15 +442,15 @@ namespace std static size_t _S_whichword(size_t __pos ) - { return __pos / _GLIBCPP_BITSET_BITS_PER_WORD; } + { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } static size_t _S_whichbyte(size_t __pos ) - { return (__pos % _GLIBCPP_BITSET_BITS_PER_WORD) / CHAR_BIT; } + { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } static size_t _S_whichbit(size_t __pos ) - { return __pos % _GLIBCPP_BITSET_BITS_PER_WORD; } + { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } static _WordT _S_maskbit(size_t __pos ) @@ -504,7 +465,10 @@ namespace std // localized to this single should-never-get-this-far function. _WordT& _M_getword(size_t) const - { __throw_out_of_range("bitset -- zero-length"); return *new _WordT; } + { + __throw_out_of_range(__N("_Base_bitset::_M_getword")); + return *new _WordT; + } _WordT _M_hiword() const { return 0; } @@ -636,16 +600,16 @@ namespace std * @endif */ template<size_t _Nb> - class bitset : private _Base_bitset<_GLIBCPP_BITSET_WORDS(_Nb)> + class bitset : private _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> { private: - typedef _Base_bitset<_GLIBCPP_BITSET_WORDS(_Nb)> _Base; + typedef _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> _Base; typedef unsigned long _WordT; void _M_do_sanitize() { - _Sanitize<_Nb%_GLIBCPP_BITSET_BITS_PER_WORD>:: + _Sanitize<_Nb%_GLIBCXX_BITSET_BITS_PER_WORD>:: _S_do_sanitize(this->_M_hiword()); } @@ -681,7 +645,7 @@ namespace std ~reference() { } - // for b[i] = __x; + // For b[i] = __x; reference& operator=(bool __x) { @@ -692,7 +656,7 @@ namespace std return *this; } - // for b[i] = b[__j]; + // For b[i] = b[__j]; reference& operator=(const reference& __j) { @@ -703,16 +667,16 @@ namespace std return *this; } - // flips the bit + // Flips the bit bool operator~() const { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) == 0; } - // for __x = b[i]; + // For __x = b[i]; operator bool() const { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; } - // for b[i].flip(); + // For b[i].flip(); reference& flip() { @@ -733,7 +697,7 @@ namespace std /** * @brief Use a subset of a string. * @param s A string of '0' and '1' characters. - * @param pos Index of the first character in @a s to use; defaults + * @param position Index of the first character in @a s to use; defaults * to zero. * @throw std::out_of_range If @a pos is bigger the size of @a s. * @throw std::invalid_argument If a character appears in the string @@ -741,19 +705,19 @@ namespace std */ template<class _CharT, class _Traits, class _Alloc> explicit bitset(const basic_string<_CharT, _Traits, _Alloc>& __s, - size_t __pos = 0) : _Base() + size_t __position = 0) : _Base() { - if (__pos > __s.size()) - __throw_out_of_range("bitset -- initial position is larger than " - "the string itself"); - _M_copy_from_string(__s, __pos, + if (__position > __s.size()) + __throw_out_of_range(__N("bitset::bitset initial position " + "not valid")); + _M_copy_from_string(__s, __position, basic_string<_CharT, _Traits, _Alloc>::npos); } /** * @brief Use a subset of a string. * @param s A string of '0' and '1' characters. - * @param pos Index of the first character in @a s to use. + * @param position Index of the first character in @a s to use. * @param n The number of characters to copy. * @throw std::out_of_range If @a pos is bigger the size of @a s. * @throw std::invalid_argument If a character appears in the string @@ -761,12 +725,12 @@ namespace std */ template<class _CharT, class _Traits, class _Alloc> bitset(const basic_string<_CharT, _Traits, _Alloc>& __s, - size_t __pos, size_t __n) : _Base() + size_t __position, size_t __n) : _Base() { - if (__pos > __s.size()) - __throw_out_of_range("bitset -- initial position is larger than " - "the string itself"); - _M_copy_from_string(__s, __pos, __n); + if (__position > __s.size()) + __throw_out_of_range(__N("bitset::bitset initial position " + "not valid")); + _M_copy_from_string(__s, __position, __n); } // 23.3.5.2 bitset operations: @@ -802,16 +766,16 @@ namespace std //@{ /** * @brief Operations on bitsets. - * @param pos The number of places to shift. + * @param position The number of places to shift. * * These should be self-explanatory. */ bitset<_Nb>& - operator<<=(size_t __pos) + operator<<=(size_t __position) { - if (__builtin_expect(__pos < _Nb, 1)) + if (__builtin_expect(__position < _Nb, 1)) { - this->_M_do_left_shift(__pos); + this->_M_do_left_shift(__position); this->_M_do_sanitize(); } else @@ -820,11 +784,11 @@ namespace std } bitset<_Nb>& - operator>>=(size_t __pos) + operator>>=(size_t __position) { - if (__builtin_expect(__pos < _Nb, 1)) + if (__builtin_expect(__position < _Nb, 1)) { - this->_M_do_right_shift(__pos); + this->_M_do_right_shift(__position); this->_M_do_sanitize(); } else @@ -892,16 +856,16 @@ namespace std /** * @brief Sets a given bit to a particular value. - * @param pos The index of the bit. + * @param position The index of the bit. * @param val Either true or false, defaults to true. * @throw std::out_of_range If @a pos is bigger the size of the %set. */ bitset<_Nb>& - set(size_t __pos, bool __val = true) + set(size_t __position, bool __val = true) { - if (__pos >= _Nb) - __throw_out_of_range("bitset -- set() argument too large"); - return _Unchecked_set(__pos, __val); + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::set")); + return _Unchecked_set(__position, __val); } /** @@ -916,17 +880,17 @@ namespace std /** * @brief Sets a given bit to false. - * @param pos The index of the bit. + * @param position The index of the bit. * @throw std::out_of_range If @a pos is bigger the size of the %set. * * Same as writing @c set(pos,false). */ bitset<_Nb>& - reset(size_t __pos) + reset(size_t __position) { - if (__pos >= _Nb) - __throw_out_of_range("bitset -- reset() argument too large"); - return _Unchecked_reset(__pos); + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::reset")); + return _Unchecked_reset(__position); } /** @@ -942,15 +906,15 @@ namespace std /** * @brief Toggles a given bit to its opposite value. - * @param pos The index of the bit. + * @param position The index of the bit. * @throw std::out_of_range If @a pos is bigger the size of the %set. */ bitset<_Nb>& - flip(size_t __pos) + flip(size_t __position) { - if (__pos >= _Nb) - __throw_out_of_range("bitset -- flip() argument too large"); - return _Unchecked_flip(__pos); + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::flip")); + return _Unchecked_flip(__position); } /// See the no-argument flip(). @@ -960,14 +924,14 @@ namespace std //@{ /** * @brief Array-indexing support. - * @param pos Index into the %bitset. + * @param position Index into the %bitset. * @return A bool for a 'const %bitset'. For non-const bitsets, an * instance of the reference proxy class. * @note These operators do no range checking and throw no exceptions, * as required by DR 11 to the standard. * * @if maint - * _GLIBCPP_RESOLVE_LIB_DEFECTS Note that this implementation already + * _GLIBCXX_RESOLVE_LIB_DEFECTS Note that this implementation already * resolves DR 11 (items 1 and 2), but does not do the range-checking * required by that DR's resolution. -pme * The DR has since been changed: range-checking is a precondition @@ -975,10 +939,10 @@ namespace std * @endif */ reference - operator[](size_t __pos) { return reference(*this,__pos); } + operator[](size_t __position) { return reference(*this,__position); } bool - operator[](size_t __pos) const { return _Unchecked_test(__pos); } + operator[](size_t __position) const { return _Unchecked_test(__position); } //@} /** @@ -1044,16 +1008,16 @@ namespace std /** * @brief Tests the value of a bit. - * @param pos The index of a bit. + * @param position The index of a bit. * @return The value at @a pos. * @throw std::out_of_range If @a pos is bigger the size of the %set. */ bool - test(size_t __pos) const + test(size_t __position) const { - if (__pos >= _Nb) - __throw_out_of_range("bitset -- test() argument too large"); - return _Unchecked_test(__pos); + if (__position >= _Nb) + __throw_out_of_range(__N("bitset::test")); + return _Unchecked_test(__position); } /** @@ -1073,12 +1037,12 @@ namespace std //@{ /// Self-explanatory. bitset<_Nb> - operator<<(size_t __pos) const - { return bitset<_Nb>(*this) <<= __pos; } + operator<<(size_t __position) const + { return bitset<_Nb>(*this) <<= __position; } bitset<_Nb> - operator>>(size_t __pos) const - { return bitset<_Nb>(*this) >>= __pos; } + operator>>(size_t __position) const + { return bitset<_Nb>(*this) >>= __position; } //@} /** @@ -1107,10 +1071,11 @@ namespace std template<size_t _Nb> template<class _CharT, class _Traits, class _Alloc> void - bitset<_Nb>::_M_copy_from_string(const basic_string<_CharT,_Traits,_Alloc>& __s, size_t __pos, size_t __n) + bitset<_Nb>::_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)); + const size_t __nbits = std::min(_Nb, std::min(__n, __s.size() - __pos)); for (size_t __i = 0; __i < __nbits; ++__i) { switch(__s[__pos + __nbits - __i - 1]) @@ -1121,8 +1086,7 @@ namespace std set(__i); break; default: - __throw_invalid_argument("bitset -- string contains characters " - "which are neither 0 nor 1"); + __throw_invalid_argument(__N("bitset::_M_copy_from_string")); } } } @@ -1130,7 +1094,8 @@ namespace std template<size_t _Nb> template<class _CharT, class _Traits, class _Alloc> void - bitset<_Nb>::_M_copy_to_string(basic_string<_CharT, _Traits, _Alloc>& __s) const + bitset<_Nb>::_M_copy_to_string(basic_string<_CharT, _Traits, + _Alloc>& __s) const { __s.assign(_Nb, '0'); for (size_t __i = 0; __i < _Nb; ++__i) @@ -1193,46 +1158,53 @@ namespace std basic_string<_CharT, _Traits> __tmp; __tmp.reserve(_Nb); - // Skip whitespace + ios_base::iostate __state = ios_base::goodbit; typename basic_istream<_CharT, _Traits>::sentry __sentry(__is); if (__sentry) { - ios_base::iostate __state = ios_base::goodbit; - basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf(); - for (size_t __i = 0; __i < _Nb; ++__i) + try { - static typename _Traits::int_type __eof = _Traits::eof(); - - typename _Traits::int_type __c1 = __buf->sbumpc(); - if (_Traits::eq_int_type(__c1, __eof)) - { - __state |= ios_base::eofbit; - break; - } - else + basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf(); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 303. Bitset input operator underspecified + const char_type __zero = __is.widen('0'); + const char_type __one = __is.widen('1'); + for (size_t __i = 0; __i < _Nb; ++__i) { - char_type __c2 = _Traits::to_char_type(__c1); - char_type __c = __is.narrow(__c2, '*'); - - if (__c == '0' || __c == '1') - __tmp.push_back(__c); - else if (_Traits::eq_int_type(__buf->sputbackc(__c2), __eof)) + static typename _Traits::int_type __eof = _Traits::eof(); + + typename _Traits::int_type __c1 = __buf->sbumpc(); + if (_Traits::eq_int_type(__c1, __eof)) { - __state |= ios_base::failbit; + __state |= ios_base::eofbit; break; } + else + { + char_type __c2 = _Traits::to_char_type(__c1); + if (__c2 == __zero) + __tmp.push_back('0'); + else if (__c2 == __one) + __tmp.push_back('1'); + else if (_Traits::eq_int_type(__buf->sputbackc(__c2), + __eof)) + { + __state |= ios_base::failbit; + break; + } + } } } - - if (__tmp.empty() && !_Nb) - __state |= ios_base::failbit; - else - __x._M_copy_from_string(__tmp, static_cast<size_t>(0), _Nb); - - if (__state != ios_base::goodbit) - __is.setstate(__state); // may throw an exception + catch(...) + { __is._M_setstate(ios_base::badbit); } } + if (__tmp.empty() && _Nb) + __state |= ios_base::failbit; + else + __x._M_copy_from_string(__tmp, static_cast<size_t>(0), _Nb); + if (__state) + __is.setstate(__state); return __is; } @@ -1247,6 +1219,11 @@ namespace std //@} } // namespace std -#undef _GLIBCPP_BITSET_WORDS +#undef _GLIBCXX_BITSET_WORDS +#undef _GLIBCXX_BITSET_BITS_PER_WORD + +#ifdef _GLIBCXX_DEBUG +# include <debug/bitset> +#endif -#endif /* _GLIBCPP_BITSET_H */ +#endif /* _GLIBCXX_BITSET */ diff --git a/contrib/libstdc++/include/std/std_complex.h b/contrib/libstdc++/include/std/std_complex.h index 252070b13895..e1027f65991f 100644 --- a/contrib/libstdc++/include/std/std_complex.h +++ b/contrib/libstdc++/include/std/std_complex.h @@ -1,6 +1,6 @@ // The template and inlines for the -*- C++ -*- complex number classes. -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -40,8 +40,8 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_COMPLEX -#define _CPP_COMPLEX 1 +#ifndef _GLIBCXX_COMPLEX +#define _GLIBCXX_COMPLEX 1 #pragma GCC system_header @@ -58,78 +58,135 @@ namespace std template<> class complex<double>; template<> class complex<long double>; + /// Return magnitude of @a z. template<typename _Tp> _Tp abs(const complex<_Tp>&); + /// Return phase angle of @a z. template<typename _Tp> _Tp arg(const complex<_Tp>&); + /// Return @a z magnitude squared. template<typename _Tp> _Tp norm(const complex<_Tp>&); + /// Return complex conjugate of @a z. template<typename _Tp> complex<_Tp> conj(const complex<_Tp>&); + /// Return complex with magnitude @a rho and angle @a theta. template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp& = 0); // Transcendentals: + /// Return complex cosine of @a z. template<typename _Tp> complex<_Tp> cos(const complex<_Tp>&); + /// Return complex hyperbolic cosine of @a z. template<typename _Tp> complex<_Tp> cosh(const complex<_Tp>&); + /// Return complex base e exponential of @a z. template<typename _Tp> complex<_Tp> exp(const complex<_Tp>&); + /// Return complex natural logarithm of @a z. template<typename _Tp> complex<_Tp> log(const complex<_Tp>&); + /// Return complex base 10 logarithm of @a z. template<typename _Tp> complex<_Tp> log10(const complex<_Tp>&); + /// Return complex cosine of @a z. template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, int); + /// Return @a x to the @a y'th power. template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const _Tp&); + /// Return @a x to the @a y'th power. template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const complex<_Tp>&); + /// Return @a x to the @a y'th power. template<typename _Tp> complex<_Tp> pow(const _Tp&, const complex<_Tp>&); + /// Return complex sine of @a z. template<typename _Tp> complex<_Tp> sin(const complex<_Tp>&); + /// Return complex hyperbolic sine of @a z. template<typename _Tp> complex<_Tp> sinh(const complex<_Tp>&); + /// Return complex square root of @a z. template<typename _Tp> complex<_Tp> sqrt(const complex<_Tp>&); + /// Return complex tangent of @a z. template<typename _Tp> complex<_Tp> tan(const complex<_Tp>&); + /// Return complex hyperbolic tangent of @a z. template<typename _Tp> complex<_Tp> tanh(const complex<_Tp>&); + //@} // 26.2.2 Primary template class complex + /** + * Template to represent complex numbers. + * + * Specializations for float, double, and long double are part of the + * library. Results with any other type are not guaranteed. + * + * @param Tp Type of real and imaginary values. + */ template<typename _Tp> class complex { public: + /// Value typedef. typedef _Tp value_type; + /// Default constructor. First parameter is x, second parameter is y. + /// Unspecified parameters default to 0. complex(const _Tp& = _Tp(), const _Tp & = _Tp()); - // Let's the compiler synthetize the copy constructor + // Lets the compiler synthesize the copy constructor // complex (const complex<_Tp>&); + /// Copy constructor. template<typename _Up> complex(const complex<_Up>&); - - _Tp real() const; - _Tp imag() const; + /// Return real part of complex number. + _Tp& real(); + /// Return real part of complex number. + const _Tp& real() const; + /// Return imaginary part of complex number. + _Tp& imag(); + /// Return imaginary part of complex number. + const _Tp& imag() const; + + /// Assign this complex number to scalar @a t. complex<_Tp>& operator=(const _Tp&); + /// Add @a t to this complex number. complex<_Tp>& operator+=(const _Tp&); + /// Subtract @a t from this complex number. complex<_Tp>& operator-=(const _Tp&); + /// Multiply this complex number by @a t. complex<_Tp>& operator*=(const _Tp&); + /// Divide this complex number by @a t. complex<_Tp>& operator/=(const _Tp&); - // Let's the compiler synthetize the + // Lets the compiler synthesize the // copy and assignment operator // complex<_Tp>& operator= (const complex<_Tp>&); + /// Assign this complex number to complex @a z. template<typename _Up> complex<_Tp>& operator=(const complex<_Up>&); + /// Add @a z to this complex number. template<typename _Up> complex<_Tp>& operator+=(const complex<_Up>&); + /// Subtract @a z from this complex number. template<typename _Up> complex<_Tp>& operator-=(const complex<_Up>&); + /// Multiply this complex number by @a z. template<typename _Up> complex<_Tp>& operator*=(const complex<_Up>&); + /// Divide this complex number by @a z. template<typename _Up> complex<_Tp>& operator/=(const complex<_Up>&); private: - _Tp _M_real, _M_imag; + _Tp _M_real; + _Tp _M_imag; }; template<typename _Tp> - inline _Tp + inline _Tp& + complex<_Tp>::real() { return _M_real; } + + template<typename _Tp> + inline const _Tp& complex<_Tp>::real() const { return _M_real; } template<typename _Tp> - inline _Tp + inline _Tp& + complex<_Tp>::imag() { return _M_imag; } + + template<typename _Tp> + inline const _Tp& complex<_Tp>::imag() const { return _M_imag; } template<typename _Tp> @@ -243,83 +300,147 @@ namespace std complex<_Tp>::operator/=(const complex<_Up>& __z) { const _Tp __r = _M_real * __z.real() + _M_imag * __z.imag(); - const _Tp __n = norm(__z); + const _Tp __n = std::norm(__z); _M_imag = (_M_imag * __z.real() - _M_real * __z.imag()) / __n; _M_real = __r / __n; return *this; } // Operators: + //@{ + /// Return new complex value @a x plus @a y. template<typename _Tp> inline complex<_Tp> operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) - { return complex<_Tp> (__x) += __y; } + { + complex<_Tp> __r = __x; + __r += __y; + return __r; + } template<typename _Tp> inline complex<_Tp> operator+(const complex<_Tp>& __x, const _Tp& __y) - { return complex<_Tp> (__x) += __y; } + { + complex<_Tp> __r = __x; + __r.real() += __y; + return __r; + } template<typename _Tp> inline complex<_Tp> operator+(const _Tp& __x, const complex<_Tp>& __y) - { return complex<_Tp> (__y) += __x; } + { + complex<_Tp> __r = __y; + __r.real() += __x; + return __r; + } + //@} + //@{ + /// Return new complex value @a x minus @a y. template<typename _Tp> inline complex<_Tp> operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) - { return complex<_Tp> (__x) -= __y; } + { + complex<_Tp> __r = __x; + __r -= __y; + return __r; + } template<typename _Tp> inline complex<_Tp> operator-(const complex<_Tp>& __x, const _Tp& __y) - { return complex<_Tp> (__x) -= __y; } + { + complex<_Tp> __r = __x; + __r.real() -= __y; + return __r; + } template<typename _Tp> inline complex<_Tp> operator-(const _Tp& __x, const complex<_Tp>& __y) - { return complex<_Tp> (__x) -= __y; } + { + complex<_Tp> __r(__x, -__y.imag()); + __r.real() -= __y.real(); + return __r; + } + //@} + //@{ + /// Return new complex value @a x times @a y. template<typename _Tp> inline complex<_Tp> operator*(const complex<_Tp>& __x, const complex<_Tp>& __y) - { return complex<_Tp> (__x) *= __y; } + { + complex<_Tp> __r = __x; + __r *= __y; + return __r; + } template<typename _Tp> inline complex<_Tp> operator*(const complex<_Tp>& __x, const _Tp& __y) - { return complex<_Tp> (__x) *= __y; } + { + complex<_Tp> __r = __x; + __r *= __y; + return __r; + } template<typename _Tp> inline complex<_Tp> operator*(const _Tp& __x, const complex<_Tp>& __y) - { return complex<_Tp> (__y) *= __x; } + { + complex<_Tp> __r = __y; + __r *= __x; + return __r; + } + //@} + //@{ + /// Return new complex value @a x divided by @a y. template<typename _Tp> inline complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y) - { return complex<_Tp> (__x) /= __y; } + { + complex<_Tp> __r = __x; + __r /= __y; + return __r; + } template<typename _Tp> inline complex<_Tp> operator/(const complex<_Tp>& __x, const _Tp& __y) - { return complex<_Tp> (__x) /= __y; } + { + complex<_Tp> __r = __x; + __r /= __y; + return __r; + } template<typename _Tp> inline complex<_Tp> operator/(const _Tp& __x, const complex<_Tp>& __y) - { return complex<_Tp> (__x) /= __y; } + { + complex<_Tp> __r = __x; + __r /= __y; + return __r; + } + //@} + /// Return @a x. template<typename _Tp> inline complex<_Tp> operator+(const complex<_Tp>& __x) { return __x; } + /// Return complex negation of @a x. template<typename _Tp> inline complex<_Tp> operator-(const complex<_Tp>& __x) { return complex<_Tp>(-__x.real(), -__x.imag()); } + //@{ + /// Return true if @a x is equal to @a y. template<typename _Tp> inline bool operator==(const complex<_Tp>& __x, const complex<_Tp>& __y) @@ -334,7 +455,10 @@ namespace std inline bool operator==(const _Tp& __x, const complex<_Tp>& __y) { return __x == __y.real() && _Tp() == __y.imag(); } + //@} + //@{ + /// Return false if @a x is equal to @a y. template<typename _Tp> inline bool operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) @@ -349,7 +473,9 @@ namespace std inline bool operator!=(const _Tp& __x, const complex<_Tp>& __y) { return __x != __y.real() || _Tp() != __y.imag(); } + //@} + /// Extraction operator for complex values. template<typename _Tp, typename _CharT, class _Traits> basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) @@ -369,7 +495,7 @@ namespace std __is.setstate(ios_base::failbit); } else if (__ch == ')') - __x = complex<_Tp>(__re_x, _Tp(0)); + __x = __re_x; else __is.setstate(ios_base::failbit); } @@ -377,11 +503,12 @@ namespace std { __is.putback(__ch); __is >> __re_x; - __x = complex<_Tp>(__re_x, _Tp(0)); + __x = __re_x; } return __is; } + /// Insertion operator for complex values. template<typename _Tp, typename _CharT, class _Traits> basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) @@ -396,12 +523,22 @@ namespace std // Values template<typename _Tp> - inline _Tp + inline _Tp& + real(complex<_Tp>& __z) + { return __z.real(); } + + template<typename _Tp> + inline const _Tp& real(const complex<_Tp>& __z) { return __z.real(); } template<typename _Tp> - inline _Tp + inline _Tp& + imag(complex<_Tp>& __z) + { return __z.imag(); } + + template<typename _Tp> + inline const _Tp& imag(const complex<_Tp>& __z) { return __z.imag(); } @@ -411,7 +548,7 @@ namespace std { _Tp __x = __z.real(); _Tp __y = __z.imag(); - const _Tp __s = max(abs(__x), abs(__y)); + const _Tp __s = std::max(abs(__x), abs(__y)); if (__s == _Tp()) // well ... return __s; __x /= __s; @@ -447,7 +584,7 @@ namespace std template<typename _Tp> static inline _Tp _S_do_it(const complex<_Tp>& __z) { - _Tp __res = abs(__z); + _Tp __res = std::abs(__z); return __res * __res; } }; @@ -456,7 +593,7 @@ namespace std inline _Tp norm(const complex<_Tp>& __z) { - return _Norm_helper<__is_floating<_Tp>::_M_type && !_GLIBCPP_FAST_MATH>::_S_do_it(__z); + return _Norm_helper<__is_floating<_Tp>::_M_type && !_GLIBCXX_FAST_MATH>::_S_do_it(__z); } template<typename _Tp> @@ -491,17 +628,17 @@ namespace std template<typename _Tp> inline complex<_Tp> exp(const complex<_Tp>& __z) - { return polar(exp(__z.real()), __z.imag()); } + { return std::polar(exp(__z.real()), __z.imag()); } template<typename _Tp> inline complex<_Tp> log(const complex<_Tp>& __z) - { return complex<_Tp>(log(abs(__z)), arg(__z)); } + { return complex<_Tp>(log(std::abs(__z)), std::arg(__z)); } template<typename _Tp> inline complex<_Tp> log10(const complex<_Tp>& __z) - { return log(__z) / log(_Tp(10.0)); } + { return std::log(__z) / log(_Tp(10.0)); } template<typename _Tp> inline complex<_Tp> @@ -535,7 +672,7 @@ namespace std } else { - _Tp __t = sqrt(2 * (abs(__z) + abs(__x))); + _Tp __t = sqrt(2 * (std::abs(__z) + abs(__x))); _Tp __u = __t / 2; return __x > _Tp() ? complex<_Tp>(__u, __y / __t) @@ -547,48 +684,48 @@ namespace std inline complex<_Tp> tan(const complex<_Tp>& __z) { - return sin(__z) / cos(__z); + return std::sin(__z) / std::cos(__z); } template<typename _Tp> inline complex<_Tp> tanh(const complex<_Tp>& __z) { - return sinh(__z) / cosh(__z); + return std::sinh(__z) / std::cosh(__z); } template<typename _Tp> inline complex<_Tp> pow(const complex<_Tp>& __z, int __n) { - return __pow_helper(__z, __n); + return std::__pow_helper(__z, __n); } template<typename _Tp> complex<_Tp> pow(const complex<_Tp>& __x, const _Tp& __y) { - if (__x.imag() == _Tp()) + if (__x.imag() == _Tp() && __x.real() > _Tp()) return pow(__x.real(), __y); - complex<_Tp> __t = log(__x); - return polar(exp(__y * __t.real()), __y * __t.imag()); + complex<_Tp> __t = std::log(__x); + return std::polar(exp(__y * __t.real()), __y * __t.imag()); } template<typename _Tp> inline complex<_Tp> pow(const complex<_Tp>& __x, const complex<_Tp>& __y) { - return __x == _Tp() ? _Tp() : exp(__y * log(__x)); + return __x == _Tp() ? _Tp() : std::exp(__y * std::log(__x)); } template<typename _Tp> inline complex<_Tp> pow(const _Tp& __x, const complex<_Tp>& __y) { - return __x == _Tp() - ? _Tp() - : polar(pow(__x, __y.real()), __y.imag() * log(__x)); + return __x > _Tp() ? std::polar(pow(__x, __y.real()), + __y.imag() * log(__x)) + : std::pow(complex<_Tp>(__x, _Tp()), __y); } // 26.2.3 complex specializations @@ -599,14 +736,16 @@ namespace std typedef float value_type; complex(float = 0.0f, float = 0.0f); -#ifdef _GLIBCPP_BUGGY_COMPLEX +#ifdef _GLIBCXX_BUGGY_COMPLEX complex(const complex& __z) : _M_value(__z._M_value) { } #endif explicit complex(const complex<double>&); explicit complex(const complex<long double>&); - float real() const; - float imag() const; + float& real(); + const float& real() const; + float& imag(); + const float& imag() const; complex<float>& operator=(float); complex<float>& operator+=(float); @@ -638,11 +777,19 @@ namespace std friend class complex<long double>; }; - inline float + inline float& + complex<float>::real() + { return __real__ _M_value; } + + inline const float& complex<float>::real() const { return __real__ _M_value; } - inline float + inline float& + complex<float>::imag() + { return __imag__ _M_value; } + + inline const float& complex<float>::imag() const { return __imag__ _M_value; } @@ -746,14 +893,16 @@ namespace std typedef double value_type; complex(double =0.0, double =0.0); -#ifdef _GLIBCPP_BUGGY_COMPLEX +#ifdef _GLIBCXX_BUGGY_COMPLEX complex(const complex& __z) : _M_value(__z._M_value) { } #endif complex(const complex<float>&); explicit complex(const complex<long double>&); - - double real() const; - double imag() const; + + double& real(); + const double& real() const; + double& imag(); + const double& imag() const; complex<double>& operator=(double); complex<double>& operator+=(double); @@ -784,11 +933,19 @@ namespace std friend class complex<long double>; }; - inline double + inline double& + complex<double>::real() + { return __real__ _M_value; } + + inline const double& complex<double>::real() const { return __real__ _M_value; } - inline double + inline double& + complex<double>::imag() + { return __imag__ _M_value; } + + inline const double& complex<double>::imag() const { return __imag__ _M_value; } @@ -892,14 +1049,16 @@ namespace std typedef long double value_type; complex(long double = 0.0L, long double = 0.0L); -#ifdef _GLIBCPP_BUGGY_COMPLEX +#ifdef _GLIBCXX_BUGGY_COMPLEX complex(const complex& __z) : _M_value(__z._M_value) { } #endif complex(const complex<float>&); complex(const complex<double>&); - long double real() const; - long double imag() const; + long double& real(); + const long double& real() const; + long double& imag(); + const long double& imag() const; complex<long double>& operator= (long double); complex<long double>& operator+= (long double); @@ -937,11 +1096,19 @@ namespace std __imag__ _M_value = __i; } - inline long double + inline long double& + complex<long double>::real() + { return __real__ _M_value; } + + inline const long double& complex<long double>::real() const { return __real__ _M_value; } - inline long double + inline long double& + complex<long double>::imag() + { return __imag__ _M_value; } + + inline const long double& complex<long double>::imag() const { return __imag__ _M_value; } @@ -1062,4 +1229,4 @@ namespace std : _M_value(_ComplexT(__z._M_value)) { } } // namespace std -#endif /* _CPP_COMPLEX */ +#endif /* _GLIBCXX_COMPLEX */ diff --git a/contrib/libstdc++/include/std/std_deque.h b/contrib/libstdc++/include/std/std_deque.h index 921c25fa4931..80817f632aa5 100644 --- a/contrib/libstdc++/include/std/std_deque.h +++ b/contrib/libstdc++/include/std/std_deque.h @@ -1,6 +1,6 @@ // <deque> -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,21 +58,24 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_DEQUE -#define _CPP_DEQUE 1 +#ifndef _GLIBCXX_DEQUE +#define _GLIBCXX_DEQUE 1 #pragma GCC system_header #include <bits/functexcept.h> #include <bits/stl_algobase.h> -#include <bits/stl_alloc.h> +#include <bits/allocator.h> #include <bits/stl_construct.h> #include <bits/stl_uninitialized.h> #include <bits/stl_deque.h> -#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT -# include <bits/deque.tcc> +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <bits/deque.tcc> #endif -#endif /* _CPP_DEQUE */ +#ifdef _GLIBCXX_DEBUG +# include <debug/deque> +#endif +#endif /* _GLIBCXX_DEQUE */ diff --git a/contrib/libstdc++/include/std/std_fstream.h b/contrib/libstdc++/include/std/std_fstream.h index bcbbb971946a..040f5798b11a 100644 --- a/contrib/libstdc++/include/std/std_fstream.h +++ b/contrib/libstdc++/include/std/std_fstream.h @@ -37,14 +37,15 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_FSTREAM -#define _CPP_FSTREAM 1 +#ifndef _GLIBCXX_FSTREAM +#define _GLIBCXX_FSTREAM 1 #pragma GCC system_header #include <istream> #include <ostream> #include <locale> // For codecvt +#include <cstdio> // For SEEK_SET, SEEK_CUR, SEEK_END, BUFSIZ #include <bits/basic_file.h> #include <bits/gthr.h> @@ -59,6 +60,11 @@ namespace std * sequences. Many of its sematics are described in terms of similar * behavior in the Standard C Library's @c FILE streams. */ + // Requirements on traits_type, specific to this class: + // traits_type::pos_type must be fpos<traits_type::state_type> + // traits_type::off_type must be streamoff + // traits_type::state_type must be Assignable and DefaultConstructable, + // and traits_type::state_type() must be the initial state for codecvt. template<typename _CharT, typename _Traits> class basic_filebuf : public basic_streambuf<_CharT, _Traits> { @@ -81,7 +87,6 @@ namespace std typedef __basic_file<char> __file_type; typedef typename traits_type::state_type __state_type; typedef codecvt<char_type, char, __state_type> __codecvt_type; - typedef ctype<char_type> __ctype_type; //@} friend class ios_base; // For sync_with_stdio. @@ -104,15 +109,56 @@ namespace std */ __file_type _M_file; - // Current and beginning state type for codecvt. + /** + * @if maint + * Place to stash in || out || in | out settings for current filebuf. + * @endif + */ + ios_base::openmode _M_mode; + + // Beginning state type for codecvt. /** * @if maint * @doctodo * @endif */ - __state_type _M_state_cur; __state_type _M_state_beg; + // During output, the state that corresponds to pptr(), + // during input, the state that corresponds to egptr() and + // _M_ext_next. + /** + * @if maint + * @doctodo + * @endif + */ + __state_type _M_state_cur; + + // Not used for output. During input, the state that corresponds + // to eback() and _M_ext_buf. + /** + * @if maint + * @doctodo + * @endif + */ + __state_type _M_state_last; + + /** + * @if maint + * Pointer to the beginning of internal buffer. + * @endif + */ + char_type* _M_buf; + + /** + * @if maint + * Actual size of internal buffer. This number is equal to the size + * of the put area + 1 position, reserved for the overflow char of + * a full area. + * @endif + */ + size_t _M_buf_size; + // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer. /** * @if maint @@ -120,18 +166,99 @@ namespace std * @endif */ bool _M_buf_allocated; - - // XXX Needed? - bool _M_last_overflowed; - // The position in the buffer corresponding to the external file - // pointer. /** * @if maint - * @doctodo + * _M_reading == false && _M_writing == false for 'uncommitted' mode; + * _M_reading == true for 'read' mode; + * _M_writing == true for 'write' mode; + * + * NB: _M_reading == true && _M_writing == true is unused. + * @endif + */ + bool _M_reading; + bool _M_writing; + + //@{ + /** + * @if maint + * Necessary bits for putback buffer management. + * + * @note pbacks of over one character are not currently supported. * @endif */ - char_type* _M_filepos; + char_type _M_pback; + char_type* _M_pback_cur_save; + char_type* _M_pback_end_save; + bool _M_pback_init; + //@} + + // Cached codecvt facet. + const __codecvt_type* _M_codecvt; + + /** + * @if maint + * Buffer for external characters. Used for input when + * codecvt::always_noconv() == false. When valid, this corresponds + * to eback(). + * @endif + */ + char* _M_ext_buf; + + /** + * @if maint + * Size of buffer held by _M_ext_buf. + * @endif + */ + streamsize _M_ext_buf_size; + + /** + * @if maint + * Pointers into the buffer held by _M_ext_buf that delimit a + * subsequence of bytes that have been read but not yet converted. + * When valid, _M_ext_next corresponds to egptr(). + * @endif + */ + const char* _M_ext_next; + char* _M_ext_end; + + /** + * @if maint + * Initializes pback buffers, and moves normal buffers to safety. + * Assumptions: + * _M_in_cur has already been moved back + * @endif + */ + void + _M_create_pback() + { + if (!_M_pback_init) + { + _M_pback_cur_save = this->gptr(); + _M_pback_end_save = this->egptr(); + this->setg(&_M_pback, &_M_pback, &_M_pback + 1); + _M_pback_init = true; + } + } + + /** + * @if maint + * Deactivates pback buffer contents, and restores normal buffer. + * Assumptions: + * The pback buffer has only moved forward. + * @endif + */ + void + _M_destroy_pback() throw() + { + if (_M_pback_init) + { + // Length _M_in_cur moved in the pback buffer. + _M_pback_cur_save += this->gptr() != this->eback(); + this->setg(this->_M_buf, _M_pback_cur_save, _M_pback_end_save); + _M_pback_init = false; + } + } public: // Constructors/destructor: @@ -148,10 +275,7 @@ namespace std */ virtual ~basic_filebuf() - { - this->close(); - _M_last_overflowed = false; - } + { this->close(); } // Members: /** @@ -217,45 +341,14 @@ namespace std // charater from the real input source when the buffer is empty. // Buffered input uses underflow() - // The only difference between underflow() and uflow() is that the - // latter bumps _M_in_cur after the read. In the sync_with_stdio - // case, this is important, as we need to unget the read character in - // the underflow() case in order to maintain synchronization. So - // instead of calling underflow() from uflow(), we create a common - // subroutine to do the real work. - /** - * @if maint - * @doctodo - * @endif - */ - int_type - _M_underflow_common(bool __bump); - // [documentation is inherited] virtual int_type underflow(); // [documentation is inherited] virtual int_type - uflow(); - - // [documentation is inherited] - virtual int_type pbackfail(int_type __c = _Traits::eof()); - // NB: For what the standard expects of the overflow function, - // see _M_really_overflow(), below. Because basic_streambuf's - // sputc/sputn call overflow directly, and the complications of - // this implementation's setting of the initial pointers all - // equal to _M_buf when initializing, it seems essential to have - // this in actuality be a helper function that checks for the - // eccentricities of this implementation, and then call - // overflow() if indeed the buffer is full. - - // [documentation is inherited] - virtual int_type - overflow(int_type __c = _Traits::eof()); - // Stroustrup, 1998, p 648 // The overflow() function is called to transfer characters to the // real output destination when the buffer is full. A call to @@ -268,8 +361,8 @@ namespace std * @doctodo * @endif */ - int_type - _M_really_overflow(int_type __c = _Traits::eof()); + virtual int_type + overflow(int_type __c = _Traits::eof()); // Convert internal byte sequence to external, char-based // sequence via codecvt. @@ -278,8 +371,8 @@ namespace std * @doctodo * @endif */ - void - _M_convert_to_external(char_type*, streamsize, streamsize&, streamsize&); + bool + _M_convert_to_external(char_type*, streamsize); /** * @brief Manipulates the buffer. @@ -306,33 +399,18 @@ namespace std seekpos(pos_type __pos, ios_base::openmode __mode = ios_base::in | ios_base::out); + // Common code for seekoff and seekpos + /** + * @if maint + * @doctodo + * @endif + */ + pos_type + _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state); + // [documentation is inherited] virtual int - sync() - { - int __ret = 0; - bool __testput = _M_out_cur && _M_out_beg < _M_out_end; - - // Make sure that the internal buffer resyncs its idea of - // the file position with the external file. - if (__testput) - { - // Need to restore current position after the write. - off_type __off = _M_out_cur - _M_out_end; - - // _M_file.sync() will be called within - if (traits_type::eq_int_type(_M_really_overflow(), - traits_type::eof())) - __ret = -1; - else if (__off) - _M_file.seekoff(__off, ios_base::cur); - } - else - _M_file.sync(); - - _M_last_overflowed = false; - return __ret; - } + sync(); // [documentation is inherited] virtual void @@ -342,18 +420,17 @@ namespace std virtual streamsize xsgetn(char_type* __s, streamsize __n) { - streamsize __ret = 0; // Clear out pback buffer before going on to the real deal... - if (_M_pback_init) + streamsize __ret = 0; + if (this->_M_pback_init) { - while (__ret < __n && _M_in_cur < _M_in_end) + if (__n && this->gptr() == this->eback()) { - *__s = *_M_in_cur; - ++__ret; - ++__s; - ++_M_in_cur; + *__s++ = *this->gptr(); + this->gbump(1); + __ret = 1; } - _M_pback_destroy(); + _M_destroy_pback(); } if (__ret < __n) __ret += __streambuf_type::xsgetn(__s, __n - __ret); @@ -362,103 +439,49 @@ namespace std // [documentation is inherited] virtual streamsize - xsputn(const char_type* __s, streamsize __n) - { - _M_pback_destroy(); - return __streambuf_type::xsputn(__s, __n); - } + xsputn(const char_type* __s, streamsize __n); + // Flushes output buffer, then writes unshift sequence. /** * @if maint * @doctodo * @endif */ - void - _M_output_unshift(); - - // These three functions are used to clarify internal buffer - // maintenance. After an overflow, or after a seekoff call that - // started at beg or end, or possibly when the stream becomes - // unbuffered, and a myrid other obscure corner cases, the - // internal buffer does not truly reflect the contents of the - // external buffer. At this point, for whatever reason, it is in - // an indeterminate state. - /** - * @if maint - * @doctodo - * @endif - */ - void - _M_set_indeterminate(void) - { - if (_M_mode & ios_base::in) - this->setg(_M_buf, _M_buf, _M_buf); - if (_M_mode & ios_base::out) - this->setp(_M_buf, _M_buf); - _M_filepos = _M_buf; - } + bool + _M_terminate_output(); /** - * @if maint - * @doctodo + * @if maint + * This function sets the pointers of the internal buffer, both get + * and put areas. Typically: + * + * __off == egptr() - eback() upon underflow/uflow ('read' mode); + * __off == 0 upon overflow ('write' mode); + * __off == -1 upon open, setbuf, seekoff/pos ('uncommitted' mode). + * + * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size + * reflects the actual allocated memory and the last cell is reserved + * for the overflow char of a full put area. * @endif */ void - _M_set_determinate(off_type __off) + _M_set_buffer(streamsize __off) { - bool __testin = _M_mode & ios_base::in; - bool __testout = _M_mode & ios_base::out; - if (__testin) - this->setg(_M_buf, _M_buf, _M_buf + __off); - if (__testout) - this->setp(_M_buf, _M_buf + __off); - _M_filepos = _M_buf + __off; - } + const bool __testin = this->_M_mode & ios_base::in; + const bool __testout = this->_M_mode & ios_base::out; + + if (__testin && __off > 0) + this->setg(this->_M_buf, this->_M_buf, this->_M_buf + __off); + else + this->setg(this->_M_buf, this->_M_buf, this->_M_buf); - /** - * @if maint - * @doctodo - * @endif - */ - bool - _M_is_indeterminate(void) - { - bool __ret = false; - // Don't return true if unbuffered. - if (_M_buf) - { - if (_M_mode & ios_base::in) - __ret = _M_in_beg == _M_in_cur && _M_in_cur == _M_in_end; - if (_M_mode & ios_base::out) - __ret = _M_out_beg == _M_out_cur && _M_out_cur == _M_out_end; - } - return __ret; + if (__testout && __off == 0 && this->_M_buf_size > 1 ) + this->setp(this->_M_buf, this->_M_buf + this->_M_buf_size - 1); + else + this->setp(NULL, NULL); } }; - // Explicit specialization declarations, defined in src/fstream.cc. - template<> - basic_filebuf<char>::int_type - basic_filebuf<char>::_M_underflow_common(bool __bump); - - #ifdef _GLIBCPP_USE_WCHAR_T - template<> - basic_filebuf<wchar_t>::int_type - basic_filebuf<wchar_t>::_M_underflow_common(bool __bump); - #endif - - // Generic definitions. - template <typename _CharT, typename _Traits> - typename basic_filebuf<_CharT, _Traits>::int_type - basic_filebuf<_CharT, _Traits>::underflow() - { return _M_underflow_common(false); } - - template <typename _CharT, typename _Traits> - typename basic_filebuf<_CharT, _Traits>::int_type - basic_filebuf<_CharT, _Traits>::uflow() - { return _M_underflow_common(true); } - - // [27.8.1.5] Template class basic_ifstream /** * @brief Controlling input for files. @@ -500,8 +523,7 @@ namespace std * @c &sb to the base class initializer. Does not open any files * (you haven't given it a filename to open). */ - basic_ifstream() - : __istream_type(NULL), _M_filebuf() + basic_ifstream() : __istream_type(), _M_filebuf() { this->init(&_M_filebuf); } /** @@ -516,7 +538,7 @@ namespace std */ explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in) - : __istream_type(NULL), _M_filebuf() + : __istream_type(), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); @@ -623,8 +645,7 @@ namespace std * @c &sb to the base class initializer. Does not open any files * (you haven't given it a filename to open). */ - basic_ofstream() - : __ostream_type(NULL), _M_filebuf() + basic_ofstream(): __ostream_type(), _M_filebuf() { this->init(&_M_filebuf); } /** @@ -641,7 +662,7 @@ namespace std explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out|ios_base::trunc) - : __ostream_type(NULL), _M_filebuf() + : __ostream_type(), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); @@ -751,7 +772,7 @@ namespace std * (you haven't given it a filename to open). */ basic_fstream() - : __iostream_type(NULL), _M_filebuf() + : __iostream_type(), _M_filebuf() { this->init(&_M_filebuf); } /** @@ -814,7 +835,7 @@ namespace std ios_base::openmode __mode = ios_base::in | ios_base::out) { if (!_M_filebuf.open(__s, __mode)) - setstate(ios_base::failbit); + this->setstate(ios_base::failbit); } /** @@ -827,16 +848,13 @@ namespace std close() { if (!_M_filebuf.close()) - setstate(ios_base::failbit); + this->setstate(ios_base::failbit); } }; } // namespace std -#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT -# define export -#endif -#ifdef _GLIBCPP_FULLY_COMPLIANT_HEADERS +#ifndef _GLIBCXX_EXPORT_TEMPLATE # include <bits/fstream.tcc> #endif -#endif +#endif /* _GLIBCXX_FSTREAM */ diff --git a/contrib/libstdc++/include/std/std_functional.h b/contrib/libstdc++/include/std/std_functional.h index 40080d95579d..6819f20b6f0f 100644 --- a/contrib/libstdc++/include/std/std_functional.h +++ b/contrib/libstdc++/include/std/std_functional.h @@ -46,17 +46,13 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_FUNCTIONAL -#define _CPP_FUNCTIONAL 1 +#ifndef _GLIBCXX_FUNCTIONAL +#define _GLIBCXX_FUNCTIONAL 1 #pragma GCC system_header + #include <bits/c++config.h> #include <cstddef> #include <bits/stl_function.h> -#endif /* _CPP_FUNCTIONAL */ - -// Local Variables: -// mode:C++ -// End: - +#endif /* _GLIBCXX_FUNCTIONAL */ diff --git a/contrib/libstdc++/include/std/std_iomanip.h b/contrib/libstdc++/include/std/std_iomanip.h index 490d5ac1cfba..0d965c28bf95 100644 --- a/contrib/libstdc++/include/std/std_iomanip.h +++ b/contrib/libstdc++/include/std/std_iomanip.h @@ -37,8 +37,8 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_IOMANIP -#define _CPP_IOMANIP 1 +#ifndef _GLIBCXX_IOMANIP +#define _GLIBCXX_IOMANIP 1 #pragma GCC system_header @@ -266,7 +266,7 @@ namespace std // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. -#if _GLIBCPP_EXTERN_TEMPLATE +#if _GLIBCXX_EXTERN_TEMPLATE extern template ostream& operator<<(ostream&, _Setfill<char>); extern template ostream& operator<<(ostream&, _Setiosflags); extern template ostream& operator<<(ostream&, _Resetiosflags); @@ -280,7 +280,7 @@ namespace std extern template istream& operator>>(istream&, _Setprecision); extern template istream& operator>>(istream&, _Setw); -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T extern template wostream& operator<<(wostream&, _Setfill<wchar_t>); extern template wostream& operator<<(wostream&, _Setiosflags); extern template wostream& operator<<(wostream&, _Resetiosflags); @@ -297,4 +297,4 @@ namespace std #endif } // namespace std -#endif +#endif /* _GLIBCXX_IOMANIP */ diff --git a/contrib/libstdc++/include/std/std_ios.h b/contrib/libstdc++/include/std/std_ios.h index a7764c89cdd0..596458f1ede4 100644 --- a/contrib/libstdc++/include/std/std_ios.h +++ b/contrib/libstdc++/include/std/std_ios.h @@ -36,8 +36,8 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_IOS -#define _CPP_IOS 1 +#ifndef _GLIBCXX_IOS +#define _GLIBCXX_IOS 1 #pragma GCC system_header @@ -50,5 +50,4 @@ #include <streambuf> #include <bits/basic_ios.h> -#endif /* _CPP_IOS */ - +#endif /* _GLIBCXX_IOS */ diff --git a/contrib/libstdc++/include/std/std_iosfwd.h b/contrib/libstdc++/include/std/std_iosfwd.h index 55b0e0b19fa7..050b9e8bab72 100644 --- a/contrib/libstdc++/include/std/std_iosfwd.h +++ b/contrib/libstdc++/include/std/std_iosfwd.h @@ -37,16 +37,17 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_IOSFWD -#define _CPP_IOSFWD 1 +#ifndef _GLIBCXX_IOSFWD +#define _GLIBCXX_IOSFWD 1 #pragma GCC system_header #include <bits/c++config.h> #include <bits/c++locale.h> +#include <bits/c++io.h> #include <cctype> // For isspace, etc. #include <bits/stringfwd.h> // For string forward declarations. -#include <bits/fpos.h> +#include <bits/postypes.h> #include <bits/functexcept.h> namespace std @@ -100,10 +101,9 @@ namespace std template<typename _CharT, typename _Traits = char_traits<_CharT> > class ostreambuf_iterator; -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS + // _GLIBCXX_RESOLVE_LIB_DEFECTS // Not included. (??? Apparently no LWG number?) class ios_base; -#endif /** * @defgroup s27_2_iosfwd I/O Forward Declarations @@ -147,7 +147,7 @@ namespace std typedef basic_ofstream<char> ofstream; ///< @isiosfwd typedef basic_fstream<char> fstream; ///< @isiosfwd -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T typedef basic_ios<wchar_t> wios; ///< @isiosfwd typedef basic_streambuf<wchar_t> wstreambuf; ///< @isiosfwd typedef basic_istream<wchar_t> wistream; ///< @isiosfwd @@ -165,4 +165,4 @@ namespace std /** @} */ } // namespace std -#endif +#endif /* _GLIBCXX_IOSFWD */ diff --git a/contrib/libstdc++/include/std/std_iostream.h b/contrib/libstdc++/include/std/std_iostream.h index d70949377df1..f5049db4a911 100644 --- a/contrib/libstdc++/include/std/std_iostream.h +++ b/contrib/libstdc++/include/std/std_iostream.h @@ -36,8 +36,8 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_IOSTREAM -#define _CPP_IOSTREAM 1 +#ifndef _GLIBCXX_IOSTREAM +#define _GLIBCXX_IOSTREAM 1 #pragma GCC system_header @@ -65,7 +65,7 @@ namespace std extern ostream cerr; ///< Linked to standard error (unbuffered) extern ostream clog; ///< Linked to standard error (buffered) -#ifdef _GLIBCPP_USE_WCHAR_T +#ifdef _GLIBCXX_USE_WCHAR_T extern wistream wcin; ///< Linked to standard input extern wostream wcout; ///< Linked to standard output extern wostream wcerr; ///< Linked to standard error (unbuffered) @@ -77,4 +77,4 @@ namespace std static ios_base::Init __ioinit; } // namespace std -#endif +#endif /* _GLIBCXX_IOSTREAM */ diff --git a/contrib/libstdc++/include/std/std_istream.h b/contrib/libstdc++/include/std/std_istream.h index da9c7db18838..a3a53ba73f6e 100644 --- a/contrib/libstdc++/include/std/std_istream.h +++ b/contrib/libstdc++/include/std/std_istream.h @@ -1,6 +1,7 @@ // Input streams -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003 +// Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -36,8 +37,8 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_ISTREAM -#define _CPP_ISTREAM 1 +#ifndef _GLIBCXX_ISTREAM +#define _GLIBCXX_ISTREAM 1 #pragma GCC system_header @@ -69,8 +70,8 @@ namespace std typedef basic_streambuf<_CharT, _Traits> __streambuf_type; typedef basic_ios<_CharT, _Traits> __ios_type; typedef basic_istream<_CharT, _Traits> __istream_type; - typedef istreambuf_iterator<_CharT, _Traits> __istreambuf_iter; - typedef num_get<_CharT, __istreambuf_iter> __numget_type; + typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> > + __num_get_type; typedef ctype<_CharT> __ctype_type; template<typename _CharT2, typename _Traits2> @@ -101,11 +102,8 @@ namespace std * their own stream buffer. */ explicit - basic_istream(__streambuf_type* __sb) - { - this->init(__sb); - _M_gcount = streamsize(0); - } + basic_istream(__streambuf_type* __sb): _M_gcount(streamsize(0)) + { this->init(__sb); } /** * @brief Base destructor. @@ -130,13 +128,13 @@ namespace std * functions in constructs like "std::cin >> std::ws". For more * information, see the iomanip header. */ - __istream_type& + inline __istream_type& operator>>(__istream_type& (*__pf)(__istream_type&)); - __istream_type& + inline __istream_type& operator>>(__ios_type& (*__pf)(__ios_type&)); - __istream_type& + inline __istream_type& operator>>(ios_base& (*__pf)(ios_base&)); //@} @@ -189,7 +187,7 @@ namespace std __istream_type& operator>>(unsigned long& __n); -#ifdef _GLIBCPP_USE_LONG_LONG +#ifdef _GLIBCXX_USE_LONG_LONG __istream_type& operator>>(long long& __n); @@ -214,7 +212,7 @@ namespace std * @param sb A pointer to a streambuf * * This function behaves like one of the basic arithmetic extractors, - * in that it also constructs a sentry onject and has the same error + * in that it also constructs a sentry object and has the same error * handling behavior. * * If @a sb is NULL, the stream will set failbit in its error state. @@ -560,6 +558,10 @@ namespace std __istream_type& seekg(off_type, ios_base::seekdir); //@} + + protected: + explicit + basic_istream(): _M_gcount(streamsize(0)) { } }; /** @@ -615,7 +617,7 @@ namespace std * For ease of use, sentries may be converted to booleans. The * return value is that of the sentry state (true == okay). */ - operator bool() { return _M_ok; } + operator bool() const { return _M_ok; } private: bool _M_ok; @@ -703,15 +705,14 @@ namespace std public basic_ostream<_CharT, _Traits> { public: -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -// 271. basic_iostream missing typedefs + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 271. basic_iostream missing typedefs // Types (inherited): typedef _CharT char_type; typedef typename _Traits::int_type int_type; typedef typename _Traits::pos_type pos_type; typedef typename _Traits::off_type off_type; typedef _Traits traits_type; -#endif // Non-standard Types: typedef basic_istream<_CharT, _Traits> __istream_type; @@ -725,14 +726,19 @@ namespace std */ explicit basic_iostream(basic_streambuf<_CharT, _Traits>* __sb) - : __istream_type(__sb), __ostream_type(__sb) - { } + : __istream_type(), __ostream_type() + { this->init(__sb); } /** * @brief Destructor does nothing. */ virtual ~basic_iostream() { } + + protected: + explicit + basic_iostream() : __istream_type(), __ostream_type() + { } }; // [27.6.1.4] standard basic_istream manipulators @@ -761,11 +767,8 @@ namespace std ws(basic_istream<_CharT, _Traits>& __is); } // namespace std -#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT -# define export -#endif -#ifdef _GLIBCPP_FULLY_COMPLIANT_HEADERS +#ifndef _GLIBCXX_EXPORT_TEMPLATE # include <bits/istream.tcc> #endif -#endif /* _CPP_ISTREAM */ +#endif /* _GLIBCXX_ISTREAM */ diff --git a/contrib/libstdc++/include/std/std_iterator.h b/contrib/libstdc++/include/std/std_iterator.h index 7b1709409b15..6e3840b1e7e3 100644 --- a/contrib/libstdc++/include/std/std_iterator.h +++ b/contrib/libstdc++/include/std/std_iterator.h @@ -58,10 +58,11 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_ITERATOR -#define _CPP_ITERATOR 1 +#ifndef _GLIBCXX_ITERATOR +#define _GLIBCXX_ITERATOR 1 #pragma GCC system_header + #include <bits/c++config.h> #include <cstddef> #include <bits/stl_iterator_base_types.h> @@ -72,8 +73,4 @@ #include <bits/stream_iterator.h> #include <bits/streambuf_iterator.h> -#endif /* _CPP_ITERATOR */ - -// Local Variables: -// mode:C++ -// End: +#endif /* _GLIBCXX_ITERATOR */ diff --git a/contrib/libstdc++/include/std/std_limits.h b/contrib/libstdc++/include/std/std_limits.h index 9be69477958f..7f96647f95de 100644 --- a/contrib/libstdc++/include/std/std_limits.h +++ b/contrib/libstdc++/include/std/std_limits.h @@ -1,6 +1,6 @@ // The template and inlines for the -*- C++ -*- numeric_limits classes. -// Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -40,8 +40,8 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_NUMERIC_LIMITS -#define _CPP_NUMERIC_LIMITS 1 +#ifndef _GLIBCXX_NUMERIC_LIMITS +#define _GLIBCXX_NUMERIC_LIMITS 1 #pragma GCC system_header @@ -82,8 +82,8 @@ // GCC only intrinsicly supports modulo integral types. The only remaining // integral exceptional values is division by zero. Only targets that do not // signal division by zero in some "hard to ignore" way should use false. -#ifndef __glibcpp_integral_traps -# define __glibcpp_integral_traps true +#ifndef __glibcxx_integral_traps +# define __glibcxx_integral_traps true #endif // float @@ -91,124 +91,220 @@ // Default values. Should be overriden in configuration files if necessary. -#ifndef __glibcpp_float_has_denorm_loss -# define __glibcpp_float_has_denorm_loss false +#ifndef __glibcxx_float_has_denorm_loss +# define __glibcxx_float_has_denorm_loss false #endif -#ifndef __glibcpp_float_traps -# define __glibcpp_float_traps false +#ifndef __glibcxx_float_traps +# define __glibcxx_float_traps false #endif -#ifndef __glibcpp_float_tinyness_before -# define __glibcpp_float_tinyness_before false +#ifndef __glibcxx_float_tinyness_before +# define __glibcxx_float_tinyness_before false #endif // double // Default values. Should be overriden in configuration files if necessary. -#ifndef __glibcpp_double_has_denorm_loss -# define __glibcpp_double_has_denorm_loss false +#ifndef __glibcxx_double_has_denorm_loss +# define __glibcxx_double_has_denorm_loss false #endif -#ifndef __glibcpp_double_traps -# define __glibcpp_double_traps false +#ifndef __glibcxx_double_traps +# define __glibcxx_double_traps false #endif -#ifndef __glibcpp_double_tinyness_before -# define __glibcpp_double_tinyness_before false +#ifndef __glibcxx_double_tinyness_before +# define __glibcxx_double_tinyness_before false #endif // long double // Default values. Should be overriden in configuration files if necessary. -#ifndef __glibcpp_long_double_has_denorm_loss -# define __glibcpp_long_double_has_denorm_loss false +#ifndef __glibcxx_long_double_has_denorm_loss +# define __glibcxx_long_double_has_denorm_loss false #endif -#ifndef __glibcpp_long_double_traps -# define __glibcpp_long_double_traps false +#ifndef __glibcxx_long_double_traps +# define __glibcxx_long_double_traps false #endif -#ifndef __glibcpp_long_double_tinyness_before -# define __glibcpp_long_double_tinyness_before false +#ifndef __glibcxx_long_double_tinyness_before +# define __glibcxx_long_double_tinyness_before false #endif // You should not need to define any macros below this point. -#define __glibcpp_signed(T) ((T)(-1) < 0) +#define __glibcxx_signed(T) ((T)(-1) < 0) -#define __glibcpp_min(T) \ - (__glibcpp_signed (T) ? (T)1 << __glibcpp_digits (T) : (T)0) +#define __glibcxx_min(T) \ + (__glibcxx_signed (T) ? (T)1 << __glibcxx_digits (T) : (T)0) -#define __glibcpp_max(T) \ - (__glibcpp_signed (T) ? ((T)1 << __glibcpp_digits (T)) - 1 : ~(T)0) +#define __glibcxx_max(T) \ + (__glibcxx_signed (T) ? ((T)1 << __glibcxx_digits (T)) - 1 : ~(T)0) -#define __glibcpp_digits(T) \ - (sizeof(T) * __CHAR_BIT__ - __glibcpp_signed (T)) +#define __glibcxx_digits(T) \ + (sizeof(T) * __CHAR_BIT__ - __glibcxx_signed (T)) // The fraction 643/2136 approximates log10(2) to 7 significant digits. -#define __glibcpp_digits10(T) \ - (__glibcpp_digits (T) * 643 / 2136) +#define __glibcxx_digits10(T) \ + (__glibcxx_digits (T) * 643 / 2136) namespace std { + /** + * @brief Describes the rounding style for floating-point types. + * + * This is used in the std::numeric_limits class. + */ enum float_round_style { - round_indeterminate = -1, - round_toward_zero = 0, - round_to_nearest = 1, - round_toward_infinity = 2, - round_toward_neg_infinity = 3 + round_indeterminate = -1, ///< Self-explanatory. + round_toward_zero = 0, ///< Self-explanatory. + round_to_nearest = 1, ///< To the nearest representable value. + round_toward_infinity = 2, ///< Self-explanatory. + round_toward_neg_infinity = 3 ///< Self-explanatory. }; + /** + * @brief Describes the denormalization for floating-point types. + * + * These values represent the presence or absence of a variable number + * of exponent bits. This type is used in the std::numeric_limits class. + */ enum float_denorm_style { + /// Indeterminate at compile time whether denormalized values are allowed. denorm_indeterminate = -1, + /// The type does not allow denormalized values. denorm_absent = 0, + /// The type allows denormalized values. denorm_present = 1 }; - // - // The primary class traits - // + /** + * @brief Part of std::numeric_limits. + * + * The @c static @c const members are usable as integral constant + * expressions. + * + * @note This is a seperate class for purposes of efficiency; you + * should only access these members as part of an instantiation + * of the std::numeric_limits class. + */ struct __numeric_limits_base { + /** This will be true for all fundamental types (which have + specializations), and false for everything else. */ static const bool is_specialized = false; + /** The number of @c radix digits that be represented without change: for + integer types, the number of non-sign bits in the mantissa; for + floating types, the number of @c radix digits in the mantissa. */ static const int digits = 0; + /** The number of base 10 digits that can be represented without change. */ static const int digits10 = 0; + /** True if the type is signed. */ static const bool is_signed = false; + /** True if the type is integer. + * @if maint + * Is this supposed to be "if the type is integral"? + * @endif + */ static const bool is_integer = false; + /** True if the type uses an exact representation. "All integer types are + exact, but not all exact types are integer. For example, rational and + fixed-exponent representations are exact but not integer." + [18.2.1.2]/15 */ static const bool is_exact = false; + /** For integer types, specifies the base of the representation. For + floating types, specifies the base of the exponent representation. */ static const int radix = 0; + /** The minimum negative integer such that @c radix raised to the power of + (one less than that integer) is a normalized floating point number. */ static const int min_exponent = 0; + /** The minimum negative integer such that 10 raised to that power is in + the range of normalized floating point numbers. */ static const int min_exponent10 = 0; + /** The maximum positive integer such that @c radix raised to the power of + (one less than that integer) is a representable finite floating point + number. */ static const int max_exponent = 0; + /** The maximum positive integer such that 10 raised to that power is in + the range of representable finite floating point numbers. */ static const int max_exponent10 = 0; + /** True if the type has a representation for positive infinity. */ static const bool has_infinity = false; + /** True if the type has a representation for a quiet (non-signaling) + "Not a Number." */ static const bool has_quiet_NaN = false; + /** True if the type has a representation for a signaling + "Not a Number." */ static const bool has_signaling_NaN = false; + /** See std::float_denorm_style for more information. */ static const float_denorm_style has_denorm = denorm_absent; + /** "True if loss of accuracy is detected as a denormalization loss, + rather than as an inexact result." [18.2.1.2]/42 */ static const bool has_denorm_loss = false; + /** True if-and-only-if the type adheres to the IEC 559 standard, also + known as IEEE 754. (Only makes sense for floating point types.) */ static const bool is_iec559 = false; + /** "True if the set of values representable by the type is finite. All + built-in types are bounded, this member would be false for arbitrary + precision types." [18.2.1.2]/54 */ static const bool is_bounded = false; + /** True if the type is @e modulo, that is, if it is possible to add two + positive numbers and have a result that wraps around to a third number + that is less. Typically false for floating types, true for unsigned + integers, and true for signed integers. */ static const bool is_modulo = false; + /** True if trapping is implemented for this type. */ static const bool traps = false; + /** True if tinyness is detected before rounding. (see IEC 559) */ static const bool tinyness_before = false; + /** See std::float_round_style for more information. This is only + meaningful for floating types; integer types will all be + round_toward_zero. */ static const float_round_style round_style = round_toward_zero; }; + /** + * @brief Properties of fundamental types. + * + * This class allows a program to obtain information about the + * representation of a fundamental type on a given platform. For + * non-fundamental types, the functions will return 0 and the data + * members will all be @c false. + * + * @if maint + * _GLIBCXX_RESOLVE_LIB_DEFECTS: DRs 201 and 184 (hi Gaby!) are + * noted, but not incorporated in this documented (yet). + * @endif + */ template<typename _Tp> struct numeric_limits : public __numeric_limits_base { + /** The minimum finite value, or for floating types with + denormalization, the minimum positive normalized value. */ static _Tp min() throw() { return static_cast<_Tp>(0); } + /** The maximum finite value. */ static _Tp max() throw() { return static_cast<_Tp>(0); } + /** The @e machine @e epsilon: the difference between 1 and the least + value greater than 1 that is representable. */ static _Tp epsilon() throw() { return static_cast<_Tp>(0); } + /** The maximum rounding error measurement (see LIA-1). */ static _Tp round_error() throw() { return static_cast<_Tp>(0); } + /** The representation of positive infinity, if @c has_infinity. */ static _Tp infinity() throw() { return static_cast<_Tp>(0); } + /** The representation of a quiet "Not a Number," if @c has_quiet_NaN. */ static _Tp quiet_NaN() throw() { return static_cast<_Tp>(0); } + /** The representation of a signaling "Not a Number," if + @c has_signaling_NaN. */ static _Tp signaling_NaN() throw() { return static_cast<_Tp>(0); } + /** The minimum positive denormalized value. For types where + @c has_denorm is false, this is the minimum positive normalized + value. */ static _Tp denorm_min() throw() { return static_cast<_Tp>(0); } }; @@ -262,7 +358,7 @@ namespace std // It is not clear what it means for a boolean type to trap. // This is a DR on the LWG issue list. Here, I use integer // promotion semantics. - static const bool traps = __glibcpp_integral_traps; + static const bool traps = __glibcxx_integral_traps; static const bool tinyness_before = false; static const float_round_style round_style = round_toward_zero; }; @@ -273,13 +369,13 @@ namespace std static const bool is_specialized = true; static char min() throw() - { return __glibcpp_min(char); } + { return __glibcxx_min(char); } static char max() throw() - { return __glibcpp_max(char); } + { return __glibcxx_max(char); } - static const int digits = __glibcpp_digits (char); - static const int digits10 = __glibcpp_digits10 (char); - static const bool is_signed = __glibcpp_signed (char); + static const int digits = __glibcxx_digits (char); + static const int digits10 = __glibcxx_digits10 (char); + static const bool is_signed = __glibcxx_signed (char); static const bool is_integer = true; static const bool is_exact = true; static const int radix = 2; @@ -312,7 +408,7 @@ namespace std static const bool is_bounded = true; static const bool is_modulo = true; - static const bool traps = __glibcpp_integral_traps; + static const bool traps = __glibcxx_integral_traps; static const bool tinyness_before = false; static const float_round_style round_style = round_toward_zero; }; @@ -327,8 +423,8 @@ namespace std static signed char max() throw() { return __SCHAR_MAX__; } - static const int digits = __glibcpp_digits (signed char); - static const int digits10 = __glibcpp_digits10 (signed char); + static const int digits = __glibcxx_digits (signed char); + static const int digits10 = __glibcxx_digits10 (signed char); static const bool is_signed = true; static const bool is_integer = true; static const bool is_exact = true; @@ -362,7 +458,7 @@ namespace std static const bool is_bounded = true; static const bool is_modulo = true; - static const bool traps = __glibcpp_integral_traps; + static const bool traps = __glibcxx_integral_traps; static const bool tinyness_before = false; static const float_round_style round_style = round_toward_zero; }; @@ -377,8 +473,8 @@ namespace std static unsigned char max() throw() { return __SCHAR_MAX__ * 2U + 1; } - static const int digits = __glibcpp_digits (unsigned char); - static const int digits10 = __glibcpp_digits10 (unsigned char); + static const int digits = __glibcxx_digits (unsigned char); + static const int digits10 = __glibcxx_digits10 (unsigned char); static const bool is_signed = false; static const bool is_integer = true; static const bool is_exact = true; @@ -412,7 +508,7 @@ namespace std static const bool is_bounded = true; static const bool is_modulo = true; - static const bool traps = __glibcpp_integral_traps; + static const bool traps = __glibcxx_integral_traps; static const bool tinyness_before = false; static const float_round_style round_style = round_toward_zero; }; @@ -423,13 +519,13 @@ namespace std static const bool is_specialized = true; static wchar_t min() throw() - { return __glibcpp_min (wchar_t); } + { return __glibcxx_min (wchar_t); } static wchar_t max() throw() - { return __glibcpp_max (wchar_t); } + { return __glibcxx_max (wchar_t); } - static const int digits = __glibcpp_digits (wchar_t); - static const int digits10 = __glibcpp_digits10 (wchar_t); - static const bool is_signed = __glibcpp_signed (wchar_t); + static const int digits = __glibcxx_digits (wchar_t); + static const int digits10 = __glibcxx_digits10 (wchar_t); + static const bool is_signed = __glibcxx_signed (wchar_t); static const bool is_integer = true; static const bool is_exact = true; static const int radix = 2; @@ -462,7 +558,7 @@ namespace std static const bool is_bounded = true; static const bool is_modulo = true; - static const bool traps = __glibcpp_integral_traps; + static const bool traps = __glibcxx_integral_traps; static const bool tinyness_before = false; static const float_round_style round_style = round_toward_zero; }; @@ -477,8 +573,8 @@ namespace std static short max() throw() { return __SHRT_MAX__; } - static const int digits = __glibcpp_digits (short); - static const int digits10 = __glibcpp_digits10 (short); + static const int digits = __glibcxx_digits (short); + static const int digits10 = __glibcxx_digits10 (short); static const bool is_signed = true; static const bool is_integer = true; static const bool is_exact = true; @@ -512,7 +608,7 @@ namespace std static const bool is_bounded = true; static const bool is_modulo = true; - static const bool traps = __glibcpp_integral_traps; + static const bool traps = __glibcxx_integral_traps; static const bool tinyness_before = false; static const float_round_style round_style = round_toward_zero; }; @@ -527,8 +623,8 @@ namespace std static unsigned short max() throw() { return __SHRT_MAX__ * 2U + 1; } - static const int digits = __glibcpp_digits (unsigned short); - static const int digits10 = __glibcpp_digits10 (unsigned short); + static const int digits = __glibcxx_digits (unsigned short); + static const int digits10 = __glibcxx_digits10 (unsigned short); static const bool is_signed = false; static const bool is_integer = true; static const bool is_exact = true; @@ -562,7 +658,7 @@ namespace std static const bool is_bounded = true; static const bool is_modulo = true; - static const bool traps = __glibcpp_integral_traps; + static const bool traps = __glibcxx_integral_traps; static const bool tinyness_before = false; static const float_round_style round_style = round_toward_zero; }; @@ -577,8 +673,8 @@ namespace std static int max() throw() { return __INT_MAX__; } - static const int digits = __glibcpp_digits (int); - static const int digits10 = __glibcpp_digits10 (int); + static const int digits = __glibcxx_digits (int); + static const int digits10 = __glibcxx_digits10 (int); static const bool is_signed = true; static const bool is_integer = true; static const bool is_exact = true; @@ -612,7 +708,7 @@ namespace std static const bool is_bounded = true; static const bool is_modulo = true; - static const bool traps = __glibcpp_integral_traps; + static const bool traps = __glibcxx_integral_traps; static const bool tinyness_before = false; static const float_round_style round_style = round_toward_zero; }; @@ -627,8 +723,8 @@ namespace std static unsigned int max() throw() { return __INT_MAX__ * 2U + 1; } - static const int digits = __glibcpp_digits (unsigned int); - static const int digits10 = __glibcpp_digits10 (unsigned int); + static const int digits = __glibcxx_digits (unsigned int); + static const int digits10 = __glibcxx_digits10 (unsigned int); static const bool is_signed = false; static const bool is_integer = true; static const bool is_exact = true; @@ -662,7 +758,7 @@ namespace std static const bool is_bounded = true; static const bool is_modulo = true; - static const bool traps = __glibcpp_integral_traps; + static const bool traps = __glibcxx_integral_traps; static const bool tinyness_before = false; static const float_round_style round_style = round_toward_zero; }; @@ -677,8 +773,8 @@ namespace std static long max() throw() { return __LONG_MAX__; } - static const int digits = __glibcpp_digits (long); - static const int digits10 = __glibcpp_digits10 (long); + static const int digits = __glibcxx_digits (long); + static const int digits10 = __glibcxx_digits10 (long); static const bool is_signed = true; static const bool is_integer = true; static const bool is_exact = true; @@ -712,7 +808,7 @@ namespace std static const bool is_bounded = true; static const bool is_modulo = true; - static const bool traps = __glibcpp_integral_traps; + static const bool traps = __glibcxx_integral_traps; static const bool tinyness_before = false; static const float_round_style round_style = round_toward_zero; }; @@ -727,8 +823,8 @@ namespace std static unsigned long max() throw() { return __LONG_MAX__ * 2UL + 1; } - static const int digits = __glibcpp_digits (unsigned long); - static const int digits10 = __glibcpp_digits10 (unsigned long); + static const int digits = __glibcxx_digits (unsigned long); + static const int digits10 = __glibcxx_digits10 (unsigned long); static const bool is_signed = false; static const bool is_integer = true; static const bool is_exact = true; @@ -762,7 +858,7 @@ namespace std static const bool is_bounded = true; static const bool is_modulo = true; - static const bool traps = __glibcpp_integral_traps; + static const bool traps = __glibcxx_integral_traps; static const bool tinyness_before = false; static const float_round_style round_style = round_toward_zero; }; @@ -777,8 +873,8 @@ namespace std static long long max() throw() { return __LONG_LONG_MAX__; } - static const int digits = __glibcpp_digits (long long); - static const int digits10 = __glibcpp_digits10 (long long); + static const int digits = __glibcxx_digits (long long); + static const int digits10 = __glibcxx_digits10 (long long); static const bool is_signed = true; static const bool is_integer = true; static const bool is_exact = true; @@ -812,7 +908,7 @@ namespace std static const bool is_bounded = true; static const bool is_modulo = true; - static const bool traps = __glibcpp_integral_traps; + static const bool traps = __glibcxx_integral_traps; static const bool tinyness_before = false; static const float_round_style round_style = round_toward_zero; }; @@ -827,8 +923,8 @@ namespace std static unsigned long long max() throw() { return __LONG_LONG_MAX__ * 2ULL + 1; } - static const int digits = __glibcpp_digits (unsigned long long); - static const int digits10 = __glibcpp_digits10 (unsigned long long); + static const int digits = __glibcxx_digits (unsigned long long); + static const int digits10 = __glibcxx_digits10 (unsigned long long); static const bool is_signed = false; static const bool is_integer = true; static const bool is_exact = true; @@ -862,7 +958,7 @@ namespace std static const bool is_bounded = true; static const bool is_modulo = true; - static const bool traps = __glibcpp_integral_traps; + static const bool traps = __glibcxx_integral_traps; static const bool tinyness_before = false; static const float_round_style round_style = round_toward_zero; }; @@ -893,14 +989,12 @@ namespace std static const int max_exponent = __FLT_MAX_EXP__; static const int max_exponent10 = __FLT_MAX_10_EXP__; - static const bool has_infinity - = __builtin_huge_valf () / 2 == __builtin_huge_valf (); - static const bool has_quiet_NaN - = __builtin_nanf ("") != __builtin_nanf (""); + static const bool has_infinity = __FLT_HAS_INFINITY__; + static const bool has_quiet_NaN = __FLT_HAS_QUIET_NAN__; static const bool has_signaling_NaN = has_quiet_NaN; static const float_denorm_style has_denorm = __FLT_DENORM_MIN__ ? denorm_present : denorm_absent; - static const bool has_denorm_loss = __glibcpp_float_has_denorm_loss; + static const bool has_denorm_loss = __glibcxx_float_has_denorm_loss; static float infinity() throw() { return __builtin_huge_valf (); } @@ -916,14 +1010,14 @@ namespace std static const bool is_bounded = true; static const bool is_modulo = false; - static const bool traps = __glibcpp_float_traps; - static const bool tinyness_before = __glibcpp_float_tinyness_before; + static const bool traps = __glibcxx_float_traps; + static const bool tinyness_before = __glibcxx_float_tinyness_before; static const float_round_style round_style = round_to_nearest; }; -#undef __glibcpp_float_has_denorm_loss -#undef __glibcpp_float_traps -#undef __glibcpp_float_tinyness_before +#undef __glibcxx_float_has_denorm_loss +#undef __glibcxx_float_traps +#undef __glibcxx_float_tinyness_before template<> struct numeric_limits<double> @@ -951,14 +1045,12 @@ namespace std static const int max_exponent = __DBL_MAX_EXP__; static const int max_exponent10 = __DBL_MAX_10_EXP__; - static const bool has_infinity - = __builtin_huge_val () / 2 == __builtin_huge_val (); - static const bool has_quiet_NaN - = __builtin_nan ("") != __builtin_nan (""); + static const bool has_infinity = __DBL_HAS_INFINITY__; + static const bool has_quiet_NaN = __DBL_HAS_QUIET_NAN__; static const bool has_signaling_NaN = has_quiet_NaN; static const float_denorm_style has_denorm = __DBL_DENORM_MIN__ ? denorm_present : denorm_absent; - static const bool has_denorm_loss = __glibcpp_double_has_denorm_loss; + static const bool has_denorm_loss = __glibcxx_double_has_denorm_loss; static double infinity() throw() { return __builtin_huge_val(); } @@ -974,14 +1066,14 @@ namespace std static const bool is_bounded = true; static const bool is_modulo = false; - static const bool traps = __glibcpp_double_traps; - static const bool tinyness_before = __glibcpp_double_tinyness_before; + static const bool traps = __glibcxx_double_traps; + static const bool tinyness_before = __glibcxx_double_tinyness_before; static const float_round_style round_style = round_to_nearest; }; -#undef __glibcpp_double_has_denorm_loss -#undef __glibcpp_double_traps -#undef __glibcpp_double_tinyness_before +#undef __glibcxx_double_has_denorm_loss +#undef __glibcxx_double_traps +#undef __glibcxx_double_tinyness_before template<> struct numeric_limits<long double> @@ -1009,15 +1101,13 @@ namespace std static const int max_exponent = __LDBL_MAX_EXP__; static const int max_exponent10 = __LDBL_MAX_10_EXP__; - static const bool has_infinity - = __builtin_huge_vall () / 2 == __builtin_huge_vall (); - static const bool has_quiet_NaN - = __builtin_nanl ("") != __builtin_nanl (""); + static const bool has_infinity = __LDBL_HAS_INFINITY__; + static const bool has_quiet_NaN = __LDBL_HAS_QUIET_NAN__; static const bool has_signaling_NaN = has_quiet_NaN; static const float_denorm_style has_denorm = __LDBL_DENORM_MIN__ ? denorm_present : denorm_absent; static const bool has_denorm_loss - = __glibcpp_long_double_has_denorm_loss; + = __glibcxx_long_double_has_denorm_loss; static long double infinity() throw() { return __builtin_huge_vall (); } @@ -1033,21 +1123,21 @@ namespace std static const bool is_bounded = true; static const bool is_modulo = false; - static const bool traps = __glibcpp_long_double_traps; - static const bool tinyness_before = __glibcpp_long_double_tinyness_before; + static const bool traps = __glibcxx_long_double_traps; + static const bool tinyness_before = __glibcxx_long_double_tinyness_before; static const float_round_style round_style = round_to_nearest; }; -#undef __glibcpp_long_double_has_denorm_loss -#undef __glibcpp_long_double_traps -#undef __glibcpp_long_double_tinyness_before +#undef __glibcxx_long_double_has_denorm_loss +#undef __glibcxx_long_double_traps +#undef __glibcxx_long_double_tinyness_before } // namespace std -#undef __glibcpp_signed -#undef __glibcpp_min -#undef __glibcpp_max -#undef __glibcpp_digits -#undef __glibcpp_digits10 +#undef __glibcxx_signed +#undef __glibcxx_min +#undef __glibcxx_max +#undef __glibcxx_digits +#undef __glibcxx_digits10 -#endif // _CPP_NUMERIC_LIMITS +#endif // _GLIBCXX_NUMERIC_LIMITS diff --git a/contrib/libstdc++/include/std/std_list.h b/contrib/libstdc++/include/std/std_list.h index 84523ad8e4fa..285a29d8131c 100644 --- a/contrib/libstdc++/include/std/std_list.h +++ b/contrib/libstdc++/include/std/std_list.h @@ -1,6 +1,6 @@ // <list> -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,21 +58,25 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_LIST -#define _CPP_LIST 1 +#ifndef _GLIBCXX_LIST +#define _GLIBCXX_LIST 1 #pragma GCC system_header #include <bits/functexcept.h> #include <bits/stl_algobase.h> -#include <bits/stl_alloc.h> +#include <bits/allocator.h> #include <bits/stl_construct.h> #include <bits/stl_uninitialized.h> #include <bits/stl_list.h> -#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT -# include <bits/list.tcc> +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <bits/list.tcc> #endif -#endif /* _CPP_LIST */ +#ifdef _GLIBCXX_DEBUG +# include <debug/list> +#endif + +#endif /* _GLIBCXX_LIST */ diff --git a/contrib/libstdc++/include/std/std_locale.h b/contrib/libstdc++/include/std/std_locale.h index 29602560766c..43417fbdddc7 100644 --- a/contrib/libstdc++/include/std/std_locale.h +++ b/contrib/libstdc++/include/std/std_locale.h @@ -36,8 +36,8 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_LOCALE -#define _CPP_LOCALE 1 +#ifndef _GLIBCXX_LOCALE +#define _GLIBCXX_LOCALE 1 #pragma GCC system_header @@ -46,4 +46,4 @@ #include <bits/locale_facets.h> #include <bits/locale_facets.tcc> -#endif +#endif /* _GLIBCXX_LOCALE */ diff --git a/contrib/libstdc++/include/std/std_map.h b/contrib/libstdc++/include/std/std_map.h index c04cbd542a67..4a88ae22ea33 100644 --- a/contrib/libstdc++/include/std/std_map.h +++ b/contrib/libstdc++/include/std/std_map.h @@ -58,8 +58,8 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_MAP -#define _CPP_MAP 1 +#ifndef _GLIBCXX_MAP +#define _GLIBCXX_MAP 1 #pragma GCC system_header @@ -67,8 +67,8 @@ #include <bits/stl_map.h> #include <bits/stl_multimap.h> -#endif /* _CPP_MAP */ +#ifdef _GLIBCXX_DEBUG +# include <debug/map> +#endif -// Local Variables: -// mode:C++ -// End: +#endif /* _GLIBCXX_MAP */ diff --git a/contrib/libstdc++/include/std/std_memory.h b/contrib/libstdc++/include/std/std_memory.h index 47c3ede8995d..4e6641ef6739 100644 --- a/contrib/libstdc++/include/std/std_memory.h +++ b/contrib/libstdc++/include/std/std_memory.h @@ -1,6 +1,6 @@ // <memory> -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -46,17 +46,18 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_MEMORY -#define _CPP_MEMORY 1 +#ifndef _GLIBCXX_MEMORY +#define _GLIBCXX_MEMORY 1 #pragma GCC system_header #include <bits/stl_algobase.h> -#include <bits/stl_alloc.h> +#include <bits/allocator.h> #include <bits/stl_construct.h> #include <bits/stl_iterator_base_types.h> //for iterator_traits #include <bits/stl_uninitialized.h> #include <bits/stl_raw_storage_iter.h> +#include <debug/debug.h> namespace std { @@ -77,33 +78,36 @@ namespace std while (__len > 0) { - _Tp* __tmp = (_Tp*) std::malloc((std::size_t)__len * sizeof(_Tp)); + _Tp* __tmp = static_cast<_Tp*>(::operator new(__len * sizeof(_Tp), + nothrow)); if (__tmp != 0) return pair<_Tp*, ptrdiff_t>(__tmp, __len); __len /= 2; } - return pair<_Tp*, ptrdiff_t>((_Tp*)0, 0); + return pair<_Tp*, ptrdiff_t>(static_cast<_Tp*>(0), 0); } /** - * @brief This is a mostly-useless wrapper around malloc(). + * @brief Allocates a temporary buffer. * @param len The number of objects of type Tp. - * @return See full description. + * @return See full description. * * Reinventing the wheel, but this time with prettier spokes! * - * This function tries to obtain storage for @c len adjacent Tp objects. - * The objects themselves are not constructed, of course. A pair<> is - * returned containing "the buffer s address and capacity (in the units of - * sizeof(Tp)), or a pair of 0 values if no storage can be obtained." - * Note that the capacity obtained may be less than that requested if the - * memory is unavailable; you should compare len with the .second return - * value. + * This function tries to obtain storage for @c len adjacent Tp + * objects. The objects themselves are not constructed, of course. + * A pair<> is returned containing "the buffer s address and + * capacity (in the units of sizeof(Tp)), or a pair of 0 values if + * no storage can be obtained." Note that the capacity obtained + * may be less than that requested if the memory is unavailable; + * you should compare len with the .second return value. + * + * Provides the nothrow exception guarantee. */ template<typename _Tp> inline pair<_Tp*,ptrdiff_t> get_temporary_buffer(ptrdiff_t __len) - { return __get_temporary_buffer(__len, (_Tp*) 0); } + { return std::__get_temporary_buffer(__len, static_cast<_Tp*>(0)); } /** * @brief The companion to get_temporary_buffer(). @@ -115,12 +119,12 @@ namespace std template<typename _Tp> void return_temporary_buffer(_Tp* __p) - { std::free(__p); } + { ::operator delete(__p, nothrow); } /** - * A wrapper class to provide auto_ptr with reference semantics. For - * example, an auto_ptr can be assigned (or constructed from) the result of - * a function which returns an auto_ptr by value. + * A wrapper class to provide auto_ptr with reference semantics. + * For example, an auto_ptr can be assigned (or constructed from) + * the result of a function which returns an auto_ptr by value. * * All the auto_ptr_ref stuff should happen behind the scenes. */ @@ -139,26 +143,28 @@ namespace std * * The Standard says: * <pre> - * An @c auto_ptr owns the object it holds a pointer to. Copying an - * @c auto_ptr copies the pointer and transfers ownership to the destination. - * If more than one @c auto_ptr owns the same object at the same time the - * behavior of the program is undefined. + * An @c auto_ptr owns the object it holds a pointer to. Copying + * an @c auto_ptr copies the pointer and transfers ownership to the + * destination. If more than one @c auto_ptr owns the same object + * at the same time the behavior of the program is undefined. * - * The uses of @c auto_ptr include providing temporary exception-safety for - * dynamically allocated memory, passing ownership of dynamically allocated - * memory to a function, and returning dynamically allocated memory from a - * function. @c auto_ptr does not meet the CopyConstructible and Assignable - * requirements for Standard Library <a href="tables.html#65">container</a> - * elements and thus instantiating a Standard Library container with an - * @c auto_ptr results in undefined behavior. + * The uses of @c auto_ptr include providing temporary + * exception-safety for dynamically allocated memory, passing + * ownership of dynamically allocated memory to a function, and + * returning dynamically allocated memory from a function. @c + * auto_ptr does not meet the CopyConstructible and Assignable + * requirements for Standard Library <a + * href="tables.html#65">container</a> elements and thus + * instantiating a Standard Library container with an @c auto_ptr + * results in undefined behavior. * </pre> * Quoted from [20.4.5]/3. * - * Good examples of what can and cannot be done with auto_ptr can be found - * in the libstdc++ testsuite. + * Good examples of what can and cannot be done with auto_ptr can + * be found in the libstdc++ testsuite. * * @if maint - * _GLIBCPP_RESOLVE_LIB_DEFECTS + * _GLIBCXX_RESOLVE_LIB_DEFECTS * 127. auto_ptr<> conversion issues * These resolutions have all been incorporated. * @endif @@ -195,7 +201,8 @@ namespace std * @brief An %auto_ptr can be constructed from another %auto_ptr. * @param a Another %auto_ptr of a different but related type. * - * A pointer-to-Tp1 must be convertible to a pointer-to-Tp/element_type. + * A pointer-to-Tp1 must be convertible to a + * pointer-to-Tp/element_type. * * This object now @e owns the object previously owned by @a a, * which has given up ownsership. @@ -237,9 +244,9 @@ namespace std } /** - * When the %auto_ptr goes out of scope, the object it owns is deleted. - * If it no longer owns anything (i.e., @c get() is @c NULL), then this - * has no effect. + * When the %auto_ptr goes out of scope, the object it owns is + * deleted. If it no longer owns anything (i.e., @c get() is + * @c NULL), then this has no effect. * * @if maint * The C++ standard says there is supposed to be an empty throw @@ -259,7 +266,11 @@ namespace std * what happens when you dereference one of those...) */ element_type& - operator*() const throw() { return *_M_ptr; } + operator*() const throw() + { + _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); + return *_M_ptr; + } /** * @brief Smart pointer dereferencing. @@ -268,15 +279,19 @@ namespace std * automatically cause to be dereferenced. */ element_type* - operator->() const throw() { return _M_ptr; } + operator->() const throw() + { + _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); + return _M_ptr; + } /** * @brief Bypassing the smart pointer. * @return The raw pointer being managed. * * You can get a copy of the pointer that this object owns, for - * situations such as passing to a function which only accepts a raw - * pointer. + * situations such as passing to a function which only accepts + * a raw pointer. * * @note This %auto_ptr still owns the memory. */ @@ -288,8 +303,8 @@ namespace std * @return The raw pointer being managed. * * You can get a copy of the pointer that this object owns, for - * situations such as passing to a function which only accepts a raw - * pointer. + * situations such as passing to a function which only accepts + * a raw pointer. * * @note This %auto_ptr no longer owns the memory. When this object * goes out of scope, nothing will happen. @@ -306,8 +321,8 @@ namespace std * @brief Forcibly deletes the managed object. * @param p A pointer (defaults to NULL). * - * This object now @e owns the object pointed to by @a p. The previous - * object has been deleted. + * This object now @e owns the object pointed to by @a p. The + * previous object has been deleted. */ void reset(element_type* __p = 0) throw() @@ -355,4 +370,4 @@ namespace std }; } // namespace std -#endif +#endif /* _GLIBCXX_MEMORY */ diff --git a/contrib/libstdc++/include/std/std_numeric.h b/contrib/libstdc++/include/std/std_numeric.h index 936eaa78945e..88661e9f5a44 100644 --- a/contrib/libstdc++/include/std/std_numeric.h +++ b/contrib/libstdc++/include/std/std_numeric.h @@ -58,18 +58,15 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_NUMERIC -#define _CPP_NUMERIC 1 +#ifndef _GLIBCXX_NUMERIC +#define _GLIBCXX_NUMERIC 1 #pragma GCC system_header + #include <bits/c++config.h> #include <cstddef> #include <iterator> #include <bits/stl_function.h> #include <bits/stl_numeric.h> -#endif /* _CPP_NUMERIC */ - -// Local Variables: -// mode:C++ -// End: +#endif /* _GLIBCXX_NUMERIC */ diff --git a/contrib/libstdc++/include/std/std_ostream.h b/contrib/libstdc++/include/std/std_ostream.h index 82f8a2864bc6..e3590f23515c 100644 --- a/contrib/libstdc++/include/std/std_ostream.h +++ b/contrib/libstdc++/include/std/std_ostream.h @@ -1,6 +1,6 @@ // Output streams -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -37,8 +37,8 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_OSTREAM -#define _CPP_OSTREAM 1 +#ifndef _GLIBCXX_OSTREAM +#define _GLIBCXX_OSTREAM 1 #pragma GCC system_header @@ -69,8 +69,8 @@ namespace std typedef basic_streambuf<_CharT, _Traits> __streambuf_type; typedef basic_ios<_CharT, _Traits> __ios_type; typedef basic_ostream<_CharT, _Traits> __ostream_type; - typedef ostreambuf_iterator<_CharT, _Traits> __ostreambuf_iter; - typedef num_put<_CharT, __ostreambuf_iter> __numput_type; + typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> > + __num_put_type; typedef ctype<_CharT> __ctype_type; template<typename _CharT2, typename _Traits2> @@ -127,13 +127,13 @@ namespace std * functions in constructs like "std::cout << std::endl". For more * information, see the iomanip header. */ - __ostream_type& + inline __ostream_type& operator<<(__ostream_type& (*__pf)(__ostream_type&)); - __ostream_type& + inline __ostream_type& operator<<(__ios_type& (*__pf)(__ios_type&)); - __ostream_type& + inline __ostream_type& operator<<(ios_base& (*__pf) (ios_base&)); //@} @@ -203,7 +203,7 @@ namespace std operator<<(unsigned int __n) { return this->operator<<(static_cast<unsigned long>(__n)); } -#ifdef _GLIBCPP_USE_LONG_LONG +#ifdef _GLIBCXX_USE_LONG_LONG __ostream_type& operator<<(long long __n); @@ -229,7 +229,7 @@ namespace std * @param sb A pointer to a streambuf * * This function behaves like one of the basic arithmetic extractors, - * in that it also constructs a sentry onject and has the same error + * in that it also constructs a sentry object and has the same error * handling behavior. * * If @a sb is NULL, the stream will set failbit in its error state. @@ -281,6 +281,15 @@ namespace std __ostream_type& put(char_type __c); + // Core write functionality, without sentry. + void + _M_write(const char_type* __s, streamsize __n) + { + streamsize __put = this->rdbuf()->sputn(__s, __n); + if (__put != __n) + this->setstate(ios_base::badbit); + } + /** * @brief Character string insertion. * @param s The array to insert. @@ -346,6 +355,10 @@ namespace std */ __ostream_type& seekp(off_type, ios_base::seekdir); + + protected: + explicit + basic_ostream() { } }; /** @@ -405,7 +418,7 @@ namespace std * For ease of use, sentries may be converted to booleans. The * return value is that of the sentry state (true == okay). */ - operator bool() + operator bool() const { return _M_ok; } }; @@ -528,11 +541,8 @@ namespace std } // namespace std -#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT -# define export -#endif -#ifdef _GLIBCPP_FULLY_COMPLIANT_HEADERS +#ifndef _GLIBCXX_EXPORT_TEMPLATE # include <bits/ostream.tcc> #endif -#endif /* _CPP_OSTREAM */ +#endif /* _GLIBCXX_OSTREAM */ diff --git a/contrib/libstdc++/include/std/std_queue.h b/contrib/libstdc++/include/std/std_queue.h index 60636e6f0dd8..9a6523bef87b 100644 --- a/contrib/libstdc++/include/std/std_queue.h +++ b/contrib/libstdc++/include/std/std_queue.h @@ -1,6 +1,6 @@ // <queue> -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,25 +58,21 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_QUEUE -#define _CPP_QUEUE 1 +#ifndef _GLIBCXX_QUEUE +#define _GLIBCXX_QUEUE 1 #pragma GCC system_header + #include <bits/c++config.h> #include <bits/functexcept.h> #include <bits/stl_algobase.h> -#include <bits/stl_alloc.h> +#include <bits/allocator.h> #include <bits/stl_construct.h> #include <bits/stl_uninitialized.h> -#include <bits/stl_vector.h> #include <bits/stl_heap.h> -#include <bits/stl_deque.h> #include <bits/stl_function.h> +#include <deque> +#include <vector> #include <bits/stl_queue.h> -#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT -# include <bits/deque.tcc> -# include <bits/vector.tcc> -#endif - -#endif /* _CPP_QUEUE */ +#endif /* _GLIBCXX_QUEUE */ diff --git a/contrib/libstdc++/include/std/std_set.h b/contrib/libstdc++/include/std/std_set.h index 249f396f1af8..7ef8c9fef3bd 100644 --- a/contrib/libstdc++/include/std/std_set.h +++ b/contrib/libstdc++/include/std/std_set.h @@ -58,8 +58,8 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_SET -#define _CPP_SET 1 +#ifndef _GLIBCXX_SET +#define _GLIBCXX_SET 1 #pragma GCC system_header @@ -67,8 +67,8 @@ #include <bits/stl_set.h> #include <bits/stl_multiset.h> -#endif /* _CPP_SET */ +#ifdef _GLIBCXX_DEBUG +# include <debug/set> +#endif -// Local Variables: -// mode:C++ -// End: +#endif /* _GLIBCXX_SET */ diff --git a/contrib/libstdc++/include/std/std_sstream.h b/contrib/libstdc++/include/std/std_sstream.h index 0940e60f52e7..6b5728b94ced 100644 --- a/contrib/libstdc++/include/std/std_sstream.h +++ b/contrib/libstdc++/include/std/std_sstream.h @@ -1,6 +1,7 @@ // String based streams -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2002, 2003 Free Software Foundation, Inc. +// Copyright (C) 1997, 1998, 1999, 2002, 2003, 2004 +// Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -36,8 +37,8 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_SSTREAM -#define _CPP_SSTREAM 1 +#ifndef _GLIBCXX_SSTREAM +#define _GLIBCXX_SSTREAM 1 #pragma GCC system_header @@ -65,10 +66,9 @@ namespace std // Types: typedef _CharT char_type; typedef _Traits traits_type; -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -// 251. basic_stringbuf missing allocator_type + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 251. basic_stringbuf missing allocator_type typedef _Alloc allocator_type; -#endif typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; @@ -85,6 +85,13 @@ namespace std //@} protected: + /** + * @if maint + * Place to stash in || out || in | out settings for current stringbuf. + * @endif + */ + ios_base::openmode _M_mode; + // Data Members: /** * @if maint @@ -104,7 +111,7 @@ namespace std */ explicit basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out) - : __streambuf_type(), _M_string() + : __streambuf_type(), _M_mode(), _M_string() { _M_stringbuf_init(__mode); } /** @@ -118,7 +125,7 @@ namespace std explicit basic_stringbuf(const __string_type& __str, ios_base::openmode __mode = ios_base::in | ios_base::out) - : __streambuf_type(), _M_string(__str.data(), __str.size()) + : __streambuf_type(), _M_mode(), _M_string(__str.data(), __str.size()) { _M_stringbuf_init(__mode); } // Get and set: @@ -133,16 +140,14 @@ namespace std __string_type str() const { - if (_M_mode & ios_base::out) + const bool __testout = this->_M_mode & ios_base::out; + if (__testout) { - // This is the deal: _M_string.size() is a value that - // represents the size of the initial string that makes - // _M_string, and may not be the correct size of the - // current stringbuf internal buffer. - __size_type __len = _M_string.size(); - if (_M_out_end > _M_out_beg) - __len = max(__size_type(_M_out_end - _M_out_beg), __len); - return __string_type(_M_out_beg, _M_out_beg + __len); + // The current egptr() may not be the actual string end. + if (this->pptr() > this->egptr()) + return __string_type(this->pbase(), this->pptr()); + else + return __string_type(this->pbase(), this->egptr()); } else return _M_string; @@ -160,7 +165,7 @@ namespace std { // Cannot use _M_string = __s, since v3 strings are COW. _M_string.assign(__s.data(), __s.size()); - _M_stringbuf_init(_M_mode); + _M_stringbuf_init(this->_M_mode); } protected: @@ -173,35 +178,17 @@ namespace std void _M_stringbuf_init(ios_base::openmode __mode) { - // _M_buf_size is a convenient alias for "what the streambuf - // thinks the allocated size of the string really is." This is - // necessary as ostringstreams are implemented with the - // streambufs having control of the allocation and - // re-allocation of the internal string object, _M_string. - _M_buf_size = _M_string.size(); - - // NB: Start ostringstream buffers at 512 bytes. This is an - // experimental value (pronounced "arbitrary" in some of the - // hipper english-speaking countries), and can be changed to - // suit particular needs. - _M_buf_size_opt = 512; - _M_mode = __mode; - if (_M_mode & (ios_base::ate | ios_base::app)) - _M_really_sync(0, _M_buf_size); - else - _M_really_sync(0, 0); + this->_M_mode = __mode; + + __size_type __len = 0; + if (this->_M_mode & (ios_base::ate | ios_base::app)) + __len = _M_string.size(); + _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len); } - // Overridden virtual functions: // [documentation is inherited] virtual int_type - underflow() - { - if (_M_in_cur && _M_in_cur < _M_in_end) - return traits_type::to_int_type(*gptr()); - else - return traits_type::eof(); - } + underflow(); // [documentation is inherited] virtual int_type @@ -225,10 +212,18 @@ namespace std virtual __streambuf_type* setbuf(char_type* __s, streamsize __n) { - if (__s && __n) + if (__s && __n >= 0) { + // This is implementation-defined behavior, and assumes + // that an external char_type array of length __n exists + // and has been pre-allocated. If this is not the case, + // things will quickly blow up. + + // Step 1: Destroy the current internal array. _M_string = __string_type(__s, __n); - _M_really_sync(0, 0); + + // Step 2: Use the external array. + _M_sync(__s, 0, 0); } return this; } @@ -254,23 +249,41 @@ namespace std * @doctodo * @endif */ - virtual int - _M_really_sync(__size_type __i, __size_type __o) + void + _M_sync(char_type* __base, __size_type __i, __size_type __o) { - char_type* __base = const_cast<char_type*>(_M_string.data()); - bool __testin = _M_mode & ios_base::in; - bool __testout = _M_mode & ios_base::out; - __size_type __len = _M_string.size(); + const bool __testin = this->_M_mode & ios_base::in; + const bool __testout = this->_M_mode & ios_base::out; + const __size_type __len = _M_string.size(); - _M_buf = __base; if (__testin) - this->setg(__base, __base + __i, __base + __len); + this->setg(__base, __base + __i, __base + __len); if (__testout) { - this->setp(__base, __base + __len); - _M_out_cur += __o; + this->setp(__base, __base + _M_string.capacity()); + this->pbump(__o); + // We need a pointer to the string end anyway, even when + // !__testin: in that case, however, for the correct + // functioning of the streambuf inlines all the get area + // pointers must be identical. + if (!__testin) + this->setg(__base + __len, __base + __len, __base + __len); } - return 0; + } + + // Internal function for correctly updating egptr() to the actual + // string end. + void + _M_update_egptr() + { + const bool __testin = this->_M_mode & ios_base::in; + const bool __testout = this->_M_mode & ios_base::out; + + if (__testout && this->pptr() > this->egptr()) + if (__testin) + this->setg(this->eback(), this->gptr(), this->pptr()); + else + this->setg(this->pptr(), this->pptr(), this->pptr()); } }; @@ -291,10 +304,9 @@ namespace std // Types: typedef _CharT char_type; typedef _Traits traits_type; -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -// 251. basic_stringbuf missing allocator_type + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 251. basic_stringbuf missing allocator_type typedef _Alloc allocator_type; -#endif typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; @@ -330,7 +342,7 @@ namespace std */ explicit basic_istringstream(ios_base::openmode __mode = ios_base::in) - : __istream_type(NULL), _M_stringbuf(__mode | ios_base::in) + : __istream_type(), _M_stringbuf(__mode | ios_base::in) { this->init(&_M_stringbuf); } /** @@ -351,7 +363,7 @@ namespace std explicit basic_istringstream(const __string_type& __str, ios_base::openmode __mode = ios_base::in) - : __istream_type(NULL), _M_stringbuf(__str, __mode | ios_base::in) + : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in) { this->init(&_M_stringbuf); } /** @@ -410,10 +422,9 @@ namespace std // Types: typedef _CharT char_type; typedef _Traits traits_type; -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -// 251. basic_stringbuf missing allocator_type + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 251. basic_stringbuf missing allocator_type typedef _Alloc allocator_type; -#endif typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; @@ -449,7 +460,7 @@ namespace std */ explicit basic_ostringstream(ios_base::openmode __mode = ios_base::out) - : __ostream_type(NULL), _M_stringbuf(__mode | ios_base::out) + : __ostream_type(), _M_stringbuf(__mode | ios_base::out) { this->init(&_M_stringbuf); } /** @@ -470,7 +481,7 @@ namespace std explicit basic_ostringstream(const __string_type& __str, ios_base::openmode __mode = ios_base::out) - : __ostream_type(NULL), _M_stringbuf(__str, __mode | ios_base::out) + : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out) { this->init(&_M_stringbuf); } /** @@ -529,10 +540,9 @@ namespace std // Types: typedef _CharT char_type; typedef _Traits traits_type; -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS -// 251. basic_stringbuf missing allocator_type + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 251. basic_stringbuf missing allocator_type typedef _Alloc allocator_type; -#endif typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; @@ -566,7 +576,7 @@ namespace std */ explicit basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in) - : __iostream_type(NULL), _M_stringbuf(__m) + : __iostream_type(), _M_stringbuf(__m) { this->init(&_M_stringbuf); } /** @@ -585,7 +595,7 @@ namespace std explicit basic_stringstream(const __string_type& __str, ios_base::openmode __m = ios_base::out | ios_base::in) - : __iostream_type(NULL), _M_stringbuf(__str, __m) + : __iostream_type(), _M_stringbuf(__str, __m) { this->init(&_M_stringbuf); } /** @@ -628,11 +638,8 @@ namespace std }; } // namespace std -#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT -# define export -#endif -#ifdef _GLIBCPP_FULLY_COMPLIANT_HEADERS +#ifndef _GLIBCXX_EXPORT_TEMPLATE # include <bits/sstream.tcc> #endif -#endif +#endif /* _GLIBCXX_SSTREAM */ diff --git a/contrib/libstdc++/include/std/std_stack.h b/contrib/libstdc++/include/std/std_stack.h index ddae7e78fc68..70f045684e0e 100644 --- a/contrib/libstdc++/include/std/std_stack.h +++ b/contrib/libstdc++/include/std/std_stack.h @@ -1,6 +1,6 @@ // <stack> -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,20 +58,16 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_STACK -#define _CPP_STACK 1 +#ifndef _GLIBCXX_STACK +#define _GLIBCXX_STACK 1 #pragma GCC system_header #include <bits/stl_algobase.h> -#include <bits/stl_alloc.h> +#include <bits/allocator.h> #include <bits/stl_construct.h> #include <bits/stl_uninitialized.h> -#include <bits/stl_deque.h> +#include <deque> #include <bits/stl_stack.h> -#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT -# include <bits/deque.tcc> -#endif - -#endif /* _CPP_STACK */ +#endif /* _GLIBCXX_STACK */ diff --git a/contrib/libstdc++/include/std/std_stdexcept.h b/contrib/libstdc++/include/std/std_stdexcept.h index 07a15e466ce5..ebd97f50f887 100644 --- a/contrib/libstdc++/include/std/std_stdexcept.h +++ b/contrib/libstdc++/include/std/std_stdexcept.h @@ -36,8 +36,8 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_STDEXCEPT -#define _CPP_STDEXCEPT 1 +#ifndef _GLIBCXX_STDEXCEPT +#define _GLIBCXX_STDEXCEPT 1 #pragma GCC system_header @@ -145,4 +145,4 @@ namespace std }; } // namespace std -#endif // _CPP_STDEXCEPT +#endif /* _GLIBCXX_STDEXCEPT */ diff --git a/contrib/libstdc++/include/std/std_streambuf.h b/contrib/libstdc++/include/std/std_streambuf.h index a1958c1a8e7c..42b3d782b0f1 100644 --- a/contrib/libstdc++/include/std/std_streambuf.h +++ b/contrib/libstdc++/include/std/std_streambuf.h @@ -1,6 +1,6 @@ // Stream buffer classes -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -37,14 +37,13 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_STREAMBUF -#define _CPP_STREAMBUF 1 +#ifndef _CLIBXX_STREAMBUF +#define _CLIBXX_STREAMBUF 1 #pragma GCC system_header #include <bits/c++config.h> #include <iosfwd> -#include <cstdio> // For SEEK_SET, SEEK_CUR, SEEK_END #include <bits/localefwd.h> #include <bits/ios_base.h> @@ -57,8 +56,7 @@ namespace std */ template<typename _CharT, typename _Traits> streamsize - __copy_streambufs(basic_ios<_CharT, _Traits>& _ios, - basic_streambuf<_CharT, _Traits>* __sbin, + __copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin, basic_streambuf<_CharT, _Traits>* __sbout); /** @@ -141,12 +139,10 @@ namespace std //@{ /** * @if maint - * These are non-standard types. + * This is a non-standard type. * @endif */ - typedef ctype<char_type> __ctype_type; typedef basic_streambuf<char_type, traits_type> __streambuf_type; - typedef typename traits_type::state_type __state_type; //@} friend class basic_ios<char_type, traits_type>; @@ -156,42 +152,10 @@ namespace std friend class ostreambuf_iterator<char_type, traits_type>; friend streamsize - __copy_streambufs<>(basic_ios<char_type, traits_type>& __ios, - __streambuf_type* __sbin,__streambuf_type* __sbout); + __copy_streambufs<>(__streambuf_type* __sbin, + __streambuf_type* __sbout); protected: - /** - * @if maint - * Pointer to the beginning of internally-allocated space. Filebuf - * manually allocates/deallocates this, whereas stringstreams attempt - * to use the built-in intelligence of the string class. If you are - * managing memory, set this. If not, leave it NULL. - * @endif - */ - char_type* _M_buf; - - /** - * @if maint - * Actual size of allocated internal buffer, in bytes. - * @endif - */ - size_t _M_buf_size; - - /** - * @if maint - * Optimal or preferred size of internal buffer, in bytes. - * @endif - */ - size_t _M_buf_size_opt; - - /** - * @if maint - * True iff _M_in_* and _M_out_* buffers should always point to - * the same place. True for fstreams, false for sstreams. - * @endif - */ - bool _M_buf_unified; - //@{ /** * @if maint @@ -202,20 +166,12 @@ namespace std * - put == output == write * @endif */ - char_type* _M_in_beg; // Start of get area. - char_type* _M_in_cur; // Current read area. - char_type* _M_in_end; // End of get area. - char_type* _M_out_beg; // Start of put area. - char_type* _M_out_cur; // Current put area. - char_type* _M_out_end; // End of put area. - //@} - - /** - * @if maint - * Place to stash in || out || in | out settings for current streambuf. - * @endif - */ - ios_base::openmode _M_mode; + char_type* _M_in_beg; // Start of get area. + char_type* _M_in_cur; // Current read area. + char_type* _M_in_end; // End of get area. + char_type* _M_out_beg; // Start of put area. + char_type* _M_out_cur; // Current put area. + char_type* _M_out_end; // End of put area. /** * @if maint @@ -224,147 +180,11 @@ namespace std */ locale _M_buf_locale; - /** - * @if maint - * True iff locale is initialized. - * @endif - */ - bool _M_buf_locale_init; - - //@{ - /** - * @if maint - * Necessary bits for putback buffer management. Only used in - * the basic_filebuf class, as necessary for the standard - * requirements. The only basic_streambuf member function that - * needs access to these data members is in_avail... - * - * @note pbacks of over one character are not currently supported. - * @endif - */ - static const size_t _S_pback_size = 1; - char_type _M_pback[_S_pback_size]; - char_type* _M_pback_cur_save; - char_type* _M_pback_end_save; - bool _M_pback_init; - //@} - - /** - * @if maint - * Yet unused. - * @endif - */ - fpos<__state_type> _M_pos; - - // Initializes pback buffers, and moves normal buffers to safety. - // Assumptions: - // _M_in_cur has already been moved back - void - _M_pback_create() - { - if (!_M_pback_init) - { - size_t __dist = _M_in_end - _M_in_cur; - size_t __len = min(_S_pback_size, __dist); - traits_type::copy(_M_pback, _M_in_cur, __len); - _M_pback_cur_save = _M_in_cur; - _M_pback_end_save = _M_in_end; - this->setg(_M_pback, _M_pback, _M_pback + __len); - _M_pback_init = true; - } - } - - // Deactivates pback buffer contents, and restores normal buffer. - // Assumptions: - // The pback buffer has only moved forward. - void - _M_pback_destroy() throw() - { - if (_M_pback_init) - { - // Length _M_in_cur moved in the pback buffer. - size_t __off_cur = _M_in_cur - _M_pback; - - // For in | out buffers, the end can be pushed back... - size_t __off_end = 0; - size_t __pback_len = _M_in_end - _M_pback; - size_t __save_len = _M_pback_end_save - _M_buf; - if (__pback_len > __save_len) - __off_end = __pback_len - __save_len; - - this->setg(_M_buf, _M_pback_cur_save + __off_cur, - _M_pback_end_save + __off_end); - _M_pback_cur_save = NULL; - _M_pback_end_save = NULL; - _M_pback_init = false; - } - } - - // Correctly sets the _M_in_cur pointer, and bumps the - // _M_out_cur pointer as well if necessary. - void - _M_in_cur_move(off_type __n) // argument needs to be +- - { - bool __testout = _M_out_cur; - _M_in_cur += __n; - if (__testout && _M_buf_unified) - _M_out_cur += __n; - } - - // Correctly sets the _M_out_cur pointer, and bumps the - // appropriate _M_*_end pointers as well. Necessary for the - // un-tied stringbufs, in in|out mode. - // Invariant: - // __n + _M_out_[cur, end] <= _M_buf + _M_buf_size - // Assuming all _M_*_[beg, cur, end] pointers are operating on - // the same range: - // _M_buf <= _M_*_ <= _M_buf + _M_buf_size - void - _M_out_cur_move(off_type __n) // argument needs to be +- - { - bool __testin = _M_in_cur; - - _M_out_cur += __n; - if (__testin && _M_buf_unified) - _M_in_cur += __n; - if (_M_out_cur > _M_out_end) - { - _M_out_end = _M_out_cur; - // NB: in | out buffers drag the _M_in_end pointer along... - if (__testin) - _M_in_end += __n; - } - } - - // Return the size of the output buffer. This depends on the - // buffer in use: allocated buffers have a stored size in - // _M_buf_size and setbuf() buffers don't. - off_type - _M_out_buf_size() - { - off_type __ret = 0; - if (_M_out_cur) - { - // Using allocated buffer. - if (_M_out_beg == _M_buf) - __ret = _M_out_beg + _M_buf_size - _M_out_cur; - // Using non-allocated buffer. - else - __ret = _M_out_end - _M_out_cur; - } - return __ret; - } - public: /// Destructor deallocates no buffer space. virtual ~basic_streambuf() - { - _M_buf_unified = false; - _M_buf_size = 0; - _M_buf_size_opt = 0; - _M_mode = ios_base::openmode(0); - } + { } // [27.5.2.2.1] locales /** @@ -379,6 +199,7 @@ namespace std { locale __tmp(this->getloc()); this->imbue(__loc); + _M_buf_locale = __loc; return __tmp; } @@ -433,21 +254,8 @@ namespace std streamsize in_avail() { - streamsize __ret; - if (_M_in_cur && _M_in_cur < _M_in_end) - { - if (_M_pback_init) - { - size_t __save_len = _M_pback_end_save - _M_pback_cur_save; - size_t __pback_len = _M_in_cur - _M_pback; - __ret = __save_len - __pback_len; - } - else - __ret = this->egptr() - this->gptr(); - } - else - __ret = this->showmanyc(); - return __ret; + const streamsize __ret = this->egptr() - this->gptr(); + return __ret ? __ret : this->showmanyc(); } /** @@ -460,9 +268,11 @@ namespace std int_type snextc() { - int_type __eof = traits_type::eof(); - return (traits_type::eq_int_type(this->sbumpc(), __eof) - ? __eof : this->sgetc()); + int_type __ret = traits_type::eof(); + if (__builtin_expect(!traits_type::eq_int_type(this->sbumpc(), + __ret), true)) + __ret = this->sgetc(); + return __ret; } /** @@ -474,7 +284,18 @@ namespace std * @c uflow(). */ int_type - sbumpc(); + sbumpc() + { + int_type __ret; + if (__builtin_expect(this->gptr() < this->egptr(), true)) + { + __ret = traits_type::to_int_type(*this->gptr()); + this->gbump(1); + } + else + __ret = this->uflow(); + return __ret; + } /** * @brief Getting the next character. @@ -488,8 +309,8 @@ namespace std sgetc() { int_type __ret; - if (_M_in_cur && _M_in_cur < _M_in_end) - __ret = traits_type::to_int_type(*(this->gptr())); + if (__builtin_expect(this->gptr() < this->egptr(), true)) + __ret = traits_type::to_int_type(*this->gptr()); else __ret = this->underflow(); return __ret; @@ -518,7 +339,20 @@ namespace std * fetched from the input stream will be @a c. */ int_type - sputbackc(char_type __c); + sputbackc(char_type __c) + { + int_type __ret; + const bool __testpos = this->eback() < this->gptr(); + if (__builtin_expect(!__testpos || + !traits_type::eq(__c, this->gptr()[-1]), false)) + __ret = this->pbackfail(traits_type::to_int_type(__c)); + else + { + this->gbump(-1); + __ret = traits_type::to_int_type(*this->gptr()); + } + return __ret; + } /** * @brief Moving backwards in the input stream. @@ -530,7 +364,18 @@ namespace std * "gotten". */ int_type - sungetc(); + sungetc() + { + int_type __ret; + if (__builtin_expect(this->eback() < this->gptr(), true)) + { + this->gbump(-1); + __ret = traits_type::to_int_type(*this->gptr()); + } + else + __ret = this->pbackfail(); + return __ret; + } // [27.5.2.2.5] put area /** @@ -546,7 +391,19 @@ namespace std * position is not available, returns @c overflow(c). */ int_type - sputc(char_type __c); + sputc(char_type __c) + { + int_type __ret; + if (__builtin_expect(this->pptr() < this->epptr(), true)) + { + *this->pptr() = __c; + this->pbump(1); + __ret = traits_type::to_int_type(__c); + } + else + __ret = this->overflow(traits_type::to_int_type(__c)); + return __ret; + } /** * @brief Entry point for all single-character output functions. @@ -574,12 +431,9 @@ namespace std * - this is not an error */ basic_streambuf() - : _M_buf(NULL), _M_buf_size(0), _M_buf_size_opt(BUFSIZ), - _M_buf_unified(false), _M_in_beg(0), _M_in_cur(0), _M_in_end(0), - _M_out_beg(0), _M_out_cur(0), _M_out_end(0), - _M_mode(ios_base::openmode(0)), _M_buf_locale(locale()), - _M_pback_cur_save(0), _M_pback_end_save(0), - _M_pback_init(false) + : _M_in_beg(0), _M_in_cur(0), _M_in_end(0), + _M_out_beg(0), _M_out_cur(0), _M_out_end(0), + _M_buf_locale(locale()) { } // [27.5.2.3.1] get area access @@ -627,8 +481,6 @@ namespace std _M_in_beg = __gbeg; _M_in_cur = __gnext; _M_in_end = __gend; - if (!(_M_mode & ios_base::in) && __gbeg && __gnext && __gend) - _M_mode = _M_mode | ios_base::in; } // [27.5.2.3.2] put area access @@ -673,9 +525,7 @@ namespace std setp(char_type* __pbeg, char_type* __pend) { _M_out_beg = _M_out_cur = __pbeg; - _M_out_end = __pend; - if (!(_M_mode & ios_base::out) && __pbeg && __pend) - _M_mode = _M_mode | ios_base::out; + _M_out_end = __pend; } // [27.5.2.4] virtual functions @@ -688,15 +538,13 @@ namespace std * are changed by this call. The standard adds, "Between invocations * of this function a class derived from streambuf can safely cache * results of calls to locale functions and to members of facets - * so obtained." This function simply stores the new locale for use - * by derived classes. + * so obtained." + * + * @note Base class version does nothing. */ virtual void - imbue(const locale& __loc) - { - if (_M_buf_locale != __loc) - _M_buf_locale = __loc; - } + imbue(const locale&) + { } // [27.5.2.4.2] buffer management and positioning /** @@ -822,14 +670,12 @@ namespace std uflow() { int_type __ret = traits_type::eof(); - bool __testeof = traits_type::eq_int_type(this->underflow(), __ret); - bool __testpending = _M_in_cur && _M_in_cur < _M_in_end; - if (!__testeof && __testpending) + const bool __testeof = traits_type::eq_int_type(this->underflow(), + __ret); + if (!__testeof) { - __ret = traits_type::to_int_type(*_M_in_cur); - ++_M_in_cur; - if (_M_buf_unified && _M_mode & ios_base::out) - ++_M_out_cur; + __ret = traits_type::to_int_type(*this->gptr()); + this->gbump(1); } return __ret; } @@ -891,7 +737,7 @@ namespace std overflow(int_type /* __c */ = traits_type::eof()) { return traits_type::eof(); } -#ifdef _GLIBCPP_DEPRECATED +#ifdef _GLIBCXX_DEPRECATED // Annex D.6 public: /** @@ -903,35 +749,36 @@ namespace std * See http://gcc.gnu.org/ml/libstdc++/2002-05/msg00168.html * * @note This function has been deprecated by the standard. You - * must define @c _GLIBCPP_DEPRECATED to make this visible; see + * must define @c _GLIBCXX_DEPRECATED to make this visible; see * c++config.h. */ void stossc() { - if (_M_in_cur < _M_in_end) - ++_M_in_cur; + if (this->gptr() < this->egptr()) + this->gbump(1); else this->uflow(); } #endif -#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS - // Side effect of DR 50. private: - basic_streambuf(const __streambuf_type&) { }; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // Side effect of DR 50. + basic_streambuf(const __streambuf_type& __sb) + : _M_in_beg(__sb._M_in_beg), _M_in_cur(__sb._M_in_cur), + _M_in_end(__sb._M_in_end), _M_out_beg(__sb._M_out_beg), + _M_out_cur(__sb._M_out_cur), _M_out_end(__sb._M_out_cur), + _M_buf_locale(__sb._M_buf_locale) + { } __streambuf_type& operator=(const __streambuf_type&) { return *this; }; -#endif }; } // namespace std -#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT -# define export -#endif -#ifdef _GLIBCPP_FULLY_COMPLIANT_HEADERS -#include <bits/streambuf.tcc> +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <bits/streambuf.tcc> #endif -#endif +#endif /* _GLIBCXX_STREAMBUF */ diff --git a/contrib/libstdc++/include/std/std_string.h b/contrib/libstdc++/include/std/std_string.h index 6b82f8ecb0cc..2b15658c7684 100644 --- a/contrib/libstdc++/include/std/std_string.h +++ b/contrib/libstdc++/include/std/std_string.h @@ -1,6 +1,6 @@ // Components for manipulating sequences of characters -*- C++ -*- -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -37,8 +37,8 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_STRING -#define _CPP_STRING 1 +#ifndef _GLIBCXX_STRING +#define _GLIBCXX_STRING 1 #pragma GCC system_header @@ -52,10 +52,9 @@ #include <bits/stl_function.h> // For less #include <bits/basic_string.h> -#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT +#ifndef _GLIBCXX_EXPORT_TEMPLATE # include <algorithm> // for find_if # include <bits/basic_string.tcc> #endif -#endif /* _CPP_STRING */ - +#endif /* _GLIBCXX_STRING */ diff --git a/contrib/libstdc++/include/std/std_utility.h b/contrib/libstdc++/include/std/std_utility.h index b9c6c09ff648..fe93090f9399 100644 --- a/contrib/libstdc++/include/std/std_utility.h +++ b/contrib/libstdc++/include/std/std_utility.h @@ -58,16 +58,13 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_UTILITY -#define _CPP_UTILITY 1 +#ifndef _GLIBCXX_UTILITY +#define _GLIBCXX_UTILITY 1 #pragma GCC system_header + #include <bits/c++config.h> #include <bits/stl_relops.h> #include <bits/stl_pair.h> -#endif /* _CPP_UTILITY */ - -// Local Variables: -// mode:C++ -// End: +#endif /* _GLIBCXX_UTILITY */ diff --git a/contrib/libstdc++/include/std/std_valarray.h b/contrib/libstdc++/include/std/std_valarray.h index b4de5dfec370..b893b3354159 100644 --- a/contrib/libstdc++/include/std/std_valarray.h +++ b/contrib/libstdc++/include/std/std_valarray.h @@ -1,6 +1,6 @@ // The template and inlines for the -*- C++ -*- valarray class. -// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -35,8 +35,8 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_VALARRAY -#define _CPP_VALARRAY 1 +#ifndef _GLIBCXX_VALARRAY +#define _GLIBCXX_VALARRAY 1 #pragma GCC system_header @@ -46,6 +46,7 @@ #include <cstdlib> #include <numeric> #include <algorithm> +#include <debug/debug.h> namespace std { @@ -90,10 +91,21 @@ namespace std } // namespace std #include <bits/valarray_array.h> -#include <bits/valarray_meta.h> +#include <bits/valarray_before.h> namespace std { + /** + * @brief Smart array designed to support numeric processing. + * + * A valarray is an array that provides constraints intended to allow for + * effective optimization of numeric array processing by reducing the + * aliasing that can result from pointer representations. It represents a + * one-dimensional array from which different multidimensional subsets can + * be accessed and modified. + * + * @param Tp Type of object in the array. + */ template<class _Tp> class valarray { @@ -107,71 +119,289 @@ namespace std typedef _Tp value_type; // _lib.valarray.cons_ construct/destroy: + /// Construct an empty array. valarray(); + + /// Construct an array with @a n elements. explicit valarray(size_t); + + /// Construct an array with @a n elements initialized to @a t. valarray(const _Tp&, size_t); + + /// Construct an array initialized to the first @a n elements of @a t. valarray(const _Tp* __restrict__, size_t); + + /// Copy constructor. valarray(const valarray&); + + /// Construct an array with the same size and values in @a sa. valarray(const slice_array<_Tp>&); + + /// Construct an array with the same size and values in @a ga. valarray(const gslice_array<_Tp>&); + + /// Construct an array with the same size and values in @a ma. valarray(const mask_array<_Tp>&); + + /// Construct an array with the same size and values in @a ia. valarray(const indirect_array<_Tp>&); + template<class _Dom> valarray(const _Expr<_Dom,_Tp>& __e); ~valarray(); // _lib.valarray.assign_ assignment: + /** + * @brief Assign elements to an array. + * + * Assign elements of array to values in @a v. Results are undefined + * if @a v is not the same size as this array. + * + * @param v Valarray to get values from. + */ valarray<_Tp>& operator=(const valarray<_Tp>&); + + /** + * @brief Assign elements to a value. + * + * Assign all elements of array to @a t. + * + * @param t Value for elements. + */ valarray<_Tp>& operator=(const _Tp&); + + /** + * @brief Assign elements to an array subset. + * + * Assign elements of array to values in @a sa. Results are undefined + * if @a sa is not the same size as this array. + * + * @param sa Array slice to get values from. + */ valarray<_Tp>& operator=(const slice_array<_Tp>&); + + /** + * @brief Assign elements to an array subset. + * + * Assign elements of array to values in @a ga. Results are undefined + * if @a ga is not the same size as this array. + * + * @param ga Array slice to get values from. + */ valarray<_Tp>& operator=(const gslice_array<_Tp>&); + + /** + * @brief Assign elements to an array subset. + * + * Assign elements of array to values in @a ma. Results are undefined + * if @a ma is not the same size as this array. + * + * @param ma Array slice to get values from. + */ valarray<_Tp>& operator=(const mask_array<_Tp>&); + + /** + * @brief Assign elements to an array subset. + * + * Assign elements of array to values in @a ia. Results are undefined + * if @a ia is not the same size as this array. + * + * @param ia Array slice to get values from. + */ valarray<_Tp>& operator=(const indirect_array<_Tp>&); template<class _Dom> valarray<_Tp>& operator= (const _Expr<_Dom,_Tp>&); // _lib.valarray.access_ element access: - // XXX: LWG to be resolved. - const _Tp& operator[](size_t) const; - _Tp& operator[](size_t); + /** + * Return a reference to the i'th array element. + * + * @param i Index of element to return. + * @return Reference to the i'th element. + */ + _Tp& operator[](size_t); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 389. Const overload of valarray::operator[] returns by value. + const _Tp& operator[](size_t) const; + // _lib.valarray.sub_ subset operations: + /** + * @brief Return an array subset. + * + * Returns a new valarray containing the elements of the array + * indicated by the slice argument. The new valarray is the size of + * the input slice. @see slice. + * + * @param s The source slice. + * @return New valarray containing elements in @a s. + */ _Expr<_SClos<_ValArray,_Tp>, _Tp> operator[](slice) const; + + /** + * @brief Return a reference to an array subset. + * + * Returns a new valarray containing the elements of the array + * indicated by the slice argument. The new valarray is the size of + * the input slice. @see slice. + * + * @param s The source slice. + * @return New valarray containing elements in @a s. + */ slice_array<_Tp> operator[](slice); + + /** + * @brief Return an array subset. + * + * Returns a slice_array referencing the elements of the array + * indicated by the slice argument. @see gslice. + * + * @param s The source slice. + * @return Slice_array referencing elements indicated by @a s. + */ _Expr<_GClos<_ValArray,_Tp>, _Tp> operator[](const gslice&) const; + + /** + * @brief Return a reference to an array subset. + * + * Returns a new valarray containing the elements of the array + * indicated by the gslice argument. The new valarray is + * the size of the input gslice. @see gslice. + * + * @param s The source gslice. + * @return New valarray containing elements in @a s. + */ gslice_array<_Tp> operator[](const gslice&); + + /** + * @brief Return an array subset. + * + * Returns a new valarray containing the elements of the array + * indicated by the argument. The input is a valarray of bool which + * represents a bitmask indicating which elements should be copied into + * the new valarray. Each element of the array is added to the return + * valarray if the corresponding element of the argument is true. + * + * @param m The valarray bitmask. + * @return New valarray containing elements indicated by @a m. + */ valarray<_Tp> operator[](const valarray<bool>&) const; + + /** + * @brief Return a reference to an array subset. + * + * Returns a new mask_array referencing the elements of the array + * indicated by the argument. The input is a valarray of bool which + * represents a bitmask indicating which elements are part of the + * subset. Elements of the array are part of the subset if the + * corresponding element of the argument is true. + * + * @param m The valarray bitmask. + * @return New valarray containing elements indicated by @a m. + */ mask_array<_Tp> operator[](const valarray<bool>&); + + /** + * @brief Return an array subset. + * + * Returns a new valarray containing the elements of the array + * indicated by the argument. The elements in the argument are + * interpreted as the indices of elements of this valarray to copy to + * the return valarray. + * + * @param i The valarray element index list. + * @return New valarray containing elements in @a s. + */ _Expr<_IClos<_ValArray, _Tp>, _Tp> operator[](const valarray<size_t>&) const; + + /** + * @brief Return a reference to an array subset. + * + * Returns an indirect_array referencing the elements of the array + * indicated by the argument. The elements in the argument are + * interpreted as the indices of elements of this valarray to include + * in the subset. The returned indirect_array refers to these + * elements. + * + * @param i The valarray element index list. + * @return Indirect_array referencing elements in @a i. + */ indirect_array<_Tp> operator[](const valarray<size_t>&); // _lib.valarray.unary_ unary operators: + /// Return a new valarray by applying unary + to each element. typename _UnaryOp<__unary_plus>::_Rt operator+() const; + + /// Return a new valarray by applying unary - to each element. typename _UnaryOp<__negate>::_Rt operator-() const; + + /// Return a new valarray by applying unary ~ to each element. typename _UnaryOp<__bitwise_not>::_Rt operator~() const; + + /// Return a new valarray by applying unary ! to each element. typename _UnaryOp<__logical_not>::_Rt operator!() const; // _lib.valarray.cassign_ computed assignment: + /// Multiply each element of array by @a t. valarray<_Tp>& operator*=(const _Tp&); + + /// Divide each element of array by @a t. valarray<_Tp>& operator/=(const _Tp&); + + /// Set each element e of array to e % @a t. valarray<_Tp>& operator%=(const _Tp&); + + /// Add @a t to each element of array. valarray<_Tp>& operator+=(const _Tp&); + + /// Subtract @a t to each element of array. valarray<_Tp>& operator-=(const _Tp&); + + /// Set each element e of array to e ^ @a t. valarray<_Tp>& operator^=(const _Tp&); + + /// Set each element e of array to e & @a t. valarray<_Tp>& operator&=(const _Tp&); + + /// Set each element e of array to e | @a t. valarray<_Tp>& operator|=(const _Tp&); + + /// Left shift each element e of array by @a t bits. valarray<_Tp>& operator<<=(const _Tp&); + + /// Right shift each element e of array by @a t bits. valarray<_Tp>& operator>>=(const _Tp&); + + /// Multiply elements of array by corresponding elements of @a v. valarray<_Tp>& operator*=(const valarray<_Tp>&); + + /// Divide elements of array by corresponding elements of @a v. valarray<_Tp>& operator/=(const valarray<_Tp>&); + + /// Modulo elements of array by corresponding elements of @a v. valarray<_Tp>& operator%=(const valarray<_Tp>&); + + /// Add corresponding elements of @a v to elements of array. valarray<_Tp>& operator+=(const valarray<_Tp>&); + + /// Subtract corresponding elements of @a v from elements of array. valarray<_Tp>& operator-=(const valarray<_Tp>&); + + /// Logical xor corresponding elements of @a v with elements of array. valarray<_Tp>& operator^=(const valarray<_Tp>&); + + /// Logical or corresponding elements of @a v with elements of array. valarray<_Tp>& operator|=(const valarray<_Tp>&); + + /// Logical and corresponding elements of @a v with elements of array. valarray<_Tp>& operator&=(const valarray<_Tp>&); + + /// Left shift elements of array by corresponding elements of @a v. valarray<_Tp>& operator<<=(const valarray<_Tp>&); + + /// Right shift elements of array by corresponding elements of @a v. valarray<_Tp>& operator>>=(const valarray<_Tp>&); template<class _Dom> @@ -197,18 +427,93 @@ namespace std // _lib.valarray.members_ member functions: + /// Return the number of elements in array. size_t size() const; - _Tp sum() const; + + /** + * @brief Return the sum of all elements in the array. + * + * Accumulates the sum of all elements into a Tp using +=. The order + * of adding the elements is unspecified. + */ + _Tp sum() const; + + /// Return the minimum element using operator<(). _Tp min() const; + + /// Return the maximum element using operator<(). _Tp max() const; // // FIXME: Extension // _Tp product () const; + /** + * @brief Return a shifted array. + * + * A new valarray is constructed as a copy of this array with elements + * in shifted positions. For an element with index i, the new position + * is i - n. The new valarray is the same size as the current one. + * New elements without a value are set to 0. Elements whos new + * position is outside the bounds of the array are discarded. + * + * Positive arguments shift toward index 0, discarding elements [0, n). + * Negative arguments discard elements from the top of the array. + * + * @param n Number of element positions to shift. + * @return New valarray with elements in shifted positions. + */ valarray<_Tp> shift (int) const; + + /** + * @brief Return a rotated array. + * + * A new valarray is constructed as a copy of this array with elements + * in shifted positions. For an element with index i, the new position + * is (i - n) % size(). The new valarray is the same size as the + * current one. Elements that are shifted beyond the array bounds are + * shifted into the other end of the array. No elements are lost. + * + * Positive arguments shift toward index 0, wrapping around the top. + * Negative arguments shift towards the top, wrapping around to 0. + * + * @param n Number of element positions to rotate. + * @return New valarray with elements in shifted positions. + */ valarray<_Tp> cshift(int) const; + + /** + * @brief Apply a function to the array. + * + * Returns a new valarray with elements assigned to the result of + * applying func to the corresponding element of this array. The new + * array is the same size as this one. + * + * @param func Function of Tp returning Tp to apply. + * @return New valarray with transformed elements. + */ _Expr<_ValFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(_Tp)) const; + + /** + * @brief Apply a function to the array. + * + * Returns a new valarray with elements assigned to the result of + * applying func to the corresponding element of this array. The new + * array is the same size as this one. + * + * @param func Function of const Tp& returning Tp to apply. + * @return New valarray with transformed elements. + */ _Expr<_RefFunClos<_ValArray,_Tp>,_Tp> apply(_Tp func(const _Tp&)) const; + + /** + * @brief Resize array. + * + * Resize this array to be @a size and set all elements to @a c. All + * references and iterators are invalidated. + * + * @param size New array size. + * @param c New value for all elements. + */ void resize(size_t __size, _Tp __c = _Tp()); private: @@ -221,15 +526,23 @@ namespace std template<typename _Tp> inline const _Tp& valarray<_Tp>::operator[](size_t __i) const - { return _M_data[__i]; } + { + __glibcxx_requires_subscript(__i); + return _M_data[__i]; + } template<typename _Tp> inline _Tp& valarray<_Tp>::operator[](size_t __i) - { return _M_data[__i]; } + { + __glibcxx_requires_subscript(__i); + return _M_data[__i]; + } } // std:: - + +#include <bits/valarray_after.h> + #include <bits/slice_array.h> #include <bits/gslice.h> #include <bits/gslice_array.h> @@ -246,32 +559,35 @@ namespace std inline valarray<_Tp>::valarray(size_t __n) : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) - { __valarray_default_construct(_M_data, _M_data + __n); } + { std::__valarray_default_construct(_M_data, _M_data + __n); } template<typename _Tp> inline valarray<_Tp>::valarray(const _Tp& __t, size_t __n) : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) - { __valarray_fill_construct(_M_data, _M_data + __n, __t); } + { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); } template<typename _Tp> inline valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n) : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) - { __valarray_copy_construct(__p, __p + __n, _M_data); } + { + _GLIBCXX_DEBUG_ASSERT(__p != 0 || __n == 0); + std::__valarray_copy_construct(__p, __p + __n, _M_data); + } template<typename _Tp> inline valarray<_Tp>::valarray(const valarray<_Tp>& __v) : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size)) - { __valarray_copy_construct(__v._M_data, __v._M_data + _M_size, _M_data); } + { std::__valarray_copy_construct(__v._M_data, __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(__valarray_get_storage<_Tp>(__sa._M_sz)) { - __valarray_copy + std::__valarray_copy (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data)); } @@ -281,7 +597,7 @@ namespace std : _M_size(__ga._M_index.size()), _M_data(__valarray_get_storage<_Tp>(_M_size)) { - __valarray_copy + std::__valarray_copy (__ga._M_array, _Array<size_t>(__ga._M_index), _Array<_Tp>(_M_data), _M_size); } @@ -291,7 +607,7 @@ namespace std valarray<_Tp>::valarray(const mask_array<_Tp>& __ma) : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz)) { - __valarray_copy + std::__valarray_copy (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size); } @@ -300,7 +616,7 @@ namespace std valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia) : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz)) { - __valarray_copy + std::__valarray_copy (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size); } @@ -308,21 +624,22 @@ namespace std inline valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e) : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size)) - { __valarray_copy(__e, _M_size, _Array<_Tp>(_M_data)); } + { std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data)); } template<typename _Tp> inline valarray<_Tp>::~valarray() { - __valarray_destroy_elements(_M_data, _M_data + _M_size); - __valarray_release_memory(_M_data); + std::__valarray_destroy_elements(_M_data, _M_data + _M_size); + std::__valarray_release_memory(_M_data); } template<typename _Tp> inline valarray<_Tp>& valarray<_Tp>::operator=(const valarray<_Tp>& __v) { - __valarray_copy(__v._M_data, _M_size, _M_data); + _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size); + std::__valarray_copy(__v._M_data, _M_size, _M_data); return *this; } @@ -330,7 +647,7 @@ namespace std inline valarray<_Tp>& valarray<_Tp>::operator=(const _Tp& __t) { - __valarray_fill(_M_data, _M_size, __t); + std::__valarray_fill(_M_data, _M_size, __t); return *this; } @@ -338,8 +655,9 @@ namespace std 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)); + _GLIBCXX_DEBUG_ASSERT(_M_size == __sa._M_sz); + std::__valarray_copy(__sa._M_array, __sa._M_sz, + __sa._M_stride, _Array<_Tp>(_M_data)); return *this; } @@ -347,8 +665,9 @@ namespace std 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); + _GLIBCXX_DEBUG_ASSERT(_M_size == __ga._M_index.size()); + std::__valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index), + _Array<_Tp>(_M_data), _M_size); return *this; } @@ -356,8 +675,9 @@ namespace std 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); + _GLIBCXX_DEBUG_ASSERT(_M_size == __ma._M_sz); + std::__valarray_copy(__ma._M_array, __ma._M_mask, + _Array<_Tp>(_M_data), _M_size); return *this; } @@ -365,8 +685,9 @@ namespace std 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); + _GLIBCXX_DEBUG_ASSERT(_M_size == __ia._M_sz); + std::__valarray_copy(__ia._M_array, __ia._M_index, + _Array<_Tp>(_M_data), _M_size); return *this; } @@ -374,8 +695,9 @@ namespace std inline valarray<_Tp>& valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) { - __valarray_copy(__e, _M_size, _Array<_Tp>(_M_data)); - return *this; + _GLIBCXX_DEBUG_ASSERT(_M_size == __e.size()); + std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data)); + return *this; } template<typename _Tp> @@ -458,7 +780,8 @@ namespace std inline _Tp valarray<_Tp>::sum() const { - return __valarray_sum(_M_data, _M_data + _M_size); + _GLIBCXX_DEBUG_ASSERT(_M_size > 0); + return std::__valarray_sum(_M_data, _M_data + _M_size); } // template<typename _Tp> @@ -475,21 +798,21 @@ namespace std _Tp* const __a = static_cast<_Tp*> (__builtin_alloca(sizeof(_Tp) * _M_size)); if (__n == 0) // no shift - __valarray_copy_construct(_M_data, _M_data + _M_size, __a); + std::__valarray_copy_construct(_M_data, _M_data + _M_size, __a); else if (__n > 0) // __n > 0: shift left { if (size_t(__n) > _M_size) - __valarray_default_construct(__a, __a + __n); + std::__valarray_default_construct(__a, __a + __n); else { - __valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a); - __valarray_default_construct(__a+_M_size-__n, __a + _M_size); + std::__valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a); + std::__valarray_default_construct(__a+_M_size-__n, __a + _M_size); } } else // __n < 0: shift right { - __valarray_copy_construct (_M_data, _M_data+_M_size+__n, __a-__n); - __valarray_default_construct(__a, __a - __n); + std::__valarray_copy_construct (_M_data, _M_data+_M_size+__n, __a-__n); + std::__valarray_default_construct(__a, __a - __n); } return valarray<_Tp> (__a, _M_size); } @@ -501,17 +824,17 @@ namespace std _Tp* const __a = static_cast<_Tp*> (__builtin_alloca (sizeof(_Tp) * _M_size)); if (__n == 0) // no cshift - __valarray_copy_construct(_M_data, _M_data + _M_size, __a); + std::__valarray_copy_construct(_M_data, _M_data + _M_size, __a); else if (__n > 0) // cshift left { - __valarray_copy_construct(_M_data, _M_data+__n, __a+_M_size-__n); - __valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a); + std::__valarray_copy_construct(_M_data, _M_data+__n, __a+_M_size-__n); + std::__valarray_copy_construct(_M_data+__n, _M_data + _M_size, __a); } else // cshift right { - __valarray_copy_construct + std::__valarray_copy_construct (_M_data + _M_size+__n, _M_data + _M_size, __a); - __valarray_copy_construct + std::__valarray_copy_construct (_M_data, _M_data + _M_size+__n, __a - __n); } return valarray<_Tp>(__a, _M_size); @@ -524,28 +847,30 @@ namespace std // This complication is so to make valarray<valarray<T> > work // even though it is not required by the standard. Nobody should // be saying valarray<valarray<T> > anyway. See the specs. - __valarray_destroy_elements(_M_data, _M_data + _M_size); + std::__valarray_destroy_elements(_M_data, _M_data + _M_size); if (_M_size != __n) { - __valarray_release_memory(_M_data); + std::__valarray_release_memory(_M_data); _M_size = __n; _M_data = __valarray_get_storage<_Tp>(__n); } - __valarray_fill_construct(_M_data, _M_data + __n, __c); + std::__valarray_fill_construct(_M_data, _M_data + __n, __c); } template<typename _Tp> inline _Tp valarray<_Tp>::min() const { - return *min_element (_M_data, _M_data+_M_size); + _GLIBCXX_DEBUG_ASSERT(_M_size > 0); + return *std::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); + _GLIBCXX_DEBUG_ASSERT(_M_size > 0); + return *std::max_element (_M_data, _M_data+_M_size); } template<class _Tp> @@ -594,6 +919,7 @@ namespace std inline valarray<_Tp>& \ valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v) \ { \ + _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size); \ _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, \ _Array<_Tp>(__v._M_data)); \ return *this; \ @@ -641,6 +967,7 @@ _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right) typename __fun<_Name, _Tp>::result_type> \ operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ { \ + _GLIBCXX_DEBUG_ASSERT(__v.size() == __w.size()); \ typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure; \ typedef typename __fun<_Name, _Tp>::result_type _Rt; \ return _Expr<_Closure, _Rt>(_Closure(__v, __w)); \ @@ -687,8 +1014,4 @@ _DEFINE_BINARY_OPERATOR(>=, __greater_equal) } // namespace std -#endif // _CPP_VALARRAY - -// Local Variables: -// mode:c++ -// End: +#endif /* _GLIBCXX_VALARRAY */ diff --git a/contrib/libstdc++/include/std/std_vector.h b/contrib/libstdc++/include/std/std_vector.h index 5738ef7ade89..16e50a99ec8c 100644 --- a/contrib/libstdc++/include/std/std_vector.h +++ b/contrib/libstdc++/include/std/std_vector.h @@ -1,6 +1,6 @@ // <vector> -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -58,22 +58,26 @@ * in your programs, rather than any of the "st[dl]_*.h" implementation files. */ -#ifndef _CPP_VECTOR -#define _CPP_VECTOR 1 +#ifndef _GLIBCXX_VECTOR +#define _GLIBCXX_VECTOR 1 #pragma GCC system_header #include <bits/functexcept.h> #include <bits/stl_algobase.h> -#include <bits/stl_alloc.h> +#include <bits/allocator.h> #include <bits/stl_construct.h> #include <bits/stl_uninitialized.h> #include <bits/stl_vector.h> #include <bits/stl_bvector.h> -#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT -# include <bits/vector.tcc> +#ifndef _GLIBCXX_EXPORT_TEMPLATE +# include <bits/vector.tcc> #endif -#endif /* _CPP_VECTOR */ +#ifdef _GLIBCXX_DEBUG +# include <debug/vector> +#endif + +#endif /* _GLIBCXX_VECTOR */ diff --git a/contrib/libstdc++/include/stdc++.h b/contrib/libstdc++/include/stdc++.h new file mode 100644 index 000000000000..d350a3c0df46 --- /dev/null +++ b/contrib/libstdc++/include/stdc++.h @@ -0,0 +1,82 @@ +// C++ includes used for precompiling -*- C++ -*- + +// Copyright (C) 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// 17.4.1.2 Headers + +// C +#include <cassert> +#include <cctype> +#include <cerrno> +#include <cfloat> +#include <ciso646> +#include <climits> +#include <clocale> +#include <cmath> +#include <csetjmp> +#include <csignal> +#include <cstdarg> +#include <cstddef> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <ctime> + +// C++ +#include <algorithm> +#include <bitset> +#include <complex> +#include <deque> +#include <exception> +#include <fstream> +#include <functional> +#include <iomanip> +#include <ios> +#include <iosfwd> +#include <iostream> +#include <istream> +#include <iterator> +#include <limits> +#include <list> +#include <locale> +#include <map> +#include <memory> +#include <new> +#include <numeric> +#include <ostream> +#include <queue> +#include <set> +#include <sstream> +#include <stack> +#include <stdexcept> +#include <streambuf> +#include <string> +#include <typeinfo> +#include <utility> +#include <valarray> +#include <vector> |