OSDN Git Service

2007-09-11 Johannes Singler <singler@ira.uka.de>
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Sep 2007 22:32:51 +0000 (22:32 +0000)
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Sep 2007 22:32:51 +0000 (22:32 +0000)
    Leonor Frias Moya  <lfrias@lsi.upc.edu>
            Felix Putze  <kontakt@felix-putze.de>
            Marius Elvert  <marius.elvert@ira.uka.de>
    Felix Bondarenko  <f.bondarenko@web.de>
    Robert Geisberger  <robert.geisberger@stud.uni-karlsruhe.de>
    Robin Dapp  <r.dapp@freenet.de>
       Benjamin Kosnik  <bkoz@redhat.com>

Add parallel mode.
* include/parallel: New.
* include/parallel/iterator.h: New.
* include/parallel/multiway_merge.h: New.
* include/parallel/parallel.h: New.
* include/parallel/algorithm
* include/parallel/find_selectors.h: New.
* include/parallel/losertree.h: New.
* include/parallel/list_partition.h: New.
* include/parallel/types.h: New.
* include/parallel/for_each.h: New.
* include/parallel/multiseq_selection.h: New.
* include/parallel/workstealing.h: New.
* include/parallel/base.h: New.
* include/parallel/par_loop.h: New.
* include/parallel/numeric
* include/parallel/features.h: New.
* include/parallel/quicksort.h: New.
* include/parallel/algorithmfwd.h: New.
* include/parallel/equally_split.h: New.
* include/parallel/compiletime_settings.h: New.
* include/parallel/for_each_selectors.h: New.
* include/parallel/basic_iterator.h: New.
* include/parallel/omp_loop_static.h: New.
* include/parallel/random_shuffle.h: New.
* include/parallel/balanced_quicksort.h: New.
* include/parallel/set_operations.h: New.
* include/parallel/tags.h: New.
* include/parallel/merge.h: New.
* include/parallel/tree.h: New.
* include/parallel/settings.h: New.
* include/parallel/unique_copy.h: New.
* include/parallel/multiway_mergesort.h: New.
* include/parallel/numericfwd.h: New.
* include/parallel/search.h: New.
* include/parallel/partition.h: New.
* include/parallel/compatibility.h: New.
* include/parallel/algobase.h: New.
* include/parallel/find.h: New.
* include/parallel/partial_sum.h: New.
* include/parallel/algo.h: New.
* include/parallel/omp_loop.h: New.
* include/parallel/queue.h: New.
* include/parallel/timing.h: New.
* include/parallel/sort.h: New.
* include/parallel/checkers.h: New.
* include/parallel/random_number.h: New.
* include/bits/algorithmfwd.h: New.

* acinclude.m4 (GLIBCXX_ENABLE_PARALLEL): New.
* configure.host: Add atomic_flags.
* configure.ac: Export ATOMIC_FLAGS, call GLIBCXX_ENABLE_PARALLEL.
* src/Makefile.am: Add parallel_list rules.
* include/Makefile.am: Add parallel files.
* testsuite/Makefile.am (check-parallel): Add.
(check-performance-parallel): Add.
* config.h.in: Regenerate.
* configure: Same.
* libsupc++/Makefile.in: Same.
* testsuite/Makefile.in: Same.
* Makefile.in: Same.
* libmath/Makefile.in: Same.
* include/Makefile.in: Same.
* src/Makefile.in: Same.
* po/Makefile.in: Same.

* config/abi/pre/gnu.ver: Export parallel list bits.

* docs/html/parallel_mode.html: New.
* docs/html/documentation.html: Add link.
* docs/doxygen/user.cfg.in: Adjust for new files and directory.
* docs/doxygen/doxygroups.cc: Adjust namespace markup.

* include/debug/set.h: Adjust for _GLIBCXX_STD_D or _P change.
* include/debug/bitset: Same.
* include/debug/multiset.h: Same.
* include/debug/vector: Same.
* include/debug/map.h: Same.
* include/debug/deque: Same.
* include/debug/list: Same.
* include/debug/debug.h: Same.
* include/debug/multimap.h: Same.
* include/std/algorithm: Same.
* include/std/numeric: Same.
* include/std/bitset: Same.
* include/std/string: Same.
* include/ext/hash_map: Same.
* include/ext/hash_set: Same.
* include/bits/stl_list.h: Same.
* include/bits/stl_map.h: Same.
* include/bits/stl_algobase.h: Same.
* include/bits/stl_set.h: Same.
* include/bits/stl_multimap.h: Same.
* include/bits/stl_vector.h: Same.
* include/bits/stl_numeric.h: Same.
* include/bits/stl_deque.h: Same.
* include/bits/stl_multiset.h: Same.
* include/bits/char_traits.h: Same.
* include/bits/stl_algo.h: Same.
* include/bits/c++config: Same.
* include/bits/vector.tcc: Same.
* include/bits/deque.tcc: Same.
* include/bits/stl_bvector.h: Same.
* include/bits/list.tcc: Same.
* src/list.cc: Same.
* src/parallel_list.cc: New.

* testsuite/lib/libstdc++.exp (check_v3_target_parallel_mode): New.
* testsuite/lib/dg-options.exp (dg-require-parallel-mode): New.
* scripts/testsuite_flags.in (--cxxparallelflags): New.
* scripts/check_performance: Adjust.
* testsuite/25_algorithms/headers/parallel_algorithm.cc: New.
* testsuite/25_algorithms/headers/algorithm_parallel_mode.cc: New.
* testsuite/25_algorithms/headers/parallel_algorithm_mixed1.cc: New.
* testsuite/25_algorithms/headers/parallel_algorithm_mixed2.cc: New.
* testsuite/26_numerics/headers/numeric/parallel_numeric.cc: New.
* testsuite/26_numerics/headers/numeric/numeric_parallel_mode.cc: New.
* testsuite/26_numerics/headers/numeric/
parallel_numeric_mixed1.cc: New.
* testsuite/26_numerics/headers/numeric/
parallel_numeric_mixed2.cc: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@128395 138bc75d-0d04-0410-961f-82ee72b054a4

112 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/Makefile.in
libstdc++-v3/acinclude.m4
libstdc++-v3/config.h.in
libstdc++-v3/config/abi/pre/gnu.ver
libstdc++-v3/configure
libstdc++-v3/configure.ac
libstdc++-v3/configure.host
libstdc++-v3/docs/doxygen/doxygroups.cc
libstdc++-v3/docs/doxygen/user.cfg.in
libstdc++-v3/docs/html/documentation.html
libstdc++-v3/docs/html/parallel_mode.html [new file with mode: 0644]
libstdc++-v3/include/Makefile.am
libstdc++-v3/include/Makefile.in
libstdc++-v3/include/bits/algorithmfwd.h [new file with mode: 0644]
libstdc++-v3/include/bits/c++config
libstdc++-v3/include/bits/char_traits.h
libstdc++-v3/include/bits/deque.tcc
libstdc++-v3/include/bits/list.tcc
libstdc++-v3/include/bits/stl_algo.h
libstdc++-v3/include/bits/stl_algobase.h
libstdc++-v3/include/bits/stl_bvector.h
libstdc++-v3/include/bits/stl_deque.h
libstdc++-v3/include/bits/stl_list.h
libstdc++-v3/include/bits/stl_map.h
libstdc++-v3/include/bits/stl_multimap.h
libstdc++-v3/include/bits/stl_multiset.h
libstdc++-v3/include/bits/stl_numeric.h
libstdc++-v3/include/bits/stl_set.h
libstdc++-v3/include/bits/stl_vector.h
libstdc++-v3/include/bits/vector.tcc
libstdc++-v3/include/debug/bitset
libstdc++-v3/include/debug/debug.h
libstdc++-v3/include/debug/deque
libstdc++-v3/include/debug/list
libstdc++-v3/include/debug/map.h
libstdc++-v3/include/debug/multimap.h
libstdc++-v3/include/debug/multiset.h
libstdc++-v3/include/debug/set.h
libstdc++-v3/include/debug/vector
libstdc++-v3/include/ext/hash_map
libstdc++-v3/include/ext/hash_set
libstdc++-v3/include/parallel/algo.h [new file with mode: 0644]
libstdc++-v3/include/parallel/algobase.h [new file with mode: 0644]
libstdc++-v3/include/parallel/algorithm [new file with mode: 0644]
libstdc++-v3/include/parallel/algorithmfwd.h [new file with mode: 0644]
libstdc++-v3/include/parallel/balanced_quicksort.h [new file with mode: 0644]
libstdc++-v3/include/parallel/base.h [new file with mode: 0644]
libstdc++-v3/include/parallel/basic_iterator.h [new file with mode: 0644]
libstdc++-v3/include/parallel/checkers.h [new file with mode: 0644]
libstdc++-v3/include/parallel/compatibility.h [new file with mode: 0644]
libstdc++-v3/include/parallel/compiletime_settings.h [new file with mode: 0644]
libstdc++-v3/include/parallel/equally_split.h [new file with mode: 0644]
libstdc++-v3/include/parallel/features.h [new file with mode: 0644]
libstdc++-v3/include/parallel/find.h [new file with mode: 0644]
libstdc++-v3/include/parallel/find_selectors.h [new file with mode: 0644]
libstdc++-v3/include/parallel/for_each.h [new file with mode: 0644]
libstdc++-v3/include/parallel/for_each_selectors.h [new file with mode: 0644]
libstdc++-v3/include/parallel/iterator.h [new file with mode: 0644]
libstdc++-v3/include/parallel/list_partition.h [new file with mode: 0644]
libstdc++-v3/include/parallel/losertree.h [new file with mode: 0644]
libstdc++-v3/include/parallel/merge.h [new file with mode: 0644]
libstdc++-v3/include/parallel/multiseq_selection.h [new file with mode: 0644]
libstdc++-v3/include/parallel/multiway_merge.h [new file with mode: 0644]
libstdc++-v3/include/parallel/multiway_mergesort.h [new file with mode: 0644]
libstdc++-v3/include/parallel/numeric [new file with mode: 0644]
libstdc++-v3/include/parallel/numericfwd.h [new file with mode: 0644]
libstdc++-v3/include/parallel/omp_loop.h [new file with mode: 0644]
libstdc++-v3/include/parallel/omp_loop_static.h [new file with mode: 0644]
libstdc++-v3/include/parallel/par_loop.h [new file with mode: 0644]
libstdc++-v3/include/parallel/parallel.h [new file with mode: 0644]
libstdc++-v3/include/parallel/partial_sum.h [new file with mode: 0644]
libstdc++-v3/include/parallel/partition.h [new file with mode: 0644]
libstdc++-v3/include/parallel/queue.h [new file with mode: 0644]
libstdc++-v3/include/parallel/quicksort.h [new file with mode: 0644]
libstdc++-v3/include/parallel/random_number.h [new file with mode: 0644]
libstdc++-v3/include/parallel/random_shuffle.h [new file with mode: 0644]
libstdc++-v3/include/parallel/search.h [new file with mode: 0644]
libstdc++-v3/include/parallel/set_operations.h [new file with mode: 0644]
libstdc++-v3/include/parallel/settings.h [new file with mode: 0644]
libstdc++-v3/include/parallel/sort.h [new file with mode: 0644]
libstdc++-v3/include/parallel/tags.h [new file with mode: 0644]
libstdc++-v3/include/parallel/timing.h [new file with mode: 0644]
libstdc++-v3/include/parallel/tree.h [new file with mode: 0644]
libstdc++-v3/include/parallel/types.h [new file with mode: 0644]
libstdc++-v3/include/parallel/unique_copy.h [new file with mode: 0644]
libstdc++-v3/include/parallel/workstealing.h [new file with mode: 0644]
libstdc++-v3/include/std/algorithm
libstdc++-v3/include/std/bitset
libstdc++-v3/include/std/numeric
libstdc++-v3/include/std/string
libstdc++-v3/libmath/Makefile.in
libstdc++-v3/libsupc++/Makefile.in
libstdc++-v3/po/Makefile.in
libstdc++-v3/scripts/check_performance
libstdc++-v3/scripts/testsuite_flags.in
libstdc++-v3/src/Makefile.am
libstdc++-v3/src/Makefile.in
libstdc++-v3/src/list.cc
libstdc++-v3/src/parallel_list.cc [new file with mode: 0644]
libstdc++-v3/testsuite/25_algorithms/headers/algorithm_parallel_mode.cc [new file with mode: 0644]
libstdc++-v3/testsuite/25_algorithms/headers/parallel_algorithm.cc [new file with mode: 0644]
libstdc++-v3/testsuite/25_algorithms/headers/parallel_algorithm_mixed1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/25_algorithms/headers/parallel_algorithm_mixed2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/26_numerics/headers/numeric/numeric_parallel_mode.cc [new file with mode: 0644]
libstdc++-v3/testsuite/26_numerics/headers/numeric/parallel_numeric.cc [new file with mode: 0644]
libstdc++-v3/testsuite/26_numerics/headers/numeric/parallel_numeric_mixed1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/26_numerics/headers/numeric/parallel_numeric_mixed2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/Makefile.am
libstdc++-v3/testsuite/Makefile.in
libstdc++-v3/testsuite/lib/dg-options.exp
libstdc++-v3/testsuite/lib/libstdc++.exp

index f6dcbdc..6beffdb 100644 (file)
@@ -1,3 +1,134 @@
+2007-09-11  Johannes Singler  <singler@ira.uka.de>
+           Leonor Frias Moya  <lfrias@lsi.upc.edu>
+            Felix Putze  <kontakt@felix-putze.de>
+            Marius Elvert  <marius.elvert@ira.uka.de>
+           Felix Bondarenko  <f.bondarenko@web.de>
+           Robert Geisberger  <robert.geisberger@stud.uni-karlsruhe.de>
+           Robin Dapp  <r.dapp@freenet.de>
+           Benjamin Kosnik  <bkoz@redhat.com>
+
+       Add parallel mode.
+       * include/parallel: New.
+       * include/parallel/iterator.h: New.
+       * include/parallel/multiway_merge.h: New.
+       * include/parallel/parallel.h: New.
+       * include/parallel/algorithm
+       * include/parallel/find_selectors.h: New.
+       * include/parallel/losertree.h: New.
+       * include/parallel/list_partition.h: New.
+       * include/parallel/types.h: New.
+       * include/parallel/for_each.h: New.
+       * include/parallel/multiseq_selection.h: New.
+       * include/parallel/workstealing.h: New.
+       * include/parallel/base.h: New.
+       * include/parallel/par_loop.h: New.
+       * include/parallel/numeric
+       * include/parallel/features.h: New.
+       * include/parallel/quicksort.h: New.
+       * include/parallel/algorithmfwd.h: New.
+       * include/parallel/equally_split.h: New.
+       * include/parallel/compiletime_settings.h: New.
+       * include/parallel/for_each_selectors.h: New.
+       * include/parallel/basic_iterator.h: New.
+       * include/parallel/omp_loop_static.h: New.
+       * include/parallel/random_shuffle.h: New.
+       * include/parallel/balanced_quicksort.h: New.
+       * include/parallel/set_operations.h: New.
+       * include/parallel/tags.h: New.
+       * include/parallel/merge.h: New.
+       * include/parallel/tree.h: New.
+       * include/parallel/settings.h: New.
+       * include/parallel/unique_copy.h: New.
+       * include/parallel/multiway_mergesort.h: New.
+       * include/parallel/numericfwd.h: New.
+       * include/parallel/search.h: New.
+       * include/parallel/partition.h: New.
+       * include/parallel/compatibility.h: New.
+       * include/parallel/algobase.h: New.
+       * include/parallel/find.h: New.
+       * include/parallel/partial_sum.h: New.
+       * include/parallel/algo.h: New.
+       * include/parallel/omp_loop.h: New.
+       * include/parallel/queue.h: New.
+       * include/parallel/timing.h: New.
+       * include/parallel/sort.h: New.
+       * include/parallel/checkers.h: New.
+       * include/parallel/random_number.h: New.
+       * include/bits/algorithmfwd.h: New.
+
+       * acinclude.m4 (GLIBCXX_ENABLE_PARALLEL): New.
+       * configure.host: Add atomic_flags.
+       * configure.ac: Export ATOMIC_FLAGS, call GLIBCXX_ENABLE_PARALLEL.
+       * src/Makefile.am: Add parallel_list rules.
+       * include/Makefile.am: Add parallel files.
+       * testsuite/Makefile.am (check-parallel): Add.
+       (check-performance-parallel): Add.
+       * config.h.in: Regenerate.
+       * configure: Same.
+       * libsupc++/Makefile.in: Same.
+       * testsuite/Makefile.in: Same.
+       * Makefile.in: Same.
+       * libmath/Makefile.in: Same.
+       * include/Makefile.in: Same.
+       * src/Makefile.in: Same.
+       * po/Makefile.in: Same.
+       
+       * config/abi/pre/gnu.ver: Export parallel list bits.
+
+       * docs/html/parallel_mode.html: New.
+       * docs/html/documentation.html: Add link.
+       * docs/doxygen/user.cfg.in: Adjust for new files and directory.
+       * docs/doxygen/doxygroups.cc: Adjust namespace markup.
+
+       * include/debug/set.h: Adjust for _GLIBCXX_STD_D or _P change.
+       * include/debug/bitset: Same.
+       * include/debug/multiset.h: Same.
+       * include/debug/vector: Same.
+       * include/debug/map.h: Same.
+       * include/debug/deque: Same.
+       * include/debug/list: Same.
+       * include/debug/debug.h: Same.
+       * include/debug/multimap.h: Same.
+       * include/std/algorithm: Same.
+       * include/std/numeric: Same.
+       * include/std/bitset: Same.
+       * include/std/string: Same.
+       * include/ext/hash_map: Same.
+       * include/ext/hash_set: Same.
+       * include/bits/stl_list.h: Same.
+       * include/bits/stl_map.h: Same.
+       * include/bits/stl_algobase.h: Same.
+       * include/bits/stl_set.h: Same.
+       * include/bits/stl_multimap.h: Same.
+       * include/bits/stl_vector.h: Same.
+       * include/bits/stl_numeric.h: Same.
+       * include/bits/stl_deque.h: Same.
+       * include/bits/stl_multiset.h: Same.
+       * include/bits/char_traits.h: Same.
+       * include/bits/stl_algo.h: Same.
+       * include/bits/c++config: Same.
+       * include/bits/vector.tcc: Same.
+       * include/bits/deque.tcc: Same.
+       * include/bits/stl_bvector.h: Same.
+       * include/bits/list.tcc: Same.
+       * src/list.cc: Same.
+       * src/parallel_list.cc: New.
+
+       * testsuite/lib/libstdc++.exp (check_v3_target_parallel_mode): New.
+       * testsuite/lib/dg-options.exp (dg-require-parallel-mode): New.
+       * scripts/testsuite_flags.in (--cxxparallelflags): New.
+       * scripts/check_performance: Adjust.
+       * testsuite/25_algorithms/headers/parallel_algorithm.cc: New.
+       * testsuite/25_algorithms/headers/algorithm_parallel_mode.cc: New.
+       * testsuite/25_algorithms/headers/parallel_algorithm_mixed1.cc: New.
+       * testsuite/25_algorithms/headers/parallel_algorithm_mixed2.cc: New.
+       * testsuite/26_numerics/headers/numeric/parallel_numeric.cc: New.
+       * testsuite/26_numerics/headers/numeric/numeric_parallel_mode.cc: New.
+       * testsuite/26_numerics/headers/numeric/
+       parallel_numeric_mixed1.cc: New.
+       * testsuite/26_numerics/headers/numeric/
+       parallel_numeric_mixed2.cc: New.
+       
 2007-09-11  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * testsuite/lib/libstdc++.exp (libstdc++_init): Revert part of
index ac125e8..c3d4cc5 100644 (file)
@@ -103,6 +103,7 @@ AMTAR = @AMTAR@
 AR = @AR@
 AS = @AS@
 ATOMICITY_SRCDIR = @ATOMICITY_SRCDIR@
+ATOMIC_FLAGS = @ATOMIC_FLAGS@
 ATOMIC_WORD_SRCDIR = @ATOMIC_WORD_SRCDIR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
@@ -140,6 +141,8 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_PARALLEL_FALSE = @ENABLE_PARALLEL_FALSE@
+ENABLE_PARALLEL_TRUE = @ENABLE_PARALLEL_TRUE@
 ENABLE_SYMVERS_DARWIN_FALSE = @ENABLE_SYMVERS_DARWIN_FALSE@
 ENABLE_SYMVERS_DARWIN_TRUE = @ENABLE_SYMVERS_DARWIN_TRUE@
 ENABLE_SYMVERS_FALSE = @ENABLE_SYMVERS_FALSE@
index d29b793..a6343ed 100644 (file)
@@ -1725,6 +1725,23 @@ AC_DEFUN([GLIBCXX_ENABLE_CONCEPT_CHECKS], [
   fi
 ])
 
+dnl
+dnl Check for parallel mode pre-requisites, including OpenMP support.
+dnl
+dnl  +  Usage:  GLIBCXX_ENABLE_PARALLEL
+dnl
+AC_DEFUN([GLIBCXX_ENABLE_PARALLEL], [
+
+  enable_parallel=no;
+  if test -f "${glibcxx_builddir}/../libgomp/omp.h"; then
+    enable_parallel=yes;
+  fi
+
+  AC_MSG_CHECKING([for parallel mode support])
+  AC_MSG_RESULT([$enable_parallel])
+  GLIBCXX_CONDITIONAL(ENABLE_PARALLEL, test $enable_parallel = yes)
+])
+
 
 dnl
 dnl Check for which I/O library to use:  stdio, or something specific.
@@ -2072,7 +2089,7 @@ AC_DEFUN([GLIBCXX_ENABLE_PCH], [
 
   GLIBCXX_CONDITIONAL(GLIBCXX_BUILD_PCH, test $enable_libstdcxx_pch = yes)
   if test $enable_libstdcxx_pch = yes; then
-    glibcxx_PCHFLAGS="-include bits/stdtr1c++.h"
+    glibcxx_PCHFLAGS="-include bits/stdc++.h"
   else
     glibcxx_PCHFLAGS=""
   fi
index 647657c..4a9ffb7 100644 (file)
@@ -63,6 +63,9 @@
 /* Define if EBADMSG exists. */
 #undef HAVE_EBADMSG
 
+/* Define if ECANCELED exists. */
+#undef HAVE_ECANCELED
+
 /* Define to 1 if you have the <endian.h> header file. */
 #undef HAVE_ENDIAN_H
 
index 12d21f1..cc6252e 100644 (file)
@@ -770,6 +770,13 @@ GLIBCXX_3.4.10 {
     _ZNKSt4hashISsEclESs;
     _ZNKSt4hashISt10error_codeEclES0_;
 
+    # for parallel mode
+    _ZNSt9__cxx199815_List_node_base4hook*;
+    _ZNSt9__cxx199815_List_node_base4swap*;
+    _ZNSt9__cxx199815_List_node_base6unhookEv;
+    _ZNSt9__cxx199815_List_node_base7reverseEv;
+    _ZNSt9__cxx199815_List_node_base8transfer*;
+
 } GLIBCXX_3.4.9;
 
 # Symbols in the support library (libsupc++) have their own tag.
index 4b4a444..74d0aae 100755 (executable)
@@ -458,7 +458,7 @@ ac_includes_default="\
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libtool_VERSION multi_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar glibcxx_builddir glibcxx_srcdir toplevel_srcdir CC ac_ct_CC EXEEXT OBJEXT CXX ac_ct_CXX CFLAGS CXXFLAGS LN_S AS ac_ct_AS AR ac_ct_AR RANLIB ac_ct_RANLIB MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT CPP CPPFLAGS EGREP LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM lt_ECHO LDFLAGS CXXCPP enable_shared enable_static GLIBCXX_HOSTED_TRUE GLIBCXX_HOSTED_FALSE GLIBCXX_BUILD_PCH_TRUE GLIBCXX_BUILD_PCH_FALSE glibcxx_PCHFLAGS CSTDIO_H BASIC_FILE_H BASIC_FILE_CC check_msgfmt glibcxx_MOFILES glibcxx_POFILES glibcxx_localedir USE_NLS CLOCALE_H CMESSAGES_H CCODECVT_CC CCOLLATE_CC CCTYPE_CC CMESSAGES_CC CMONEY_CC CNUMERIC_CC CTIME_H CTIME_CC CLOCALE_CC CLOCALE_INTERNAL_H ALLOCATOR_H ALLOCATOR_NAME C_INCLUDE_DIR GLIBCXX_C_HEADERS_C_TRUE GLIBCXX_C_HEADERS_C_FALSE GLIBCXX_C_HEADERS_C_STD_TRUE GLIBCXX_C_HEADERS_C_STD_FALSE GLIBCXX_C_HEADERS_C_GLOBAL_TRUE GLIBCXX_C_HEADERS_C_GLOBAL_FALSE GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE GLIBCXX_C_HEADERS_EXTRA_TRUE GLIBCXX_C_HEADERS_EXTRA_FALSE DEBUG_FLAGS GLIBCXX_BUILD_DEBUG_TRUE GLIBCXX_BUILD_DEBUG_FALSE EXTRA_CXX_FLAGS glibcxx_thread_h WERROR SECTION_FLAGS SECTION_LDFLAGS OPT_LDFLAGS LIBMATHOBJS LIBICONV LTLIBICONV SYMVER_FILE port_specific_symbol_files ENABLE_SYMVERS_TRUE ENABLE_SYMVERS_FALSE ENABLE_SYMVERS_GNU_TRUE ENABLE_SYMVERS_GNU_FALSE ENABLE_SYMVERS_GNU_NAMESPACE_TRUE ENABLE_SYMVERS_GNU_NAMESPACE_FALSE ENABLE_SYMVERS_DARWIN_TRUE ENABLE_SYMVERS_DARWIN_FALSE ENABLE_VISIBILITY_TRUE ENABLE_VISIBILITY_FALSE GLIBCXX_LDBL_COMPAT_TRUE GLIBCXX_LDBL_COMPAT_FALSE baseline_dir ATOMICITY_SRCDIR ATOMIC_WORD_SRCDIR CPU_DEFINES_SRCDIR ABI_TWEAKS_SRCDIR OS_INC_SRCDIR ERROR_CONSTANTS_SRCDIR glibcxx_prefixdir gxx_include_dir glibcxx_toolexecdir glibcxx_toolexeclibdir GLIBCXX_INCLUDES TOPLEVEL_INCLUDES OPTIMIZE_CXXFLAGS WARN_FLAGS LIBSUPCXX_PICFLAGS LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS libtool_VERSION multi_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar glibcxx_builddir glibcxx_srcdir toplevel_srcdir CC ac_ct_CC EXEEXT OBJEXT CXX ac_ct_CXX CFLAGS CXXFLAGS LN_S AS ac_ct_AS AR ac_ct_AR RANLIB ac_ct_RANLIB MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT CPP CPPFLAGS EGREP LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM lt_ECHO LDFLAGS CXXCPP enable_shared enable_static GLIBCXX_HOSTED_TRUE GLIBCXX_HOSTED_FALSE GLIBCXX_BUILD_PCH_TRUE GLIBCXX_BUILD_PCH_FALSE glibcxx_PCHFLAGS CSTDIO_H BASIC_FILE_H BASIC_FILE_CC check_msgfmt glibcxx_MOFILES glibcxx_POFILES glibcxx_localedir USE_NLS CLOCALE_H CMESSAGES_H CCODECVT_CC CCOLLATE_CC CCTYPE_CC CMESSAGES_CC CMONEY_CC CNUMERIC_CC CTIME_H CTIME_CC CLOCALE_CC CLOCALE_INTERNAL_H ALLOCATOR_H ALLOCATOR_NAME C_INCLUDE_DIR GLIBCXX_C_HEADERS_C_TRUE GLIBCXX_C_HEADERS_C_FALSE GLIBCXX_C_HEADERS_C_STD_TRUE GLIBCXX_C_HEADERS_C_STD_FALSE GLIBCXX_C_HEADERS_C_GLOBAL_TRUE GLIBCXX_C_HEADERS_C_GLOBAL_FALSE GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE GLIBCXX_C_HEADERS_EXTRA_TRUE GLIBCXX_C_HEADERS_EXTRA_FALSE DEBUG_FLAGS GLIBCXX_BUILD_DEBUG_TRUE GLIBCXX_BUILD_DEBUG_FALSE ENABLE_PARALLEL_TRUE ENABLE_PARALLEL_FALSE EXTRA_CXX_FLAGS glibcxx_thread_h WERROR SECTION_FLAGS SECTION_LDFLAGS OPT_LDFLAGS LIBMATHOBJS LIBICONV LTLIBICONV SYMVER_FILE port_specific_symbol_files ENABLE_SYMVERS_TRUE ENABLE_SYMVERS_FALSE ENABLE_SYMVERS_GNU_TRUE ENABLE_SYMVERS_GNU_FALSE ENABLE_SYMVERS_GNU_NAMESPACE_TRUE ENABLE_SYMVERS_GNU_NAMESPACE_FALSE ENABLE_SYMVERS_DARWIN_TRUE ENABLE_SYMVERS_DARWIN_FALSE ENABLE_VISIBILITY_TRUE ENABLE_VISIBILITY_FALSE GLIBCXX_LDBL_COMPAT_TRUE GLIBCXX_LDBL_COMPAT_FALSE baseline_dir ATOMICITY_SRCDIR ATOMIC_WORD_SRCDIR ATOMIC_FLAGS CPU_DEFINES_SRCDIR ABI_TWEAKS_SRCDIR OS_INC_SRCDIR ERROR_CONSTANTS_SRCDIR glibcxx_prefixdir gxx_include_dir glibcxx_toolexecdir glibcxx_toolexeclibdir GLIBCXX_INCLUDES TOPLEVEL_INCLUDES OPTIMIZE_CXXFLAGS WARN_FLAGS LIBSUPCXX_PICFLAGS LIBOBJS LTLIBOBJS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -13949,7 +13949,7 @@ echo "${ECHO_T}$enable_libstdcxx_pch" >&6
 
 
   if test $enable_libstdcxx_pch = yes; then
-    glibcxx_PCHFLAGS="-include bits/stdtr1c++.h"
+    glibcxx_PCHFLAGS="-include bits/stdc++.h"
   else
     glibcxx_PCHFLAGS=""
   fi
@@ -16468,6 +16468,19 @@ fi;
 echo "${ECHO_T}$enable_libstdcxx_debug" >&6
 
 
+
+
+  enable_parallel=no;
+  if test -f "${glibcxx_builddir}/../libgomp/omp.h"; then
+    enable_parallel=yes;
+  fi
+
+  echo "$as_me:$LINENO: checking for parallel mode support" >&5
+echo $ECHO_N "checking for parallel mode support... $ECHO_C" >&6
+  echo "$as_me:$LINENO: result: $enable_parallel" >&5
+echo "${ECHO_T}$enable_parallel" >&6
+
+
   echo "$as_me:$LINENO: checking for extra compiler flags for building" >&5
 echo $ECHO_N "checking for extra compiler flags for building... $ECHO_C" >&6
    # Check whether --enable-cxx-flags or --disable-cxx-flags was given.
@@ -17279,7 +17292,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
   # Fake what AC_TRY_COMPILE does.  XXX Look at redoing this new-style.
     cat > conftest.$ac_ext << EOF
-#line 17282 "configure"
+#line 17295 "configure"
 int main()
 {
   // NB: _Atomic_word not necessarily int.
@@ -93897,6 +93910,7 @@ done
 # Propagate the target-specific source directories through the build chain.
 ATOMICITY_SRCDIR=config/${atomicity_dir}
 ATOMIC_WORD_SRCDIR=config/${atomic_word_dir}
+ATOMIC_FLAGS=${atomic_flags}
 CPU_DEFINES_SRCDIR=config/${cpu_defines_dir}
 OS_INC_SRCDIR=config/${os_include_dir}
 ERROR_CONSTANTS_SRCDIR=config/${error_constants_dir}
@@ -93909,6 +93923,7 @@ ABI_TWEAKS_SRCDIR=config/${abi_tweaks_dir}
 
 
 
+
 # Determine cross-compile flags and AM_CONDITIONALs.
 #AC_SUBST(GLIBCXX_IS_NATIVE)
 #AM_CONDITIONAL(CANADIAN, test $CANADIAN = yes)
 
 
 
+if test $enable_parallel = yes; then
+  ENABLE_PARALLEL_TRUE=
+  ENABLE_PARALLEL_FALSE='#'
+else
+  ENABLE_PARALLEL_TRUE='#'
+  ENABLE_PARALLEL_FALSE=
+fi
+
+
+
+
 if test $enable_symvers != no; then
   ENABLE_SYMVERS_TRUE=
   ENABLE_SYMVERS_FALSE='#'
@@ -94429,6 +94455,13 @@ echo "$as_me: error: conditional \"GLIBCXX_BUILD_DEBUG\" was never defined.
 Usually this means the macro was only invoked conditionally." >&2;}
    { (exit 1); exit 1; }; }
 fi
+if test -z "${ENABLE_PARALLEL_TRUE}" && test -z "${ENABLE_PARALLEL_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"ENABLE_PARALLEL\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"ENABLE_PARALLEL\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
 if test -z "${ENABLE_SYMVERS_TRUE}" && test -z "${ENABLE_SYMVERS_FALSE}"; then
   { { echo "$as_me:$LINENO: error: conditional \"ENABLE_SYMVERS\" was never defined.
 Usually this means the macro was only invoked conditionally." >&5
@@ -95474,6 +95507,8 @@ s,@GLIBCXX_C_HEADERS_EXTRA_FALSE@,$GLIBCXX_C_HEADERS_EXTRA_FALSE,;t t
 s,@DEBUG_FLAGS@,$DEBUG_FLAGS,;t t
 s,@GLIBCXX_BUILD_DEBUG_TRUE@,$GLIBCXX_BUILD_DEBUG_TRUE,;t t
 s,@GLIBCXX_BUILD_DEBUG_FALSE@,$GLIBCXX_BUILD_DEBUG_FALSE,;t t
+s,@ENABLE_PARALLEL_TRUE@,$ENABLE_PARALLEL_TRUE,;t t
+s,@ENABLE_PARALLEL_FALSE@,$ENABLE_PARALLEL_FALSE,;t t
 s,@EXTRA_CXX_FLAGS@,$EXTRA_CXX_FLAGS,;t t
 s,@glibcxx_thread_h@,$glibcxx_thread_h,;t t
 s,@WERROR@,$WERROR,;t t
@@ -95500,6 +95535,7 @@ s,@GLIBCXX_LDBL_COMPAT_FALSE@,$GLIBCXX_LDBL_COMPAT_FALSE,;t t
 s,@baseline_dir@,$baseline_dir,;t t
 s,@ATOMICITY_SRCDIR@,$ATOMICITY_SRCDIR,;t t
 s,@ATOMIC_WORD_SRCDIR@,$ATOMIC_WORD_SRCDIR,;t t
+s,@ATOMIC_FLAGS@,$ATOMIC_FLAGS,;t t
 s,@CPU_DEFINES_SRCDIR@,$CPU_DEFINES_SRCDIR,;t t
 s,@ABI_TWEAKS_SRCDIR@,$ABI_TWEAKS_SRCDIR,;t t
 s,@OS_INC_SRCDIR@,$OS_INC_SRCDIR,;t t
index a89e21d..72471f1 100644 (file)
@@ -107,6 +107,7 @@ GLIBCXX_ENABLE_C99([yes])
 GLIBCXX_ENABLE_CONCEPT_CHECKS([no])
 GLIBCXX_ENABLE_DEBUG_FLAGS(["-g3 -O0"])
 GLIBCXX_ENABLE_DEBUG([no])
+GLIBCXX_ENABLE_PARALLEL
 GLIBCXX_ENABLE_CXX_FLAGS
 GLIBCXX_ENABLE_FULLY_DYNAMIC_STRING([no])
 
@@ -327,12 +328,14 @@ GLIBCXX_CONFIGURE_TESTSUITE
 # Propagate the target-specific source directories through the build chain.
 ATOMICITY_SRCDIR=config/${atomicity_dir}
 ATOMIC_WORD_SRCDIR=config/${atomic_word_dir}
+ATOMIC_FLAGS=${atomic_flags}
 CPU_DEFINES_SRCDIR=config/${cpu_defines_dir}
 OS_INC_SRCDIR=config/${os_include_dir}
 ERROR_CONSTANTS_SRCDIR=config/${error_constants_dir}
 ABI_TWEAKS_SRCDIR=config/${abi_tweaks_dir}
 AC_SUBST(ATOMICITY_SRCDIR)
 AC_SUBST(ATOMIC_WORD_SRCDIR)
+AC_SUBST(ATOMIC_FLAGS)
 AC_SUBST(CPU_DEFINES_SRCDIR)
 AC_SUBST(ABI_TWEAKS_SRCDIR)
 AC_SUBST(OS_INC_SRCDIR)
index b916aba..4031b4e 100644 (file)
@@ -39,6 +39,9 @@
 #   atomic_word_dir        location of atomic_word.h
 #                          defaults to generic.
 #
+#   atomic_flags           extra flags to pass to use atomic instructions
+#                          defaults to nothing.
+#
 #   cpu_defines_dir        location of cpu_defines.h
 #                          defaults to generic.
 #
@@ -71,6 +74,7 @@
 c_model=c_global
 c_compatibility=no
 atomic_word_dir=cpu/generic
+atomic_flags=""
 atomicity_dir="cpu/generic"
 cpu_defines_dir="cpu/generic"
 try_cpu=generic
@@ -130,7 +134,8 @@ case "${host_cpu}" in
 esac
 
 
-# Set specific CPU overrides for atomic_word_dir. Most can just use generic.
+# Set specific CPU overrides for atomic_word_dir and atomic_flags. 
+# Most can just use generic.
 # THIS TABLE IS SORTED.  KEEP IT THAT WAY.
 case "${host_cpu}" in
   alpha*)
@@ -142,11 +147,15 @@ case "${host_cpu}" in
   ia64)
     atomic_word_dir=cpu/ia64
     ;;
+  i[567]86 | x86_64)
+    atomic_flags="-march=native"
+    ;;
   powerpc* | rs6000)
     atomic_word_dir=cpu/powerpc
     ;;
   sparc* | ultrasparc)
     atomic_word_dir=cpu/sparc
+    atomic_flags="-mcpu=v9"
     ;;
 esac
 
index 9824754..68d142f 100644 (file)
@@ -45,7 +45,7 @@
  *  export. Used only when anonymous namespaces cannot be substituted.
 */
 /** @namespace __gnu_debug
- *  @brief GNU debug mode classes for public use.
+ *  @brief GNU debug classes for public use.
 */
 // // // // // // // // // // // // // // // // // // // // // // // //
 /** @addtogroup SGIextensions STL extensions from SGI
index 9854f76..ab22db0 100644 (file)
@@ -478,6 +478,7 @@ INPUT                  = @srcdir@/docs/doxygen/doxygroups.cc \
                          include/@host_alias@/bits \
                          include/bits \
                          include/debug \
+                         include/parallel \
                          include/ext \
                          include/tr1 \
                          include/tr1_impl \
@@ -562,6 +563,8 @@ INPUT                  = @srcdir@/docs/doxygen/doxygroups.cc \
                          include/ext/slist \
                          include/ext/pb_ds \
                          include/ext/pb_ds/detail \
+                         include/parallel/algorithm \
+                         include/parallel/numeric \
                          include/tr1/array \
                          include/tr1/ccomplex \
                          include/tr1/cctype \
index f211165..2881caf 100644 (file)
    </ul>
    </li>
 
-   <li>Extensions to the Standard Library
+   <li>Extensions
    <ul>
+     <li><a href="ext/howto.html#4">Compile-time checks</a></li>
+     <li><a href="debug_mode.html">Debug mode</a></li>
+     <li><a href="parallel_mode.html">Parallel mode</a></li>
      <li><a href="ext/pb_ds/index.html">Policy Based Data Structures</a></li>
      <li><a href="ext/howto.html#1">Ropes and trees and hashes, oh my!</a></li>
      <li><a href="ext/howto.html#2">Added members and types</a></li>
      <li><a href="ext/mt_allocator.html"><code>__mt_alloc</code> </a></li>
-     <li><a href="ext/howto.html#4">Compile-time checks</a></li>
      <li><a href="ext/howto.html#5">LWG Issues</a></li>
      <li><a href="ext/../18_support/howto.html#6">Demangling</a></li>
    </ul>
diff --git a/libstdc++-v3/docs/html/parallel_mode.html b/libstdc++-v3/docs/html/parallel_mode.html
new file mode 100644 (file)
index 0000000..74db8ca
--- /dev/null
@@ -0,0 +1,457 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE html
+          PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+   <meta name="AUTHOR" content="bkoz@gcc.gnu.org (Benjamin Kosnik)" />
+   <meta name="KEYWORDS" content="c++, libstdc++, gdb, g++, debug" />
+   <meta name="DESCRIPTION" content="The libstdc++ parallel mode." />
+   <meta name="GENERATOR" content="emacs and ten fingers" />
+   <title>The libstdc++ parallel mode</title>
+<link rel="StyleSheet" href="lib3styles.css" type="text/css" />
+<link rel="Copyright" href="17_intro/license.html" type="text/html" />
+</head>
+<body>
+
+<h1 class="centered"><a name="top">The libstdc++ parallel mode</a></h1>
+
+<p class="fineprint"><em>
+   The latest version of this document is always available at
+   <a href="http://gcc.gnu.org/onlinedocs/libstdc++/parallel_mode.html">
+   http://gcc.gnu.org/onlinedocs/libstdc++/parallel_mode.html</a>.
+</em></p>
+
+<p><em>
+   To the <a href="http://gcc.gnu.org/libstdc++/">libstdc++-v3 homepage</a>.
+</em></p>
+
+<!-- ####################################################### -->
+<hr />
+<p> The libstdc++ parallel mode is an experimental parallel
+implementation of many algorithms the C++ Standard Library.
+</p>
+
+<p>
+Several of the standard algorithms, for instance
+<code>std::search</code>, are made parallel using OpenMP
+annotations. These parallel mode constructs and can be invoked by
+explicit source declaration or by compiling existing sources with a
+specific compiler flag.
+</p>
+
+<h3 class="left"><a name="parallel">The libstdc++ parallel mode</a></h3>
+
+<p>The libstdc++ parallel mode performs parallization of algorithms,
+function objects, classes, and functions in the C++ Standard.</p>
+
+<h4 class="left">Using the libstdc++ parallel mode</h4>
+
+<p>To use the libstdc++ parallel mode, compile your application with
+  the compiler flag <code>-D_GLIBCXX_PARALLEL -fopenmp</code>. This
+  will link in <code>libgomp</code>, the GNU OpenMP <a
+  href="http://gcc.gnu.org/onlinedocs/libgomp">implementation</a>,
+  whose presence is mandatory. In addition, hardware capable of atomic
+  operations is de rigueur. Actually activating these atomic
+  operations may require explicit compiler flags on some targets
+  (like sparc and x86), such as <code>-march=i686</code>,
+  <code>-march=native</code> or <code>-mcpu=v9</code>.
+</p>
+
+<p>Note that the <code>_GLIBCXX_PARALLEL</code> define may change the
+  sizes and behavior of standard class templates such as
+  <code>std::search</code>, and therefore one can only link code
+  compiled with parallel mode and code compiled without parallel mode
+  if no instantiation of a container is passed between the two
+  translation units. Parallel mode functionality has distinct linkage,
+  and cannot be confused with normal mode symbols.</p>
+
+
+<p>The following library components in the include
+<code>&lt;numeric&gt;</code> are included in the parallel mode:</p>
+<ul>
+  <li><code>std::accumulate</code></li>
+  <li><code>std::adjacent_difference</code></li>
+  <li><code>std::inner_product</code></li>
+  <li><code>std::partial_sum</code></li>
+</ul>
+
+<p>The following library components in the include
+<code>&lt;algorithm&gt;</code> are included in the parallel mode:</p>
+<ul>
+  <li><code>std::adjacent_find</code></li>
+  <li><code>std::count</code></li>
+  <li><code>std::count_if</code></li>
+  <li><code>std::equal</code></li>
+  <li><code>std::find</code></li>
+  <li><code>std::find_if</code></li>
+  <li><code>std::find_first_of</code></li>
+  <li><code>std::for_each</code></li>
+  <li><code>std::generate</code></li>
+  <li><code>std::generate_n</code></li>
+  <li><code>std::lexicographical_compare</code></li>
+  <li><code>std::mismatch</code></li>
+  <li><code>std::search</code></li>
+  <li><code>std::search_n</code></li>
+  <li><code>std::transform</code></li>
+  <li><code>std::replace</code></li>
+  <li><code>std::replace_if</code></li>
+  <li><code>std::max_element</code></li>
+  <li><code>std::merge</code></li>
+  <li><code>std::min_element</code></li>
+  <li><code>std::nth_element</code></li>
+  <li><code>std::partial_sort</code></li>
+  <li><code>std::partition</code></li>
+  <li><code>std::random_shuffle</code></li>
+  <li><code>std::set_union</code></li>
+  <li><code>std::set_intersection</code></li>
+  <li><code>std::set_symmetric_difference</code></li>
+  <li><code>std::set_difference</code></li>
+  <li><code>std::sort</code></li>
+  <li><code>std::stable_sort</code></li>
+  <li><code>std::unique_copy</code></li>
+</ul>
+
+
+<h4 class="left">Using the parallel algorithms without parallel mode</h4>
+
+<p>When it is not feasible to recompile your entire application, or
+  only specific algorithms need to be parallel-aware, individual
+  parallel algorithms can be made available explicitly. These
+  parallel algorithms are functionally equivalent to the standard
+  drop-in algorithms used in parallel mode, but they are available in
+  a separate namespace as GNU extensions and may be used in programs
+  compiled with either release mode or with parallel mode. The
+  following table provides the names and headers of the parallel
+  algorithms:
+</p>
+
+
+<table title="Parallel algorithms" border="1">
+  <tr>
+    <th>Algorithm</th>
+    <th>Header</th>
+    <th>Parallel algorithm</th>
+    <th>Parallel header</th>
+  </tr>
+  <tr>
+    <td>std::accumulate</td>
+    <td>&lt;numeric&gt;</td>
+    <td>__gnu_parallel::accumulate</td>
+    <td>&lt;parallel/numeric&gt;</td>
+  </tr>
+  <tr>
+    <td>std::adjacent_difference</td>
+    <td>&lt;numeric&gt;</td>
+    <td>__gnu_parallel::adjacent_difference</td>
+    <td>&lt;parallel/numeric&gt;</td>
+  </tr>
+  <tr>
+    <td>std::inner_product</td>
+    <td>&lt;numeric&gt;</td>
+    <td>__gnu_parallel::inner_product</td>
+    <td>&lt;parallel/numeric&gt;</td>
+  </tr>
+  <tr>
+    <td>std::partial_sum</td>
+    <td>&lt;numeric&gt;</td>
+    <td>__gnu_parallel::partial_sum</td>
+    <td>&lt;parallel/numeric&gt;</td>
+  </tr>
+  <tr>
+    <td>std::adjacent_find</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::adjacent_find</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::count</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::count</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::count_if</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::count_if</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::equal</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::equal</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::find</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::find</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::find_if</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::find_if</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::find_first_of</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::find_first_of</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::for_each</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::for_each</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::generate</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::generate</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::generate_n</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::generate_n</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::lexicographical_compare</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::lexicographical_compare</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::mismatch</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::mismatch</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::search</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::search</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::search_n</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::search_n</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::transform</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::transform</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::replace</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::replace</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::replace_if</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::replace_if</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::max_element</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::max_element</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::merge</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::merge</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::min_element</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::min_element</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::nth_element</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::nth_element</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::partial_sort</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::partial_sort</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::partition</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::partition</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::random_shuffle</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::random_shuffle</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::set_union</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::set_union</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::set_intersection</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::set_intersection</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::set_symmetric_difference</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::set_symmetric_difference</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::set_difference</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::set_difference</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::sort</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::sort</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::stable_sort</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::stable_sort</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+  <tr>
+    <td>std::unique_copy</td>
+    <td>&lt;algorithm&gt;</td>
+    <td>__gnu_parallel::unique_copy</td>
+    <td>&lt;parallel/algorithm&gt;</td>
+  </tr>
+
+</table>
+
+
+<h4 class="left">Parallel mode semantics</h4>
+<p> Something about exception safety, interaction with threads,
+etc. Goal is to have the usual constraints of the STL with respect to
+exception safety and threads, but add in support for parallel
+computing.</p>
+
+<p> Something about compile-time settings and configuration, ie using
+<code>__gnu_parallel::Settings</code>. XXX Up in the air.</p>
+
+<h4 class="left">Interface basics and relevant namespaces</h4>
+
+<p> Two namespaces contain the parallel mode:
+<code>std::__parallel</code> and <code>__gnu_parallel</code>. 
+</p>
+
+<p> One namespace contain versions of code that are explicitly sequential:
+<code>__gnu_serial</code>.
+</p>
+
+<p> Parallel implementations of the sequential standard components are
+defined in <code>namespace std::__parallel</code>. For instance,
+<code>std::transform</code> from &lt;algorithm&gt; has a parallel
+counterpart in <code>std::__parallel::transform</code> from
+&lt;parallel/algorithm&gt;. In addition, these parallel
+implementatations are injected into <code>namespace
+__gnu_parallel</code> with using declarations. 
+</p>
+
+<p> Support and infrastructure is in <code>namespace __gnu_parallel</code>.
+</p>
+
+<p> More information, and an organized index of types and functions
+related to the parallel mode on a per-namespace basis, can be found in
+the generated source documentation.
+</p>
+
+<h4 class="left">Testing</h4>
+
+<p> Both the normal conformance and regression tests and the
+supplemental performance tests work.</p>
+
+<p> To run the conformance and regression tests with the parallel mode
+active,</p>
+<code>make check-parallel</code>
+
+<p>The log and summary files for conformance testing are in the
+<code>testsuite/parallel</code> directory.</p>
+
+<p> To run the performance tests  with the parallel mode active, </p>
+<code>make check-performance-parallel</code>
+
+<p>The result file for performance testing are in the
+<code>testsuite</code> directory, in the file
+<code>libstdc++_performance.sum</code>. In addition, the policy-based
+containers have their own visualizations, which have additional
+software dependencies than the usual bare-boned text file, and can be
+generated by using the <code>make doc-performance</code> rule in the
+testsuite's Makefile.</p>
+
+<p>Return <a href="#top">to the top of the page</a> or
+   <a href="http://gcc.gnu.org/libstdc++/">to the libstdc++ homepage</a>.
+</p>
+
+
+<!-- ####################################################### -->
+
+<hr />
+<p class="fineprint"><em>
+See <a href="17_intro/license.html">license.html</a> for copying conditions.
+Comments and suggestions are welcome, and may be sent to
+<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
+</em></p>
+
+
+</body>
+</html>
index 53ede2b..3dd11b4 100644 (file)
@@ -70,6 +70,7 @@ std_headers = \
 bits_srcdir = ${glibcxx_srcdir}/include/bits
 bits_builddir = ./bits
 bits_headers = \
+        ${bits_srcdir}/algorithmfwd.h \
        ${bits_srcdir}/allocator.h \
        ${bits_srcdir}/basic_ios.h \
        ${bits_srcdir}/basic_ios.tcc \
@@ -730,6 +731,58 @@ debug_headers = \
        ${debug_srcdir}/string \
        ${debug_srcdir}/vector
 
+# Parallel mode headers
+parallel_srcdir = ${glibcxx_srcdir}/include/parallel
+parallel_builddir = ./parallel
+parallel_headers = \
+        ${parallel_srcdir}/algorithm \
+        ${parallel_srcdir}/algobase.h \
+        ${parallel_srcdir}/algo.h \
+        ${parallel_srcdir}/algorithm \
+        ${parallel_srcdir}/algorithmfwd.h \
+        ${parallel_srcdir}/balanced_quicksort.h \
+        ${parallel_srcdir}/base.h \
+        ${parallel_srcdir}/basic_iterator.h \
+        ${parallel_srcdir}/checkers.h \
+        ${parallel_srcdir}/compatibility.h \
+        ${parallel_srcdir}/compiletime_settings.h \
+        ${parallel_srcdir}/equally_split.h \
+        ${parallel_srcdir}/features.h \
+        ${parallel_srcdir}/find.h \
+        ${parallel_srcdir}/find_selectors.h \
+        ${parallel_srcdir}/for_each.h \
+        ${parallel_srcdir}/for_each_selectors.h \
+        ${parallel_srcdir}/iterator.h \
+        ${parallel_srcdir}/list_partition.h \
+        ${parallel_srcdir}/losertree.h \
+        ${parallel_srcdir}/merge.h \
+        ${parallel_srcdir}/multiseq_selection.h \
+        ${parallel_srcdir}/multiway_merge.h \
+        ${parallel_srcdir}/multiway_mergesort.h \
+        ${parallel_srcdir}/numeric \
+        ${parallel_srcdir}/numericfwd.h \
+        ${parallel_srcdir}/omp_loop.h \
+        ${parallel_srcdir}/omp_loop_static.h \
+        ${parallel_srcdir}/parallel.h \
+        ${parallel_srcdir}/par_loop.h \
+        ${parallel_srcdir}/partial_sum.h \
+        ${parallel_srcdir}/partition.h \
+        ${parallel_srcdir}/queue.h \
+        ${parallel_srcdir}/quicksort.h \
+        ${parallel_srcdir}/random_number.h \
+        ${parallel_srcdir}/random_shuffle.h \
+        ${parallel_srcdir}/search.h \
+        ${parallel_srcdir}/set_operations.h \
+        ${parallel_srcdir}/settings.h \
+        ${parallel_srcdir}/sort.h \
+        ${parallel_srcdir}/tags.h \
+        ${parallel_srcdir}/timing.h \
+        ${parallel_srcdir}/tree.h \
+        ${parallel_srcdir}/types.h \
+        ${parallel_srcdir}/unique_copy.h \
+        ${parallel_srcdir}/workstealing.h 
+
+
 # Some of the different "C" header models need extra files.
 # Some "C" header schemes require the "C" compatibility headers.
 # For --enable-cheaders=c_std
@@ -791,7 +844,8 @@ pch1_output_anchor = ${host_builddir}/stdc++.h
 pch1_output_installdir = ${host_installdir}/stdc++.h.gch
 pch1a_output = ${pch1_output_builddir}/O0g.gch
 pch1b_output = ${pch1_output_builddir}/O2g.gch
-pch1_output = ${pch1a_output} ${pch1b_output}
+pch1c_output = ${pch1_output_builddir}/O2gp.gch
+pch1_output = ${pch1a_output} ${pch1b_output} ${pch1c_output}
 
 pch2_source = ${glibcxx_srcdir}/include/precompiled/stdtr1c++.h
 pch2_output_builddir = ${host_builddir}/stdtr1c++.h.gch
@@ -823,7 +877,7 @@ endif
 allstamped = \
        stamp-std stamp-bits stamp-c_base stamp-c_base_extra \
        stamp-c_compatibility  stamp-backward stamp-ext stamp-pb \
-       stamp-tr1 stamp-tr1-impl stamp-debug stamp-host
+       stamp-tr1 stamp-tr1-impl stamp-debug stamp-parallel stamp-host
 
 # List of all files that are created by explicit building, editing, or
 # catenation.
@@ -980,6 +1034,15 @@ stamp-debug: ${debug_headers}
        fi ;\
        $(STAMP) stamp-debug
 
+stamp-parallel: ${parallel_headers}
+       @if [ ! -d "${parallel_builddir}" ]; then \
+         mkdir -p ${parallel_builddir} ;\
+       fi ;\
+       if [ ! -f stamp-parallel ]; then \
+         (cd ${parallel_builddir} && @LN_S@ $? . || true) ;\
+       fi ;\
+       $(STAMP) stamp-parallel
+
 stamp-${host_alias}:
        @if [ ! -d ${host_builddir} ]; then \
          mkdir -p ${host_builddir} ;\
@@ -1091,7 +1154,7 @@ ${host_builddir}/gthr-default.h: ${toplevel_srcdir}/gcc/${glibcxx_thread_h} \
            -e 's,^#include "\(.*\)",#include <bits/\1>,g' \
            < ${toplevel_srcdir}/gcc/${glibcxx_thread_h} > $@
 
-# Build two precompiled C++ includes, stdc++.h.gch/*.gch
+# Build three precompiled C++ includes, stdc++.h.gch/*.gch
 ${pch1a_output}: ${allstamped} ${host_builddir}/c++config.h ${pch1_source}
        if [ ! -d "${pch1_output_builddir}" ]; then \
          mkdir -p ${pch1_output_builddir}; \
@@ -1106,6 +1169,14 @@ ${pch1b_output}: ${allstamped} ${host_builddir}/c++config.h ${pch1_source}
        $(CXX) $(PCHFLAGS) $(AM_CPPFLAGS) -O2 -g ${pch1_source} -o $@
        touch ${pch1_output_anchor}
 
+${pch1c_output}: ${allstamped} ${host_builddir}/c++config.h ${pch1_source}
+       if [ ! -d "${pch1_output_builddir}" ]; then \
+         mkdir -p ${pch1_output_builddir}; \
+       fi; \
+       CXX_PARALLEL_FLAGS="-fgomp -march=native";
+       $(CXX) $(PCHFLAGS) $(AM_CPPFLAGS) -O2 -g $(CXX_PARALLEL_FLAGS) ${pch1_source} -o $@
+       touch ${pch1_output_anchor}
+
 # Build a precompiled TR1 include, stdtr1c++.h.gch/O2.gch
 ${pch2_output}: ${pch2_source} ${pch1_output}
        if [ ! -d "${pch2_output_builddir}" ]; then \
@@ -1217,6 +1288,9 @@ install-headers:
        $(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}/${parallel_builddir}
+       for file in ${parallel_headers}; do \
+         $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${parallel_builddir}; done
        $(mkinstalldirs) $(DESTDIR)${host_installdir}
        for file in ${host_headers} ${host_headers_extra} \
         ${thread_host_headers}; do \
index 4f779a0..80a7c24 100644 (file)
@@ -71,6 +71,7 @@ AMTAR = @AMTAR@
 AR = @AR@
 AS = @AS@
 ATOMICITY_SRCDIR = @ATOMICITY_SRCDIR@
+ATOMIC_FLAGS = @ATOMIC_FLAGS@
 ATOMIC_WORD_SRCDIR = @ATOMIC_WORD_SRCDIR@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
@@ -108,6 +109,8 @@ ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_PARALLEL_FALSE = @ENABLE_PARALLEL_FALSE@
+ENABLE_PARALLEL_TRUE = @ENABLE_PARALLEL_TRUE@
 ENABLE_SYMVERS_DARWIN_FALSE = @ENABLE_SYMVERS_DARWIN_FALSE@
 ENABLE_SYMVERS_DARWIN_TRUE = @ENABLE_SYMVERS_DARWIN_TRUE@
 ENABLE_SYMVERS_FALSE = @ENABLE_SYMVERS_FALSE@
@@ -316,6 +319,7 @@ std_headers = \
 bits_srcdir = ${glibcxx_srcdir}/include/bits
 bits_builddir = ./bits
 bits_headers = \
+        ${bits_srcdir}/algorithmfwd.h \
        ${bits_srcdir}/allocator.h \
        ${bits_srcdir}/basic_ios.h \
        ${bits_srcdir}/basic_ios.tcc \
@@ -965,6 +969,58 @@ debug_headers = \
        ${debug_srcdir}/string \
        ${debug_srcdir}/vector
 
+
+# Parallel mode headers
+parallel_srcdir = ${glibcxx_srcdir}/include/parallel
+parallel_builddir = ./parallel
+parallel_headers = \
+        ${parallel_srcdir}/algorithm \
+        ${parallel_srcdir}/algobase.h \
+        ${parallel_srcdir}/algo.h \
+        ${parallel_srcdir}/algorithm \
+        ${parallel_srcdir}/algorithmfwd.h \
+        ${parallel_srcdir}/balanced_quicksort.h \
+        ${parallel_srcdir}/base.h \
+        ${parallel_srcdir}/basic_iterator.h \
+        ${parallel_srcdir}/checkers.h \
+        ${parallel_srcdir}/compatibility.h \
+        ${parallel_srcdir}/compiletime_settings.h \
+        ${parallel_srcdir}/equally_split.h \
+        ${parallel_srcdir}/features.h \
+        ${parallel_srcdir}/find.h \
+        ${parallel_srcdir}/find_selectors.h \
+        ${parallel_srcdir}/for_each.h \
+        ${parallel_srcdir}/for_each_selectors.h \
+        ${parallel_srcdir}/iterator.h \
+        ${parallel_srcdir}/list_partition.h \
+        ${parallel_srcdir}/losertree.h \
+        ${parallel_srcdir}/merge.h \
+        ${parallel_srcdir}/multiseq_selection.h \
+        ${parallel_srcdir}/multiway_merge.h \
+        ${parallel_srcdir}/multiway_mergesort.h \
+        ${parallel_srcdir}/numeric \
+        ${parallel_srcdir}/numericfwd.h \
+        ${parallel_srcdir}/omp_loop.h \
+        ${parallel_srcdir}/omp_loop_static.h \
+        ${parallel_srcdir}/parallel.h \
+        ${parallel_srcdir}/par_loop.h \
+        ${parallel_srcdir}/partial_sum.h \
+        ${parallel_srcdir}/partition.h \
+        ${parallel_srcdir}/queue.h \
+        ${parallel_srcdir}/quicksort.h \
+        ${parallel_srcdir}/random_number.h \
+        ${parallel_srcdir}/random_shuffle.h \
+        ${parallel_srcdir}/search.h \
+        ${parallel_srcdir}/set_operations.h \
+        ${parallel_srcdir}/settings.h \
+        ${parallel_srcdir}/sort.h \
+        ${parallel_srcdir}/tags.h \
+        ${parallel_srcdir}/timing.h \
+        ${parallel_srcdir}/tree.h \
+        ${parallel_srcdir}/types.h \
+        ${parallel_srcdir}/unique_copy.h \
+        ${parallel_srcdir}/workstealing.h 
+
 @GLIBCXX_C_HEADERS_EXTRA_FALSE@c_base_headers_extra = 
 
 # Some of the different "C" header models need extra files.
@@ -1020,7 +1076,8 @@ pch1_output_anchor = ${host_builddir}/stdc++.h
 pch1_output_installdir = ${host_installdir}/stdc++.h.gch
 pch1a_output = ${pch1_output_builddir}/O0g.gch
 pch1b_output = ${pch1_output_builddir}/O2g.gch
-pch1_output = ${pch1a_output} ${pch1b_output}
+pch1c_output = ${pch1_output_builddir}/O2gp.gch
+pch1_output = ${pch1a_output} ${pch1b_output} ${pch1c_output}
 pch2_source = ${glibcxx_srcdir}/include/precompiled/stdtr1c++.h
 pch2_output_builddir = ${host_builddir}/stdtr1c++.h.gch
 pch2_output_anchor = ${host_builddir}/stdtr1c++.h
@@ -1047,7 +1104,7 @@ PCHFLAGS = -Winvalid-pch -Wno-deprecated -x c++-header $(CXXFLAGS)
 allstamped = \
        stamp-std stamp-bits stamp-c_base stamp-c_base_extra \
        stamp-c_compatibility  stamp-backward stamp-ext stamp-pb \
-       stamp-tr1 stamp-tr1-impl stamp-debug stamp-host
+       stamp-tr1 stamp-tr1-impl stamp-debug stamp-parallel stamp-host
 
 
 # List of all files that are created by explicit building, editing, or
@@ -1374,6 +1431,15 @@ stamp-debug: ${debug_headers}
        fi ;\
        $(STAMP) stamp-debug
 
+stamp-parallel: ${parallel_headers}
+       @if [ ! -d "${parallel_builddir}" ]; then \
+         mkdir -p ${parallel_builddir} ;\
+       fi ;\
+       if [ ! -f stamp-parallel ]; then \
+         (cd ${parallel_builddir} && @LN_S@ $? . || true) ;\
+       fi ;\
+       $(STAMP) stamp-parallel
+
 stamp-${host_alias}:
        @if [ ! -d ${host_builddir} ]; then \
          mkdir -p ${host_builddir} ;\
@@ -1476,7 +1542,7 @@ ${host_builddir}/gthr-default.h: ${toplevel_srcdir}/gcc/${glibcxx_thread_h} \
            -e 's,^#include "\(.*\)",#include <bits/\1>,g' \
            < ${toplevel_srcdir}/gcc/${glibcxx_thread_h} > $@
 
-# Build two precompiled C++ includes, stdc++.h.gch/*.gch
+# Build three precompiled C++ includes, stdc++.h.gch/*.gch
 ${pch1a_output}: ${allstamped} ${host_builddir}/c++config.h ${pch1_source}
        if [ ! -d "${pch1_output_builddir}" ]; then \
          mkdir -p ${pch1_output_builddir}; \
@@ -1491,6 +1557,14 @@ ${pch1b_output}: ${allstamped} ${host_builddir}/c++config.h ${pch1_source}
        $(CXX) $(PCHFLAGS) $(AM_CPPFLAGS) -O2 -g ${pch1_source} -o $@
        touch ${pch1_output_anchor}
 
+${pch1c_output}: ${allstamped} ${host_builddir}/c++config.h ${pch1_source}
+       if [ ! -d "${pch1_output_builddir}" ]; then \
+         mkdir -p ${pch1_output_builddir}; \
+       fi; \
+       CXX_PARALLEL_FLAGS="-fgomp -march=native";
+       $(CXX) $(PCHFLAGS) $(AM_CPPFLAGS) -O2 -g $(CXX_PARALLEL_FLAGS) ${pch1_source} -o $@
+       touch ${pch1_output_anchor}
+
 # Build a precompiled TR1 include, stdtr1c++.h.gch/O2.gch
 ${pch2_output}: ${pch2_source} ${pch1_output}
        if [ ! -d "${pch2_output_builddir}" ]; then \
@@ -1599,6 +1673,9 @@ install-headers:
        $(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}/${parallel_builddir}
+       for file in ${parallel_headers}; do \
+         $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${parallel_builddir}; done
        $(mkinstalldirs) $(DESTDIR)${host_installdir}
        for file in ${host_headers} ${host_headers_extra} \
         ${thread_host_headers}; do \
diff --git a/libstdc++-v3/include/bits/algorithmfwd.h b/libstdc++-v3/include/bits/algorithmfwd.h
new file mode 100644 (file)
index 0000000..1b2bf23
--- /dev/null
@@ -0,0 +1,597 @@
+// <algorithm> declarations  -*- C++ -*-
+
+// Copyright (C) 2007 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+/** @file bits/algorithmfwd.h
+ *  This is an internal header file, included by other library headers.
+ *  You should not attempt to use it directly.
+ */
+
+
+/*
+  adjacent_find
+  binary_search
+  copy
+  copy_backward
+  count
+  count_if
+  equal
+  equal_range
+  fill
+  fill_n
+  find
+  find_end
+  find_first_of
+  find_if
+  for_each
+  generate
+  generate_n
+  includes
+  inplace_merge
+  iter_swap
+  lexicographical_compare
+  lower_bound
+  make_heap
+  max
+  max_element
+  merge
+  min
+  min_element
+  mismatch
+  next_permutation
+  nth_element
+  parital_sort
+  partial_sort_copy
+  partition
+  pop_heap
+  prev_permutation
+  push_heap
+  random_shuffle
+  remove
+  remove_copy
+  remove_copy_if
+  remove_if
+  replace
+  replace_copy
+  replace_copy_if
+  replace_if
+  reverse
+  reverse_copy
+  rotate
+  rotate_copy
+  search
+  search_n
+  set_differernce
+  set_intersection
+  set_symmetric_difference
+  set_union
+  sort
+  sort_heap
+  stable_partition
+  stable_sort
+  stable_sort
+  swap
+  swap_ranges
+  transform
+  unique
+  unique_copy
+  upper_bound
+*/
+
+#ifndef _GLIBCXX_ALGORITHMFWD_H
+#define _GLIBCXX_ALGORITHMFWD_H 1
+
+#pragma GCC system_header
+
+#include <bits/c++config.h>
+#include <bits/stl_pair.h>
+#include <bits/stl_iterator_base_types.h>
+
+_GLIBCXX_BEGIN_NAMESPACE(std)
+
+  // adjacent_find
+
+  template<typename _FIter, typename _Tp>
+    bool 
+    binary_search(_FIter, _FIter, const _Tp&);
+
+  template<typename _FIter, typename _Tp, typename _Compare>
+    bool 
+    binary_search(_FIter, _FIter, const _Tp&, _Compare);
+
+  template<typename _IIter, typename _OIter>
+    _OIter 
+    copy(_IIter, _IIter, _OIter);
+
+  template<typename _BIter1, typename _BIter2>
+    _BIter2
+    copy_backward (_BIter1, _BIter1, _BIter2);
+
+  // count
+  // count_if
+
+  template<typename _FIter, typename _Tp>
+    pair<_FIter, _FIter>
+    equal_range(_FIter, _FIter, const _Tp&);
+
+  template<typename _FIter, typename _Tp, typename _Compare>
+    pair<_FIter, _FIter>
+    equal_range(_FIter, _FIter, const _Tp&, _Compare);
+
+  template<typename _FIter, typename _Tp>
+    void 
+    fill(_FIter, _FIter, const _Tp&);
+
+/*
+  XXX NB: return type different from ISO C++.
+  template<typename _OIter, typename _Size, typename _Tp>
+    void 
+    fill_n(_OIter, _Size, const _Tp&);
+*/
+
+  template<typename _OIter, typename _Size, typename _Tp>
+    _OIter
+    fill_n(_OIter, _Size, const _Tp&);
+
+  // find
+  // find_end
+  // find_first_of
+  // find_if
+  // for_each
+  // generate
+  // generate_n
+
+  template<typename _IIter1, typename _IIter2>
+    bool 
+    includes(_IIter1, _IIter1, _IIter2, _IIter2);
+
+  template<typename _IIter1, typename _IIter2, typename _Compare>
+    bool 
+    includes(_IIter1, _IIter1, _IIter2, _IIter2, _Compare);
+
+  template<typename _BIter>
+    void 
+    inplace_merge(_BIter, _BIter, _BIter);
+
+  template<typename _BIter, typename _Compare>
+    void 
+    inplace_merge(_BIter, _BIter, _BIter, _Compare);
+
+  template<typename _FIter1, typename _FIter2>
+    void 
+    iter_swap(_FIter1, _FIter2);
+
+  // Specializations for char and unsigned char.
+  inline bool
+  lexicographical_compare(const unsigned char*, const unsigned char*, 
+                         const unsigned char*, const unsigned char*);
+
+  inline bool
+  lexicographical_compare(const char*, const char*, const char*, const char*);
+
+  template<typename _FIter, typename _Tp>
+    _FIter 
+    lower_bound(_FIter, _FIter, const _Tp&);
+
+  template<typename _FIter, typename _Tp, typename _Compare>
+    _FIter 
+    lower_bound(_FIter, _FIter, const _Tp&, _Compare);
+
+  template<typename _RAIter>
+    void 
+    make_heap(_RAIter, _RAIter);
+
+  template<typename _RAIter, typename _Compare>
+    void 
+    make_heap(_RAIter, _RAIter, _Compare);
+
+  template<typename _Tp> 
+    const _Tp& 
+    max(const _Tp&, const _Tp&);
+
+  template<typename _Tp, typename _Compare>
+    const _Tp& 
+    max(const _Tp&, const _Tp&, _Compare);
+
+  // max_element
+  // merge
+
+  template<typename _Tp> 
+    const _Tp& 
+    min(const _Tp&, const _Tp&);
+
+  template<typename _Tp, typename _Compare>
+    const _Tp& 
+    min(const _Tp&, const _Tp&, _Compare);
+
+  // min_element
+  // mismatch
+
+  template<typename _BIter>
+    bool 
+    next_permutation(_BIter, _BIter);
+
+  template<typename _BIter, typename _Compare>
+    bool 
+    next_permutation(_BIter, _BIter, _Compare);
+
+  // nth_element
+  // partial_sort
+
+  template<typename _IIter, typename _RAIter>
+    _RAIter
+    partial_sort_copy(_IIter, _IIter, _RAIter, _RAIter);
+
+  template<typename _IIter, typename _RAIter, typename _Compare>
+    _RAIter
+    partial_sort_copy(_IIter, _IIter, _RAIter, _RAIter, _Compare);
+
+  template<typename _RAIter>
+    void 
+    pop_heap(_RAIter, _RAIter);
+
+  template<typename _RAIter, typename _Compare>
+    void 
+    pop_heap(_RAIter, _RAIter, _Compare);
+
+  template<typename _BIter>
+    bool 
+    prev_permutation(_BIter, _BIter);
+
+  template<typename _BIter, typename _Compare>
+    bool 
+    prev_permutation(_BIter, _BIter, _Compare);
+
+  template<typename _RAIter>
+    void 
+    push_heap(_RAIter, _RAIter);
+
+  template<typename _RAIter, typename _Compare>
+    void 
+    push_heap(_RAIter, _RAIter, _Compare);
+
+  // random_shuffle
+
+  template<typename _FIter, typename _Tp>
+    _FIter 
+    remove(_FIter, _FIter, const _Tp&);
+
+  template<typename _FIter, typename _Predicate>
+    _FIter 
+    remove_if(_FIter, _FIter, _Predicate);
+
+  template<typename _IIter, typename _OIter, typename _Tp>
+    _OIter 
+    remove_copy(_IIter, _IIter, _OIter, const _Tp&);
+
+  template<typename _IIter, typename _OIter, typename _Predicate>
+    _OIter 
+    remove_copy_if(_IIter, _IIter, _OIter, _Predicate);
+
+  // replace
+
+  template<typename _IIter, typename _OIter, typename _Tp>
+    _OIter 
+    replace_copy(_IIter, _IIter, _OIter, const _Tp&, const _Tp&);
+
+  template<typename _Iter, typename _OIter, typename _Predicate, typename _Tp>
+    _OIter 
+    replace_copy_if(_Iter, _Iter, _OIter, _Predicate, const _Tp&);
+
+  // replace_if
+
+  template<typename _BIter>
+    void 
+    reverse(_BIter, _BIter);
+
+  template<typename _BIter, typename _OIter>
+    _OIter 
+    reverse_copy(_BIter, _BIter, _OIter);
+
+  template<typename _FIter>
+    void 
+    rotate(_FIter, _FIter, _FIter);
+
+  template<typename _FIter, typename _OIter>
+    _OIter 
+    rotate_copy (_FIter, _FIter, _FIter, _OIter);
+
+  // search
+  // search_n
+  // set_difference
+  // set_intersection
+  // set_symmetric_difference
+  // set_union
+
+  template<typename _RAIter>
+    void 
+    sort_heap(_RAIter, _RAIter);
+
+  template<typename _RAIter, typename _Compare>
+    void 
+    sort_heap(_RAIter, _RAIter, _Compare);
+
+  template<typename _BIter, typename _Predicate>
+    _BIter 
+    stable_partition(_BIter, _BIter, _Predicate);
+
+  template<typename _Tp> 
+    void 
+    swap(_Tp&, _Tp& b);
+
+  template<typename _FIter1, typename _FIter2>
+    _FIter2 
+    swap_ranges(_FIter1 first1, _FIter1, _FIter2);
+
+  // transform
+
+  template<typename _FIter>
+    _FIter 
+    unique(_FIter, _FIter);
+
+  template<typename _FIter, typename _BinaryPredicate>
+    _FIter 
+    unique(_FIter, _FIter, _BinaryPredicate);
+
+  // unique_copy
+
+  template<typename _FIter, typename _Tp>
+    _FIter 
+    upper_bound(_FIter, _FIter, const _Tp&);
+
+  template<typename _FIter, typename _Tp, typename _Compare>
+    _FIter 
+    upper_bound(_FIter, _FIter, const _Tp&, _Compare);
+
+_GLIBCXX_END_NAMESPACE
+
+_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_P)
+
+  template<typename _FIter>
+    _FIter 
+    adjacent_find(_FIter, _FIter);
+
+  template<typename _FIter, typename _BinaryPredicate>
+    _FIter 
+    adjacent_find(_FIter, _FIter, _BinaryPredicate);
+
+  template<typename _IIter, typename _Tp>
+    typename iterator_traits<_IIter>::difference_type
+    count(_IIter, _IIter, const _Tp&);
+
+  template<typename _IIter, typename _Predicate>
+    typename iterator_traits<_IIter>::difference_type
+    count_if(_IIter, _IIter, _Predicate);
+
+  template<typename _IIter1, typename _IIter2>
+    bool 
+    equal(_IIter1, _IIter1, _IIter2);
+
+  template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
+    bool 
+    equal(_IIter1, _IIter1, _IIter2, _BinaryPredicate);
+
+  template<typename _IIter, typename _Tp>
+    _IIter 
+    find(_IIter, _IIter, const _Tp&);
+
+  template<typename _FIter1, typename _FIter2>
+    _FIter1
+    find_end(_FIter1, _FIter1, _FIter2, _FIter2);
+
+  template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
+    _FIter1
+    find_end(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
+
+  template<typename _FIter1, typename _FIter2>
+    _FIter1
+    find_first_of(_FIter1, _FIter1, _FIter2, _FIter2);
+
+  template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
+    _FIter1
+    find_first_of(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
+
+  template<typename _IIter, typename _Predicate>
+    _IIter 
+    find_if(_IIter, _IIter, _Predicate);
+
+  template<typename _IIter, typename _Funct>
+    _Funct 
+    for_each(_IIter, _IIter, _Funct);
+
+  template<typename _FIter, typename _Generator>
+    void 
+    generate(_FIter, _FIter, _Generator);
+
+  template<typename _OIter, typename _Size, typename _Generator>
+    void 
+    generate_n(_OIter, _Size, _Generator);
+
+  template<typename _IIter1, typename _IIter2>
+    bool 
+    lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2);
+
+  template<typename _IIter1, typename _IIter2, typename _Compare>
+    bool 
+    lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, _Compare);
+
+  template<typename _FIter>
+    _FIter 
+    max_element(_FIter, _FIter);
+
+  template<typename _FIter, typename _Compare>
+    _FIter 
+    max_element(_FIter, _FIter, _Compare);
+
+  template<typename _IIter1, typename _IIter2, typename _OIter>
+    _OIter 
+    merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
+
+  template<typename _IIter1, typename _IIter2, typename _OIter, 
+          typename _Compare>
+    _OIter 
+    merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
+
+  template<typename _FIter>
+    _FIter 
+    min_element(_FIter, _FIter);
+
+  template<typename _FIter, typename _Compare>
+    _FIter 
+    min_element(_FIter, _FIter, _Compare);
+
+  template<typename _IIter1, typename _IIter2>
+    pair<_IIter1, _IIter2>
+    mismatch(_IIter1, _IIter1, _IIter2);
+
+  template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
+    pair<_IIter1, _IIter2>
+    mismatch(_IIter1, _IIter1, _IIter2, _BinaryPredicate);
+
+  template<typename _RAIter>
+    void 
+    nth_element(_RAIter, _RAIter, _RAIter);
+
+  template<typename _RAIter, typename _Compare>
+    void 
+    nth_element(_RAIter, _RAIter, _RAIter, _Compare);
+
+  template<typename _RAIter>
+    void 
+    partial_sort(_RAIter, _RAIter, _RAIter);
+
+  template<typename _RAIter, typename _Compare>
+    void 
+    partial_sort(_RAIter, _RAIter, _RAIter, _Compare);
+
+  template<typename _BIter, typename _Predicate>
+    _BIter 
+    partition(_BIter, _BIter, _Predicate);
+
+  template<typename _RAIter>
+    void 
+    random_shuffle(_RAIter, _RAIter);
+
+  template<typename _RAIter, typename _Generator>
+    void 
+    random_shuffle(_RAIter, _RAIter, _Generator&);
+
+  template<typename _FIter, typename _Tp>
+    void 
+    replace(_FIter, _FIter, const _Tp&, const _Tp&);
+
+  template<typename _FIter, typename _Predicate, typename _Tp>
+    void 
+    replace_if(_FIter, _FIter, _Predicate, const _Tp&);
+
+  template<typename _FIter1, typename _FIter2>
+    _FIter1 
+    search(_FIter1, _FIter1, _FIter2, _FIter2);
+
+  template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
+    _FIter1 
+    search(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
+
+  template<typename _FIter, typename _Size, typename _Tp>
+    _FIter 
+    search_n(_FIter, _FIter, _Size, const _Tp&);
+
+  template<typename _FIter, typename _Size, typename _Tp, 
+          typename _BinaryPredicate>
+    _FIter 
+    search_n(_FIter, _FIter, _Size, const _Tp&, _BinaryPredicate);
+
+  template<typename _IIter1, typename _IIter2, typename _OIter>
+    _OIter 
+    set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
+
+  template<typename _IIter1, typename _IIter2, typename _OIter, 
+          typename _Compare>
+    _OIter 
+    set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
+
+  template<typename _IIter1, typename _IIter2, typename _OIter>
+    _OIter 
+    set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
+
+  template<typename _IIter1, typename _IIter2, typename _OIter,
+          typename _Compare>
+    _OIter 
+    set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
+
+  template<typename _IIter1, typename _IIter2, typename _OIter>
+    _OIter
+    set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
+
+  template<typename _IIter1, typename _IIter2, typename _OIter, 
+          typename _Compare>
+    _OIter
+    set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, 
+                            _OIter, _Compare);
+
+  template<typename _IIter1, typename _IIter2, typename _OIter>
+    _OIter 
+    set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
+
+  template<typename _IIter1, typename _IIter2, typename _OIter,
+          typename _Compare>
+    _OIter 
+    set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
+
+  template<typename _RAIter>
+    void 
+    sort(_RAIter, _RAIter);
+
+  template<typename _RAIter, typename _Compare>
+    void 
+    sort(_RAIter, _RAIter, _Compare);
+
+  template<typename _RAIter>
+    void 
+    stable_sort(_RAIter, _RAIter);
+
+  template<typename _RAIter, typename _Compare>
+    void 
+    stable_sort(_RAIter, _RAIter, _Compare);
+
+  template<typename _IIter, typename _OIter, typename _UnaryOperation>
+    _OIter 
+    transform(_IIter, _IIter, _OIter, _UnaryOperation);
+
+  template<typename _IIter1, typename _IIter2, typename _OIter, 
+          typename _BinaryOperation>
+    _OIter 
+    transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation);
+
+  template<typename _IIter, typename _OIter>
+    _OIter 
+    unique_copy(_IIter, _IIter, _OIter);
+
+  template<typename _IIter, typename _OIter, typename _BinaryPredicate>
+    _OIter 
+    unique_copy(_IIter, _IIter, _OIter, _BinaryPredicate);
+
+_GLIBCXX_END_NESTED_NAMESPACE
+
+#ifdef _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL
+# include <parallel/algorithmfwd.h>
+#endif
+
+#endif
+
index a519018..2628345 100644 (file)
 // The current version of the C++ library in compressed ISO date format.
 #define __GLIBCXX__ 
 
-// Macro used to indicate that the native "C" includes, when compiled
-// as "C++", have declarations in namespace std and not the global
-// namespace. Note, this is unrelated to possible "C" compatibility
-// includes that inject C90/C99 names into the global namespace.
-// XXX May not be necessary
-#if __cplusplus == 199711L
-# define _GLIBCXX_NAMESPACE_GLOBAL_INJECTION 1
-#endif
-
-// Macros for visibility.
+// Macros for visibility support.
 #define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY
 
 #if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY
 # define _GLIBCXX_VISIBILITY(V) 
 #endif
 
-// Macros for controlling various namespace association schemes and modes.
+// Guide to libstdc++ namespaces.
+/*
+  namespace std
+  {
+    namespace __debug { }
+    namespace __parallel { }
+    namespace __norm { } // __normative, __shadow, __replaced
+    namespace __cxx1998 { }
+
+    namespace tr1 { }
+  }
+
+  namespace __gnu_cxx
+  {
+    namespace __debug { }
+    namespace __norm { }
+  }
+*/
+
+// Macros for activating various namespace association modes.
 // _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG
-// _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION 
-// _GLIBCXX_NAMESPACE_ASSOCIATION_CXX200x
+// _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL
+// _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION
+
 #ifdef _GLIBCXX_DEBUG
 # define _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG 1
 #endif
 
+#ifdef _GLIBCXX_PARALLEL
+# define _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL 1
+#endif
+
 #define _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION 
 
-// Macros for namespace scope.
+// Defined if any namespace association modes are active.
+#if _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG \
+  || _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL \
+  || _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION
+# define _GLIBCXX_USE_NAMESPACE_ASSOCIATION 1
+#endif
+
+// Macros for namespace scope. Either namespace std:: or __gnu_cxx::,
+// or the name of some nested namespace within it.
+// _GLIBCXX_STD
+// _GLIBCXX_STD_D
+// _GLIBCXX_STD_P
+// _GLIBCXX_EXT
+// _GLIBCXX_EXT_D
+// _GLIBCXX_EXT_P
+
+//
+// Macros for enclosing namepaces and possibly nested namespaces.
 // _GLIBCXX_BEGIN_NAMESPACE
 // _GLIBCXX_END_NAMESPACE
 // _GLIBCXX_BEGIN_NESTED_NAMESPACE
 // _GLIBCXX_END_NESTED_NAMESPACE
-#if _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION
-# define _GLIBCXX_BEGIN_NESTED_NAMESPACE(X, Y)  namespace X { namespace Y _GLIBCXX_VISIBILITY(default) {
-# define _GLIBCXX_END_NESTED_NAMESPACE } }
-# define _GLIBCXX_BEGIN_NAMESPACE(X) _GLIBCXX_BEGIN_NESTED_NAMESPACE(X, _6)
-# define _GLIBCXX_END_NAMESPACE _GLIBCXX_END_NESTED_NAMESPACE
+// _GLIBCXX_BEGIN_POTENTIAL_NESTED_NAMESPACE
+// _GLIBCXX_END_POTENTIAL_NESTED_NAMESPACE
+#ifndef _GLIBCXX_USE_NAMESPACE_ASSOCIATION
+# define _GLIBCXX_STD_D _GLIBCXX_STD
+# define _GLIBCXX_STD_P _GLIBCXX_STD
+# define _GLIBCXX_STD std
+# define _GLIBCXX_EXT_D _GLIBCXX_EXT
+# define _GLIBCXX_EXT_P _GLIBCXX_EXT
+# define _GLIBCXX_EXT __gnu_cxx
+# define _GLIBCXX_BEGIN_NESTED_NAMESPACE(X, Y) _GLIBCXX_BEGIN_NAMESPACE(X)
+# define _GLIBCXX_END_NESTED_NAMESPACE _GLIBCXX_END_NAMESPACE
+# define _GLIBCXX_BEGIN_NAMESPACE(X) namespace X _GLIBCXX_VISIBILITY(default) {
+# define _GLIBCXX_END_NAMESPACE }
 #else
-# define _GLIBCXX_BEGIN_NAMESPACE(X) namespace X _GLIBCXX_VISIBILITY(default) { 
-# define _GLIBCXX_END_NAMESPACE } 
-# if _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG
-#  define _GLIBCXX_BEGIN_NESTED_NAMESPACE(X, Y) namespace X { namespace Y _GLIBCXX_VISIBILITY(default) {
-#  define _GLIBCXX_END_NESTED_NAMESPACE  } }
-# else
-#  define _GLIBCXX_BEGIN_NESTED_NAMESPACE(X, Y) _GLIBCXX_BEGIN_NAMESPACE(X)
-#  define _GLIBCXX_END_NESTED_NAMESPACE _GLIBCXX_END_NAMESPACE
+
+# if _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION // && not anything else
+#  define _GLIBCXX_STD_D _GLIBCXX_STD
+#  define _GLIBCXX_STD_P _GLIBCXX_STD
+#  define _GLIBCXX_STD _6
+#  define _GLIBCXX_EXT _6
+#  define _GLIBCXX_BEGIN_NAMESPACE(X) _GLIBCXX_BEGIN_NESTED_NAMESPACE(X, _6)
+#  define _GLIBCXX_END_NAMESPACE _GLIBCXX_END_NESTED_NAMESPACE
 # endif
+
+//  debug
+# if _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG && !_GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL
+#  define _GLIBCXX_STD_D __norm
+#  define _GLIBCXX_STD_P _GLIBCXX_STD
+#  define _GLIBCXX_STD __cxx1998
+#  define _GLIBCXX_EXT_D __norm
+#  define _GLIBCXX_EXT_P _GLIBCXX_EXT
+#  define _GLIBCXX_EXT __cxx1998
+#  define _GLIBCXX_BEGIN_NAMESPACE(X) namespace X _GLIBCXX_VISIBILITY(default) { 
+#  define _GLIBCXX_END_NAMESPACE }
+#  define _GLIBCXX_EXTERN_TEMPLATE 0
+# endif
+
+// parallel
+# if _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL && !_GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG 
+#  define _GLIBCXX_STD_D _GLIBCXX_STD
+#  define _GLIBCXX_STD_P __norm
+#  define _GLIBCXX_STD __cxx1998
+#  define _GLIBCXX_EXT_D _GLIBCXX_EXT
+#  define _GLIBCXX_EXT_P __norm
+#  define _GLIBCXX_EXT __cxx1998
+#  define _GLIBCXX_BEGIN_NAMESPACE(X) namespace X _GLIBCXX_VISIBILITY(default) { 
+#  define _GLIBCXX_END_NAMESPACE }
+#  define _GLIBCXX_EXTERN_TEMPLATE 0
+# endif
+
+// debug + parallel
+# if _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL && _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG 
+#  define _GLIBCXX_STD_D __norm
+#  define _GLIBCXX_STD_P __norm
+#  define _GLIBCXX_STD __cxx1998
+#  define _GLIBCXX_EXT_D __norm
+#  define _GLIBCXX_EXT_P __norm
+#  define _GLIBCXX_EXT __gnu_cxx
+#  define _GLIBCXX_BEGIN_NAMESPACE(X) namespace X _GLIBCXX_VISIBILITY(default) { 
+#  define _GLIBCXX_END_NAMESPACE }
+#  define _GLIBCXX_EXTERN_TEMPLATE 0
+# endif
+
+# if __NO_INLINE__ && !__GXX_WEAK__
+#  warning currently using namepace associated mode which may fail \
+   without inlining due to lack of weak symbols
+# endif
+
+# define _GLIBCXX_BEGIN_NESTED_NAMESPACE(X, Y)  namespace X { namespace Y _GLIBCXX_VISIBILITY(default) {
+# define _GLIBCXX_END_NESTED_NAMESPACE } }
+#endif
+
+// Namespace associations for debug mode.
+#if _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG
+namespace std
+{ 
+  namespace __norm { } 
+  namespace __debug { }
+  namespace __cxx1998 { }
+
+  using namespace __debug __attribute__ ((strong)); 
+  using namespace __cxx1998 __attribute__ ((strong)); 
+}
+
+namespace __gnu_cxx
+{
+  namespace __norm { }
+  namespace __debug { }
+  namespace __cxx1998 { }
+
+  using namespace __debug __attribute__ ((strong)); 
+  using namespace __cxx1998 __attribute__ ((strong)); 
+}
+#endif
+
+// Namespace associations for parallel mode.
+#if _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL
+namespace std
+{ 
+  namespace __norm { } 
+  namespace __parallel { }
+  namespace __cxx1998 { }
+
+  using namespace __parallel __attribute__ ((strong));
+  using namespace __cxx1998 __attribute__ ((strong)); 
+}
+
+namespace __gnu_cxx
+{
+  namespace __norm { }
+  namespace __parallel { }
+  namespace __cxx1998 { }
+
+  using namespace __parallel __attribute__ ((strong)); 
+  using namespace __cxx1998 __attribute__ ((strong)); 
+}
 #endif
 
 // Namespace associations for versioning mode.
@@ -119,38 +252,6 @@ namespace std
 }
 #endif
 
-// Namespace associations for debug mode.
-#if _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG
-namespace std
-{ 
-  namespace __norm { }
-  namespace __debug { }
-  using namespace __debug __attribute__ ((strong)); 
-}
-
-namespace __gnu_cxx
-{
-  namespace __norm { }
-  namespace __debug { }
-  using namespace __debug __attribute__ ((strong)); 
-}
-
-# define _GLIBCXX_STD __norm
-# define _GLIBCXX_EXT __norm
-# define _GLIBCXX_EXTERN_TEMPLATE 0
-# if __NO_INLINE__ && !__GXX_WEAK__
-#  warning debug mode without inlining may fail due to lack of weak symbols
-# endif
-#else
-#if _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION
-# define _GLIBCXX_STD _6
-# define _GLIBCXX_EXT _6
-#else
-# define _GLIBCXX_STD std
-# define _GLIBCXX_EXT __gnu_cxx
-#endif
-#endif
-
 // Define if compatibility should be provided for -mlong-double-64.
 #undef _GLIBCXX_LONG_DOUBLE_COMPAT
 
@@ -193,6 +294,14 @@ _GLIBCXX_END_NAMESPACE
 # define _GLIBCXX_WEAK_DEFINITION
 #endif
 
+// Macro used to indicate that the native "C" includes, when compiled
+// as "C++", have declarations in namespace std and not the global
+// namespace. Note, this is unrelated to possible "C" compatibility
+// includes that inject C90/C99 names into the global namespace.
+#if __cplusplus == 199711L
+# define _GLIBCXX_NAMESPACE_GLOBAL_INJECTION 1
+#endif
+
 // The remainder of the prewritten config is automatic; all the
 // user hooks are listed above.
 
index 250faf5..daa13b7 100644 (file)
@@ -43,7 +43,7 @@
 
 #pragma GCC system_header
 
-#include <bits/stl_algobase.h>  // For copy, fill_n
+#include <bits/algorithmfwd.h>   // std::copy, std::fill_n
 #include <bits/postypes.h>      // For streampos
 #include <cstdio>               // For EOF
 #include <cwchar>               // For WEOF, wmemmove, wmemset, etc.
@@ -194,6 +194,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
     char_traits<_CharT>::
     copy(char_type* __s1, const char_type* __s2, std::size_t __n)
     {
+      // NB: Inline std::copy so no recursive dependencies.
       std::copy(__s2, __s2 + __n, __s1);
       return __s1;
     }
@@ -203,6 +204,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
     char_traits<_CharT>::
     assign(char_type* __s, std::size_t __n, char_type __a)
     {
+      // NB: Inline std::fill_n so no recursive dependencies.
       std::fill_n(__s, __n, __a);
       return __s;
     }
index 3f53f20..b5cacc1 100644 (file)
@@ -62,7 +62,7 @@
 #ifndef _DEQUE_TCC
 #define _DEQUE_TCC 1
 
-_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
+_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
 
   template <typename _Tp, typename _Alloc>
     deque<_Tp, _Alloc>&
index 6bde3b7..3fdc5bb 100644 (file)
@@ -62,7 +62,7 @@
 #ifndef _LIST_TCC
 #define _LIST_TCC 1
 
-_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
+_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
 
   template<typename _Tp, typename _Alloc>
     void
index 160dc2f..d03ae13 100644 (file)
 #ifndef _STL_ALGO_H
 #define _STL_ALGO_H 1
 
+#include <cstdlib>             // for rand
 #include <bits/stl_heap.h>
 #include <bits/stl_tempbuf.h>  // for _Temporary_buffer
-#include <cstdlib>             // for rand
+#include <bits/algorithmfwd.h>
 #include <debug/debug.h>
 
 // See concept_check.h for the __glibcxx_*_requires macros.
@@ -138,28 +139,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
        return __b;
     }
 
-  /**
-   *  @brief Apply a function to every element of a sequence.
-   *  @param  first  An input iterator.
-   *  @param  last   An input iterator.
-   *  @param  f      A unary function object.
-   *  @return   @p f.
-   *
-   *  Applies the function object @p f to each element in the range
-   *  @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 _InputIterator, typename _Function>
-    _Function
-    for_each(_InputIterator __first, _InputIterator __last, _Function __f)
-    {
-      // concept requirements
-      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
-      __glibcxx_requires_valid_range(__first, __last);
-      for (; __first != __last; ++__first)
-       __f(*__first);
-      return __f;
-    }
+  // for_each
 
   /**
    *  @if maint
@@ -295,306 +275,333 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
        }
     }
 
-  /**
-   *  @brief Find the first occurrence of a value in a sequence.
-   *  @param  first  An input iterator.
-   *  @param  last   An input iterator.
-   *  @param  val    The value to find.
-   *  @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 _InputIterator, typename _Tp>
-    inline _InputIterator
-    find(_InputIterator __first, _InputIterator __last,
-        const _Tp& __val)
-    {
-      // concept requirements
-      __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));
-    }
+  // set_difference
+  // set_intersection
+  // set_symmetric_difference
+  // set_union
+  // for_each
+  // find
+  // find_if
+  // find_first_of
+  // adjacent_find
+  // count
+  // count_if
+  // search
 
   /**
-   *  @brief Find the first element in a sequence for which a predicate is true.
-   *  @param  first  An input iterator.
-   *  @param  last   An input iterator.
-   *  @param  pred   A predicate.
-   *  @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.
+   *  @if maint
+   *  This is an uglified
+   *  search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&)
+   *  overloaded for forward iterators.
+   *  @endif
   */
-  template<typename _InputIterator, typename _Predicate>
-    inline _InputIterator
-    find_if(_InputIterator __first, _InputIterator __last,
-           _Predicate __pred)
+  template<typename _ForwardIterator, typename _Integer, typename _Tp>
+    _ForwardIterator
+    __search_n(_ForwardIterator __first, _ForwardIterator __last,
+              _Integer __count, const _Tp& __val,
+              std::forward_iterator_tag)
     {
-      // concept requirements
-      __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));
+      __first = _GLIBCXX_STD_P::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;
+         if (__i == __last)
+           return __last;
+         __first = _GLIBCXX_STD_P::find(++__i, __last, __val);
+       }
+      return __last;
     }
 
   /**
-   *  @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.
+   *  @if maint
+   *  This is an uglified
+   *  search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&)
+   *  overloaded for random access iterators.
+   *  @endif
   */
-  template<typename _InputIterator, typename _ForwardIterator>
-    _InputIterator
-    find_first_of(_InputIterator __first1, _InputIterator __last1,
-                 _ForwardIterator __first2, _ForwardIterator __last2)
+  template<typename _RandomAccessIter, typename _Integer, typename _Tp>
+    _RandomAccessIter
+    __search_n(_RandomAccessIter __first, _RandomAccessIter __last,
+              _Integer __count, const _Tp& __val, 
+              std::random_access_iterator_tag)
     {
-      // concept requirements
-      __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);
+      
+      typedef typename std::iterator_traits<_RandomAccessIter>::difference_type
+       _DistanceType;
 
-      for (; __first1 != __last1; ++__first1)
-       for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter)
-         if (*__first1 == *__iter)
-           return __first1;
-      return __last1;
-    }
+      _DistanceType __tailSize = __last - __first;
+      const _DistanceType __pattSize = __count;
 
-  /**
-   *  @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
-      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
-      __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
-      __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);
+      if (__tailSize < __pattSize)
+        return __last;
 
-      for (; __first1 != __last1; ++__first1)
-       for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter)
-         if (__comp(*__first1, *__iter))
-           return __first1;
-      return __last1;
+      const _DistanceType __skipOffset = __pattSize - 1;
+      _RandomAccessIter __lookAhead = __first + __skipOffset;
+      __tailSize -= __pattSize;
+
+      while (1) // the main loop...
+       {
+         // __lookAhead here is always pointing to the last element of next 
+         // possible match.
+         while (!(*__lookAhead == __val)) // the skip loop...
+           {
+             if (__tailSize < __pattSize)
+               return __last;  // Failure
+             __lookAhead += __pattSize;
+             __tailSize -= __pattSize;
+           }
+         _DistanceType __remainder = __skipOffset;
+         for (_RandomAccessIter __backTrack = __lookAhead - 1; 
+              *__backTrack == __val; --__backTrack)
+           {
+             if (--__remainder == 0)
+               return (__lookAhead - __skipOffset); // Success
+           }
+         if (__remainder > __tailSize)
+           return __last; // Failure
+         __lookAhead += __remainder;
+         __tailSize -= __remainder;
+       }
     }
 
+  // search_n
+
   /**
-   *  @brief Find two adjacent values in a sequence that are equal.
-   *  @param  first  A forward iterator.
-   *  @param  last   A forward iterator.
-   *  @return   The first iterator @c i such that @c i and @c i+1 are both
-   *  valid iterators in @p [first,last) and such that @c *i == @c *(i+1),
-   *  or @p last if no such iterator exists.
+   *  @if maint
+   *  This is an uglified
+   *  search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&,
+   *          _BinaryPredicate)
+   *  overloaded for forward iterators.
+   *  @endif
   */
-  template<typename _ForwardIterator>
+  template<typename _ForwardIterator, typename _Integer, typename _Tp,
+           typename _BinaryPredicate>
     _ForwardIterator
-    adjacent_find(_ForwardIterator __first, _ForwardIterator __last)
+    __search_n(_ForwardIterator __first, _ForwardIterator __last,
+              _Integer __count, const _Tp& __val,
+              _BinaryPredicate __binary_pred, std::forward_iterator_tag)
     {
-      // concept requirements
-      __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;
-      _ForwardIterator __next = __first;
-      while(++__next != __last)
+      while (__first != __last && !bool(__binary_pred(*__first, __val)))
+        ++__first;
+
+      while (__first != __last)
        {
-         if (*__first == *__next)
+         typename iterator_traits<_ForwardIterator>::difference_type
+           __n = __count;
+         _ForwardIterator __i = __first;
+         ++__i;
+         while (__i != __last && __n != 1 && bool(__binary_pred(*__i, __val)))
+           {
+             ++__i;
+             --__n;
+           }
+         if (__n == 1)
            return __first;
-         __first = __next;
+         if (__i == __last)
+           return __last;
+         __first = ++__i;
+         while (__first != __last
+                && !bool(__binary_pred(*__first, __val)))
+           ++__first;
        }
       return __last;
     }
 
   /**
-   *  @brief Find two adjacent values in a sequence using a predicate.
-   *  @param  first         A forward iterator.
-   *  @param  last          A forward iterator.
-   *  @param  binary_pred   A binary predicate.
-   *  @return   The first iterator @c i such that @c i and @c i+1 are both
-   *  valid iterators in @p [first,last) and such that
-   *  @p binary_pred(*i,*(i+1)) is true, or @p last if no such iterator
-   *  exists.
-  */
-  template<typename _ForwardIterator, typename _BinaryPredicate>
-    _ForwardIterator
-    adjacent_find(_ForwardIterator __first, _ForwardIterator __last,
-                 _BinaryPredicate __binary_pred)
+   *  @if maint
+   *  This is an uglified
+   *  search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&,
+   *          _BinaryPredicate)
+   *  overloaded for random access iterators.
+   *  @endif
+  */
+  template<typename _RandomAccessIter, typename _Integer, typename _Tp,
+          typename _BinaryPredicate>
+    _RandomAccessIter
+    __search_n(_RandomAccessIter __first, _RandomAccessIter __last,
+              _Integer __count, const _Tp& __val,
+              _BinaryPredicate __binary_pred, std::random_access_iterator_tag)
     {
-      // concept requirements
-      __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;
-      _ForwardIterator __next = __first;
-      while(++__next != __last)
+      
+      typedef typename std::iterator_traits<_RandomAccessIter>::difference_type
+       _DistanceType;
+
+      _DistanceType __tailSize = __last - __first;
+      const _DistanceType __pattSize = __count;
+
+      if (__tailSize < __pattSize)
+        return __last;
+
+      const _DistanceType __skipOffset = __pattSize - 1;
+      _RandomAccessIter __lookAhead = __first + __skipOffset;
+      __tailSize -= __pattSize;
+
+      while (1) // the main loop...
        {
-         if (__binary_pred(*__first, *__next))
-           return __first;
-         __first = __next;
+         // __lookAhead here is always pointing to the last element of next 
+         // possible match.
+         while (!bool(__binary_pred(*__lookAhead, __val))) // the skip loop...
+           {
+             if (__tailSize < __pattSize)
+               return __last;  // Failure
+             __lookAhead += __pattSize;
+             __tailSize -= __pattSize;
+           }
+         _DistanceType __remainder = __skipOffset;
+         for (_RandomAccessIter __backTrack = __lookAhead - 1; 
+              __binary_pred(*__backTrack, __val); --__backTrack)
+           {
+             if (--__remainder == 0)
+               return (__lookAhead - __skipOffset); // Success
+           }
+         if (__remainder > __tailSize)
+           return __last; // Failure
+         __lookAhead += __remainder;
+         __tailSize -= __remainder;
        }
-      return __last;
     }
 
-  /**
-   *  @brief Count the number of copies of a value in a sequence.
-   *  @param  first  An input iterator.
-   *  @param  last   An input iterator.
-   *  @param  value  The value to be counted.
-   *  @return   The number of iterators @c i in the range @p [first,last)
-   *  for which @c *i == @p value
-  */
-  template<typename _InputIterator, typename _Tp>
-    typename iterator_traits<_InputIterator>::difference_type
-    count(_InputIterator __first, _InputIterator __last, const _Tp& __value)
+  // find_end for forward iterators.
+  template<typename _ForwardIterator1, typename _ForwardIterator2>
+    _ForwardIterator1
+    __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+              _ForwardIterator2 __first2, _ForwardIterator2 __last2,
+              forward_iterator_tag, forward_iterator_tag)
     {
-      // concept requirements
-      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
-      __glibcxx_function_requires(_EqualOpConcept<
-       typename iterator_traits<_InputIterator>::value_type, _Tp>)
-      __glibcxx_requires_valid_range(__first, __last);
-      typename iterator_traits<_InputIterator>::difference_type __n = 0;
-      for (; __first != __last; ++__first)
-       if (*__first == __value)
-         ++__n;
-      return __n;
+      if (__first2 == __last2)
+       return __last1;
+      else
+       {
+         _ForwardIterator1 __result = __last1;
+         while (1)
+           {
+             _ForwardIterator1 __new_result
+               = _GLIBCXX_STD_P::search(__first1, __last1, __first2, __last2);
+             if (__new_result == __last1)
+               return __result;
+             else
+               {
+                 __result = __new_result;
+                 __first1 = __new_result;
+                 ++__first1;
+               }
+           }
+       }
     }
 
-  /**
-   *  @brief Count the elements of a sequence for which a predicate is true.
-   *  @param  first  An input iterator.
-   *  @param  last   An input iterator.
-   *  @param  pred   A predicate.
-   *  @return   The number of iterators @c i in the range @p [first,last)
-   *  for which @p pred(*i) is true.
-  */
-  template<typename _InputIterator, typename _Predicate>
-    typename iterator_traits<_InputIterator>::difference_type
-    count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)
+  template<typename _ForwardIterator1, typename _ForwardIterator2,
+          typename _BinaryPredicate>
+    _ForwardIterator1
+    __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+              _ForwardIterator2 __first2, _ForwardIterator2 __last2,
+              forward_iterator_tag, forward_iterator_tag,
+              _BinaryPredicate __comp)
     {
-      // concept requirements
-      __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;
+      if (__first2 == __last2)
+       return __last1;
+      else
+       {
+         _ForwardIterator1 __result = __last1;
+         while (1)
+           {
+             _ForwardIterator1 __new_result
+               = _GLIBCXX_STD_P::search(__first1, __last1, __first2, __last2, __comp);
+             if (__new_result == __last1)
+               return __result;
+             else
+               {
+                 __result = __new_result;
+                 __first1 = __new_result;
+                 ++__first1;
+               }
+           }
+       }
     }
 
-  /**
-   *  @brief Finds the places in ranges which don't match.
-   *  @param  first1  An input iterator.
-   *  @param  last1   An input iterator.
-   *  @param  first2  An input iterator.
-   *  @return   A pair of iterators pointing to the first mismatch.
-   *
-   *  This compares the elements of two ranges using @c == and returns a pair
-   *  of iterators.  The first iterator points into the first range, the
-   *  second iterator points into the second range, and the elements pointed
-   *  to by the iterators are not equal.
-  */
-  template<typename _InputIterator1, typename _InputIterator2>
-    pair<_InputIterator1, _InputIterator2>
-    mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
-            _InputIterator2 __first2)
+  // find_end for bidirectional iterators (much faster).
+  template<typename _BidirectionalIterator1, typename _BidirectionalIterator2>
+    _BidirectionalIterator1
+    __find_end(_BidirectionalIterator1 __first1,
+              _BidirectionalIterator1 __last1,
+              _BidirectionalIterator2 __first2,
+              _BidirectionalIterator2 __last2,
+              bidirectional_iterator_tag, bidirectional_iterator_tag)
     {
       // concept requirements
-      __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);
+      __glibcxx_function_requires(_BidirectionalIteratorConcept<
+                                 _BidirectionalIterator1>)
+      __glibcxx_function_requires(_BidirectionalIteratorConcept<
+                                 _BidirectionalIterator2>)
 
-      while (__first1 != __last1 && *__first1 == *__first2)
-        {
-         ++__first1;
-         ++__first2;
-        }
-      return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
+      typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1;
+      typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2;
+
+      _RevIterator1 __rlast1(__first1);
+      _RevIterator2 __rlast2(__first2);
+      _RevIterator1 __rresult = _GLIBCXX_STD_P::search(_RevIterator1(__last1), __rlast1, _RevIterator2(__last2), __rlast2);
+
+      if (__rresult == __rlast1)
+       return __last1;
+      else
+       {
+         _BidirectionalIterator1 __result = __rresult.base();
+         std::advance(__result, -std::distance(__first2, __last2));
+         return __result;
+       }
     }
 
-  /**
-   *  @brief Finds the places in ranges which don't match.
-   *  @param  first1  An input iterator.
-   *  @param  last1   An input iterator.
-   *  @param  first2  An input iterator.
-   *  @param  binary_pred  A binary predicate @link s20_3_1_base functor@endlink.
-   *  @return   A pair of iterators pointing to the first mismatch.
-   *
-   *  This compares the elements of two ranges using the binary_pred
-   *  parameter, and returns a pair
-   *  of iterators.  The first iterator points into the first range, the
-   *  second iterator points into the second range, and the elements pointed
-   *  to by the iterators are not equal.
-  */
-  template<typename _InputIterator1, typename _InputIterator2,
+  template<typename _BidirectionalIterator1, typename _BidirectionalIterator2,
           typename _BinaryPredicate>
-    pair<_InputIterator1, _InputIterator2>
-    mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
-            _InputIterator2 __first2, _BinaryPredicate __binary_pred)
+    _BidirectionalIterator1
+    __find_end(_BidirectionalIterator1 __first1,
+              _BidirectionalIterator1 __last1,
+              _BidirectionalIterator2 __first2,
+              _BidirectionalIterator2 __last2,
+              bidirectional_iterator_tag, bidirectional_iterator_tag,
+              _BinaryPredicate __comp)
     {
       // concept requirements
-      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
-      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
-      __glibcxx_requires_valid_range(__first1, __last1);
+      __glibcxx_function_requires(_BidirectionalIteratorConcept<
+                                 _BidirectionalIterator1>)
+      __glibcxx_function_requires(_BidirectionalIteratorConcept<
+                                 _BidirectionalIterator2>)
 
-      while (__first1 != __last1 && bool(__binary_pred(*__first1, *__first2)))
-        {
-         ++__first1;
-         ++__first2;
-        }
-      return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
+      typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1;
+      typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2;
+
+      _RevIterator1 __rlast1(__first1);
+      _RevIterator2 __rlast2(__first2);
+      _RevIterator1 __rresult = std::search(_RevIterator1(__last1), __rlast1,
+                                           _RevIterator2(__last2), __rlast2,
+                                           __comp);
+
+      if (__rresult == __rlast1)
+       return __last1;
+      else
+       {
+         _BidirectionalIterator1 __result = __rresult.base();
+         std::advance(__result, -std::distance(__first2, __last2));
+         return __result;
+       }
     }
 
   /**
-   *  @brief Search a sequence for a matching sub-sequence.
-   *  @param  first1  A forward iterator.
-   *  @param  last1   A forward iterator.
-   *  @param  first2  A forward iterator.
-   *  @param  last2   A forward iterator.
-   *  @return   The first iterator @c i in the range
+   *  @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.
@@ -602,7 +609,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
    *  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.
+   *  @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
@@ -612,9 +620,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
    *  @p [first1,last1-(last2-first2))
   */
   template<typename _ForwardIterator1, typename _ForwardIterator2>
-    _ForwardIterator1
-    search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-          _ForwardIterator2 __first2, _ForwardIterator2 __last2)
+    inline _ForwardIterator1
+    find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+            _ForwardIterator2 __first2, _ForwardIterator2 __last2)
     {
       // concept requirements
       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>)
@@ -625,68 +633,43 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       __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.
-      _ForwardIterator2 __p1(__first2);
-      if (++__p1 == __last2)
-       return std::find(__first1, __last1, *__first2);
-
-      // General case.
-      _ForwardIterator2 __p;
-      _ForwardIterator1 __current = __first1;
-
-      for (;;)
-       {
-         __first1 = std::find(__first1, __last1, *__first2);
-         if (__first1 == __last1)
-           return __last1;
-
-         __p = __p1;
-         __current = __first1;
-         if (++__current == __last1)
-           return __last1;
-
-         while (*__current == *__p)
-           {
-             if (++__p == __last2)
-               return __first1;
-             if (++__current == __last1)
-               return __last1;
-           }
-         ++__first1;
-       }
-      return __first1;
+      return std::__find_end(__first1, __last1, __first2, __last2,
+                            std::__iterator_category(__first1),
+                            std::__iterator_category(__first2));
     }
 
   /**
-   *  @brief Search a sequence for a matching sub-sequence using a predicate.
-   *  @param  first1     A forward iterator.
-   *  @param  last1      A forward iterator.
-   *  @param  first2     A forward iterator.
-   *  @param  last2      A forward iterator.
-   *  @param  predicate  A binary predicate.
-   *  @return   The first iterator @c i in the range
-   *  @p [first1,last1-(last2-first2)) such that
-   *  @p predicate(*(i+N),*(first2+N)) is true for each @c N in the range
-   *  @p [0,last2-first2), or @p last1 if no such iterator exists.
+   *  @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 @p predicate to determine equality, and returns an iterator
-   *  to the first element of the sub-sequence, or @p last1 if no such
-   *  iterator exists.
+   *  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).
    *
-   *  @see search(_ForwardIter1, _ForwardIter1, _ForwardIter2, _ForwardIter2)
+   *  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>
-    _ForwardIterator1
-    search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-          _ForwardIterator2 __first2, _ForwardIterator2 __last2,
-          _BinaryPredicate  __predicate)
+    inline _ForwardIterator1
+    find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+            _ForwardIterator2 __first2, _ForwardIterator2 __last2,
+            _BinaryPredicate __comp)
     {
       // concept requirements
       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>)
@@ -697,3032 +680,2570 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       __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.
-      _ForwardIterator2 __p1(__first2);
-      if (++__p1 == __last2)
-       {
-         while (__first1 != __last1
-                && !bool(__predicate(*__first1, *__first2)))
-           ++__first1;
-         return __first1;
-       }
-
-      // General case.
-      _ForwardIterator2 __p;
-      _ForwardIterator1 __current = __first1;
+      return std::__find_end(__first1, __last1, __first2, __last2,
+                            std::__iterator_category(__first1),
+                            std::__iterator_category(__first2),
+                            __comp);
+    }
 
-      for (;;)
-       {
-         while (__first1 != __last1
-                && !bool(__predicate(*__first1, *__first2)))
-           ++__first1;
-         if (__first1 == __last1)
-           return __last1;
 
-         __p = __p1;
-         __current = __first1;
-         if (++__current == __last1)
-           return __last1;
+  /**
+   *  @brief Copy a sequence, removing elements of a given value.
+   *  @param  first   An input iterator.
+   *  @param  last    An input iterator.
+   *  @param  result  An output iterator.
+   *  @param  value   The value to be removed.
+   *  @return   An iterator designating the end of the resulting sequence.
+   *
+   *  Copies each element in the range @p [first,last) not equal to @p value
+   *  to the range beginning at @p result.
+   *  remove_copy() is stable, so the relative order of elements that are
+   *  copied is unchanged.
+  */
+  template<typename _InputIterator, typename _OutputIterator, typename _Tp>
+    _OutputIterator
+    remove_copy(_InputIterator __first, _InputIterator __last,
+               _OutputIterator __result, const _Tp& __value)
+    {
+      // concept requirements
+      __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);
 
-         while (__predicate(*__current, *__p))
-           {
-             if (++__p == __last2)
-               return __first1;
-             if (++__current == __last1)
-               return __last1;
-           }
-         ++__first1;
-       }
-      return __first1;
+      for (; __first != __last; ++__first)
+       if (!(*__first == __value))
+         {
+           *__result = *__first;
+           ++__result;
+         }
+      return __result;
     }
 
   /**
-   *  @if maint
-   *  This is an uglified
-   *  search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&)
-   *  overloaded for forward iterators.
-   *  @endif
+   *  @brief Copy a sequence, removing elements for which a predicate is true.
+   *  @param  first   An input iterator.
+   *  @param  last    An input iterator.
+   *  @param  result  An output iterator.
+   *  @param  pred    A predicate.
+   *  @return   An iterator designating the end of the resulting sequence.
+   *
+   *  Copies each element in the range @p [first,last) for which
+   *  @p pred returns true to the range beginning at @p result.
+   *
+   *  remove_copy_if() is stable, so the relative order of elements that are
+   *  copied is unchanged.
   */
-  template<typename _ForwardIterator, typename _Integer, typename _Tp>
-    _ForwardIterator
-    __search_n(_ForwardIterator __first, _ForwardIterator __last,
-              _Integer __count, const _Tp& __val,
-              std::forward_iterator_tag)
+  template<typename _InputIterator, typename _OutputIterator,
+          typename _Predicate>
+    _OutputIterator
+    remove_copy_if(_InputIterator __first, _InputIterator __last,
+                  _OutputIterator __result, _Predicate __pred)
     {
-      __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;
-         if (__i == __last)
-           return __last;
-         __first = std::find(++__i, __last, __val);
-       }
-      return __last;
+      // concept requirements
+      __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 (!bool(__pred(*__first)))
+         {
+           *__result = *__first;
+           ++__result;
+         }
+      return __result;
     }
 
   /**
-   *  @if maint
-   *  This is an uglified
-   *  search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&)
-   *  overloaded for random access iterators.
-   *  @endif
+   *  @brief Remove elements from a sequence.
+   *  @param  first  An input iterator.
+   *  @param  last   An input iterator.
+   *  @param  value  The value to be removed.
+   *  @return   An iterator designating the end of the resulting sequence.
+   *
+   *  All elements equal to @p value are removed from the range
+   *  @p [first,last).
+   *
+   *  remove() is stable, so the relative order of elements that are
+   *  not removed is unchanged.
+   *
+   *  Elements between the end of the resulting sequence and @p last
+   *  are still present, but their value is unspecified.
   */
-  template<typename _RandomAccessIter, typename _Integer, typename _Tp>
-    _RandomAccessIter
-    __search_n(_RandomAccessIter __first, _RandomAccessIter __last,
-              _Integer __count, const _Tp& __val, 
-              std::random_access_iterator_tag)
+  template<typename _ForwardIterator, typename _Tp>
+    _ForwardIterator
+    remove(_ForwardIterator __first, _ForwardIterator __last,
+          const _Tp& __value)
     {
-      
-      typedef typename std::iterator_traits<_RandomAccessIter>::difference_type
-       _DistanceType;
-
-      _DistanceType __tailSize = __last - __first;
-      const _DistanceType __pattSize = __count;
+      // concept requirements
+      __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
+                                 _ForwardIterator>)
+      __glibcxx_function_requires(_EqualOpConcept<
+           typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
+      __glibcxx_requires_valid_range(__first, __last);
 
-      if (__tailSize < __pattSize)
-        return __last;
-
-      const _DistanceType __skipOffset = __pattSize - 1;
-      _RandomAccessIter __lookAhead = __first + __skipOffset;
-      __tailSize -= __pattSize;
-
-      while (1) // the main loop...
-       {
-         // __lookAhead here is always pointing to the last element of next 
-         // possible match.
-         while (!(*__lookAhead == __val)) // the skip loop...
-           {
-             if (__tailSize < __pattSize)
-               return __last;  // Failure
-             __lookAhead += __pattSize;
-             __tailSize -= __pattSize;
-           }
-         _DistanceType __remainder = __skipOffset;
-         for (_RandomAccessIter __backTrack = __lookAhead - 1; 
-              *__backTrack == __val; --__backTrack)
-           {
-             if (--__remainder == 0)
-               return (__lookAhead - __skipOffset); // Success
-           }
-         if (__remainder > __tailSize)
-           return __last; // Failure
-         __lookAhead += __remainder;
-         __tailSize -= __remainder;
-       }
-    }
+      __first = _GLIBCXX_STD_P::find(__first, __last, __value);
+      _ForwardIterator __i = __first;
+      return __first == __last ? __first
+                       : std::remove_copy(++__i, __last, __first, __value);
+    }
 
   /**
-   *  @brief Search a sequence for a number of consecutive values.
+   *  @brief Remove elements from a sequence using a predicate.
    *  @param  first  A forward iterator.
    *  @param  last   A forward iterator.
-   *  @param  count  The number of consecutive values.
-   *  @param  val    The value to find.
-   *  @return   The first iterator @c i in the range @p [first,last-count)
-   *  such that @c *(i+N) == @p val for each @c N in the range @p [0,count),
-   *  or @p last if no such iterator exists.
+   *  @param  pred   A predicate.
+   *  @return   An iterator designating the end of the resulting sequence.
    *
-   *  Searches the range @p [first,last) for @p count consecutive elements
-   *  equal to @p val.
+   *  All elements for which @p pred returns true are removed from the range
+   *  @p [first,last).
+   *
+   *  remove_if() is stable, so the relative order of elements that are
+   *  not removed is unchanged.
+   *
+   *  Elements between the end of the resulting sequence and @p last
+   *  are still present, but their value is unspecified.
   */
-  template<typename _ForwardIterator, typename _Integer, typename _Tp>
+  template<typename _ForwardIterator, typename _Predicate>
     _ForwardIterator
-    search_n(_ForwardIterator __first, _ForwardIterator __last,
-            _Integer __count, const _Tp& __val)
+    remove_if(_ForwardIterator __first, _ForwardIterator __last,
+             _Predicate __pred)
     {
       // concept requirements
-      __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
-      __glibcxx_function_requires(_EqualOpConcept<
-       typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
+      __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
+                                 _ForwardIterator>)
+      __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
+           typename iterator_traits<_ForwardIterator>::value_type>)
       __glibcxx_requires_valid_range(__first, __last);
 
-      if (__count <= 0)
-       return __first;
-      if (__count == 1)
-       return std::find(__first, __last, __val);
-      return std::__search_n(__first, __last, __count, __val,
-                            std::__iterator_category(__first));
+      __first = _GLIBCXX_STD_P::find_if(__first, __last, __pred);
+      _ForwardIterator __i = __first;
+      return __first == __last ? __first
+                              : std::remove_copy_if(++__i, __last,
+                                                    __first, __pred);
     }
 
   /**
-   *  @if maint
-   *  This is an uglified
-   *  search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&,
-   *          _BinaryPredicate)
-   *  overloaded for forward iterators.
-   *  @endif
+   *  @brief Remove consecutive duplicate values from a sequence.
+   *  @param  first  A forward iterator.
+   *  @param  last   A forward iterator.
+   *  @return  An iterator designating the end of the resulting sequence.
+   *
+   *  Removes all but the first element from each group of consecutive
+   *  values that compare equal.
+   *  unique() is stable, so the relative order of elements that are
+   *  not removed is unchanged.
+   *  Elements between the end of the resulting sequence and @p last
+   *  are still present, but their value is unspecified.
   */
-  template<typename _ForwardIterator, typename _Integer, typename _Tp,
-           typename _BinaryPredicate>
+  template<typename _ForwardIterator>
     _ForwardIterator
-    __search_n(_ForwardIterator __first, _ForwardIterator __last,
-              _Integer __count, const _Tp& __val,
-              _BinaryPredicate __binary_pred, std::forward_iterator_tag)
-    {
-      while (__first != __last && !bool(__binary_pred(*__first, __val)))
-        ++__first;
-
-      while (__first != __last)
-       {
-         typename iterator_traits<_ForwardIterator>::difference_type
-           __n = __count;
-         _ForwardIterator __i = __first;
-         ++__i;
-         while (__i != __last && __n != 1 && bool(__binary_pred(*__i, __val)))
-           {
-             ++__i;
-             --__n;
-           }
-         if (__n == 1)
-           return __first;
-         if (__i == __last)
-           return __last;
-         __first = ++__i;
-         while (__first != __last
-                && !bool(__binary_pred(*__first, __val)))
-           ++__first;
-       }
-      return __last;
-    }
-
-  /**
-   *  @if maint
-   *  This is an uglified
-   *  search_n(_ForwardIterator, _ForwardIterator, _Integer, const _Tp&,
-   *          _BinaryPredicate)
-   *  overloaded for random access iterators.
-   *  @endif
-  */
-  template<typename _RandomAccessIter, typename _Integer, typename _Tp,
-          typename _BinaryPredicate>
-    _RandomAccessIter
-    __search_n(_RandomAccessIter __first, _RandomAccessIter __last,
-              _Integer __count, const _Tp& __val,
-              _BinaryPredicate __binary_pred, std::random_access_iterator_tag)
+    unique(_ForwardIterator __first, _ForwardIterator __last)
     {
-      
-      typedef typename std::iterator_traits<_RandomAccessIter>::difference_type
-       _DistanceType;
-
-      _DistanceType __tailSize = __last - __first;
-      const _DistanceType __pattSize = __count;
-
-      if (__tailSize < __pattSize)
-        return __last;
+      // concept requirements
+      __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
+                                 _ForwardIterator>)
+      __glibcxx_function_requires(_EqualityComparableConcept<
+                    typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
-      const _DistanceType __skipOffset = __pattSize - 1;
-      _RandomAccessIter __lookAhead = __first + __skipOffset;
-      __tailSize -= __pattSize;
+      // Skip the beginning, if already unique.
+      __first = _GLIBCXX_STD_P::adjacent_find(__first, __last);
+      if (__first == __last)
+       return __last;
 
-      while (1) // the main loop...
-       {
-         // __lookAhead here is always pointing to the last element of next 
-         // possible match.
-         while (!bool(__binary_pred(*__lookAhead, __val))) // the skip loop...
-           {
-             if (__tailSize < __pattSize)
-               return __last;  // Failure
-             __lookAhead += __pattSize;
-             __tailSize -= __pattSize;
-           }
-         _DistanceType __remainder = __skipOffset;
-         for (_RandomAccessIter __backTrack = __lookAhead - 1; 
-              __binary_pred(*__backTrack, __val); --__backTrack)
-           {
-             if (--__remainder == 0)
-               return (__lookAhead - __skipOffset); // Success
-           }
-         if (__remainder > __tailSize)
-           return __last; // Failure
-         __lookAhead += __remainder;
-         __tailSize -= __remainder;
-       }
+      // Do the real copy work.
+      _ForwardIterator __dest = __first;
+      ++__first;
+      while (++__first != __last)
+       if (!(*__dest == *__first))
+         *++__dest = *__first;
+      return ++__dest;
     }
 
   /**
-   *  @brief Search a sequence for a number of consecutive values using a
-   *         predicate.
+   *  @brief Remove consecutive values from a sequence using a predicate.
    *  @param  first        A forward iterator.
    *  @param  last         A forward iterator.
-   *  @param  count        The number of consecutive values.
-   *  @param  val          The value to find.
    *  @param  binary_pred  A binary predicate.
-   *  @return   The first iterator @c i in the range @p [first,last-count)
-   *  such that @p binary_pred(*(i+N),val) is true for each @c N in the
-   *  range @p [0,count), or @p last if no such iterator exists.
+   *  @return  An iterator designating the end of the resulting sequence.
    *
-   *  Searches the range @p [first,last) for @p count consecutive elements
-   *  for which the predicate returns true.
+   *  Removes all but the first element from each group of consecutive
+   *  values for which @p binary_pred returns true.
+   *  unique() is stable, so the relative order of elements that are
+   *  not removed is unchanged.
+   *  Elements between the end of the resulting sequence and @p last
+   *  are still present, but their value is unspecified.
   */
-  template<typename _ForwardIterator, typename _Integer, typename _Tp,
-           typename _BinaryPredicate>
+  template<typename _ForwardIterator, typename _BinaryPredicate>
     _ForwardIterator
-    search_n(_ForwardIterator __first, _ForwardIterator __last,
-            _Integer __count, const _Tp& __val,
-            _BinaryPredicate __binary_pred)
+    unique(_ForwardIterator __first, _ForwardIterator __last,
+           _BinaryPredicate __binary_pred)
     {
       // concept requirements
-      __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
+      __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
+                                 _ForwardIterator>)
       __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
-           typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
+               typename iterator_traits<_ForwardIterator>::value_type,
+               typename iterator_traits<_ForwardIterator>::value_type>)
       __glibcxx_requires_valid_range(__first, __last);
 
-      if (__count <= 0)
-       return __first;
-      if (__count == 1)
-       {
-         while (__first != __last && !bool(__binary_pred(*__first, __val)))
-           ++__first;
-         return __first;
-       }
-      return std::__search_n(__first, __last, __count, __val, __binary_pred,
-                            std::__iterator_category(__first));
+      // Skip the beginning, if already unique.
+      __first = _GLIBCXX_STD_P::adjacent_find(__first, __last, __binary_pred);
+      if (__first == __last)
+       return __last;
+
+      // Do the real copy work.
+      _ForwardIterator __dest = __first;
+      ++__first;
+      while (++__first != __last)
+       if (!bool(__binary_pred(*__dest, *__first)))
+         *++__dest = *__first;
+      return ++__dest;
     }
 
-  // find_end for forward iterators.
-  template<typename _ForwardIterator1, typename _ForwardIterator2>
-    _ForwardIterator1
-    __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-              _ForwardIterator2 __first2, _ForwardIterator2 __last2,
-              forward_iterator_tag, forward_iterator_tag)
+  /**
+   *  @if maint
+   *  This is an uglified unique_copy(_InputIterator, _InputIterator,
+   *                                  _OutputIterator)
+   *  overloaded for forward iterators and output iterator as result.
+   *  @endif
+  */
+  template<typename _ForwardIterator, typename _OutputIterator>
+    _OutputIterator
+    __unique_copy(_ForwardIterator __first, _ForwardIterator __last,
+                 _OutputIterator __result,
+                 forward_iterator_tag, output_iterator_tag)
     {
-      if (__first2 == __last2)
-       return __last1;
-      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;
-               }
-           }
-       }
+      // concept requirements -- taken care of in dispatching function
+      _ForwardIterator __next = __first;
+      *__result = *__first;
+      while (++__next != __last)
+       if (!(*__first == *__next))
+         {
+           __first = __next;
+           *++__result = *__first;
+         }
+      return ++__result;
     }
 
-  template<typename _ForwardIterator1, typename _ForwardIterator2,
-          typename _BinaryPredicate>
-    _ForwardIterator1
-    __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-              _ForwardIterator2 __first2, _ForwardIterator2 __last2,
-              forward_iterator_tag, forward_iterator_tag,
-              _BinaryPredicate __comp)
+  /**
+   *  @if maint
+   *  This is an uglified unique_copy(_InputIterator, _InputIterator,
+   *                                  _OutputIterator)
+   *  overloaded for input iterators and output iterator as result.
+   *  @endif
+  */
+  template<typename _InputIterator, typename _OutputIterator>
+    _OutputIterator
+    __unique_copy(_InputIterator __first, _InputIterator __last,
+                 _OutputIterator __result,
+                 input_iterator_tag, output_iterator_tag)
     {
-      if (__first2 == __last2)
-       return __last1;
-      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;
-               }
-           }
-       }
+      // concept requirements -- taken care of in dispatching function
+      typename iterator_traits<_InputIterator>::value_type __value = *__first;
+      *__result = __value;
+      while (++__first != __last)
+       if (!(__value == *__first))
+         {
+           __value = *__first;
+           *++__result = __value;
+         }
+      return ++__result;
     }
 
-  // find_end for bidirectional iterators (much faster).
-  template<typename _BidirectionalIterator1, typename _BidirectionalIterator2>
-    _BidirectionalIterator1
-    __find_end(_BidirectionalIterator1 __first1,
-              _BidirectionalIterator1 __last1,
-              _BidirectionalIterator2 __first2,
-              _BidirectionalIterator2 __last2,
-              bidirectional_iterator_tag, bidirectional_iterator_tag)
+  /**
+   *  @if maint
+   *  This is an uglified unique_copy(_InputIterator, _InputIterator,
+   *                                  _OutputIterator)
+   *  overloaded for input iterators and forward iterator as result.
+   *  @endif
+  */
+  template<typename _InputIterator, typename _ForwardIterator>
+    _ForwardIterator
+    __unique_copy(_InputIterator __first, _InputIterator __last,
+                 _ForwardIterator __result,
+                 input_iterator_tag, forward_iterator_tag)
     {
-      // concept requirements
-      __glibcxx_function_requires(_BidirectionalIteratorConcept<
-                                 _BidirectionalIterator1>)
-      __glibcxx_function_requires(_BidirectionalIteratorConcept<
-                                 _BidirectionalIterator2>)
-
-      typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1;
-      typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2;
-
-      _RevIterator1 __rlast1(__first1);
-      _RevIterator2 __rlast2(__first2);
-      _RevIterator1 __rresult = std::search(_RevIterator1(__last1), __rlast1,
-                                           _RevIterator2(__last2), __rlast2);
-
-      if (__rresult == __rlast1)
-       return __last1;
-      else
-       {
-         _BidirectionalIterator1 __result = __rresult.base();
-         std::advance(__result, -std::distance(__first2, __last2));
-         return __result;
-       }
+      // concept requirements -- taken care of in dispatching function
+      *__result = *__first;
+      while (++__first != __last)
+       if (!(*__result == *__first))
+         *++__result = *__first;
+      return ++__result;
     }
 
-  template<typename _BidirectionalIterator1, typename _BidirectionalIterator2,
+  /**
+   *  @if maint
+   *  This is an uglified
+   *  unique_copy(_InputIterator, _InputIterator, _OutputIterator,
+   *              _BinaryPredicate)
+   *  overloaded for forward iterators and output iterator as result.
+   *  @endif
+  */
+  template<typename _ForwardIterator, typename _OutputIterator,
           typename _BinaryPredicate>
-    _BidirectionalIterator1
-    __find_end(_BidirectionalIterator1 __first1,
-              _BidirectionalIterator1 __last1,
-              _BidirectionalIterator2 __first2,
-              _BidirectionalIterator2 __last2,
-              bidirectional_iterator_tag, bidirectional_iterator_tag,
-              _BinaryPredicate __comp)
+    _OutputIterator
+    __unique_copy(_ForwardIterator __first, _ForwardIterator __last,
+                 _OutputIterator __result, _BinaryPredicate __binary_pred,
+                 forward_iterator_tag, output_iterator_tag)
     {
-      // concept requirements
-      __glibcxx_function_requires(_BidirectionalIteratorConcept<
-                                 _BidirectionalIterator1>)
-      __glibcxx_function_requires(_BidirectionalIteratorConcept<
-                                 _BidirectionalIterator2>)
-
-      typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1;
-      typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2;
-
-      _RevIterator1 __rlast1(__first1);
-      _RevIterator2 __rlast2(__first2);
-      _RevIterator1 __rresult = std::search(_RevIterator1(__last1), __rlast1,
-                                           _RevIterator2(__last2), __rlast2,
-                                           __comp);
+      // concept requirements -- iterators already checked
+      __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
+         typename iterator_traits<_ForwardIterator>::value_type,
+         typename iterator_traits<_ForwardIterator>::value_type>)
 
-      if (__rresult == __rlast1)
-       return __last1;
-      else
-       {
-         _BidirectionalIterator1 __result = __rresult.base();
-         std::advance(__result, -std::distance(__first2, __last2));
-         return __result;
-       }
+      _ForwardIterator __next = __first;
+      *__result = *__first;
+      while (++__next != __last)
+       if (!bool(__binary_pred(*__first, *__next)))
+         {
+           __first = __next;
+           *++__result = *__first;
+         }
+      return ++__result;
     }
 
   /**
-   *  @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))
+   *  @if maint
+   *  This is an uglified
+   *  unique_copy(_InputIterator, _InputIterator, _OutputIterator,
+   *              _BinaryPredicate)
+   *  overloaded for input iterators and output iterator as result.
+   *  @endif
   */
-  template<typename _ForwardIterator1, typename _ForwardIterator2>
-    inline _ForwardIterator1
-    find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-            _ForwardIterator2 __first2, _ForwardIterator2 __last2)
+  template<typename _InputIterator, typename _OutputIterator,
+          typename _BinaryPredicate>
+    _OutputIterator
+    __unique_copy(_InputIterator __first, _InputIterator __last,
+                 _OutputIterator __result, _BinaryPredicate __binary_pred,
+                 input_iterator_tag, output_iterator_tag)
     {
-      // concept requirements
-      __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);
+      // concept requirements -- iterators already checked
+      __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
+         typename iterator_traits<_InputIterator>::value_type,
+         typename iterator_traits<_InputIterator>::value_type>)
 
-      return std::__find_end(__first1, __last1, __first2, __last2,
-                            std::__iterator_category(__first1),
-                            std::__iterator_category(__first2));
+      typename iterator_traits<_InputIterator>::value_type __value = *__first;
+      *__result = __value;
+      while (++__first != __last)
+       if (!bool(__binary_pred(__value, *__first)))
+         {
+           __value = *__first;
+           *++__result = __value;
+         }
+      return ++__result;
     }
 
   /**
-   *  @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))
+   *  @if maint
+   *  This is an uglified
+   *  unique_copy(_InputIterator, _InputIterator, _OutputIterator,
+   *              _BinaryPredicate)
+   *  overloaded for input iterators and forward iterator as result.
+   *  @endif
   */
-  template<typename _ForwardIterator1, typename _ForwardIterator2,
+  template<typename _InputIterator, typename _ForwardIterator,
           typename _BinaryPredicate>
-    inline _ForwardIterator1
-    find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-            _ForwardIterator2 __first2, _ForwardIterator2 __last2,
-            _BinaryPredicate __comp)
+    _ForwardIterator
+    __unique_copy(_InputIterator __first, _InputIterator __last,
+                 _ForwardIterator __result, _BinaryPredicate __binary_pred,
+                 input_iterator_tag, forward_iterator_tag)
     {
-      // concept requirements
-      __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>)
-      __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>)
+      // concept requirements -- iterators already checked
       __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);
-    }
-
-  /**
-   *  @brief Perform an operation on a sequence.
-   *  @param  first     An input iterator.
-   *  @param  last      An input iterator.
-   *  @param  result    An output iterator.
-   *  @param  unary_op  A unary operator.
-   *  @return   An output iterator equal to @p result+(last-first).
-   *
-   *  Applies the operator to each element in the input range and assigns
-   *  the results to successive elements of the output sequence.
-   *  Evaluates @p *(result+N)=unary_op(*(first+N)) for each @c N in the
-   *  range @p [0,last-first).
-   *
-   *  @p unary_op must not alter its argument.
-  */
-  template<typename _InputIterator, typename _OutputIterator,
-          typename _UnaryOperation>
-    _OutputIterator
-    transform(_InputIterator __first, _InputIterator __last,
-             _OutputIterator __result, _UnaryOperation __unary_op)
-    {
-      // concept requirements
-      __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);
+         typename iterator_traits<_ForwardIterator>::value_type,
+         typename iterator_traits<_InputIterator>::value_type>)
 
-      for (; __first != __last; ++__first, ++__result)
-       *__result = __unary_op(*__first);
-      return __result;
+      *__result = *__first;
+      while (++__first != __last)
+       if (!bool(__binary_pred(*__result, *__first)))
+         *++__result = *__first;
+      return ++__result;
     }
 
   /**
-   *  @brief Perform an operation on corresponding elements of two sequences.
-   *  @param  first1     An input iterator.
-   *  @param  last1      An input iterator.
-   *  @param  first2     An input iterator.
-   *  @param  result     An output iterator.
-   *  @param  binary_op  A binary operator.
-   *  @return   An output iterator equal to @p result+(last-first).
-   *
-   *  Applies the operator to the corresponding elements in the two
-   *  input ranges and assigns the results to successive elements of the
-   *  output sequence.
-   *  Evaluates @p *(result+N)=binary_op(*(first1+N),*(first2+N)) for each
-   *  @c N in the range @p [0,last1-first1).
-   *
-   *  @p binary_op must not alter either of its arguments.
+   *  @if maint
+   *  This is an uglified reverse(_BidirectionalIterator,
+   *                              _BidirectionalIterator)
+   *  overloaded for bidirectional iterators.
+   *  @endif
   */
-  template<typename _InputIterator1, typename _InputIterator2,
-          typename _OutputIterator, typename _BinaryOperation>
-    _OutputIterator
-    transform(_InputIterator1 __first1, _InputIterator1 __last1,
-             _InputIterator2 __first2, _OutputIterator __result,
-             _BinaryOperation __binary_op)
+  template<typename _BidirectionalIterator>
+    void
+    __reverse(_BidirectionalIterator __first, _BidirectionalIterator __last,
+             bidirectional_iterator_tag)
     {
-      // concept requirements
-      __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);
-      return __result;
+      while (true)
+       if (__first == __last || __first == --__last)
+         return;
+       else
+         {
+           std::iter_swap(__first, __last);
+           ++__first;
+         }
     }
 
   /**
-   *  @brief Replace each occurrence of one value in a sequence with another
-   *         value.
-   *  @param  first      A forward iterator.
-   *  @param  last       A forward iterator.
-   *  @param  old_value  The value to be replaced.
-   *  @param  new_value  The replacement value.
-   *  @return   replace() returns no value.
-   *
-   *  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.
+   *  @if maint
+   *  This is an uglified reverse(_BidirectionalIterator,
+   *                              _BidirectionalIterator)
+   *  overloaded for random access iterators.
+   *  @endif
   */
-  template<typename _ForwardIterator, typename _Tp>
+  template<typename _RandomAccessIterator>
     void
-    replace(_ForwardIterator __first, _ForwardIterator __last,
-           const _Tp& __old_value, const _Tp& __new_value)
+    __reverse(_RandomAccessIterator __first, _RandomAccessIterator __last,
+             random_access_iterator_tag)
     {
-      // concept requirements
-      __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)
-         *__first = __new_value;
+      if (__first == __last)
+       return;
+      --__last;
+      while (__first < __last)
+       {
+         std::iter_swap(__first, __last);
+         ++__first;
+         --__last;
+       }
     }
 
   /**
-   *  @brief Replace each value in a sequence for which a predicate returns
-   *         true with another value.
-   *  @param  first      A forward iterator.
-   *  @param  last       A forward iterator.
-   *  @param  pred       A predicate.
-   *  @param  new_value  The replacement value.
-   *  @return   replace_if() returns no value.
+   *  @brief Reverse a sequence.
+   *  @param  first  A bidirectional iterator.
+   *  @param  last   A bidirectional iterator.
+   *  @return   reverse() returns no value.
    *
-   *  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.
+   *  Reverses the order of the elements in the range @p [first,last),
+   *  so that the first element becomes the last etc.
+   *  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 _ForwardIterator, typename _Predicate, typename _Tp>
-    void
-    replace_if(_ForwardIterator __first, _ForwardIterator __last,
-              _Predicate __pred, const _Tp& __new_value)
+  template<typename _BidirectionalIterator>
+    inline void
+    reverse(_BidirectionalIterator __first, _BidirectionalIterator __last)
     {
       // concept requirements
-      __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_function_requires(_Mutable_BidirectionalIteratorConcept<
+                                 _BidirectionalIterator>)
       __glibcxx_requires_valid_range(__first, __last);
-
-      for (; __first != __last; ++__first)
-       if (__pred(*__first))
-         *__first = __new_value;
+      std::__reverse(__first, __last, std::__iterator_category(__first));
     }
 
   /**
-   *  @brief Copy a sequence, replacing each element of one value with another
-   *         value.
-   *  @param  first      An input iterator.
-   *  @param  last       An input iterator.
-   *  @param  result     An output iterator.
-   *  @param  old_value  The value to be replaced.
-   *  @param  new_value  The replacement value.
-   *  @return   The end of the output sequence, @p result+(last-first).
+   *  @brief Copy a sequence, reversing its elements.
+   *  @param  first   A bidirectional iterator.
+   *  @param  last    A bidirectional iterator.
+   *  @param  result  An output iterator.
+   *  @return  An iterator designating the end of the resulting sequence.
    *
-   *  Copies each element in the input range @p [first,last) to the
-   *  output range @p [result,result+(last-first)) replacing elements
-   *  equal to @p old_value with @p new_value.
+   *  Copies the elements in the range @p [first,last) to the range
+   *  @p [result,result+(last-first)) such that the order of the
+   *  elements is reversed.
+   *  For every @c i such that @p 0<=i<=(last-first), @p reverse_copy()
+   *  performs the assignment @p *(result+(last-first)-i) = *(first+i).
+   *  The ranges @p [first,last) and @p [result,result+(last-first))
+   *  must not overlap.
   */
-  template<typename _InputIterator, typename _OutputIterator, typename _Tp>
+  template<typename _BidirectionalIterator, typename _OutputIterator>
     _OutputIterator
-    replace_copy(_InputIterator __first, _InputIterator __last,
-                _OutputIterator __result,
-                const _Tp& __old_value, const _Tp& __new_value)
+    reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last,
+                            _OutputIterator __result)
     {
       // concept requirements
-      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
+      __glibcxx_function_requires(_BidirectionalIteratorConcept<
+                                 _BidirectionalIterator>)
       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
-           typename iterator_traits<_InputIterator>::value_type>)
-      __glibcxx_function_requires(_EqualOpConcept<
-           typename iterator_traits<_InputIterator>::value_type, _Tp>)
+               typename iterator_traits<_BidirectionalIterator>::value_type>)
       __glibcxx_requires_valid_range(__first, __last);
 
-      for (; __first != __last; ++__first, ++__result)
-       if (*__first == __old_value)
-         *__result = __new_value;
-       else
-         *__result = *__first;
+      while (__first != __last)
+       {
+         --__last;
+         *__result = *__last;
+         ++__result;
+       }
       return __result;
     }
 
   /**
-   *  @brief Copy a sequence, replacing each value for which a predicate
-   *         returns true with another value.
-   *  @param  first      An input iterator.
-   *  @param  last       An input iterator.
-   *  @param  result     An output iterator.
-   *  @param  pred       A predicate.
-   *  @param  new_value  The replacement value.
-   *  @return   The end of the output sequence, @p result+(last-first).
-   *
-   *  Copies each element in the range @p [first,last) to the range
-   *  @p [result,result+(last-first)) replacing elements for which
-   *  @p pred returns true with @p new_value.
+   *  @if maint
+   *  This is a helper function for the rotate algorithm specialized on RAIs.
+   *  It returns the greatest common divisor of two integer values.
+   *  @endif
   */
-  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)
+  template<typename _EuclideanRingElement>
+    _EuclideanRingElement
+    __gcd(_EuclideanRingElement __m, _EuclideanRingElement __n)
     {
-      // concept requirements
-      __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)
-       if (__pred(*__first))
-         *__result = __new_value;
-       else
-         *__result = *__first;
-      return __result;
+      while (__n != 0)
+       {
+         _EuclideanRingElement __t = __m % __n;
+         __m = __n;
+         __n = __t;
+       }
+      return __m;
     }
 
   /**
-   *  @brief Assign the result of a function object to each value in a
-   *         sequence.
-   *  @param  first  A forward iterator.
-   *  @param  last   A forward iterator.
-   *  @param  gen    A function object taking no arguments.
-   *  @return   generate() returns no value.
-   *
-   *  Performs the assignment @c *i = @p gen() for each @c i in the range
-   *  @p [first,last).
+   *  @if maint
+   *  This is a helper function for the rotate algorithm.
+   *  @endif
   */
-  template<typename _ForwardIterator, typename _Generator>
+  template<typename _ForwardIterator>
     void
-    generate(_ForwardIterator __first, _ForwardIterator __last,
-            _Generator __gen)
+    __rotate(_ForwardIterator __first,
+            _ForwardIterator __middle,
+            _ForwardIterator __last,
+            forward_iterator_tag)
     {
-      // concept requirements
-      __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
-      __glibcxx_function_requires(_GeneratorConcept<_Generator,
-           typename iterator_traits<_ForwardIterator>::value_type>)
-      __glibcxx_requires_valid_range(__first, __last);
+      if (__first == __middle || __last  == __middle)
+       return;
 
-      for (; __first != __last; ++__first)
-       *__first = __gen();
+      _ForwardIterator __first2 = __middle;
+      do
+       {
+         swap(*__first, *__first2);
+         ++__first;
+         ++__first2;
+         if (__first == __middle)
+           __middle = __first2;
+       }
+      while (__first2 != __last);
+
+      __first2 = __middle;
+
+      while (__first2 != __last)
+       {
+         swap(*__first, *__first2);
+         ++__first;
+         ++__first2;
+         if (__first == __middle)
+           __middle = __first2;
+         else if (__first2 == __last)
+           __first2 = __middle;
+       }
     }
 
   /**
-   *  @brief Assign the result of a function object to each value in a
-   *         sequence.
-   *  @param  first  A forward iterator.
-   *  @param  n      The length of the sequence.
-   *  @param  gen    A function object taking no arguments.
-   *  @return   The end of the sequence, @p first+n
-   *
-   *  Performs the assignment @c *i = @p gen() for each @c i in the range
-   *  @p [first,first+n).
+   *  @if maint
+   *  This is a helper function for the rotate algorithm.
+   *  @endif
   */
-  template<typename _OutputIterator, typename _Size, typename _Generator>
-    _OutputIterator
-    generate_n(_OutputIterator __first, _Size __n, _Generator __gen)
+  template<typename _BidirectionalIterator>
+    void
+    __rotate(_BidirectionalIterator __first,
+            _BidirectionalIterator __middle,
+            _BidirectionalIterator __last,
+             bidirectional_iterator_tag)
     {
       // concept requirements
-      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
-            // "the type returned by a _Generator"
-            __typeof__(__gen())>)
+      __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
+                                 _BidirectionalIterator>)
 
-      for (; __n > 0; --__n, ++__first)
-       *__first = __gen();
-      return __first;
+      if (__first == __middle || __last  == __middle)
+       return;
+
+      std::__reverse(__first,  __middle, bidirectional_iterator_tag());
+      std::__reverse(__middle, __last,   bidirectional_iterator_tag());
+
+      while (__first != __middle && __middle != __last)
+       {
+         swap(*__first, *--__last);
+         ++__first;
+       }
+
+      if (__first == __middle)
+       std::__reverse(__middle, __last,   bidirectional_iterator_tag());
+      else
+       std::__reverse(__first,  __middle, bidirectional_iterator_tag());
     }
 
   /**
-   *  @brief Copy a sequence, removing elements of a given value.
-   *  @param  first   An input iterator.
-   *  @param  last    An input iterator.
-   *  @param  result  An output iterator.
-   *  @param  value   The value to be removed.
-   *  @return   An iterator designating the end of the resulting sequence.
-   *
-   *  Copies each element in the range @p [first,last) not equal to @p value
-   *  to the range beginning at @p result.
-   *  remove_copy() is stable, so the relative order of elements that are
-   *  copied is unchanged.
+   *  @if maint
+   *  This is a helper function for the rotate algorithm.
+   *  @endif
   */
-  template<typename _InputIterator, typename _OutputIterator, typename _Tp>
-    _OutputIterator
-    remove_copy(_InputIterator __first, _InputIterator __last,
-               _OutputIterator __result, const _Tp& __value)
+  template<typename _RandomAccessIterator>
+    void
+    __rotate(_RandomAccessIterator __first,
+            _RandomAccessIterator __middle,
+            _RandomAccessIterator __last,
+            random_access_iterator_tag)
     {
       // concept requirements
-      __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);
+      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
+                                 _RandomAccessIterator>)
 
-      for (; __first != __last; ++__first)
-       if (!(*__first == __value))
-         {
-           *__result = *__first;
-           ++__result;
-         }
-      return __result;
+      if (__first == __middle || __last  == __middle)
+       return;
+
+      typedef typename iterator_traits<_RandomAccessIterator>::difference_type
+       _Distance;
+      typedef typename iterator_traits<_RandomAccessIterator>::value_type
+       _ValueType;
+
+      const _Distance __n = __last   - __first;
+      const _Distance __k = __middle - __first;
+      const _Distance __l = __n - __k;
+
+      if (__k == __l)
+       {
+         std::swap_ranges(__first, __middle, __middle);
+         return;
+       }
+
+      const _Distance __d = std::__gcd(__n, __k);
+
+      for (_Distance __i = 0; __i < __d; __i++)
+       {
+         _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 = __tmp;
+         ++__first;
+       }
     }
 
   /**
-   *  @brief Copy a sequence, removing elements for which a predicate is true.
-   *  @param  first   An input iterator.
-   *  @param  last    An input iterator.
-   *  @param  result  An output iterator.
-   *  @param  pred    A predicate.
-   *  @return   An iterator designating the end of the resulting sequence.
+   *  @brief Rotate the elements of a sequence.
+   *  @param  first   A forward iterator.
+   *  @param  middle  A forward iterator.
+   *  @param  last    A forward iterator.
+   *  @return  Nothing.
    *
-   *  Copies each element in the range @p [first,last) for which
-   *  @p pred returns true to the range beginning at @p result.
+   *  Rotates the elements of the range @p [first,last) by @p (middle-first)
+   *  positions so that the element at @p middle is moved to @p first, the
+   *  element at @p middle+1 is moved to @first+1 and so on for each element
+   *  in the range @p [first,last).
    *
-   *  remove_copy_if() is stable, so the relative order of elements that are
-   *  copied is unchanged.
+   *  This effectively swaps the ranges @p [first,middle) and
+   *  @p [middle,last).
+   *
+   *  Performs @p *(first+(n+(last-middle))%(last-first))=*(first+n) for
+   *  each @p n in the range @p [0,last-first).
   */
-  template<typename _InputIterator, typename _OutputIterator,
-          typename _Predicate>
-    _OutputIterator
-    remove_copy_if(_InputIterator __first, _InputIterator __last,
-                  _OutputIterator __result, _Predicate __pred)
-    {
-      // concept requirements
-      __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 (!bool(__pred(*__first)))
-         {
-           *__result = *__first;
-           ++__result;
-         }
-      return __result;
-    }
-
-  /**
-   *  @brief Remove elements from a sequence.
-   *  @param  first  An input iterator.
-   *  @param  last   An input iterator.
-   *  @param  value  The value to be removed.
-   *  @return   An iterator designating the end of the resulting sequence.
-   *
-   *  All elements equal to @p value are removed from the range
-   *  @p [first,last).
-   *
-   *  remove() is stable, so the relative order of elements that are
-   *  not removed is unchanged.
-   *
-   *  Elements between the end of the resulting sequence and @p last
-   *  are still present, but their value is unspecified.
-  */
-  template<typename _ForwardIterator, typename _Tp>
-    _ForwardIterator
-    remove(_ForwardIterator __first, _ForwardIterator __last,
-          const _Tp& __value)
+  template<typename _ForwardIterator>
+    inline void
+    rotate(_ForwardIterator __first, _ForwardIterator __middle,
+          _ForwardIterator __last)
     {
       // concept requirements
       __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
                                  _ForwardIterator>)
-      __glibcxx_function_requires(_EqualOpConcept<
-           typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
-      __glibcxx_requires_valid_range(__first, __last);
+      __glibcxx_requires_valid_range(__first, __middle);
+      __glibcxx_requires_valid_range(__middle, __last);
 
-      __first = std::find(__first, __last, __value);
-      _ForwardIterator __i = __first;
-      return __first == __last ? __first
-                              : std::remove_copy(++__i, __last,
-                                                 __first, __value);
+      typedef typename iterator_traits<_ForwardIterator>::iterator_category
+       _IterType;
+      std::__rotate(__first, __middle, __last, _IterType());
     }
 
   /**
-   *  @brief Remove elements from a sequence using a predicate.
-   *  @param  first  A forward iterator.
-   *  @param  last   A forward iterator.
-   *  @param  pred   A predicate.
+   *  @brief Copy a sequence, rotating its elements.
+   *  @param  first   A forward iterator.
+   *  @param  middle  A forward iterator.
+   *  @param  last    A forward iterator.
+   *  @param  result  An output iterator.
    *  @return   An iterator designating the end of the resulting sequence.
    *
-   *  All elements for which @p pred returns true are removed from the range
-   *  @p [first,last).
-   *
-   *  remove_if() is stable, so the relative order of elements that are
-   *  not removed is unchanged.
+   *  Copies the elements of the range @p [first,last) to the range
+   *  beginning at @result, rotating the copied elements by @p (middle-first)
+   *  positions so that the element at @p middle is moved to @p result, the
+   *  element at @p middle+1 is moved to @result+1 and so on for each element
+   *  in the range @p [first,last).
    *
-   *  Elements between the end of the resulting sequence and @p last
-   *  are still present, but their value is unspecified.
+   *  Performs @p *(result+(n+(last-middle))%(last-first))=*(first+n) for
+   *  each @p n in the range @p [0,last-first).
   */
-  template<typename _ForwardIterator, typename _Predicate>
-    _ForwardIterator
-    remove_if(_ForwardIterator __first, _ForwardIterator __last,
-             _Predicate __pred)
+  template<typename _ForwardIterator, typename _OutputIterator>
+    _OutputIterator
+    rotate_copy(_ForwardIterator __first, _ForwardIterator __middle,
+                _ForwardIterator __last, _OutputIterator __result)
     {
       // concept requirements
-      __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
-                                 _ForwardIterator>)
-      __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
-           typename iterator_traits<_ForwardIterator>::value_type>)
-      __glibcxx_requires_valid_range(__first, __last);
+      __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);
 
-      __first = std::find_if(__first, __last, __pred);
-      _ForwardIterator __i = __first;
-      return __first == __last ? __first
-                              : std::remove_copy_if(++__i, __last,
-                                                    __first, __pred);
+      return std::copy(__first, __middle,
+                       std::copy(__middle, __last, __result));
     }
 
   /**
-   *  @brief Remove consecutive duplicate values from a sequence.
-   *  @param  first  A forward iterator.
-   *  @param  last   A forward iterator.
-   *  @return  An iterator designating the end of the resulting sequence.
-   *
-   *  Removes all but the first element from each group of consecutive
-   *  values that compare equal.
-   *  unique() is stable, so the relative order of elements that are
-   *  not removed is unchanged.
-   *  Elements between the end of the resulting sequence and @p last
-   *  are still present, but their value is unspecified.
+   *  @if maint
+   *  This is a helper function...
+   *  @endif
   */
-  template<typename _ForwardIterator>
+  template<typename _ForwardIterator, typename _Predicate>
     _ForwardIterator
-    unique(_ForwardIterator __first, _ForwardIterator __last)
+    __partition(_ForwardIterator __first, _ForwardIterator __last,
+               _Predicate __pred,
+               forward_iterator_tag)
     {
-      // 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;
+       return __first;
 
-      // Do the real copy work.
-      _ForwardIterator __dest = __first;
-      ++__first;
-      while (++__first != __last)
-       if (!(*__dest == *__first))
-         *++__dest = *__first;
-      return ++__dest;
-    }
+      while (__pred(*__first))
+       if (++__first == __last)
+         return __first;
 
-  /**
-   *  @brief Remove consecutive values from a sequence using a predicate.
-   *  @param  first        A forward iterator.
-   *  @param  last         A forward iterator.
-   *  @param  binary_pred  A binary predicate.
-   *  @return  An iterator designating the end of the resulting sequence.
-   *
-   *  Removes all but the first element from each group of consecutive
-   *  values for which @p binary_pred returns true.
-   *  unique() is stable, so the relative order of elements that are
-   *  not removed is unchanged.
-   *  Elements between the end of the resulting sequence and @p last
-   *  are still present, but their value is unspecified.
-  */
-  template<typename _ForwardIterator, typename _BinaryPredicate>
-    _ForwardIterator
-    unique(_ForwardIterator __first, _ForwardIterator __last,
-           _BinaryPredicate __binary_pred)
-    {
-      // concept requirements
-      __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);
+      _ForwardIterator __next = __first;
 
-      // Skip the beginning, if already unique.
-      __first = std::adjacent_find(__first, __last, __binary_pred);
-      if (__first == __last)
-       return __last;
+      while (++__next != __last)
+       if (__pred(*__next))
+         {
+           swap(*__first, *__next);
+           ++__first;
+         }
 
-      // Do the real copy work.
-      _ForwardIterator __dest = __first;
-      ++__first;
-      while (++__first != __last)
-       if (!bool(__binary_pred(*__dest, *__first)))
-         *++__dest = *__first;
-      return ++__dest;
+      return __first;
     }
 
   /**
    *  @if maint
-   *  This is an uglified unique_copy(_InputIterator, _InputIterator,
-   *                                  _OutputIterator)
-   *  overloaded for forward iterators and output iterator as result.
+   *  This is a helper function...
    *  @endif
   */
-  template<typename _ForwardIterator, typename _OutputIterator>
-    _OutputIterator
-    __unique_copy(_ForwardIterator __first, _ForwardIterator __last,
-                 _OutputIterator __result,
-                 forward_iterator_tag, output_iterator_tag)
+  template<typename _BidirectionalIterator, typename _Predicate>
+    _BidirectionalIterator
+    __partition(_BidirectionalIterator __first, _BidirectionalIterator __last,
+               _Predicate __pred,
+               bidirectional_iterator_tag)
     {
-      // concept requirements -- taken care of in dispatching function
-      _ForwardIterator __next = __first;
-      *__result = *__first;
-      while (++__next != __last)
-       if (!(*__first == *__next))
-         {
-           __first = __next;
-           *++__result = *__first;
-         }
-      return ++__result;
+      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 (!bool(__pred(*__last)))
+             --__last;
+           else
+             break;
+         std::iter_swap(__first, __last);
+         ++__first;
+       }
     }
 
+  // partition
+
   /**
    *  @if maint
-   *  This is an uglified unique_copy(_InputIterator, _InputIterator,
-   *                                  _OutputIterator)
-   *  overloaded for input iterators and output iterator as result.
+   *  This is a helper function...
    *  @endif
   */
-  template<typename _InputIterator, typename _OutputIterator>
-    _OutputIterator
-    __unique_copy(_InputIterator __first, _InputIterator __last,
-                 _OutputIterator __result,
-                 input_iterator_tag, output_iterator_tag)
+  template<typename _ForwardIterator, typename _Predicate, typename _Distance>
+    _ForwardIterator
+    __inplace_stable_partition(_ForwardIterator __first,
+                              _ForwardIterator __last,
+                              _Predicate __pred, _Distance __len)
     {
-      // concept requirements -- taken care of in dispatching function
-      typename iterator_traits<_InputIterator>::value_type __value = *__first;
-      *__result = __value;
-      while (++__first != __last)
-       if (!(__value == *__first))
-         {
-           __value = *__first;
-           *++__result = __value;
-         }
-      return ++__result;
+      if (__len == 1)
+       return __pred(*__first) ? __last : __first;
+      _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;
     }
 
   /**
    *  @if maint
-   *  This is an uglified unique_copy(_InputIterator, _InputIterator,
-   *                                  _OutputIterator)
-   *  overloaded for input iterators and forward iterator as result.
+   *  This is a helper function...
    *  @endif
   */
-  template<typename _InputIterator, typename _ForwardIterator>
+  template<typename _ForwardIterator, typename _Pointer, typename _Predicate,
+          typename _Distance>
     _ForwardIterator
-    __unique_copy(_InputIterator __first, _InputIterator __last,
-                 _ForwardIterator __result,
-                 input_iterator_tag, forward_iterator_tag)
+    __stable_partition_adaptive(_ForwardIterator __first,
+                               _ForwardIterator __last,
+                               _Predicate __pred, _Distance __len,
+                               _Pointer __buffer,
+                               _Distance __buffer_size)
     {
-      // concept requirements -- taken care of in dispatching function
-      *__result = *__first;
-      while (++__first != __last)
-       if (!(*__result == *__first))
-         *++__result = *__first;
-      return ++__result;
+      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;
+       }
     }
 
   /**
-   *  @if maint
-   *  This is an uglified
-   *  unique_copy(_InputIterator, _InputIterator, _OutputIterator,
-   *              _BinaryPredicate)
-   *  overloaded for forward iterators and output iterator as result.
-   *  @endif
+   *  @brief Move elements for which a predicate is true to the beginning
+   *         of a sequence, preserving relative ordering.
+   *  @param  first   A forward iterator.
+   *  @param  last    A forward iterator.
+   *  @param  pred    A predicate functor.
+   *  @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 _ForwardIterator, typename _OutputIterator,
-          typename _BinaryPredicate>
-    _OutputIterator
-    __unique_copy(_ForwardIterator __first, _ForwardIterator __last,
-                 _OutputIterator __result, _BinaryPredicate __binary_pred,
-                 forward_iterator_tag, output_iterator_tag)
+  template<typename _ForwardIterator, typename _Predicate>
+    _ForwardIterator
+    stable_partition(_ForwardIterator __first, _ForwardIterator __last,
+                    _Predicate __pred)
     {
-      // concept requirements -- iterators already checked
-      __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
-         typename iterator_traits<_ForwardIterator>::value_type,
-         typename iterator_traits<_ForwardIterator>::value_type>)
+      // concept requirements
+      __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
+                                 _ForwardIterator>)
+      __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
+           typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
-      _ForwardIterator __next = __first;
-      *__result = *__first;
-      while (++__next != __last)
-       if (!bool(__binary_pred(*__first, *__next)))
-         {
-           __first = __next;
-           *++__result = *__first;
-         }
-      return ++__result;
+      if (__first == __last)
+       return __first;
+      else
+       {
+         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
+           std::__stable_partition_adaptive(__first, __last, __pred,
+                                         _DistanceType(__buf.requested_size()),
+                                         __buf.begin(),
+                                         _DistanceType(__buf.size()));
+       else
+         return
+           std::__inplace_stable_partition(__first, __last, __pred,
+                                        _DistanceType(__buf.requested_size()));
+       }
     }
 
   /**
    *  @if maint
-   *  This is an uglified
-   *  unique_copy(_InputIterator, _InputIterator, _OutputIterator,
-   *              _BinaryPredicate)
-   *  overloaded for input iterators and output iterator as result.
+   *  This is a helper function for the sort routines.
    *  @endif
   */
-  template<typename _InputIterator, typename _OutputIterator,
-          typename _BinaryPredicate>
-    _OutputIterator
-    __unique_copy(_InputIterator __first, _InputIterator __last,
-                 _OutputIterator __result, _BinaryPredicate __binary_pred,
-                 input_iterator_tag, output_iterator_tag)
+  template<typename _RandomAccessIterator>
+    void
+    __heap_select(_RandomAccessIterator __first,
+                 _RandomAccessIterator __middle,
+                 _RandomAccessIterator __last)
     {
-      // concept requirements -- iterators already checked
-      __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
-         typename iterator_traits<_InputIterator>::value_type,
-         typename iterator_traits<_InputIterator>::value_type>)
+      typedef typename iterator_traits<_RandomAccessIterator>::value_type
+       _ValueType;
 
-      typename iterator_traits<_InputIterator>::value_type __value = *__first;
-      *__result = __value;
-      while (++__first != __last)
-       if (!bool(__binary_pred(__value, *__first)))
-         {
-           __value = *__first;
-           *++__result = __value;
-         }
-      return ++__result;
+      std::make_heap(__first, __middle);
+      for (_RandomAccessIterator __i = __middle; __i < __last; ++__i)
+       if (*__i < *__first)
+         std::__pop_heap(__first, __middle, __i, _ValueType(*__i));
     }
 
   /**
    *  @if maint
-   *  This is an uglified
-   *  unique_copy(_InputIterator, _InputIterator, _OutputIterator,
-   *              _BinaryPredicate)
-   *  overloaded for input iterators and forward iterator as result.
+   *  This is a helper function for the sort routines.
    *  @endif
   */
-  template<typename _InputIterator, typename _ForwardIterator,
-          typename _BinaryPredicate>
-    _ForwardIterator
-    __unique_copy(_InputIterator __first, _InputIterator __last,
-                 _ForwardIterator __result, _BinaryPredicate __binary_pred,
-                 input_iterator_tag, forward_iterator_tag)
+  template<typename _RandomAccessIterator, typename _Compare>
+    void
+    __heap_select(_RandomAccessIterator __first,
+                 _RandomAccessIterator __middle,
+                 _RandomAccessIterator __last, _Compare __comp)
     {
-      // concept requirements -- iterators already checked
-      __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
-         typename iterator_traits<_ForwardIterator>::value_type,
-         typename iterator_traits<_InputIterator>::value_type>)
+      typedef typename iterator_traits<_RandomAccessIterator>::value_type
+       _ValueType;
 
-      *__result = *__first;
-      while (++__first != __last)
-       if (!bool(__binary_pred(*__result, *__first)))
-         *++__result = *__first;
-      return ++__result;
+      std::make_heap(__first, __middle, __comp);
+      for (_RandomAccessIterator __i = __middle; __i < __last; ++__i)
+       if (__comp(*__i, *__first))
+         std::__pop_heap(__first, __middle, __i, _ValueType(*__i), __comp);
     }
 
+  // partial_sort
+
   /**
-   *  @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.
+   *  @brief Copy the smallest elements of a sequence.
+   *  @param  first   An iterator.
+   *  @param  last    Another iterator.
+   *  @param  result_first   A random-access iterator.
+   *  @param  result_last    Another random-access iterator.
+   *  @return   An iterator indicating the end of the resulting sequence.
    *
-   *  @if maint
-   *  _GLIBCXX_RESOLVE_LIB_DEFECTS
-   *  DR 241. Does unique_copy() require CopyConstructible and Assignable?
-   *  
-   *  _GLIBCXX_RESOLVE_LIB_DEFECTS
-   *  DR 538. 241 again: Does unique_copy() require CopyConstructible and 
-   *  Assignable?
-   *  @endif
+   *  Copies and sorts the smallest N values from the range @p [first,last)
+   *  to the range beginning at @p result_first, where the number of
+   *  elements to be copied, @p N, is the smaller of @p (last-first) and
+   *  @p (result_last-result_first).
+   *  After the sort if @p i and @j are iterators in the range
+   *  @p [result_first,result_first+N) such that @i precedes @j then
+   *  @p *j<*i is false.
+   *  The value returned is @p result_first+N.
   */
-  template<typename _InputIterator, typename _OutputIterator>
-    inline _OutputIterator
-    unique_copy(_InputIterator __first, _InputIterator __last,
-               _OutputIterator __result)
+  template<typename _InputIterator, typename _RandomAccessIterator>
+    _RandomAccessIterator
+    partial_sort_copy(_InputIterator __first, _InputIterator __last,
+                     _RandomAccessIterator __result_first,
+                     _RandomAccessIterator __result_last)
     {
-      // 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>)
+      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
+      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
+      __glibcxx_function_requires(_ConvertibleConcept<_InputValueType,
+                                 _OutputValueType>)
+      __glibcxx_function_requires(_LessThanOpConcept<_InputValueType,
+                                                    _OutputValueType>)
+      __glibcxx_function_requires(_LessThanComparableConcept<_OutputValueType>)
       __glibcxx_requires_valid_range(__first, __last);
+      __glibcxx_requires_valid_range(__result_first, __result_last);
 
-      if (__first == __last)
-       return __result;
-      return std::__unique_copy(__first, __last, __result,
-                               std::__iterator_category(__first),
-                               std::__iterator_category(__result));
+      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;
     }
 
   /**
-   *  @brief Copy a sequence, removing consecutive values using a predicate.
-   *  @param  first        An input iterator.
-   *  @param  last         An input iterator.
-   *  @param  result       An output iterator.
-   *  @param  binary_pred  A binary predicate.
-   *  @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 for which @p binary_pred returns
-   *  true.
-   *  unique_copy() is stable, so the relative order of elements that are
-   *  copied is unchanged.
+   *  @brief Copy the smallest elements of a sequence using a predicate for
+   *         comparison.
+   *  @param  first   An input iterator.
+   *  @param  last    Another input iterator.
+   *  @param  result_first   A random-access iterator.
+   *  @param  result_last    Another random-access iterator.
+   *  @param  comp    A comparison functor.
+   *  @return   An iterator indicating the end of the resulting sequence.
    *
-   *  @if maint
-   *  _GLIBCXX_RESOLVE_LIB_DEFECTS
-   *  DR 241. Does unique_copy() require CopyConstructible and Assignable?
-   *  @endif
+   *  Copies and sorts the smallest N values from the range @p [first,last)
+   *  to the range beginning at @p result_first, where the number of
+   *  elements to be copied, @p N, is the smaller of @p (last-first) and
+   *  @p (result_last-result_first).
+   *  After the sort if @p i and @j are iterators in the range
+   *  @p [result_first,result_first+N) such that @i precedes @j then
+   *  @p comp(*j,*i) is false.
+   *  The value returned is @p result_first+N.
   */
-  template<typename _InputIterator, typename _OutputIterator,
-          typename _BinaryPredicate>
-    inline _OutputIterator
-    unique_copy(_InputIterator __first, _InputIterator __last,
-               _OutputIterator __result,
-               _BinaryPredicate __binary_pred)
+  template<typename _InputIterator, typename _RandomAccessIterator, typename _Compare>
+    _RandomAccessIterator
+    partial_sort_copy(_InputIterator __first, _InputIterator __last,
+                     _RandomAccessIterator __result_first,
+                     _RandomAccessIterator __result_last,
+                     _Compare __comp)
     {
-      // concept requirements -- predicates checked later
+      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
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
-      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
-           typename iterator_traits<_InputIterator>::value_type>)
+      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
+                                 _RandomAccessIterator>)
+      __glibcxx_function_requires(_ConvertibleConcept<_InputValueType,
+                                 _OutputValueType>)
+      __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
+                                 _InputValueType, _OutputValueType>)
+      __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
+                                 _OutputValueType, _OutputValueType>)
       __glibcxx_requires_valid_range(__first, __last);
+      __glibcxx_requires_valid_range(__result_first, __result_last);
 
-      if (__first == __last)
-       return __result;
-      return std::__unique_copy(__first, __last, __result, __binary_pred,
-                               std::__iterator_category(__first),
-                               std::__iterator_category(__result));
+      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;
     }
 
   /**
    *  @if maint
-   *  This is an uglified reverse(_BidirectionalIterator,
-   *                              _BidirectionalIterator)
-   *  overloaded for bidirectional iterators.
+   *  This is a helper function for the sort routine.
    *  @endif
   */
-  template<typename _BidirectionalIterator>
+  template<typename _RandomAccessIterator, typename _Tp>
     void
-    __reverse(_BidirectionalIterator __first, _BidirectionalIterator __last,
-             bidirectional_iterator_tag)
+    __unguarded_linear_insert(_RandomAccessIterator __last, _Tp __val)
     {
-      while (true)
-       if (__first == __last || __first == --__last)
-         return;
-       else
-         {
-           std::iter_swap(__first, __last);
-           ++__first;
-         }
+      _RandomAccessIterator __next = __last;
+      --__next;
+      while (__val < *__next)
+       {
+         *__last = *__next;
+         __last = __next;
+         --__next;
+       }
+      *__last = __val;
     }
 
   /**
    *  @if maint
-   *  This is an uglified reverse(_BidirectionalIterator,
-   *                              _BidirectionalIterator)
-   *  overloaded for random access iterators.
+   *  This is a helper function for the sort routine.
    *  @endif
   */
-  template<typename _RandomAccessIterator>
+  template<typename _RandomAccessIterator, typename _Tp, typename _Compare>
     void
-    __reverse(_RandomAccessIterator __first, _RandomAccessIterator __last,
-             random_access_iterator_tag)
+    __unguarded_linear_insert(_RandomAccessIterator __last, _Tp __val,
+                             _Compare __comp)
     {
-      if (__first == __last)
-       return;
-      --__last;
-      while (__first < __last)
+      _RandomAccessIterator __next = __last;
+      --__next;
+      while (__comp(__val, *__next))
        {
-         std::iter_swap(__first, __last);
-         ++__first;
-         --__last;
+         *__last = *__next;
+         __last = __next;
+         --__next;
        }
+      *__last = __val;
     }
 
   /**
-   *  @brief Reverse a sequence.
-   *  @param  first  A bidirectional iterator.
-   *  @param  last   A bidirectional iterator.
-   *  @return   reverse() returns no value.
-   *
-   *  Reverses the order of the elements in the range @p [first,last),
-   *  so that the first element becomes the last etc.
-   *  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 _BidirectionalIterator>
-    inline void
-    reverse(_BidirectionalIterator __first, _BidirectionalIterator __last)
-    {
-      // concept requirements
-      __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
-                                 _BidirectionalIterator>)
-      __glibcxx_requires_valid_range(__first, __last);
-      std::__reverse(__first, __last, std::__iterator_category(__first));
-    }
-
-  /**
-   *  @brief Copy a sequence, reversing its elements.
-   *  @param  first   A bidirectional iterator.
-   *  @param  last    A bidirectional iterator.
-   *  @param  result  An output iterator.
-   *  @return  An iterator designating the end of the resulting sequence.
-   *
-   *  Copies the elements in the range @p [first,last) to the range
-   *  @p [result,result+(last-first)) such that the order of the
-   *  elements is reversed.
-   *  For every @c i such that @p 0<=i<=(last-first), @p reverse_copy()
-   *  performs the assignment @p *(result+(last-first)-i) = *(first+i).
-   *  The ranges @p [first,last) and @p [result,result+(last-first))
-   *  must not overlap.
+   *  @if maint
+   *  This is a helper function for the sort routine.
+   *  @endif
   */
-  template<typename _BidirectionalIterator, typename _OutputIterator>
-    _OutputIterator
-    reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last,
-                            _OutputIterator __result)
+  template<typename _RandomAccessIterator>
+    void
+    __insertion_sort(_RandomAccessIterator __first,
+                    _RandomAccessIterator __last)
     {
-      // concept requirements
-      __glibcxx_function_requires(_BidirectionalIteratorConcept<
-                                 _BidirectionalIterator>)
-      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
-               typename iterator_traits<_BidirectionalIterator>::value_type>)
-      __glibcxx_requires_valid_range(__first, __last);
+      if (__first == __last)
+       return;
 
-      while (__first != __last)
+      for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
        {
-         --__last;
-         *__result = *__last;
-         ++__result;
+         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);
        }
-      return __result;
     }
 
   /**
    *  @if maint
-   *  This is a helper function for the rotate algorithm specialized on RAIs.
-   *  It returns the greatest common divisor of two integer values.
+   *  This is a helper function for the sort routine.
    *  @endif
   */
-  template<typename _EuclideanRingElement>
-    _EuclideanRingElement
-    __gcd(_EuclideanRingElement __m, _EuclideanRingElement __n)
+  template<typename _RandomAccessIterator, typename _Compare>
+    void
+    __insertion_sort(_RandomAccessIterator __first,
+                    _RandomAccessIterator __last, _Compare __comp)
     {
-      while (__n != 0)
+      if (__first == __last) return;
+
+      for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
        {
-         _EuclideanRingElement __t = __m % __n;
-         __m = __n;
-         __n = __t;
+         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);
        }
-      return __m;
     }
 
   /**
    *  @if maint
-   *  This is a helper function for the rotate algorithm.
+   *  This is a helper function for the sort routine.
    *  @endif
   */
-  template<typename _ForwardIterator>
-    void
-    __rotate(_ForwardIterator __first,
-            _ForwardIterator __middle,
-            _ForwardIterator __last,
-            forward_iterator_tag)
+  template<typename _RandomAccessIterator>
+    inline void
+    __unguarded_insertion_sort(_RandomAccessIterator __first,
+                              _RandomAccessIterator __last)
     {
-      if (__first == __middle || __last  == __middle)
-       return;
-
-      _ForwardIterator __first2 = __middle;
-      do
-       {
-         swap(*__first, *__first2);
-         ++__first;
-         ++__first2;
-         if (__first == __middle)
-           __middle = __first2;
-       }
-      while (__first2 != __last);
-
-      __first2 = __middle;
+      typedef typename iterator_traits<_RandomAccessIterator>::value_type
+       _ValueType;
 
-      while (__first2 != __last)
-       {
-         swap(*__first, *__first2);
-         ++__first;
-         ++__first2;
-         if (__first == __middle)
-           __middle = __first2;
-         else if (__first2 == __last)
-           __first2 = __middle;
-       }
+      for (_RandomAccessIterator __i = __first; __i != __last; ++__i)
+       std::__unguarded_linear_insert(__i, _ValueType(*__i));
     }
 
   /**
    *  @if maint
-   *  This is a helper function for the rotate algorithm.
+   *  This is a helper function for the sort routine.
    *  @endif
   */
-  template<typename _BidirectionalIterator>
-    void
-    __rotate(_BidirectionalIterator __first,
-            _BidirectionalIterator __middle,
-            _BidirectionalIterator __last,
-             bidirectional_iterator_tag)
+  template<typename _RandomAccessIterator, typename _Compare>
+    inline void
+    __unguarded_insertion_sort(_RandomAccessIterator __first,
+                              _RandomAccessIterator __last, _Compare __comp)
     {
-      // concept requirements
-      __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
-                                 _BidirectionalIterator>)
+      typedef typename iterator_traits<_RandomAccessIterator>::value_type
+       _ValueType;
 
-      if (__first == __middle || __last  == __middle)
-       return;
+      for (_RandomAccessIterator __i = __first; __i != __last; ++__i)
+       std::__unguarded_linear_insert(__i, _ValueType(*__i), __comp);
+    }
 
-      std::__reverse(__first,  __middle, bidirectional_iterator_tag());
-      std::__reverse(__middle, __last,   bidirectional_iterator_tag());
+  /**
+   *  @if maint
+   *  @doctodo
+   *  This controls some aspect of the sort routines.
+   *  @endif
+  */
+  enum { _S_threshold = 16 };
 
-      while (__first != __middle && __middle != __last)
+  /**
+   *  @if maint
+   *  This is a helper function for the sort routine.
+   *  @endif
+  */
+  template<typename _RandomAccessIterator>
+    void
+    __final_insertion_sort(_RandomAccessIterator __first,
+                          _RandomAccessIterator __last)
+    {
+      if (__last - __first > int(_S_threshold))
        {
-         swap(*__first, *--__last);
-         ++__first;
+         std::__insertion_sort(__first, __first + int(_S_threshold));
+         std::__unguarded_insertion_sort(__first + int(_S_threshold), __last);
        }
-
-      if (__first == __middle)
-       std::__reverse(__middle, __last,   bidirectional_iterator_tag());
       else
-       std::__reverse(__first,  __middle, bidirectional_iterator_tag());
+       std::__insertion_sort(__first, __last);
     }
 
   /**
    *  @if maint
-   *  This is a helper function for the rotate algorithm.
+   *  This is a helper function for the sort routine.
    *  @endif
   */
-  template<typename _RandomAccessIterator>
+  template<typename _RandomAccessIterator, typename _Compare>
     void
-    __rotate(_RandomAccessIterator __first,
-            _RandomAccessIterator __middle,
-            _RandomAccessIterator __last,
-            random_access_iterator_tag)
+    __final_insertion_sort(_RandomAccessIterator __first,
+                          _RandomAccessIterator __last, _Compare __comp)
     {
-      // concept requirements
-      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
-                                 _RandomAccessIterator>)
-
-      if (__first == __middle || __last  == __middle)
-       return;
-
-      typedef typename iterator_traits<_RandomAccessIterator>::difference_type
-       _Distance;
-      typedef typename iterator_traits<_RandomAccessIterator>::value_type
-       _ValueType;
-
-      const _Distance __n = __last   - __first;
-      const _Distance __k = __middle - __first;
-      const _Distance __l = __n - __k;
-
-      if (__k == __l)
+      if (__last - __first > int(_S_threshold))
        {
-         std::swap_ranges(__first, __middle, __middle);
-         return;
+         std::__insertion_sort(__first, __first + int(_S_threshold), __comp);
+         std::__unguarded_insertion_sort(__first + int(_S_threshold), __last,
+                                         __comp);
        }
+      else
+       std::__insertion_sort(__first, __last, __comp);
+    }
 
-      const _Distance __d = std::__gcd(__n, __k);
-
-      for (_Distance __i = 0; __i < __d; __i++)
+  /**
+   *  @if maint
+   *  This is a helper function...
+   *  @endif
+  */
+  template<typename _RandomAccessIterator, typename _Tp>
+    _RandomAccessIterator
+    __unguarded_partition(_RandomAccessIterator __first,
+                         _RandomAccessIterator __last, _Tp __pivot)
+    {
+      while (true)
        {
-         _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 = __tmp;
+         while (*__first < __pivot)
+           ++__first;
+         --__last;
+         while (__pivot < *__last)
+           --__last;
+         if (!(__first < __last))
+           return __first;
+         std::iter_swap(__first, __last);
          ++__first;
        }
     }
 
   /**
-   *  @brief Rotate the elements of a sequence.
-   *  @param  first   A forward iterator.
-   *  @param  middle  A forward iterator.
-   *  @param  last    A forward iterator.
-   *  @return  Nothing.
-   *
-   *  Rotates the elements of the range @p [first,last) by @p (middle-first)
-   *  positions so that the element at @p middle is moved to @p first, the
-   *  element at @p middle+1 is moved to @first+1 and so on for each element
-   *  in the range @p [first,last).
-   *
-   *  This effectively swaps the ranges @p [first,middle) and
-   *  @p [middle,last).
-   *
-   *  Performs @p *(first+(n+(last-middle))%(last-first))=*(first+n) for
-   *  each @p n in the range @p [0,last-first).
+   *  @if maint
+   *  This is a helper function...
+   *  @endif
   */
-  template<typename _ForwardIterator>
-    inline void
-    rotate(_ForwardIterator __first, _ForwardIterator __middle,
-          _ForwardIterator __last)
+  template<typename _RandomAccessIterator, typename _Tp, typename _Compare>
+    _RandomAccessIterator
+    __unguarded_partition(_RandomAccessIterator __first,
+                         _RandomAccessIterator __last,
+                         _Tp __pivot, _Compare __comp)
     {
-      // concept requirements
-      __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
-                                 _ForwardIterator>)
-      __glibcxx_requires_valid_range(__first, __middle);
-      __glibcxx_requires_valid_range(__middle, __last);
-
-      typedef typename iterator_traits<_ForwardIterator>::iterator_category
-       _IterType;
-      std::__rotate(__first, __middle, __last, _IterType());
+      while (true)
+       {
+         while (__comp(*__first, __pivot))
+           ++__first;
+         --__last;
+         while (__comp(__pivot, *__last))
+           --__last;
+         if (!(__first < __last))
+           return __first;
+         std::iter_swap(__first, __last);
+         ++__first;
+       }
     }
 
   /**
-   *  @brief Copy a sequence, rotating its elements.
-   *  @param  first   A forward iterator.
-   *  @param  middle  A forward iterator.
-   *  @param  last    A forward iterator.
-   *  @param  result  An output iterator.
-   *  @return   An iterator designating the end of the resulting sequence.
-   *
-   *  Copies the elements of the range @p [first,last) to the range
-   *  beginning at @result, rotating the copied elements by @p (middle-first)
-   *  positions so that the element at @p middle is moved to @p result, the
-   *  element at @p middle+1 is moved to @result+1 and so on for each element
-   *  in the range @p [first,last).
-   *
-   *  Performs @p *(result+(n+(last-middle))%(last-first))=*(first+n) for
-   *  each @p n in the range @p [0,last-first).
-  */
-  template<typename _ForwardIterator, typename _OutputIterator>
-    _OutputIterator
-    rotate_copy(_ForwardIterator __first, _ForwardIterator __middle,
-                _ForwardIterator __last, _OutputIterator __result)
-    {
-      // concept requirements
-      __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 std::copy(__first, __middle,
-                       std::copy(__middle, __last, __result));
-    }
-
-  /**
-   *  @brief Randomly shuffle the elements of a sequence.
-   *  @param  first   A forward iterator.
-   *  @param  last    A forward iterator.
-   *  @return  Nothing.
-   *
-   *  Reorder the elements in the range @p [first,last) using a random
-   *  distribution, so that every possible ordering of the sequence is
-   *  equally likely.
+   *  @if maint
+   *  This is a helper function for the sort routine.
+   *  @endif
   */
-  template<typename _RandomAccessIterator>
-    inline void
-    random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
+  template<typename _RandomAccessIterator, typename _Size>
+    void
+    __introsort_loop(_RandomAccessIterator __first,
+                    _RandomAccessIterator __last,
+                    _Size __depth_limit)
     {
-      // concept requirements
-      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
-           _RandomAccessIterator>)
-      __glibcxx_requires_valid_range(__first, __last);
+      typedef typename iterator_traits<_RandomAccessIterator>::value_type
+       _ValueType;
 
-      if (__first != __last)
-       for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
-         std::iter_swap(__i, __first + (std::rand() % ((__i - __first) + 1)));
+      while (__last - __first > int(_S_threshold))
+       {
+         if (__depth_limit == 0)
+           {
+             _GLIBCXX_STD_P: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;
+       }
     }
 
   /**
-   *  @brief Shuffle the elements of a sequence using a random number
-   *         generator.
-   *  @param  first   A forward iterator.
-   *  @param  last    A forward iterator.
-   *  @param  rand    The RNG functor or function.
-   *  @return  Nothing.
-   *
-   *  Reorders the elements in the range @p [first,last) using @p rand to
-   *  provide a random distribution. Calling @p rand(N) for a positive
-   *  integer @p N should return a randomly chosen integer from the
-   *  range [0,N).
+   *  @if maint
+   *  This is a helper function for the sort routine.
+   *  @endif
   */
-  template<typename _RandomAccessIterator, typename _RandomNumberGenerator>
+  template<typename _RandomAccessIterator, typename _Size, typename _Compare>
     void
-    random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
-                  _RandomNumberGenerator& __rand)
+    __introsort_loop(_RandomAccessIterator __first,
+                    _RandomAccessIterator __last,
+                    _Size __depth_limit, _Compare __comp)
     {
-      // concept requirements
-      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
-           _RandomAccessIterator>)
-      __glibcxx_requires_valid_range(__first, __last);
+      typedef typename iterator_traits<_RandomAccessIterator>::value_type
+       _ValueType;
 
-      if (__first == __last)
-       return;
-      for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
-       std::iter_swap(__i, __first + __rand((__i - __first) + 1));
+      while (__last - __first > int(_S_threshold))
+       {
+         if (__depth_limit == 0)
+           {
+             _GLIBCXX_STD_P::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;
+       }
     }
 
-
   /**
    *  @if maint
-   *  This is a helper function...
+   *  This is a helper function for the sort routines.
    *  @endif
   */
-  template<typename _ForwardIterator, typename _Predicate>
-    _ForwardIterator
-    __partition(_ForwardIterator __first, _ForwardIterator __last,
-               _Predicate __pred,
-               forward_iterator_tag)
+  template<typename _Size>
+    inline _Size
+    __lg(_Size __n)
     {
-      if (__first == __last)
-       return __first;
-
-      while (__pred(*__first))
-       if (++__first == __last)
-         return __first;
+      _Size __k;
+      for (__k = 0; __n != 1; __n >>= 1)
+       ++__k;
+      return __k;
+    }
 
-      _ForwardIterator __next = __first;
+  // sort
 
-      while (++__next != __last)
-       if (__pred(*__next))
-         {
-           swap(*__first, *__next);
-           ++__first;
-         }
+  template<typename _RandomAccessIterator, typename _Size>
+    void
+    __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth,
+                 _RandomAccessIterator __last, _Size __depth_limit)
+    {
+      typedef typename iterator_traits<_RandomAccessIterator>::value_type
+       _ValueType;
 
-      return __first;
+      while (__last - __first > 3)
+       {
+         if (__depth_limit == 0)
+           {
+             std::__heap_select(__first, __nth + 1, __last);
+             // Place the nth largest element in its final position.
+             std::iter_swap(__first, __nth);
+             return;
+           }
+         --__depth_limit;
+         _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);
     }
 
-  /**
-   *  @if maint
-   *  This is a helper function...
-   *  @endif
-  */
-  template<typename _BidirectionalIterator, typename _Predicate>
-    _BidirectionalIterator
-    __partition(_BidirectionalIterator __first, _BidirectionalIterator __last,
-               _Predicate __pred,
-               bidirectional_iterator_tag)
+  template<typename _RandomAccessIterator, typename _Size, typename _Compare>
+    void
+    __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth,
+                 _RandomAccessIterator __last, _Size __depth_limit,
+                 _Compare __comp)
     {
-      while (true)
+      typedef typename iterator_traits<_RandomAccessIterator>::value_type
+       _ValueType;
+
+      while (__last - __first > 3)
        {
-         while (true)
-           if (__first == __last)
-             return __first;
-           else if (__pred(*__first))
-             ++__first;
-           else
-             break;
-         --__last;
-         while (true)
-           if (__first == __last)
-             return __first;
-           else if (!bool(__pred(*__last)))
-             --__last;
-           else
-             break;
-         std::iter_swap(__first, __last);
-         ++__first;
+         if (__depth_limit == 0)
+           {
+             std::__heap_select(__first, __nth + 1, __last, __comp);
+             // Place the nth largest element in its final position.
+             std::iter_swap(__first, __nth);
+             return;
+           }
+         --__depth_limit;
+         _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);
     }
 
+  // nth_element
+
   /**
-   *  @brief Move elements for which a predicate is true to the beginning
-   *         of a sequence.
-   *  @param  first   A forward iterator.
-   *  @param  last    A forward iterator.
-   *  @param  pred    A predicate functor.
-   *  @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.
+   *  @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, or end() if every element is less than 
+   *                  @a val.
+   *  @ingroup binarysearch
   */
-  template<typename _ForwardIterator, typename _Predicate>
-    inline _ForwardIterator
-    partition(_ForwardIterator __first, _ForwardIterator __last,
-             _Predicate   __pred)
+  template<typename _ForwardIterator, typename _Tp>
+    _ForwardIterator
+    lower_bound(_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
-      __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
-                                 _ForwardIterator>)
-      __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
-           typename iterator_traits<_ForwardIterator>::value_type>)
-      __glibcxx_requires_valid_range(__first, __last);
+      __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
+      __glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>)
+      __glibcxx_requires_partitioned(__first, __last, __val);
 
-      return std::__partition(__first, __last, __pred,
-                             std::__iterator_category(__first));
-    }
+      _DistanceType __len = std::distance(__first, __last);
+      _DistanceType __half;
+      _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;
+       }
+      return __first;
+    }
 
   /**
-   *  @if maint
-   *  This is a helper function...
-   *  @endif
+   *  @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.
+   *  @param  comp    A functor to use for comparisons.
+   *  @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 _ForwardIterator, typename _Predicate, typename _Distance>
+  template<typename _ForwardIterator, typename _Tp, typename _Compare>
     _ForwardIterator
-    __inplace_stable_partition(_ForwardIterator __first,
-                              _ForwardIterator __last,
-                              _Predicate __pred, _Distance __len)
+    lower_bound(_ForwardIterator __first, _ForwardIterator __last,
+               const _Tp& __val, _Compare __comp)
     {
-      if (__len == 1)
-       return __pred(*__first) ? __last : __first;
-      _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;
+      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_requires_partitioned_pred(__first, __last, __val, __comp);
+
+      _DistanceType __len = std::distance(__first, __last);
+      _DistanceType __half;
+      _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;
+       }
+      return __first;
     }
 
   /**
-   *  @if maint
-   *  This is a helper function...
-   *  @endif
+   *  @brief Finds the last 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 greater than @a val,
+   *           or end() if no elements are greater than @a val.
+   *  @ingroup binarysearch
   */
-  template<typename _ForwardIterator, typename _Pointer, typename _Predicate,
-          typename _Distance>
+  template<typename _ForwardIterator, typename _Tp>
     _ForwardIterator
-    __stable_partition_adaptive(_ForwardIterator __first,
-                               _ForwardIterator __last,
-                               _Predicate __pred, _Distance __len,
-                               _Pointer __buffer,
-                               _Distance __buffer_size)
+    upper_bound(_ForwardIterator __first, _ForwardIterator __last,
+               const _Tp& __val)
     {
-      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
+      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(_LessThanOpConcept<_Tp, _ValueType>)
+      __glibcxx_requires_partitioned(__first, __last, __val);
+
+      _DistanceType __len = std::distance(__first, __last);
+      _DistanceType __half;
+      _ForwardIterator __middle;
+
+      while (__len > 0)
        {
-         _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;
+         __half = __len >> 1;
+         __middle = __first;
+         std::advance(__middle, __half);
+         if (__val < *__middle)
+           __len = __half;
+         else
+           {
+             __first = __middle;
+             ++__first;
+             __len = __len - __half - 1;
+           }
        }
+      return __first;
     }
 
   /**
-   *  @brief Move elements for which a predicate is true to the beginning
-   *         of a sequence, preserving relative ordering.
-   *  @param  first   A forward iterator.
-   *  @param  last    A forward iterator.
-   *  @param  pred    A predicate functor.
-   *  @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).
+   *  @brief Finds the last 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.
+   *  @param  comp    A functor to use for comparisons.
+   *  @return  An iterator pointing to the first element greater than @a val,
+   *           or end() if no elements are greater than @a val.
+   *  @ingroup binarysearch
    *
-   *  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().
+   *  The comparison function should have the same effects on ordering as
+   *  the function used for the initial sort.
   */
-  template<typename _ForwardIterator, typename _Predicate>
+  template<typename _ForwardIterator, typename _Tp, typename _Compare>
     _ForwardIterator
-    stable_partition(_ForwardIterator __first, _ForwardIterator __last,
-                    _Predicate __pred)
+    upper_bound(_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(_Mutable_ForwardIteratorConcept<
-                                 _ForwardIterator>)
-      __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
-           typename iterator_traits<_ForwardIterator>::value_type>)
-      __glibcxx_requires_valid_range(__first, __last);
+      __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
+      __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
+                                 _Tp, _ValueType>)
+      __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp);
 
-      if (__first == __last)
-       return __first;
-      else
-       {
-         typedef typename iterator_traits<_ForwardIterator>::value_type
-           _ValueType;
-         typedef typename iterator_traits<_ForwardIterator>::difference_type
-           _DistanceType;
+      _DistanceType __len = std::distance(__first, __last);
+      _DistanceType __half;
+      _ForwardIterator __middle;
 
-         _Temporary_buffer<_ForwardIterator, _ValueType> __buf(__first,
-                                                               __last);
-       if (__buf.size() > 0)
-         return
-           std::__stable_partition_adaptive(__first, __last, __pred,
-                                         _DistanceType(__buf.requested_size()),
-                                         __buf.begin(),
-                                         _DistanceType(__buf.size()));
-       else
-         return
-           std::__inplace_stable_partition(__first, __last, __pred,
-                                        _DistanceType(__buf.requested_size()));
+      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;
     }
 
   /**
-   *  @if maint
-   *  This is a helper function for the sort routines.
-   *  @endif
+   *  @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 _RandomAccessIterator>
-    void
-    __heap_select(_RandomAccessIterator __first,
-                 _RandomAccessIterator __middle,
-                 _RandomAccessIterator __last)
+  template<typename _ForwardIterator, typename _Tp>
+    pair<_ForwardIterator, _ForwardIterator>
+    equal_range(_ForwardIterator __first, _ForwardIterator __last,
+               const _Tp& __val)
     {
-      typedef typename iterator_traits<_RandomAccessIterator>::value_type
+      typedef typename iterator_traits<_ForwardIterator>::value_type
        _ValueType;
+      typedef typename iterator_traits<_ForwardIterator>::difference_type
+       _DistanceType;
 
-      std::make_heap(__first, __middle);
-      for (_RandomAccessIterator __i = __middle; __i < __last; ++__i)
-       if (*__i < *__first)
-         std::__pop_heap(__first, __middle, __i, _ValueType(*__i));
+      // concept requirements
+      __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
+      __glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>)
+      __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>) 
+      __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);
     }
 
   /**
-   *  @if maint
-   *  This is a helper function for the sort routines.
-   *  @endif
+   *  @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 _RandomAccessIterator, typename _Compare>
-    void
-    __heap_select(_RandomAccessIterator __first,
-                 _RandomAccessIterator __middle,
-                 _RandomAccessIterator __last, _Compare __comp)
+  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<_RandomAccessIterator>::value_type
+      typedef typename iterator_traits<_ForwardIterator>::value_type
        _ValueType;
+      typedef typename iterator_traits<_ForwardIterator>::difference_type
+       _DistanceType;
 
-      std::make_heap(__first, __middle, __comp);
-      for (_RandomAccessIterator __i = __middle; __i < __last; ++__i)
-       if (__comp(*__i, *__first))
-         std::__pop_heap(__first, __middle, __i, _ValueType(*__i), __comp);
+      // 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 Sort the smallest elements of a sequence.
+   *  @brief Determines whether an element exists in a range.
    *  @param  first   An iterator.
-   *  @param  middle  Another iterator.
    *  @param  last    Another iterator.
-   *  @return  Nothing.
+   *  @param  val     The search term.
+   *  @return  True if @a val (or its equivelent) is in [@a first,@a last ].
+   *  @ingroup binarysearch
    *
-   *  Sorts the smallest @p (middle-first) elements in the range
-   *  @p [first,last) and moves them to the range @p [first,middle). The
-   *  order of the remaining elements in the range @p [middle,last) is
-   *  undefined.
-   *  After the sort if @p i and @j are iterators in the range
-   *  @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.
+   *  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 _RandomAccessIterator>
-    inline void
-    partial_sort(_RandomAccessIterator __first,
-                _RandomAccessIterator __middle,
-                _RandomAccessIterator __last)
+  template<typename _ForwardIterator, typename _Tp>
+    bool
+    binary_search(_ForwardIterator __first, _ForwardIterator __last,
+                  const _Tp& __val)
     {
-      typedef typename iterator_traits<_RandomAccessIterator>::value_type
+      typedef typename iterator_traits<_ForwardIterator>::value_type
        _ValueType;
 
       // concept requirements
-      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
-           _RandomAccessIterator>)
-      __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
-      __glibcxx_requires_valid_range(__first, __middle);
-      __glibcxx_requires_valid_range(__middle, __last);
+      __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
+      __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>)
+      __glibcxx_requires_partitioned(__first, __last, __val);
 
-      std::__heap_select(__first, __middle, __last);
-      std::sort_heap(__first, __middle);
+      _ForwardIterator __i = std::lower_bound(__first, __last, __val);
+      return __i != __last && !(__val < *__i);
     }
 
   /**
-   *  @brief Sort the smallest elements of a sequence using a predicate
-   *         for comparison.
+   *  @brief Determines whether an element exists in a range.
    *  @param  first   An iterator.
-   *  @param  middle  Another iterator.
    *  @param  last    Another iterator.
-   *  @param  comp    A comparison functor.
-   *  @return  Nothing.
+   *  @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
    *
-   *  Sorts the smallest @p (middle-first) elements in the range
-   *  @p [first,last) and moves them to the range @p [first,middle). The
-   *  order of the remaining elements in the range @p [middle,last) is
-   *  undefined.
-   *  After the sort if @p i and @j are iterators in the range
-   *  @p [first,middle) such that @i precedes @j and @k is an iterator in
-   *  the range @p [middle,last) then @p *comp(j,*i) and @p comp(*k,*i)
-   *  are both false.
+   *  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 _RandomAccessIterator, typename _Compare>
-    inline void
-    partial_sort(_RandomAccessIterator __first,
-                _RandomAccessIterator __middle,
-                _RandomAccessIterator __last,
-                _Compare __comp)
+  template<typename _ForwardIterator, typename _Tp, typename _Compare>
+    bool
+    binary_search(_ForwardIterator __first, _ForwardIterator __last,
+                  const _Tp& __val, _Compare __comp)
     {
-      typedef typename iterator_traits<_RandomAccessIterator>::value_type
+      typedef typename iterator_traits<_ForwardIterator>::value_type
        _ValueType;
 
       // concept requirements
-      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
-           _RandomAccessIterator>)
+      __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
-                                 _ValueType, _ValueType>)
-      __glibcxx_requires_valid_range(__first, __middle);
-      __glibcxx_requires_valid_range(__middle, __last);
+                                 _Tp, _ValueType>)
+      __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp);
 
-      std::__heap_select(__first, __middle, __last, __comp);
-      std::sort_heap(__first, __middle, __comp);
+      _ForwardIterator __i = std::lower_bound(__first, __last, __val, __comp);
+      return __i != __last && !bool(__comp(__val, *__i));
     }
 
+  // merge
+
   /**
-   *  @brief Copy the smallest elements of a sequence.
-   *  @param  first   An iterator.
-   *  @param  last    Another iterator.
-   *  @param  result_first   A random-access iterator.
-   *  @param  result_last    Another random-access iterator.
-   *  @return   An iterator indicating the end of the resulting sequence.
-   *
-   *  Copies and sorts the smallest N values from the range @p [first,last)
-   *  to the range beginning at @p result_first, where the number of
-   *  elements to be copied, @p N, is the smaller of @p (last-first) and
-   *  @p (result_last-result_first).
-   *  After the sort if @p i and @j are iterators in the range
-   *  @p [result_first,result_first+N) such that @i precedes @j then
-   *  @p *j<*i is false.
-   *  The value returned is @p result_first+N.
-  */
-  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
-      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
-      __glibcxx_function_requires(_ConvertibleConcept<_InputValueType,
-                                 _OutputValueType>)
-      __glibcxx_function_requires(_LessThanOpConcept<_InputValueType,
-                                                    _OutputValueType>)
-      __glibcxx_function_requires(_LessThanComparableConcept<_OutputValueType>)
-      __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;
-    }
-
-  /**
-   *  @brief Copy the smallest elements of a sequence using a predicate for
-   *         comparison.
-   *  @param  first   An input iterator.
-   *  @param  last    Another input iterator.
-   *  @param  result_first   A random-access iterator.
-   *  @param  result_last    Another random-access iterator.
-   *  @param  comp    A comparison functor.
-   *  @return   An iterator indicating the end of the resulting sequence.
-   *
-   *  Copies and sorts the smallest N values from the range @p [first,last)
-   *  to the range beginning at @p result_first, where the number of
-   *  elements to be copied, @p N, is the smaller of @p (last-first) and
-   *  @p (result_last-result_first).
-   *  After the sort if @p i and @j are iterators in the range
-   *  @p [result_first,result_first+N) such that @i precedes @j then
-   *  @p comp(*j,*i) is false.
-   *  The value returned is @p result_first+N.
+   *  @if maint
+   *  This is a helper function for the merge routines.
+   *  @endif
   */
-  template<typename _InputIterator, typename _RandomAccessIterator, typename _Compare>
-    _RandomAccessIterator
-    partial_sort_copy(_InputIterator __first, _InputIterator __last,
-                     _RandomAccessIterator __result_first,
-                     _RandomAccessIterator __result_last,
-                     _Compare __comp)
+  template<typename _BidirectionalIterator1, typename _BidirectionalIterator2,
+          typename _BidirectionalIterator3>
+    _BidirectionalIterator3
+    __merge_backward(_BidirectionalIterator1 __first1,
+                    _BidirectionalIterator1 __last1,
+                    _BidirectionalIterator2 __first2,
+                    _BidirectionalIterator2 __last2,
+                    _BidirectionalIterator3 __result)
     {
-      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
-      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
-      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
-                                 _RandomAccessIterator>)
-      __glibcxx_function_requires(_ConvertibleConcept<_InputValueType,
-                                 _OutputValueType>)
-      __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
-                                 _InputValueType, _OutputValueType>)
-      __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
-                                 _OutputValueType, _OutputValueType>)
-      __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 (__first1 == __last1)
+       return std::copy_backward(__first2, __last2, __result);
+      if (__first2 == __last2)
+       return std::copy_backward(__first1, __last1, __result);
+      --__last1;
+      --__last2;
+      while (true)
        {
-         if (__comp(*__first, *__result_first))
-           std::__adjust_heap(__result_first, _DistanceType(0),
-                              _DistanceType(__result_real_last
-                                            - __result_first),
-                              _InputValueType(*__first),
-                              __comp);
-         ++__first;
+         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;
+           }
        }
-      std::sort_heap(__result_first, __result_real_last, __comp);
-      return __result_real_last;
     }
 
   /**
    *  @if maint
-   *  This is a helper function for the sort routine.
+   *  This is a helper function for the merge routines.
    *  @endif
   */
-  template<typename _RandomAccessIterator, typename _Tp>
-    void
-    __unguarded_linear_insert(_RandomAccessIterator __last, _Tp __val)
+  template<typename _BidirectionalIterator1, typename _BidirectionalIterator2,
+          typename _BidirectionalIterator3, typename _Compare>
+    _BidirectionalIterator3
+    __merge_backward(_BidirectionalIterator1 __first1,
+                    _BidirectionalIterator1 __last1,
+                    _BidirectionalIterator2 __first2,
+                    _BidirectionalIterator2 __last2,
+                    _BidirectionalIterator3 __result,
+                    _Compare __comp)
     {
-      _RandomAccessIterator __next = __last;
-      --__next;
-      while (__val < *__next)
+      if (__first1 == __last1)
+       return std::copy_backward(__first2, __last2, __result);
+      if (__first2 == __last2)
+       return std::copy_backward(__first1, __last1, __result);
+      --__last1;
+      --__last2;
+      while (true)
        {
-         *__last = *__next;
-         __last = __next;
-         --__next;
+         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;
+           }
        }
-      *__last = __val;
     }
 
   /**
    *  @if maint
-   *  This is a helper function for the sort routine.
+   *  This is a helper function for the merge routines.
    *  @endif
   */
-  template<typename _RandomAccessIterator, typename _Tp, typename _Compare>
-    void
-    __unguarded_linear_insert(_RandomAccessIterator __last, _Tp __val,
-                             _Compare __comp)
+  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)
     {
-      _RandomAccessIterator __next = __last;
-      --__next;
-      while (__comp(__val, *__next))
+      _BidirectionalIterator2 __buffer_end;
+      if (__len1 > __len2 && __len2 <= __buffer_size)
        {
-         *__last = *__next;
-         __last = __next;
-         --__next;
+         __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;
        }
-      *__last = __val;
     }
 
   /**
    *  @if maint
-   *  This is a helper function for the sort routine.
+   *  This is a helper function for the merge routines.
    *  @endif
   */
-  template<typename _RandomAccessIterator>
+  template<typename _BidirectionalIterator, typename _Distance,
+          typename _Pointer>
     void
-    __insertion_sort(_RandomAccessIterator __first,
-                    _RandomAccessIterator __last)
+    __merge_adaptive(_BidirectionalIterator __first,
+                     _BidirectionalIterator __middle,
+                    _BidirectionalIterator __last,
+                    _Distance __len1, _Distance __len2,
+                    _Pointer __buffer, _Distance __buffer_size)
     {
-      if (__first == __last)
-       return;
-
-      for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
+      if (__len1 <= __len2 && __len1 <= __buffer_size)
        {
-         typename iterator_traits<_RandomAccessIterator>::value_type
-           __val = *__i;
-         if (__val < *__first)
+         _Pointer __buffer_end = std::copy(__first, __middle, __buffer);
+         _GLIBCXX_STD_P::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)
            {
-             std::copy_backward(__first, __i, __i + 1);
-             *__first = __val;
+             __len11 = __len1 / 2;
+             std::advance(__first_cut, __len11);
+             __second_cut = std::lower_bound(__middle, __last,
+                                             *__first_cut);
+             __len22 = std::distance(__middle, __second_cut);
            }
          else
-           std::__unguarded_linear_insert(__i, __val);
+           {
+             __len22 = __len2 / 2;
+             std::advance(__second_cut, __len22);
+             __first_cut = std::upper_bound(__first, __middle,
+                                            *__second_cut);
+             __len11 = std::distance(__first, __first_cut);
+           }
+         _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);
        }
     }
 
   /**
    *  @if maint
-   *  This is a helper function for the sort routine.
+   *  This is a helper function for the merge routines.
    *  @endif
   */
-  template<typename _RandomAccessIterator, typename _Compare>
+  template<typename _BidirectionalIterator, typename _Distance, 
+          typename _Pointer, typename _Compare>
     void
-    __insertion_sort(_RandomAccessIterator __first,
-                    _RandomAccessIterator __last, _Compare __comp)
+    __merge_adaptive(_BidirectionalIterator __first,
+                     _BidirectionalIterator __middle,
+                    _BidirectionalIterator __last,
+                    _Distance __len1, _Distance __len2,
+                    _Pointer __buffer, _Distance __buffer_size,
+                    _Compare __comp)
     {
-      if (__first == __last) return;
-
-      for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
+      if (__len1 <= __len2 && __len1 <= __buffer_size)
        {
-         typename iterator_traits<_RandomAccessIterator>::value_type
-           __val = *__i;
-         if (__comp(__val, *__first))
+         _Pointer __buffer_end = std::copy(__first, __middle, __buffer);
+         _GLIBCXX_STD_P::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)
            {
-             std::copy_backward(__first, __i, __i + 1);
-             *__first = __val;
+             __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
-           std::__unguarded_linear_insert(__i, __val, __comp);
+           {
+             __len22 = __len2 / 2;
+             std::advance(__second_cut, __len22);
+             __first_cut = std::upper_bound(__first, __middle, *__second_cut,
+                                            __comp);
+             __len11 = std::distance(__first, __first_cut);
+           }
+         _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);
        }
     }
 
   /**
    *  @if maint
-   *  This is a helper function for the sort routine.
-   *  @endif
-  */
-  template<typename _RandomAccessIterator>
-    inline void
-    __unguarded_insertion_sort(_RandomAccessIterator __first,
-                              _RandomAccessIterator __last)
-    {
-      typedef typename iterator_traits<_RandomAccessIterator>::value_type
-       _ValueType;
-
-      for (_RandomAccessIterator __i = __first; __i != __last; ++__i)
-       std::__unguarded_linear_insert(__i, _ValueType(*__i));
-    }
-
-  /**
-   *  @if maint
-   *  This is a helper function for the sort routine.
-   *  @endif
-  */
-  template<typename _RandomAccessIterator, typename _Compare>
-    inline void
-    __unguarded_insertion_sort(_RandomAccessIterator __first,
-                              _RandomAccessIterator __last, _Compare __comp)
-    {
-      typedef typename iterator_traits<_RandomAccessIterator>::value_type
-       _ValueType;
-
-      for (_RandomAccessIterator __i = __first; __i != __last; ++__i)
-       std::__unguarded_linear_insert(__i, _ValueType(*__i), __comp);
-    }
-
-  /**
-   *  @if maint
-   *  @doctodo
-   *  This controls some aspect of the sort routines.
-   *  @endif
-  */
-  enum { _S_threshold = 16 };
-
-  /**
-   *  @if maint
-   *  This is a helper function for the sort routine.
+   *  This is a helper function for the merge routines.
    *  @endif
   */
-  template<typename _RandomAccessIterator>
+  template<typename _BidirectionalIterator, typename _Distance>
     void
-    __final_insertion_sort(_RandomAccessIterator __first,
-                          _RandomAccessIterator __last)
+    __merge_without_buffer(_BidirectionalIterator __first,
+                          _BidirectionalIterator __middle,
+                          _BidirectionalIterator __last,
+                          _Distance __len1, _Distance __len2)
     {
-      if (__last - __first > int(_S_threshold))
+      if (__len1 == 0 || __len2 == 0)
+       return;
+      if (__len1 + __len2 == 2)
        {
-         std::__insertion_sort(__first, __first + int(_S_threshold));
-         std::__unguarded_insertion_sort(__first + int(_S_threshold), __last);
+         if (*__middle < *__first)
+           std::iter_swap(__first, __middle);
+         return;
+       }
+      _BidirectionalIterator __first_cut = __first;
+      _BidirectionalIterator __second_cut = __middle;
+      _Distance __len11 = 0;
+      _Distance __len22 = 0;
+      if (__len1 > __len2)
+       {
+         __len11 = __len1 / 2;
+         std::advance(__first_cut, __len11);
+         __second_cut = std::lower_bound(__middle, __last, *__first_cut);
+         __len22 = std::distance(__middle, __second_cut);
        }
       else
-       std::__insertion_sort(__first, __last);
+       {
+         __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);
     }
 
   /**
    *  @if maint
-   *  This is a helper function for the sort routine.
+   *  This is a helper function for the merge routines.
    *  @endif
   */
-  template<typename _RandomAccessIterator, typename _Compare>
+  template<typename _BidirectionalIterator, typename _Distance,
+          typename _Compare>
     void
-    __final_insertion_sort(_RandomAccessIterator __first,
-                          _RandomAccessIterator __last, _Compare __comp)
+    __merge_without_buffer(_BidirectionalIterator __first,
+                           _BidirectionalIterator __middle,
+                          _BidirectionalIterator __last,
+                          _Distance __len1, _Distance __len2,
+                          _Compare __comp)
     {
-      if (__last - __first > int(_S_threshold))
+      if (__len1 == 0 || __len2 == 0)
+       return;
+      if (__len1 + __len2 == 2)
        {
-         std::__insertion_sort(__first, __first + int(_S_threshold), __comp);
-         std::__unguarded_insertion_sort(__first + int(_S_threshold), __last,
+         if (__comp(*__middle, *__first))
+           std::iter_swap(__first, __middle);
+         return;
+       }
+      _BidirectionalIterator __first_cut = __first;
+      _BidirectionalIterator __second_cut = __middle;
+      _Distance __len11 = 0;
+      _Distance __len22 = 0;
+      if (__len1 > __len2)
+       {
+         __len11 = __len1 / 2;
+         std::advance(__first_cut, __len11);
+         __second_cut = std::lower_bound(__middle, __last, *__first_cut,
                                          __comp);
+         __len22 = std::distance(__middle, __second_cut);
        }
       else
-       std::__insertion_sort(__first, __last, __comp);
-    }
-
-  /**
-   *  @if maint
-   *  This is a helper function...
-   *  @endif
-  */
-  template<typename _RandomAccessIterator, typename _Tp>
-    _RandomAccessIterator
-    __unguarded_partition(_RandomAccessIterator __first,
-                         _RandomAccessIterator __last, _Tp __pivot)
-    {
-      while (true)
        {
-         while (*__first < __pivot)
-           ++__first;
-         --__last;
-         while (__pivot < *__last)
-           --__last;
-         if (!(__first < __last))
-           return __first;
-         std::iter_swap(__first, __last);
-         ++__first;
+         __len22 = __len2 / 2;
+         std::advance(__second_cut, __len22);
+         __first_cut = std::upper_bound(__first, __middle, *__second_cut,
+                                        __comp);
+         __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, __comp);
+      std::__merge_without_buffer(__new_middle, __second_cut, __last,
+                                 __len1 - __len11, __len2 - __len22, __comp);
     }
 
   /**
-   *  @if maint
-   *  This is a helper function...
-   *  @endif
-  */
-  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))
-           --__last;
-         if (!(__first < __last))
-           return __first;
-         std::iter_swap(__first, __last);
-         ++__first;
-       }
-    }
-
-  /**
-   *  @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 > int(_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 > int(_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;
-       }
-    }
-
-  /**
-   *  @if maint
-   *  This is a helper function for the sort routines.
-   *  @endif
-  */
-  template<typename _Size>
-    inline _Size
-    __lg(_Size __n)
-    {
-      _Size __k;
-      for (__k = 0; __n != 1; __n >>= 1)
-       ++__k;
-      return __k;
-    }
-
-  /**
-   *  @brief Sort the elements of a sequence.
+   *  @brief Merges two sorted ranges in place.
    *  @param  first   An iterator.
+   *  @param  middle  Another 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).
+   *  Merges two sorted and consecutive ranges, [first,middle) and
+   *  [middle,last), and puts the result in [first,last).  The output will
+   *  be sorted.  The sort is @e stable, that is, for equivalent
+   *  elements in the two ranges, elements from the first range will always
+   *  come before elements from the second.
    *
-   *  The relative ordering of equivalent elements is not preserved, use
-   *  @p stable_sort() if this is needed.
+   *  If enough additional memory is available, this takes (last-first)-1
+   *  comparisons.  Otherwise an NlogN algorithm is used, where N is
+   *  distance(first,last).
   */
-  template<typename _RandomAccessIterator>
-    inline void
-    sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
+  template<typename _BidirectionalIterator>
+    void
+    inplace_merge(_BidirectionalIterator __first,
+                 _BidirectionalIterator __middle,
+                 _BidirectionalIterator __last)
     {
-      typedef typename iterator_traits<_RandomAccessIterator>::value_type
-       _ValueType;
+      typedef typename iterator_traits<_BidirectionalIterator>::value_type
+          _ValueType;
+      typedef typename iterator_traits<_BidirectionalIterator>::difference_type
+          _DistanceType;
 
       // concept requirements
-      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
-           _RandomAccessIterator>)
+      __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
+           _BidirectionalIterator>)
       __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
-      __glibcxx_requires_valid_range(__first, __last);
+      __glibcxx_requires_sorted(__first, __middle);
+      __glibcxx_requires_sorted(__middle, __last);
 
-      if (__first != __last)
-       {
-         std::__introsort_loop(__first, __last,
-                               std::__lg(__last - __first) * 2);
-         std::__final_insertion_sort(__first, __last);
-       }
+      if (__first == __middle || __middle == __last)
+       return;
+
+      _DistanceType __len1 = std::distance(__first, __middle);
+      _DistanceType __len2 = std::distance(__middle, __last);
+
+      _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first,
+                                                                 __last);
+      if (__buf.begin() == 0)
+       std::__merge_without_buffer(__first, __middle, __last, __len1, __len2);
+      else
+       std::__merge_adaptive(__first, __middle, __last, __len1, __len2,
+                             __buf.begin(), _DistanceType(__buf.size()));
     }
 
   /**
-   *  @brief Sort the elements of a sequence using a predicate for comparison.
+   *  @brief Merges two sorted ranges in place.
    *  @param  first   An iterator.
+   *  @param  middle  Another iterator.
    *  @param  last    Another iterator.
-   *  @param  comp    A comparison functor.
+   *  @param  comp    A functor to use for comparisons.
    *  @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).
+   *  Merges two sorted and consecutive ranges, [first,middle) and
+   *  [middle,last), and puts the result in [first,last).  The output will
+   *  be sorted.  The sort is @e stable, that is, for equivalent
+   *  elements in the two ranges, elements from the first range will always
+   *  come before elements from the second.
    *
-   *  The relative ordering of equivalent elements is not preserved, use
-   *  @p stable_sort() if this is needed.
+   *  If enough additional memory is available, this takes (last-first)-1
+   *  comparisons.  Otherwise an NlogN algorithm is used, where N is
+   *  distance(first,last).
+   *
+   *  The comparison function should have the same effects on ordering as
+   *  the function used for the initial sort.
   */
-  template<typename _RandomAccessIterator, typename _Compare>
-    inline void
-    sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
-        _Compare __comp)
+  template<typename _BidirectionalIterator, typename _Compare>
+    void
+    inplace_merge(_BidirectionalIterator __first,
+                 _BidirectionalIterator __middle,
+                 _BidirectionalIterator __last,
+                 _Compare __comp)
     {
-      typedef typename iterator_traits<_RandomAccessIterator>::value_type
-       _ValueType;
+      typedef typename iterator_traits<_BidirectionalIterator>::value_type
+          _ValueType;
+      typedef typename iterator_traits<_BidirectionalIterator>::difference_type
+          _DistanceType;
 
       // concept requirements
-      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
-           _RandomAccessIterator>)
-      __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType,
-                                 _ValueType>)
-      __glibcxx_requires_valid_range(__first, __last);
+      __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 != __last)
-       {
-         std::__introsort_loop(__first, __last,
-                               std::__lg(__last - __first) * 2, __comp);
-         std::__final_insertion_sort(__first, __last, __comp);
-       }
+      if (__first == __middle || __middle == __last)
+       return;
+
+      const _DistanceType __len1 = std::distance(__first, __middle);
+      const _DistanceType __len2 = std::distance(__middle, __last);
+
+      _Temporary_buffer<_BidirectionalIterator, _ValueType> __buf(__first,
+                                                                 __last);
+      if (__buf.begin() == 0)
+       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 _Size>
+  template<typename _RandomAccessIterator1, typename _RandomAccessIterator2,
+          typename _Distance>
     void
-    __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth,
-                 _RandomAccessIterator __last, _Size __depth_limit)
+    __merge_sort_loop(_RandomAccessIterator1 __first,
+                     _RandomAccessIterator1 __last,
+                     _RandomAccessIterator2 __result,
+                     _Distance __step_size)
     {
-      typedef typename iterator_traits<_RandomAccessIterator>::value_type
-       _ValueType;
+      const _Distance __two_step = 2 * __step_size;
 
-      while (__last - __first > 3)
+      while (__last - __first >= __two_step)
        {
-         if (__depth_limit == 0)
-           {
-             std::__heap_select(__first, __nth + 1, __last);
-             // Place the nth largest element in its final position.
-             std::iter_swap(__first, __nth);
-             return;
-           }
-         --__depth_limit;
-         _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;
+         __result = _GLIBCXX_STD_P::merge(__first, __first + __step_size,
+                               __first + __step_size, __first + __two_step,
+                               __result);
+         __first += __two_step;
        }
-      std::__insertion_sort(__first, __last);
+
+      __step_size = std::min(_Distance(__last - __first), __step_size);
+      _GLIBCXX_STD_P::merge(__first, __first + __step_size, 
+                           __first + __step_size, __last,
+                __result);
     }
 
-  template<typename _RandomAccessIterator, typename _Size, typename _Compare>
+  template<typename _RandomAccessIterator1, typename _RandomAccessIterator2,
+          typename _Distance, typename _Compare>
     void
-    __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth,
-                 _RandomAccessIterator __last, _Size __depth_limit,
-                 _Compare __comp)
+    __merge_sort_loop(_RandomAccessIterator1 __first,
+                     _RandomAccessIterator1 __last,
+                     _RandomAccessIterator2 __result, _Distance __step_size,
+                     _Compare __comp)
     {
-      typedef typename iterator_traits<_RandomAccessIterator>::value_type
-       _ValueType;
+      const _Distance __two_step = 2 * __step_size;
 
-      while (__last - __first > 3)
+      while (__last - __first >= __two_step)
        {
-         if (__depth_limit == 0)
-           {
-             std::__heap_select(__first, __nth + 1, __last, __comp);
-             // Place the nth largest element in its final position.
-             std::iter_swap(__first, __nth);
-             return;
-           }
-         --__depth_limit;
-         _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;
+         __result = _GLIBCXX_STD_P::merge(__first, __first + __step_size,
+                               __first + __step_size, __first + __two_step,
+                               __result,
+                               __comp);
+         __first += __two_step;
        }
-      std::__insertion_sort(__first, __last, __comp);
+      __step_size = std::min(_Distance(__last - __first), __step_size);
+
+      _GLIBCXX_STD_P::merge(__first, __first + __step_size,
+                           __first + __step_size, __last, __result, __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>
-    inline void
-    nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth,
-               _RandomAccessIterator __last)
+  template<typename _RandomAccessIterator, typename _Distance>
+    void
+    __chunk_insertion_sort(_RandomAccessIterator __first,
+                          _RandomAccessIterator __last,
+                          _Distance __chunk_size)
     {
-      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);
-
-      if (__first == __last || __nth == __last)
-       return;
-
-      std::__introselect(__first, __nth, __last,
-                        std::__lg(__last - __first) * 2);
+      while (__last - __first >= __chunk_size)
+       {
+         std::__insertion_sort(__first, __first + __chunk_size);
+         __first += __chunk_size;
+       }
+      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>
-    inline void
-    nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth,
-               _RandomAccessIterator __last, _Compare __comp)
+  template<typename _RandomAccessIterator, typename _Distance, typename _Compare>
+    void
+    __chunk_insertion_sort(_RandomAccessIterator __first,
+                          _RandomAccessIterator __last,
+                          _Distance __chunk_size, _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);
-
-      if (__first == __last || __nth == __last)
-       return;
-
-      std::__introselect(__first, __nth, __last,
-                        std::__lg(__last - __first) * 2, __comp);
+      while (__last - __first >= __chunk_size)
+       {
+         std::__insertion_sort(__first, __first + __chunk_size, __comp);
+         __first += __chunk_size;
+       }
+      std::__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,
-   *           or end() if every element is less than @a val.
-   *  @ingroup binarysearch
-  */
-  template<typename _ForwardIterator, typename _Tp>
-    _ForwardIterator
-    lower_bound(_ForwardIterator __first, _ForwardIterator __last,
-               const _Tp& __val)
+  enum { _S_chunk_size = 7 };
+
+  template<typename _RandomAccessIterator, typename _Pointer>
+    void
+    __merge_sort_with_buffer(_RandomAccessIterator __first,
+                            _RandomAccessIterator __last,
+                             _Pointer __buffer)
     {
-      typedef typename iterator_traits<_ForwardIterator>::value_type
-       _ValueType;
-      typedef typename iterator_traits<_ForwardIterator>::difference_type
-       _DistanceType;
+      typedef typename iterator_traits<_RandomAccessIterator>::difference_type
+       _Distance;
 
-      // concept requirements
-      __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
-      __glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>)
-      __glibcxx_requires_partitioned(__first, __last, __val);
+      const _Distance __len = __last - __first;
+      const _Pointer __buffer_last = __buffer + __len;
 
-      _DistanceType __len = std::distance(__first, __last);
-      _DistanceType __half;
-      _ForwardIterator __middle;
+      _Distance __step_size = _S_chunk_size;
+      std::__chunk_insertion_sort(__first, __last, __step_size);
 
-      while (__len > 0)
+      while (__step_size < __len)
        {
-         __half = __len >> 1;
-         __middle = __first;
-         std::advance(__middle, __half);
-         if (*__middle < __val)
-           {
-             __first = __middle;
-             ++__first;
-             __len = __len - __half - 1;
-           }
-         else
-           __len = __half;
+         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;
        }
-      return __first;
     }
 
-  /**
-   *  @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.
-   *  @param  comp    A functor to use for comparisons.
-   *  @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 _ForwardIterator, typename _Tp, typename _Compare>
-    _ForwardIterator
-    lower_bound(_ForwardIterator __first, _ForwardIterator __last,
-               const _Tp& __val, _Compare __comp)
+  template<typename _RandomAccessIterator, typename _Pointer, typename _Compare>
+    void
+    __merge_sort_with_buffer(_RandomAccessIterator __first,
+                            _RandomAccessIterator __last,
+                             _Pointer __buffer, _Compare __comp)
     {
-      typedef typename iterator_traits<_ForwardIterator>::value_type
-       _ValueType;
-      typedef typename iterator_traits<_ForwardIterator>::difference_type
-       _DistanceType;
+      typedef typename iterator_traits<_RandomAccessIterator>::difference_type
+       _Distance;
 
-      // concept requirements
-      __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
-      __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
-                                 _ValueType, _Tp>)
-      __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp);
+      const _Distance __len = __last - __first;
+      const _Pointer __buffer_last = __buffer + __len;
 
-      _DistanceType __len = std::distance(__first, __last);
-      _DistanceType __half;
-      _ForwardIterator __middle;
+      _Distance __step_size = _S_chunk_size;
+      std::__chunk_insertion_sort(__first, __last, __step_size, __comp);
 
-      while (__len > 0)
+      while (__step_size < __len)
        {
-         __half = __len >> 1;
-         __middle = __first;
-         std::advance(__middle, __half);
-         if (__comp(*__middle, __val))
-           {
-             __first = __middle;
-             ++__first;
-             __len = __len - __half - 1;
-           }
-         else
-           __len = __half;
+         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;
        }
-      return __first;
     }
 
-  /**
-   *  @brief Finds the last 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 greater than @a val,
-   *           or end() if no elements are greater than @a val.
-   *  @ingroup binarysearch
-  */
-  template<typename _ForwardIterator, typename _Tp>
-    _ForwardIterator
-    upper_bound(_ForwardIterator __first, _ForwardIterator __last,
-               const _Tp& __val)
+  template<typename _RandomAccessIterator, typename _Pointer,
+          typename _Distance>
+    void
+    __stable_sort_adaptive(_RandomAccessIterator __first,
+                          _RandomAccessIterator __last,
+                           _Pointer __buffer, _Distance __buffer_size)
     {
-      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(_LessThanOpConcept<_Tp, _ValueType>)
-      __glibcxx_requires_partitioned(__first, __last, __val);
-
-      _DistanceType __len = std::distance(__first, __last);
-      _DistanceType __half;
-      _ForwardIterator __middle;
+      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
+       {
+         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);
+    }
 
-      while (__len > 0)
+  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)
        {
-         __half = __len >> 1;
-         __middle = __first;
-         std::advance(__middle, __half);
-         if (__val < *__middle)
-           __len = __half;
-         else
-           {
-             __first = __middle;
-             ++__first;
-             __len = __len - __half - 1;
-           }
+         std::__stable_sort_adaptive(__first, __middle, __buffer,
+                                     __buffer_size, __comp);
+         std::__stable_sort_adaptive(__middle, __last, __buffer,
+                                     __buffer_size, __comp);
        }
-      return __first;
+      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 Finds the last 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.
-   *  @param  comp    A functor to use for comparisons.
-   *  @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.
+   *  @if maint
+   *  This is a helper function for the stable sorting routines.
+   *  @endif
   */
-  template<typename _ForwardIterator, typename _Tp, typename _Compare>
-    _ForwardIterator
-    upper_bound(_ForwardIterator __first, _ForwardIterator __last,
-               const _Tp& __val, _Compare __comp)
+  template<typename _RandomAccessIterator>
+    void
+    __inplace_stable_sort(_RandomAccessIterator __first,
+                         _RandomAccessIterator __last)
     {
-      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,
-                                 _Tp, _ValueType>)
-      __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp);
-
-      _DistanceType __len = std::distance(__first, __last);
-      _DistanceType __half;
-      _ForwardIterator __middle;
-
-      while (__len > 0)
+      if (__last - __first < 15)
        {
-         __half = __len >> 1;
-         __middle = __first;
-         std::advance(__middle, __half);
-         if (__comp(__val, *__middle))
-           __len = __half;
-         else
-           {
-             __first = __middle;
-             ++__first;
-             __len = __len - __half - 1;
-           }
+         std::__insertion_sort(__first, __last);
+         return;
        }
-      return __first;
+      _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 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 stable sorting routines.
+   *  @endif
   */
-  template<typename _ForwardIterator, typename _Tp>
-    pair<_ForwardIterator, _ForwardIterator>
-    equal_range(_ForwardIterator __first, _ForwardIterator __last,
-               const _Tp& __val)
+  template<typename _RandomAccessIterator, typename _Compare>
+    void
+    __inplace_stable_sort(_RandomAccessIterator __first,
+                         _RandomAccessIterator __last, _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(_LessThanOpConcept<_ValueType, _Tp>)
-      __glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>) 
-      __glibcxx_requires_partitioned(__first, __last, __val);
-
-      _DistanceType __len = std::distance(__first, __last);
-      _DistanceType __half;
-      _ForwardIterator __middle, __left, __right;
-
-      while (__len > 0)
+      if (__last - __first < 15)
        {
-         __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);
-           }
+         std::__insertion_sort(__first, __last, __comp);
+         return;
        }
-      return pair<_ForwardIterator, _ForwardIterator>(__first, __first);
+      _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);
     }
 
+  // stable_sort
+
+  // Set algorithms: includes, set_union, set_intersection, set_difference,
+  // set_symmetric_difference.  All of these algorithms have the precondition
+  // that their input ranges are sorted and the postcondition that their output
+  // ranges are sorted.
+
   /**
-   *  @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
+   *  @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 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(_ForwardIteratorC