aboutsummaryrefslogtreecommitdiff
path: root/contrib/libstdc++/include
diff options
context:
space:
mode:
authorAlexander Kabaev <kan@FreeBSD.org>2004-07-28 03:12:05 +0000
committerAlexander Kabaev <kan@FreeBSD.org>2004-07-28 03:12:05 +0000
commitffeaf689a248da869b6bc8d4fd2233dfe513c060 (patch)
tree75ef0e6da73746d6849e25a0996ae34e1aeff51d /contrib/libstdc++/include
parent9a63ad9273061dc19cbd117762e365ea9634e241 (diff)
downloadsrc-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')
-rw-r--r--contrib/libstdc++/include/Makefile.am417
-rw-r--r--contrib/libstdc++/include/Makefile.in797
-rw-r--r--contrib/libstdc++/include/backward/algo.h124
-rw-r--r--contrib/libstdc++/include/backward/algobase.h32
-rw-r--r--contrib/libstdc++/include/backward/alloc.h16
-rw-r--r--contrib/libstdc++/include/backward/backward_warning.h8
-rw-r--r--contrib/libstdc++/include/backward/bvector.h11
-rw-r--r--contrib/libstdc++/include/backward/complex.h10
-rw-r--r--contrib/libstdc++/include/backward/defalloc.h28
-rw-r--r--contrib/libstdc++/include/backward/deque.h6
-rw-r--r--contrib/libstdc++/include/backward/fstream.h6
-rw-r--r--contrib/libstdc++/include/backward/function.h120
-rw-r--r--contrib/libstdc++/include/backward/hash_map.h6
-rw-r--r--contrib/libstdc++/include/backward/hash_set.h6
-rw-r--r--contrib/libstdc++/include/backward/hashtable.h8
-rw-r--r--contrib/libstdc++/include/backward/heap.h6
-rw-r--r--contrib/libstdc++/include/backward/iomanip.h4
-rw-r--r--contrib/libstdc++/include/backward/iostream.h6
-rw-r--r--contrib/libstdc++/include/backward/istream.h4
-rw-r--r--contrib/libstdc++/include/backward/iterator.h39
-rw-r--r--contrib/libstdc++/include/backward/list.h6
-rw-r--r--contrib/libstdc++/include/backward/map.h6
-rw-r--r--contrib/libstdc++/include/backward/multimap.h6
-rw-r--r--contrib/libstdc++/include/backward/multiset.h6
-rw-r--r--contrib/libstdc++/include/backward/new.h18
-rw-r--r--contrib/libstdc++/include/backward/ostream.h6
-rw-r--r--contrib/libstdc++/include/backward/pair.h6
-rw-r--r--contrib/libstdc++/include/backward/queue.h6
-rw-r--r--contrib/libstdc++/include/backward/rope.h18
-rw-r--r--contrib/libstdc++/include/backward/set.h6
-rw-r--r--contrib/libstdc++/include/backward/slist.h6
-rw-r--r--contrib/libstdc++/include/backward/stack.h6
-rw-r--r--contrib/libstdc++/include/backward/stream.h6
-rw-r--r--contrib/libstdc++/include/backward/streambuf.h6
-rw-r--r--contrib/libstdc++/include/backward/strstream17
-rw-r--r--contrib/libstdc++/include/backward/tempbuf.h12
-rw-r--r--contrib/libstdc++/include/backward/tree.h6
-rw-r--r--contrib/libstdc++/include/backward/vector.h8
-rw-r--r--contrib/libstdc++/include/bits/allocator.h130
-rw-r--r--contrib/libstdc++/include/bits/allocator_traits.h237
-rw-r--r--contrib/libstdc++/include/bits/atomicity.h46
-rw-r--r--contrib/libstdc++/include/bits/basic_ios.h185
-rw-r--r--contrib/libstdc++/include/bits/basic_ios.tcc165
-rw-r--r--contrib/libstdc++/include/bits/basic_string.h1645
-rw-r--r--contrib/libstdc++/include/bits/basic_string.tcc795
-rw-r--r--contrib/libstdc++/include/bits/boost_concept_check.h150
-rw-r--r--contrib/libstdc++/include/bits/c++config89
-rw-r--r--contrib/libstdc++/include/bits/char_traits.h291
-rw-r--r--contrib/libstdc++/include/bits/codecvt.h327
-rw-r--r--contrib/libstdc++/include/bits/concept_check.h38
-rw-r--r--contrib/libstdc++/include/bits/concurrence.h95
-rw-r--r--contrib/libstdc++/include/bits/cpp_type_traits.h271
-rw-r--r--contrib/libstdc++/include/bits/deque.tcc860
-rw-r--r--contrib/libstdc++/include/bits/fstream.tcc864
-rw-r--r--contrib/libstdc++/include/bits/functexcept.h8
-rw-r--r--contrib/libstdc++/include/bits/gslice.h125
-rw-r--r--contrib/libstdc++/include/bits/gslice_array.h92
-rw-r--r--contrib/libstdc++/include/bits/indirect_array.h176
-rw-r--r--contrib/libstdc++/include/bits/ios_base.h440
-rw-r--r--contrib/libstdc++/include/bits/istream.tcc1067
-rw-r--r--contrib/libstdc++/include/bits/list.tcc293
-rw-r--r--contrib/libstdc++/include/bits/locale_classes.h601
-rw-r--r--contrib/libstdc++/include/bits/locale_facets.h4128
-rw-r--r--contrib/libstdc++/include/bits/locale_facets.tcc3050
-rw-r--r--contrib/libstdc++/include/bits/localefwd.h91
-rw-r--r--contrib/libstdc++/include/bits/mask_array.h100
-rw-r--r--contrib/libstdc++/include/bits/ostream.tcc654
-rw-r--r--contrib/libstdc++/include/bits/postypes.h215
-rw-r--r--contrib/libstdc++/include/bits/slice_array.h111
-rw-r--r--contrib/libstdc++/include/bits/sstream.tcc222
-rw-r--r--contrib/libstdc++/include/bits/stl_algo.h5612
-rw-r--r--contrib/libstdc++/include/bits/stl_algobase.h557
-rw-r--r--contrib/libstdc++/include/bits/stl_bvector.h1213
-rw-r--r--contrib/libstdc++/include/bits/stl_construct.h61
-rw-r--r--contrib/libstdc++/include/bits/stl_deque.h2556
-rw-r--r--contrib/libstdc++/include/bits/stl_function.h1486
-rw-r--r--contrib/libstdc++/include/bits/stl_heap.h357
-rw-r--r--contrib/libstdc++/include/bits/stl_iterator.h398
-rw-r--r--contrib/libstdc++/include/bits/stl_iterator_base_funcs.h62
-rw-r--r--contrib/libstdc++/include/bits/stl_iterator_base_types.h23
-rw-r--r--contrib/libstdc++/include/bits/stl_list.h2004
-rw-r--r--contrib/libstdc++/include/bits/stl_map.h1045
-rw-r--r--contrib/libstdc++/include/bits/stl_multimap.h987
-rw-r--r--contrib/libstdc++/include/bits/stl_multiset.h728
-rw-r--r--contrib/libstdc++/include/bits/stl_numeric.h163
-rw-r--r--contrib/libstdc++/include/bits/stl_pair.h176
-rw-r--r--contrib/libstdc++/include/bits/stl_queue.h596
-rw-r--r--contrib/libstdc++/include/bits/stl_raw_storage_iter.h31
-rw-r--r--contrib/libstdc++/include/bits/stl_relops.h114
-rw-r--r--contrib/libstdc++/include/bits/stl_set.h735
-rw-r--r--contrib/libstdc++/include/bits/stl_stack.h296
-rw-r--r--contrib/libstdc++/include/bits/stl_tempbuf.h186
-rw-r--r--contrib/libstdc++/include/bits/stl_threads.h168
-rw-r--r--contrib/libstdc++/include/bits/stl_tree.h1623
-rw-r--r--contrib/libstdc++/include/bits/stl_uninitialized.h223
-rw-r--r--contrib/libstdc++/include/bits/stl_vector.h532
-rw-r--r--contrib/libstdc++/include/bits/stream_iterator.h166
-rw-r--r--contrib/libstdc++/include/bits/streambuf.tcc196
-rw-r--r--contrib/libstdc++/include/bits/streambuf_iterator.h154
-rw-r--r--contrib/libstdc++/include/bits/stringfwd.h14
-rw-r--r--contrib/libstdc++/include/bits/type_traits.h508
-rw-r--r--contrib/libstdc++/include/bits/valarray_after.h499
-rw-r--r--contrib/libstdc++/include/bits/valarray_array.h115
-rw-r--r--contrib/libstdc++/include/bits/valarray_array.tcc299
-rw-r--r--contrib/libstdc++/include/bits/valarray_before.h701
-rw-r--r--contrib/libstdc++/include/bits/vector.tcc315
-rw-r--r--contrib/libstdc++/include/c/std_cctype.h8
-rw-r--r--contrib/libstdc++/include/c/std_cerrno.h6
-rw-r--r--contrib/libstdc++/include/c/std_cfloat.h6
-rw-r--r--contrib/libstdc++/include/c/std_climits.h6
-rw-r--r--contrib/libstdc++/include/c/std_clocale.h6
-rw-r--r--contrib/libstdc++/include/c/std_cmath.h26
-rw-r--r--contrib/libstdc++/include/c/std_csetjmp.h6
-rw-r--r--contrib/libstdc++/include/c/std_csignal.h6
-rw-r--r--contrib/libstdc++/include/c/std_cstdarg.h6
-rw-r--r--contrib/libstdc++/include/c/std_cstddef.h6
-rw-r--r--contrib/libstdc++/include/c/std_cstdio.h6
-rw-r--r--contrib/libstdc++/include/c/std_cstdlib.h8
-rw-r--r--contrib/libstdc++/include/c/std_cstring.h4
-rw-r--r--contrib/libstdc++/include/c/std_ctime.h6
-rw-r--r--contrib/libstdc++/include/c/std_cwchar.h16
-rw-r--r--contrib/libstdc++/include/c/std_cwctype.h10
-rw-r--r--contrib/libstdc++/include/c_compatibility/ctype.h4
-rw-r--r--contrib/libstdc++/include/c_compatibility/errno.h4
-rw-r--r--contrib/libstdc++/include/c_compatibility/float.h4
-rw-r--r--contrib/libstdc++/include/c_compatibility/iso646.h6
-rw-r--r--contrib/libstdc++/include/c_compatibility/limits.h6
-rw-r--r--contrib/libstdc++/include/c_compatibility/locale.h6
-rw-r--r--contrib/libstdc++/include/c_compatibility/math.h6
-rw-r--r--contrib/libstdc++/include/c_compatibility/setjmp.h4
-rw-r--r--contrib/libstdc++/include/c_compatibility/signal.h4
-rw-r--r--contrib/libstdc++/include/c_compatibility/stdarg.h4
-rw-r--r--contrib/libstdc++/include/c_compatibility/stddef.h4
-rw-r--r--contrib/libstdc++/include/c_compatibility/stdio.h6
-rw-r--r--contrib/libstdc++/include/c_compatibility/stdlib.h4
-rw-r--r--contrib/libstdc++/include/c_compatibility/string.h6
-rw-r--r--contrib/libstdc++/include/c_compatibility/time.h6
-rw-r--r--contrib/libstdc++/include/c_compatibility/wchar.h20
-rw-r--r--contrib/libstdc++/include/c_compatibility/wctype.h6
-rw-r--r--contrib/libstdc++/include/c_std/cmath.tcc12
-rw-r--r--contrib/libstdc++/include/c_std/std_cassert.h2
-rw-r--r--contrib/libstdc++/include/c_std/std_cctype.h6
-rw-r--r--contrib/libstdc++/include/c_std/std_cerrno.h4
-rw-r--r--contrib/libstdc++/include/c_std/std_cfloat.h4
-rw-r--r--contrib/libstdc++/include/c_std/std_climits.h4
-rw-r--r--contrib/libstdc++/include/c_std/std_clocale.h4
-rw-r--r--contrib/libstdc++/include/c_std/std_cmath.h657
-rw-r--r--contrib/libstdc++/include/c_std/std_csetjmp.h4
-rw-r--r--contrib/libstdc++/include/c_std/std_csignal.h4
-rw-r--r--contrib/libstdc++/include/c_std/std_cstdarg.h4
-rw-r--r--contrib/libstdc++/include/c_std/std_cstddef.h6
-rw-r--r--contrib/libstdc++/include/c_std/std_cstdio.h14
-rw-r--r--contrib/libstdc++/include/c_std/std_cstdlib.h48
-rw-r--r--contrib/libstdc++/include/c_std/std_cstring.h6
-rw-r--r--contrib/libstdc++/include/c_std/std_ctime.h4
-rw-r--r--contrib/libstdc++/include/c_std/std_cwchar.h56
-rw-r--r--contrib/libstdc++/include/c_std/std_cwctype.h24
-rw-r--r--contrib/libstdc++/include/debug/bitset299
-rw-r--r--contrib/libstdc++/include/debug/debug.h531
-rw-r--r--contrib/libstdc++/include/debug/deque386
-rw-r--r--contrib/libstdc++/include/debug/formatter.h391
-rw-r--r--contrib/libstdc++/include/debug/hash_map38
-rw-r--r--contrib/libstdc++/include/debug/hash_map.h270
-rw-r--r--contrib/libstdc++/include/debug/hash_multimap.h261
-rw-r--r--contrib/libstdc++/include/debug/hash_multiset.h236
-rw-r--r--contrib/libstdc++/include/debug/hash_set38
-rw-r--r--contrib/libstdc++/include/debug/hash_set.h245
-rw-r--r--contrib/libstdc++/include/debug/list505
-rw-r--r--contrib/libstdc++/include/debug/map38
-rw-r--r--contrib/libstdc++/include/debug/map.h323
-rw-r--r--contrib/libstdc++/include/debug/multimap.h314
-rw-r--r--contrib/libstdc++/include/debug/multiset.h320
-rw-r--r--contrib/libstdc++/include/debug/safe_base.h207
-rw-r--r--contrib/libstdc++/include/debug/safe_iterator.h618
-rw-r--r--contrib/libstdc++/include/debug/safe_iterator.tcc140
-rw-r--r--contrib/libstdc++/include/debug/safe_sequence.h180
-rw-r--r--contrib/libstdc++/include/debug/set38
-rw-r--r--contrib/libstdc++/include/debug/set.h325
-rw-r--r--contrib/libstdc++/include/debug/string1001
-rw-r--r--contrib/libstdc++/include/debug/vector412
-rw-r--r--contrib/libstdc++/include/ext/algorithm274
-rw-r--r--contrib/libstdc++/include/ext/bitmap_allocator.h859
-rw-r--r--contrib/libstdc++/include/ext/debug_allocator.h121
-rw-r--r--contrib/libstdc++/include/ext/demangle.h2789
-rw-r--r--contrib/libstdc++/include/ext/enc_filebuf.h37
-rw-r--r--contrib/libstdc++/include/ext/functional32
-rw-r--r--contrib/libstdc++/include/ext/hash_fun.h122
-rw-r--r--contrib/libstdc++/include/ext/hash_map89
-rw-r--r--contrib/libstdc++/include/ext/hash_set112
-rw-r--r--contrib/libstdc++/include/ext/hashtable.h994
-rw-r--r--contrib/libstdc++/include/ext/iterator22
-rw-r--r--contrib/libstdc++/include/ext/malloc_allocator.h118
-rw-r--r--contrib/libstdc++/include/ext/memory37
-rw-r--r--contrib/libstdc++/include/ext/mt_allocator.h718
-rw-r--r--contrib/libstdc++/include/ext/new_allocator.h113
-rw-r--r--contrib/libstdc++/include/ext/numeric21
-rw-r--r--contrib/libstdc++/include/ext/pod_char_traits.h158
-rw-r--r--contrib/libstdc++/include/ext/pool_allocator.h254
-rw-r--r--contrib/libstdc++/include/ext/rb_tree48
-rw-r--r--contrib/libstdc++/include/ext/rope2452
-rw-r--r--contrib/libstdc++/include/ext/ropeimpl.h327
-rw-r--r--contrib/libstdc++/include/ext/slist203
-rw-r--r--contrib/libstdc++/include/ext/stdio_filebuf.h111
-rw-r--r--contrib/libstdc++/include/ext/stdio_sync_filebuf.h281
-rw-r--r--contrib/libstdc++/include/std/std_algorithm.h10
-rw-r--r--contrib/libstdc++/include/std/std_bitset.h367
-rw-r--r--contrib/libstdc++/include/std/std_complex.h291
-rw-r--r--contrib/libstdc++/include/std/std_deque.h17
-rw-r--r--contrib/libstdc++/include/std/std_fstream.h376
-rw-r--r--contrib/libstdc++/include/std/std_functional.h12
-rw-r--r--contrib/libstdc++/include/std/std_iomanip.h10
-rw-r--r--contrib/libstdc++/include/std/std_ios.h7
-rw-r--r--contrib/libstdc++/include/std/std_iosfwd.h14
-rw-r--r--contrib/libstdc++/include/std/std_iostream.h8
-rw-r--r--contrib/libstdc++/include/std/std_istream.h55
-rw-r--r--contrib/libstdc++/include/std/std_iterator.h11
-rw-r--r--contrib/libstdc++/include/std/std_limits.h328
-rw-r--r--contrib/libstdc++/include/std/std_list.h18
-rw-r--r--contrib/libstdc++/include/std/std_locale.h6
-rw-r--r--contrib/libstdc++/include/std/std_map.h12
-rw-r--r--contrib/libstdc++/include/std/std_memory.h109
-rw-r--r--contrib/libstdc++/include/std/std_numeric.h11
-rw-r--r--contrib/libstdc++/include/std/std_ostream.h42
-rw-r--r--contrib/libstdc++/include/std/std_queue.h20
-rw-r--r--contrib/libstdc++/include/std/std_set.h12
-rw-r--r--contrib/libstdc++/include/std/std_sstream.h159
-rw-r--r--contrib/libstdc++/include/std/std_stack.h16
-rw-r--r--contrib/libstdc++/include/std/std_stdexcept.h6
-rw-r--r--contrib/libstdc++/include/std/std_streambuf.h361
-rw-r--r--contrib/libstdc++/include/std/std_string.h11
-rw-r--r--contrib/libstdc++/include/std/std_utility.h11
-rw-r--r--contrib/libstdc++/include/std/std_valarray.h435
-rw-r--r--contrib/libstdc++/include/std/std_vector.h18
-rw-r--r--contrib/libstdc++/include/stdc++.h82
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>