2003-11-11 Doug Gregor <gregod@cs.rpi.edu>
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Nov 2003 20:09:16 +0000 (20:09 +0000)
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Nov 2003 20:09:16 +0000 (20:09 +0000)
* docs/html/debug.html: Document libstdc++ debug mode.
* docs/html/debug_mode.html: Document libstdc++ debug mode design.
* docs/html/test.html: Document how to test under debug mode.
* docs/html/17_intro/howto.html: Document debug-mode macros.
* include/Makefile.am: Install debug-mode headers.
* src/Makefile.am: Include debug.cc.
* include/bits/basic_string.tcc:
  (basic_string::_S_construct): Fix NULL pointer check.
  (__is_null_pointer): New.
  Add precondition annotations.
* include/bits/stream_iterator.h (istream_iterator,
ostream_iterator): Added precondition annotations.
* include/bits/streambuf_iterator.h (istreambuf_iterator): Ditto.
* include/bits/stl_queue.h (queue, priority_queue): Ditto.
* include/bits/stl_stack.h (stack): Ditto.
* include/bits/basic_string.h (basic_string): Ditto.
* include/bits/basic_string.tcc (basic_string): Ditto.
* include/std/std_memory.h (auto_ptr): Ditto.
* include/std/std_valarray.h (valarray): Ditto.
* include/bits/stl_algo.h: Added algorithm precondition
annotations.
* include/bits/stl_algobase.h: Added algorithm precondition
annotations.
* include/bits/stl_numeric.h: Ditto.
* include/ext/algorithm: Added algorithm precondition
annotations.
(__is_heap): Moved away from here.
* include/bits/stl_heap.h: Added algorithm precondition
annotations.
(__is_heap): Moved to the top of this file.
(__is_heap): Added iterator range overloads.
* testsuite/20_util/auto_ptr_neg.cc: Fix line numbers to match up
with changes in std_memory.h.
* testsuite/23_containers/list/operators/4.cc: Don't verify
performance guarantees when in debug mode.
* testsuite/23_containers/bitset/invalidation/1.cc: New.
* testsuite/23_containers/deque/invalidation/1.cc: New.
* testsuite/23_containers/deque/invalidation/2.cc: New.
* testsuite/23_containers/deque/invalidation/3.cc: New.
* testsuite/23_containers/deque/invalidation/4.cc: New.
* testsuite/23_containers/list/invalidation/1.cc: New.
* testsuite/23_containers/list/invalidation/2.cc: New.
* testsuite/23_containers/list/invalidation/3.cc: New.
* testsuite/23_containers/list/invalidation/4.cc: New.
* testsuite/23_containers/map/invalidation/1.cc: New.
* testsuite/23_containers/map/invalidation/2.cc: New.
* testsuite/23_containers/multimap/invalidation/1.cc: New.
* testsuite/23_containers/multimap/invalidation/2.cc: New.
* testsuite/23_containers/multiset/invalidation/1.cc: New.
* testsuite/23_containers/multiset/invalidation/2.cc: New.
* testsuite/23_containers/set/invalidation/1.cc: New.
* testsuite/23_containers/set/invalidation/2.cc: New.
* testsuite/23_containers/vector/invalidation/1.cc: New.
* testsuite/23_containers/vector/invalidation/2.cc: New.
* testsuite/23_containers/vector/invalidation/3.cc: New.
* testsuite/23_containers/vector/invalidation/4.cc: New.
* testsuite/25_algorithms/heap.cc: Don't verify
performance guarantees when in debug mode.
* include/debug/bitset: New.
* include/debug/debug.h: New.
* include/debug/deque: New.
* include/debug/formatter.h: New.
* include/debug/hash_map: New.
* include/debug/hash_map.h: New.
* include/debug/hash_multimap.h: New.
* include/debug/hash_set: New.
* include/debug/hash_set.h: New.
* include/debug/hash_multiset.h: New.
* include/debug/list: New.
* include/debug/map: New.
* include/debug/map.h: New.
* include/debug/multimap.h: New.
* include/debug/multiset.h: New.
* include/debug/safe_base.h: New.
* include/debug/safe_iterator.h: New.
* include/debug/safe_iterator.tcc: New.
* include/debug/safe_sequence.h: New.
* include/debug/set: New.
* include/debug/set.h: New.
* include/debug/string: New.
* include/debug/vector: New.
* src/debug.cc: New.
* config/linker-map.gnu: Add debug mode symbols.

2003-11-11  Benjamin Kosnik  <bkoz@redhat.com>

* src/string-inst.cc: Tweak namespaces.
* src/misc-inst.cc: Same.
* docs/html/debug.html: Edits.
* config/link-map.gnu: Remove cruft.

* include/bits/c++config: Add in namespace associations.
* include/std/std_bitset.h: Adjust namespace to __gnu_norm,
comment tweaks.
* include/bits/deque.tcc: Same.
* include/bits/list.tcc: Same.
* include/bits/stl_bvector.h: Same.
* include/bits/stl_deque.h: Same.
* include/bits/stl_list.h: Same.
* include/bits/stl_map.h: Same.
* include/bits/stl_multimap.h: Same.
* include/bits/stl_multiset.h: Same.
* include/bits/stl_set.h: Same.
* include/bits/stl_vector.h: Same.
* include/bits/vector.tcc: Same.

* include/std/std_algorithm.h: Remove markup comments.
* include/std/std_functional.h: Same.
* include/std/std_iterator.h: Same.
* include/std/std_numeric.h: Same.
* include/std/std_utility.h: Same.
* include/bits/stl_queue.h: Formatting tweaks.
* include/bits/stl_stack.h: Same.
* include/std/std_deque.h: Include debugging version in debug mode.
* include/std/std_list.h: Same.
* include/std/std_map.h: Same.
* include/std/std_set.h: Same.
* include/std/std_vector.h: Same.
* include/std/std_queue.h: Use deque, vector.
* include/std/std_stack.h: Same.

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

98 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/config/linker-map.gnu
libstdc++-v3/docs/html/17_intro/howto.html
libstdc++-v3/docs/html/debug.html
libstdc++-v3/docs/html/debug_mode.html [new file with mode: 0644]
libstdc++-v3/docs/html/test.html
libstdc++-v3/include/Makefile.am
libstdc++-v3/include/Makefile.in
libstdc++-v3/include/bits/basic_string.h
libstdc++-v3/include/bits/basic_string.tcc
libstdc++-v3/include/bits/c++config
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_heap.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_queue.h
libstdc++-v3/include/bits/stl_set.h
libstdc++-v3/include/bits/stl_stack.h
libstdc++-v3/include/bits/stl_vector.h
libstdc++-v3/include/bits/stream_iterator.h
libstdc++-v3/include/bits/streambuf_iterator.h
libstdc++-v3/include/bits/vector.tcc
libstdc++-v3/include/debug/bitset [new file with mode: 0644]
libstdc++-v3/include/debug/debug.h [new file with mode: 0644]
libstdc++-v3/include/debug/deque [new file with mode: 0644]
libstdc++-v3/include/debug/formatter.h [new file with mode: 0644]
libstdc++-v3/include/debug/hash_map [new file with mode: 0644]
libstdc++-v3/include/debug/hash_map.h [new file with mode: 0644]
libstdc++-v3/include/debug/hash_multimap.h [new file with mode: 0644]
libstdc++-v3/include/debug/hash_multiset.h [new file with mode: 0644]
libstdc++-v3/include/debug/hash_set [new file with mode: 0644]
libstdc++-v3/include/debug/hash_set.h [new file with mode: 0644]
libstdc++-v3/include/debug/list [new file with mode: 0644]
libstdc++-v3/include/debug/map [new file with mode: 0644]
libstdc++-v3/include/debug/map.h [new file with mode: 0644]
libstdc++-v3/include/debug/multimap.h [new file with mode: 0644]
libstdc++-v3/include/debug/multiset.h [new file with mode: 0644]
libstdc++-v3/include/debug/safe_base.h [new file with mode: 0644]
libstdc++-v3/include/debug/safe_iterator.h [new file with mode: 0644]
libstdc++-v3/include/debug/safe_iterator.tcc [new file with mode: 0644]
libstdc++-v3/include/debug/safe_sequence.h [new file with mode: 0644]
libstdc++-v3/include/debug/set [new file with mode: 0644]
libstdc++-v3/include/debug/set.h [new file with mode: 0644]
libstdc++-v3/include/debug/string [new file with mode: 0644]
libstdc++-v3/include/debug/vector [new file with mode: 0644]
libstdc++-v3/include/ext/algorithm
libstdc++-v3/include/std/std_algorithm.h
libstdc++-v3/include/std/std_bitset.h
libstdc++-v3/include/std/std_deque.h
libstdc++-v3/include/std/std_functional.h
libstdc++-v3/include/std/std_iterator.h
libstdc++-v3/include/std/std_list.h
libstdc++-v3/include/std/std_map.h
libstdc++-v3/include/std/std_memory.h
libstdc++-v3/include/std/std_numeric.h
libstdc++-v3/include/std/std_queue.h
libstdc++-v3/include/std/std_set.h
libstdc++-v3/include/std/std_stack.h
libstdc++-v3/include/std/std_utility.h
libstdc++-v3/include/std/std_valarray.h
libstdc++-v3/include/std/std_vector.h
libstdc++-v3/src/Makefile.am
libstdc++-v3/src/Makefile.in
libstdc++-v3/src/debug.cc [new file with mode: 0644]
libstdc++-v3/src/misc-inst.cc
libstdc++-v3/src/string-inst.cc
libstdc++-v3/testsuite/20_util/auto_ptr_neg.cc
libstdc++-v3/testsuite/23_containers/bitset/invalidation/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/deque/invalidation/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/deque/invalidation/2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/deque/invalidation/3.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/deque/invalidation/4.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/list/invalidation/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/list/invalidation/2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/list/invalidation/3.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/list/invalidation/4.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/list/operators/4.cc
libstdc++-v3/testsuite/23_containers/map/invalidation/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/map/invalidation/2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multimap/invalidation/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multimap/invalidation/2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multiset/invalidation/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multiset/invalidation/2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/set/invalidation/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/set/invalidation/2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/vector/invalidation/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/vector/invalidation/2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/vector/invalidation/3.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/vector/invalidation/4.cc [new file with mode: 0644]
libstdc++-v3/testsuite/25_algorithms/heap.cc

index 5255ff4..1df66ab 100644 (file)
@@ -1,3 +1,126 @@
+2003-11-11  Doug Gregor  <gregod@cs.rpi.edu>
+
+       * docs/html/debug.html: Document libstdc++ debug mode.
+       * docs/html/debug_mode.html: Document libstdc++ debug mode design.
+       * docs/html/test.html: Document how to test under debug mode.
+       * docs/html/17_intro/howto.html: Document debug-mode macros.
+       * include/Makefile.am: Install debug-mode headers.
+       * src/Makefile.am: Include debug.cc.
+       * include/bits/basic_string.tcc: 
+         (basic_string::_S_construct): Fix NULL pointer check.
+         (__is_null_pointer): New.
+         Add precondition annotations.
+       * include/bits/stream_iterator.h (istream_iterator,
+       ostream_iterator): Added precondition annotations.
+       * include/bits/streambuf_iterator.h (istreambuf_iterator): Ditto.
+       * include/bits/stl_queue.h (queue, priority_queue): Ditto.
+       * include/bits/stl_stack.h (stack): Ditto.
+       * include/bits/basic_string.h (basic_string): Ditto.
+       * include/bits/basic_string.tcc (basic_string): Ditto.
+       * include/std/std_memory.h (auto_ptr): Ditto.
+       * include/std/std_valarray.h (valarray): Ditto.
+       * include/bits/stl_algo.h: Added algorithm precondition
+       annotations.
+       * include/bits/stl_algobase.h: Added algorithm precondition
+       annotations.
+       * include/bits/stl_numeric.h: Ditto.
+       * include/ext/algorithm: Added algorithm precondition
+       annotations. 
+       (__is_heap): Moved away from here.
+       * include/bits/stl_heap.h: Added algorithm precondition
+       annotations. 
+       (__is_heap): Moved to the top of this file.
+       (__is_heap): Added iterator range overloads.
+       * testsuite/20_util/auto_ptr_neg.cc: Fix line numbers to match up
+       with changes in std_memory.h.
+       * testsuite/23_containers/list/operators/4.cc: Don't verify
+       performance guarantees when in debug mode.
+       * testsuite/23_containers/bitset/invalidation/1.cc: New.
+       * testsuite/23_containers/deque/invalidation/1.cc: New.
+       * testsuite/23_containers/deque/invalidation/2.cc: New.
+       * testsuite/23_containers/deque/invalidation/3.cc: New.
+       * testsuite/23_containers/deque/invalidation/4.cc: New.
+       * testsuite/23_containers/list/invalidation/1.cc: New.
+       * testsuite/23_containers/list/invalidation/2.cc: New.
+       * testsuite/23_containers/list/invalidation/3.cc: New.
+       * testsuite/23_containers/list/invalidation/4.cc: New.
+       * testsuite/23_containers/map/invalidation/1.cc: New.
+       * testsuite/23_containers/map/invalidation/2.cc: New.
+       * testsuite/23_containers/multimap/invalidation/1.cc: New.
+       * testsuite/23_containers/multimap/invalidation/2.cc: New.
+       * testsuite/23_containers/multiset/invalidation/1.cc: New.
+       * testsuite/23_containers/multiset/invalidation/2.cc: New.
+       * testsuite/23_containers/set/invalidation/1.cc: New.
+       * testsuite/23_containers/set/invalidation/2.cc: New.
+       * testsuite/23_containers/vector/invalidation/1.cc: New.
+       * testsuite/23_containers/vector/invalidation/2.cc: New.
+       * testsuite/23_containers/vector/invalidation/3.cc: New.
+       * testsuite/23_containers/vector/invalidation/4.cc: New.
+       * testsuite/25_algorithms/heap.cc: Don't verify
+       performance guarantees when in debug mode.
+       * include/debug/bitset: New.
+       * include/debug/debug.h: New.
+       * include/debug/deque: New.
+       * include/debug/formatter.h: New.
+       * include/debug/hash_map: New.
+       * include/debug/hash_map.h: New.        
+       * include/debug/hash_multimap.h: New.
+       * include/debug/hash_set: New.
+       * include/debug/hash_set.h: New.
+       * include/debug/hash_multiset.h: New.   
+       * include/debug/list: New.
+       * include/debug/map: New.
+       * include/debug/map.h: New.
+       * include/debug/multimap.h: New.
+       * include/debug/multiset.h: New.        
+       * include/debug/safe_base.h: New.
+       * include/debug/safe_iterator.h: New.
+       * include/debug/safe_iterator.tcc: New.
+       * include/debug/safe_sequence.h: New.
+       * include/debug/set: New.
+       * include/debug/set.h: New.     
+       * include/debug/string: New.
+       * include/debug/vector: New.
+       * src/debug.cc: New.
+       * config/linker-map.gnu: Add debug mode symbols.
+       
+2003-11-11  Benjamin Kosnik  <bkoz@redhat.com>
+
+       * src/string-inst.cc: Tweak namespaces.
+       * src/misc-inst.cc: Same.
+       * docs/html/debug.html: Edits.
+       * config/link-map.gnu: Remove cruft.
+
+       * include/bits/c++config: Add in namespace associations.
+       * include/std/std_bitset.h: Adjust namespace to __gnu_norm,
+       comment tweaks.
+       * include/bits/deque.tcc: Same.
+       * include/bits/list.tcc: Same.
+       * include/bits/stl_bvector.h: Same.
+       * include/bits/stl_deque.h: Same.
+       * include/bits/stl_list.h: Same.
+       * include/bits/stl_map.h: Same.
+       * include/bits/stl_multimap.h: Same.
+       * include/bits/stl_multiset.h: Same.
+       * include/bits/stl_set.h: Same.
+       * include/bits/stl_vector.h: Same.
+       * include/bits/vector.tcc: Same.
+
+       * include/std/std_algorithm.h: Remove markup comments.
+       * include/std/std_functional.h: Same.
+       * include/std/std_iterator.h: Same.
+       * include/std/std_numeric.h: Same.
+       * include/std/std_utility.h: Same.
+       * include/bits/stl_queue.h: Formatting tweaks.
+       * include/bits/stl_stack.h: Same.
+       * include/std/std_deque.h: Include debugging version in debug mode.
+       * include/std/std_list.h: Same.
+       * include/std/std_map.h: Same.
+       * include/std/std_set.h: Same.
+       * include/std/std_vector.h: Same.       
+       * include/std/std_queue.h: Use deque, vector.
+       * include/std/std_stack.h: Same.
+
 2003-11-09  Paolo Carlini  <pcarlini@suse.de>
 
        * include/bits/locale_facets.tcc (_M_insert_int,
index adbd390..671e421 100644 (file)
@@ -57,7 +57,11 @@ GLIBCXX_3.4 {
       std::__num_base::_S_atoms_out;
       std::__moneypunct_cache*;
       std::__numpunct_cache*;
-      std::__timepunct_cache*
+      std::__timepunct_cache*;
+      __gnu_norm::*;
+      __gnu_debug::_Safe_iterator_base*;
+      __gnu_debug::_Safe_sequence_base*;
+      __gnu_debug::_Error_formatter*
     };
 
     # Names not in an 'extern' block are mangled names.
@@ -88,7 +92,7 @@ GLIBCXX_3.4 {
     # std::locale::facet destructors
     _ZNSt6locale5facetD*;
         
-    # std::locale::_Impl constructors, destrutors
+    # std::locale::_Impl constructors, destructors
     _ZNSt6locale5_ImplC*;
     _ZNSt6locale5_ImplD*;
 
@@ -104,9 +108,6 @@ GLIBCXX_3.4 {
     _ZSt21_Rb_tree_rotate_rightPSt18_Rb_tree_node_baseRS0_;
     _ZSt28_Rb_tree_rebalance_for_erasePSt18_Rb_tree_node_baseRS_;
 
-    # std::__ctype_abstract_base*
-    _ZNSt21__ctype_abstract_base*;
-
     # std::__codecvt_abstract_base*
     _ZNStSt23__codecvt_abstract_base*;
 
index d1fc584..29d0db7 100644 (file)
         violations of the requirements of the standard.  This is described
         in more detail <a href="../19_diagnostics/howto.html#3">here</a>.
     </dd>
+    <dt><code>_GLIBCXX_DEBUG</code></dt>
+    <dd>Undefined by default. Configurable. When defined, compiles
+    user code using the <a href="../debug.html#safe">libstdc++ debug
+    mode</a>.
+    </dd>
+    <dt><code>_GLIBCXX_DEBUG_PEDANTIC</code></dt>
+    <dd>Undefined by default. Configurable. When defined while
+    compiling with the <a href="../debug.html#safe">libstdc++ debug
+    mode</a>, makes the debug mode extremely picky by making the use
+    of libstdc++ extensions and libstdc++-specific behavior into
+    errors.
+    </dd>
     <!--
     <dt><code></code></dt>
     <dd>
index dcd035c..be4a861 100644 (file)
@@ -29,9 +29,8 @@
 <!-- ####################################################### -->
 <hr />
 <p>There are numerous things that can be done to improve the ease with
-   which C++ binaries are debugged when using the GNU C++
-   tool chain. Here are some things to keep in mind when debugging C++
-   code with GNU tools.
+   which C++ binaries are debugged when using the GNU 
+   tool chain. Here are some of them.
 </p>
 
 <h3 class="left"><a name="gplusplus">Compiler flags determine debug info</a></h3>
    be varied to change debugging characteristics. For instance,
    turning off all optimization via the <code>-g -O0</code> flag will
    disable inlining, so that stepping through all functions, including
-   inlined constructors and destructors, is possible. Or, the debug
-   format that the compiler and debugger use to communicate
+   inlined constructors and destructors, is possible. In addition,
+   <code>-fno-eliminate-unused-debug-types<code> can be used when
+   additional debug information, such as nested class info, is desired.
+</p>
+
+<p>Or, the debug format that the compiler and debugger use to communicate
    information about source constructs can be changed via <code>
    -gdwarf-2 </code> or <code> -gstabs </code> flags: some debugging
    formats permit more expressive type and scope information to be
-   shown in gdb.
-   The default debug information for a particular platform can be
-   identified via the value set by the PREFERRED_DEBUGGING_TYPE macro
-   in the gcc sources.
+   shown in gdb.  The default debug information for a particular
+   platform can be identified via the value set by the
+   PREFERRED_DEBUGGING_TYPE macro in the gcc sources.
 </p>
 
 <p>Many other options are available: please see
    in Using the GNU Compiler Collection (GCC) for a complete list.
 </p>
 
-
 <h3 class="left"><a name="lib">Using special flags to make a debug binary</a></h3>
-<p>There are two ways to build libstdc++ with debug flags. The first
-   is to run make from the toplevel in a freshly-configured tree with
-   specialized debug <code>CXXFLAGS</code>, as in
-</p>
-<pre>
-     make CXXFLAGS='-g3 -O0' all
-</pre>
-
-<p>This quick and dirty approach is often sufficient for quick
-   debugging tasks, but the lack of state can be confusing in the long
-   term.
-</p>
-<p>A second approach is to use the configuration flags 
-</p>
+<p>If you would like debug symbols in libstdc++, there are two ways to
+  build libstdc++ with debug flags. The first is to run make from the
+  toplevel in a freshly-configured tree with
 <pre>
-     --enable-debug
+     --enable-libstdcxx-debug
 </pre>
 <p>and perhaps</p>
 <pre>
-     --enable-debug-flags='...'
+     --enable-libstdcxx-debug-flags='...'
 </pre>
 <p>to create a separate debug build. Both the normal build and the
    debug build will persist, without having to specify
    options</a> document.
 </p>
 
+<p>A second approach is to use the configuration flags 
+</p>
+<pre>
+     make CXXFLAGS='-g3 -O0' all
+</pre>
+
+<p>This quick and dirty approach is often sufficient for quick
+  debugging tasks, when you cannot or don't want to recompile your
+  application to use the <a href="#safe">debug mode</a>.</p>
+
+<h3 class="left"><a name="safe">The libstdc++ debug mode</a></h3>
+<p>By default, libstdc++ is built with efficiency in mind, and
+  therefore performs little or no error checking that is not required
+  by the C++ standard. This means that programs that incorrectly use
+  the C++ standard library will exhibit behavior that is not portable
+  and may not even be predictable, because they tread into 
+  implementation-specific or undefined behavior. To detect some of
+  these errors before they can become problematic, libstdc++ offers a
+  debug mode that provides additional checking of library facilities,
+  and will report errors in the use of libstdc++ as soon as they can
+  be detected by emitting a description of the problem to standard
+  error and aborting the program. </p>
+
+<p>The libstdc++ debug mode performs checking for many areas of the C++
+  standard, but the focus is on checking interactions among standard
+  iterators, containers, and algorithms, including:</p>
+
+  <ul>
+    <li><em>Safe iterators</em>: Iterators keep track of the
+    container whose elements they reference, so errors such as
+    incrementing a past-the-end iterator or dereferencing an iterator
+    that points to a container that has been destructed are diagnosed
+    immediately.</li>
+    
+    <li><em>Algorithm preconditions</em>: Algorithms attempt to
+    validate their input parameters to detect errors as early as
+    possible. For instance, the <code>set_intersection</code>
+    algorithm requires that its iterator
+    parameters <code>first1</code> and <code>last1</code> form a valid
+    iterator range, and that the sequence
+    [<code>first1</code>, <code>last1</code>) is sorted according to
+    the same predicate that was passed
+    to <code>set_intersection</code>; the libstdc++ debug mode will
+    detect an error if the sequence is not sorted or was sorted by a
+    different predicate.</li>
+  </ul>
+
+<h4 class="left">Using the libstdc++ debug mode</h4>
+<p>To use the libstdc++ debug mode, compile your application with the
+  compiler flag <code>-D_GLIBCXX_DEBUG</code>. Note that this flag
+  changes the sizes and behavior of standard class templates such
+  as <code>std::vector</code>, and therefore you can only link code
+  compiled with debug mode and code compiled without debug mode if no
+  instantiation of a container is passed between the two translation
+  units.</p>
+
+<p>For information about the design of the libstdc++ debug mode,
+  please see the <a href="debug_mode.html">libstdc++ debug mode design
+  document</a>.</p>
+
+<h4 class="left">Using the debugging containers without debug
+  mode</h4>
+<p>When it is not feasible to recompile your entire application, or
+  only specific containers need checking, debugging containers are
+  available as GNU extensions. These debugging containers are
+  functionally equivalent to the standard drop-in containers used in
+  debug 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 debug mode. However, unlike the containers in namespace
+  <code>std</code>, these containers may not be specialized. The
+  following table provides the names and headers of the debugging
+  containers:
+
+<table title="Debugging containers" border="1">
+  <tr>
+    <th>Container</th>
+    <th>Header</th>
+    <th>Debug container</th>
+    <th>Debug header</th>
+  </tr>
+  <tr>
+    <td>std::bitset</td>
+    <td>&lt;bitset&gt;</td>
+    <td>__gnu_debug::bitset</td>
+    <td>&lt;debug/bitset&gt;</td>
+  </tr>
+  <tr>
+    <td>std::deque</td>
+    <td>&lt;deque&gt;</td>
+    <td>__gnu_debug::deque</td>
+    <td>&lt;debug/deque&gt;</td>
+  </tr>
+  <tr>
+    <td>std::list</td>
+    <td>&lt;list&gt;</td>
+    <td>__gnu_debug::list</td>
+    <td>&lt;debug/list&gt;</td>
+  </tr>
+  <tr>
+    <td>std::map</td>
+    <td>&lt;map&gt;</td>
+    <td>__gnu_debug::map</td>
+    <td>&lt;debug/map&gt;</td>
+  </tr>
+  <tr>
+    <td>std::multimap</td>
+    <td>&lt;map&gt;</td>
+    <td>__gnu_debug::multimap</td>
+    <td>&lt;debug/map&gt;</td>
+  </tr>
+  <tr>
+    <td>std::multiset</td>
+    <td>&lt;set&gt;</td>
+    <td>__gnu_debug::multiset</td>
+    <td>&lt;debug/set&gt;</td>
+  </tr>
+  <tr>
+    <td>std::set</td>
+    <td>&lt;set&gt;</td>
+    <td>__gnu_debug::set</td>
+    <td>&lt;debug/set&gt;</td>
+  </tr>
+  <tr>
+    <td>std::string</td>
+    <td>&lt;string&gt;</td>
+    <td>__gnu_debug::string</td>
+    <td>&lt;debug/string&gt;</td>
+  </tr>
+  <tr>
+    <td>std::wstring</td>
+    <td>&lt;string&gt;</td>
+    <td>__gnu_debug::wstring</td>
+    <td>&lt;debug/string&gt;</td>
+  </tr>
+  <tr>
+    <td>std::basic_string</td>
+    <td>&lt;string&gt;</td>
+    <td>__gnu_debug::basic_string</td>
+    <td>&lt;debug/string&gt;</td>
+  </tr>
+  <tr>
+    <td>std::vector</td>
+    <td>&lt;vector&gt;</td>
+    <td>__gnu_debug::vector</td>
+    <td>&lt;debug/vector&gt;</td>
+  </tr>
+  <tr>
+    <td>__gnu_cxx::hash_map</td>
+    <td>&lt;ext/hash_map&gt;</td>
+    <td>__gnu_debug::hash_map</td>
+    <td>&lt;debug/hash_map&gt;</td>
+  </tr>
+  <tr>
+    <td>__gnu_cxx::hash_multimap</td>
+    <td>&lt;ext/hash_map&gt;</td>
+    <td>__gnu_debug::hash_multimap</td>
+    <td>&lt;debug/hash_map&gt;</td>
+  </tr>
+  <tr>
+    <td>__gnu_cxx::hash_set</td>
+    <td>&lt;ext/hash_set&gt;</td>
+    <td>__gnu_debug::hash_set</td>
+    <td>&lt;debug/hash_set&gt;</td>
+  </tr>
+  <tr>
+    <td>__gnu_cxx::hash_multiset</td>
+    <td>&lt;ext/hash_set&gt;</td>
+    <td>__gnu_debug::hash_multiset</td>
+    <td>&lt;debug/hash_set&gt;</td>
+  </tr>
+</table>
+
+<h4 class="left">Debug mode semantics</h4>
+<p>A program that does not use the C++ standard library incorrectly
+  will maintain the same semantics under debug mode as it had with
+  the normal (release) library. All functional and exception-handling
+  guarantees made by the normal library also hold for the debug mode
+  library, with one exception: performance guarantees made by the
+  normal library may not hold in the debug mode library. For
+  instance, erasing an element in a <code>std::list</code> is a
+  constant-time operation in normal library, but in debug mode it is
+  linear in the number of iterators that reference that particular
+  list. So while your (correct) program won't change its results, it 
+  is likely to execute more slowly.</p>
+
+<p>libstdc++ includes many extensions to the C++ standard library. In
+  some cases the extensions are obvious, such as the hashed
+  associative containers, whereas other extensions give predictable
+  results to behavior that would otherwise be undefined, such as
+  throwing an exception when a <code>std::basic_string</code> is
+  constructed from a NULL character pointer. This latter category also
+  includes implementation-defined and unspecified semantics, such as
+  the growth rate of a vector. Use of these extensions is not
+  considered incorrect, so code that relies on them will not be
+  rejected by debug mode. However, use of these extensions may affect
+  the portability of code to other implementations of the C++ standard
+  library, and is therefore somewhat hazardous. For this reason, the
+  libstdc++ debug mode offers a "pedantic" mode (similar to
+  GCC's <code>-pedantic</code> compiler flag) that attempts to emulate
+  the semantics guaranteed by the C++ standard. In pedantic mode, for
+  instance, constructing a <code>std::basic_string</code> with a NULL
+  character pointer would result in an exception under normal mode or
+  non-pedantic debug mode (this is a libstdc++ extension), whereas
+  under pedantic debug mode libstdc++ would signal an error. To enable
+  the pedantic debug mode, compile your program with
+  both <code>-D_GLIBCXX_DEBUG</code>
+  and <code>-D_GLIBCXX_DEBUG_PEDANTIC</code> .</p>
+
+<p>The following library components provide extra debugging
+  capabilities in debug mode:</p>
+<ul>
+  <li><code>std::bitset</code></li>
+  <li><code>std::deque</code></li>
+  <li><code>__gnu_cxx::hash_map</code></li>
+  <li><code>__gnu_cxx::hash_multimap</code></li>
+  <li><code>__gnu_cxx::hash_multiset</code></li>
+  <li><code>__gnu_cxx::hash_set</code></li>
+  <li><code>std::list</code></li>
+  <li><code>std::map</code></li>
+  <li><code>std::multimap</code></li>
+  <li><code>std::multiset</code></li>
+  <li><code>std::set</code></li>
+  <li><code>std::vector</code></li>
+</ul>
+
 
 <h3 class="left"><a name="mem">Tips for memory leak hunting</a></h3>
 
    that can be used to provide detailed memory allocation information
    about C++ code. An exhaustive list of tools is not going to be
    attempted, but includes <code>mtrace</code>, <code>valgrind</code>,
-   <code>mudflap</code>, and <code>purify</code>. Also highly
-   recommended are <code>libcwd</code> and some other one that I
-   forget right now.
+   <code>mudflap</code>, and the non-free commercial product
+   <code>purify</code>. In addition, <code>libcwd</code> has a
+   replacement for the global new and delete operators that can track
+   memory allocation and deallocation and provide useful memory
+   statistics.
 </p>
 
 <p>Regardless of the memory debugging tool being used, there is one
 
 <p>In a nutshell, the default allocator used by <code>
    std::allocator</code> is a high-performance pool allocator, and can
-   give the mistaken impression that memory is being leaked, when in
-   reality the memory is still being used by the library and is reclaimed
-   after program termination.
+   give the mistaken impression that in a suspect executable, memory
+   is being leaked, when in reality the memory "leak" is a pool being
+   used by the library's allocator and is reclaimed after program
+   termination.
 </p>
 
 <p>For valgrind, there are some specific items to keep in mind. First
    versions should work at least as well. Second of all, use a
    completely unoptimized build to avoid confusing valgrind. Third,
    use GLIBCXX_FORCE_NEW to keep extraneous pool allocation noise from
-   cluttering debug information. 
+   cluttering debug information.
 </p>
 
 <p>Fourth, it may be necessary to force deallocation in other
diff --git a/libstdc++-v3/docs/html/debug_mode.html b/libstdc++-v3/docs/html/debug_mode.html
new file mode 100644 (file)
index 0000000..6ec7c4b
--- /dev/null
@@ -0,0 +1,547 @@
+<?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="dgregor@apple.com (Doug Gregor)" />
+   <meta name="KEYWORDS" content="libstdc++, libstdc++-v3, GCC, g++, debug" />
+   <meta name="DESCRIPTION" content="Design of the libstdc++ debug mode." />
+   <meta name="GENERATOR" content="vi and eight fingers" />
+   <title>Design of the libstdc++ debug mode</title>
+<link rel="StyleSheet" href="lib3styles.css" />
+</head>
+<body>
+
+<h1 class="centered"><a name="top">Design of the libstdc++ debug 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++/debug_mode.html">
+   http://gcc.gnu.org/onlinedocs/libstdc++/debug_mode.html</a>.
+</em></p>
+
+<p><em>
+   To the <a href="http://gcc.gnu.org/libstdc++/">libstdc++-v3 homepage</a>.
+</em></p>
+
+
+<!-- ####################################################### -->
+
+<hr />
+<h1>Debug mode design</h1>
+<p> The libstdc++ debug mode replaces unsafe (but efficient) standard
+  containers and iterators with semantically equivalent safe standard
+  containers and iterators to aid in debugging user programs. The
+  following goals directed the design of the libstdc++ debug mode:</p>
+
+  <ul>
+
+    <li><b>Correctness</b>: the libstdc++ debug mode must not change
+    the semantics of the standard library for all cases specified in
+    the ANSI/ISO C++ standard. The essence of this constraint is that
+    any valid C++ program should behave in the same manner regardless
+    of whether it is compiled with debug mode or release mode. In
+    particular, entities that are defined in namespace std in release
+    mode should remain defined in namespace std in debug mode, so that
+    legal specializations of namespace std entities will remain
+    valid. A program that is not valid C++ (e.g., invokes undefined
+    behavior) is not required to behave similarly, although the debug
+    mode will abort with a diagnostic when it detects undefined
+    behavior.</li>
+
+    <li><b>Performance</b>: the additional of the libstdc++ debug mode
+    must not affect the performance of the library when it is compiled
+    in release mode. Performance of the libstdc++ debug mode is
+    secondary (and, in fact, will be worse than the release
+    mode).</li>
+
+    <li><b>Usability</b>: the libstdc++ debug mode should be easy to
+    use. It should be easily incorporated into the user's development
+    environment (e.g., by requiring only a single new compiler switch)
+    and should produce reasonable diagnostics when it detects a
+    problem with the user program. Usability also involves detection
+    of errors when using the debug mode incorrectly, e.g., by linking
+    a release-compiled object against a debug-compiled object if in
+    fact the resulting program will not run correctly.</li>
+
+    <li><b>Minimize recompilation</b>: While it is expected that
+    users recompile at least part of their program to use debug
+    mode, the amount of recompilation affects the
+    detect-compile-debug turnaround time. This indirectly affects the
+    usefulness of the debug mode, because debugging some applications
+    may require rebuilding a large amount of code, which may not be
+    feasible when the suspect code may be very localized. There are
+    several levels of conformance to this requirement, each with its
+    own usability and implementation characteristics. In general, the
+    higher-numbered conformance levels are more usable (i.e., require
+    less recompilation) but are more complicated to implement than
+    the lower-numbered conformance levels. 
+      <ol>
+       <li><b>Full recompilation</b>: The user must recompile his or
+       her entire application and all C++ libraries it depends on,
+       including the C++ standard library that ships with the
+       compiler. This must be done even if only a small part of the
+       program can use debugging features.</li>
+
+       <li><b>Full user recompilation</b>: The user must recompile
+       his or her entire application and all C++ libraries it depends
+       on, but not the C++ standard library itself. This must be done
+       even if only a small part of the program can use debugging
+       features. This can be achieved given a full recompilation
+       system by compiling two versions of the standard library when
+       the compiler is installed and linking against the appropriate
+       one, e.g., a multilibs approach.</li>
+
+       <li><b>Partial recompilation</b>: The user must recompile the
+       parts of his or her application and the C++ libraries it
+       depends on that will use the debugging facilities
+       directly. This means that any code that uses the debuggable
+       standard containers would need to be recompiled, but code
+       that does not use them (but may, for instance, use IOStreams)
+       would not have to be recompiled.</li>
+
+       <li><b>Per-use recompilation</b>: The user must recompile the
+       parts of his or her application and the C++ libraries it
+       depends on where debugging should occur, and any other code
+       that interacts with those containers. This means that a set of
+       translation units that accesses a particular standard
+       container instance may either be compiled in release mode (no
+       checking) or debug mode (full checking), but must all be
+       compiled in the same way; a translation unit that does not see
+       that standard container instance need not be recompiled. This
+       also means that a translation unit <em>A</em> that contains a
+       particular instantiation
+       (say, <code>std::vector&lt;int&gt;</code>) compiled in release
+       mode can be linked against a translation unit <em>B</em> that
+       contains the same instantiation compiled in debug mode (a
+       feature not present with partial recompilation). While this
+       behavior is technically a violation of the One Definition
+       Rule, this ability tends to be very important in
+       practice. The libstdc++ debug mode supports this level of
+       recompilation. </li>
+
+       <li><b>Per-unit recompilation</b>: The user must only
+       recompile the translation units where checking should occur,
+       regardless of where debuggable standard containers are
+       used. This has also been dubbed "<code>-g</code> mode",
+       because the <code>-g</code> compiler switch works in this way,
+       emitting debugging information at a per--translation-unit
+       granularity. We believe that this level of recompilation is in
+       fact not possible if we intend to supply safe iterators, leave
+       the program semantics unchanged, and not regress in
+       performance under release mode because we cannot associate
+       extra information with an iterator (to form a safe iterator)
+       without either reserving that space in release mode
+       (performance regression) or allocating extra memory associated
+       with each iterator with <code>new</code> (changes the program
+       semantics).</li>
+      </ol>
+    </li>
+  </ul>
+
+<h2><a name="other">Other implementations</a></h2>
+<p> There are several existing implementations of debug modes for C++
+  standard library implementations, although none of them directly
+  supports debugging for programs using libstdc++. The existing
+  implementations include:</p>
+<ul>
+  <li><a
+  href="http://www.mathcs.sjsu.edu/faculty/horstman/safestl.html">SafeSTL</a>:
+  SafeSTL was the original debugging version of the Standard Template
+  Library (STL), implemented by Cay S. Horstmann on top of the
+  Hewlett-Packard STL. Though it inspired much work in this area, it
+  has not been kept up-to-date for use with modern compilers or C++
+  standard library implementations.</li>
+
+  <li><a href="http://www.stlport.org/">STLport</a>: STLport is a free
+  implementation of the C++ standard library derived from the <a
+  href="http://www.sgi.com/tech/stl/">SGI implementation</a>, and
+  ported to many other platforms. It includes a debug mode that uses a
+  wrapper model (that in some way inspired the libstdc++ debug mode
+  design), although at the time of this writing the debug mode is
+  somewhat incomplete and meets only the "Full user recompilation" (2)
+  recompilation guarantee by requiring the user to link against a
+  different library in debug mode vs. release mode.</li>
+
+  <li><a href="http://www.metrowerks.com/mw/default.htm">Metrowerks
+  CodeWarrior</a>: The C++ standard library that ships with Metrowerks
+  CodeWarrior includes a debug mode. It is a full debug-mode
+  implementation (including debugging for CodeWarrior extensions) and
+  is easy to use, although it meets only the "Full recompilation" (1)
+  recompilation guarantee.</li>
+</ul>
+
+<h2><a name="design">Debug mode design methodology</a></h2>
+<p>This section provides an overall view of the design of the
+  libstdc++ debug mode and details the relationship between design
+  decisions and the stated design goals.</p>
+
+<h3><a name="wrappers">The wrapper model</a></h3>
+<p>The libstdc++ debug mode uses a wrapper model where the debugging
+  versions of library components (e.g., iterators and containers) form
+  a layer on top of the release versions of the library
+  components. The debugging components first verify that the operation
+  is correct (aborting with a diagnostic if an error is found) and
+  will then forward to the underlying release-mode container that will
+  perform the actual work. This design decision ensures that we cannot
+  regress release-mode performance (because the release-mode
+  containers are left untouched) and partially enables <a
+  href="#mixing">mixing debug and release code</a> at link time,
+  although that will not be discussed at this time.</p>
+
+<p>Two types of wrappers are used in the implementation of the debug
+  mode: container wrappers and iterator wrappers. The two types of
+  wrappers interact to maintain relationships between iterators and
+  their associated containers, which are necessary to detect certain
+  types of standard library usage errors such as dereferencing
+  past-the-end iterators or inserting into a container using an
+  iterator from a different container.</p>
+
+<h4><a name="safe_iterator">Safe iterators</a></h4>
+<p>Iterator wrappers provide a debugging layer over any iterator that
+  is attached to a particular container, and will manage the
+  information detailing the iterator's state (singular,
+  dereferenceable, etc.) and tracking the container to which the
+  iterator is attached. Because iterators have a well-defined, common
+  interface the iterator wrapper is implemented with the iterator
+  adaptor class template <code>__gnu_debug::_Safe_iterator</code>,
+  which takes two template parameters:</p>
+
+<ul>
+  <li><code>Iterator</code>: The underlying iterator type, which must
+    be either the <code>iterator</code> or <code>const_iterator</code>
+    typedef from the sequence type this iterator can reference.</li>
+  
+  <li><code>Sequence</code>: The type of sequence that this iterator
+  references. This sequence must be a safe sequence (discussed below)
+  whose <code>iterator</code> or <code>const_iterator</code> typedef
+  is the type of the safe iterator.</li>
+</ul>
+
+<h4><a name="safe_sequence">Safe sequences (containers)</a></h4>
+<p>Container wrappers provide a debugging layer over a particular
+  container type. Because containers vary greatly in the member
+  functions they support and the semantics of those member functions
+  (especially in the area of iterator invalidation), container
+  wrappers are tailored to the container they reference, e.g., the
+  debugging version of <code>std::list</code> duplicates the entire
+  interface of <code>std::list</code>, adding additional semantic
+  checks and then forwarding operations to the
+  real <code>std::list</code> (a public base class of the debugging
+  version) as appropriate. However, all safe containers inherit from
+  the class template <code>__gnu_debug::_Safe_sequence</code>,
+  instantiated with the type of the safe container itself (an instance
+  of the curiously recurring template pattern).</p>
+
+<p>The iterators of a container wrapper will be 
+  <a href="#safe_iterator">safe iterators</a> that reference sequences
+  of this type and wrap the iterators provided by the release-mode
+  base class. The debugging container will use only the safe
+  iterators within its own interface (therefore requiring the user to
+  use safe iterators, although this does not change correct user
+  code) and will communicate with the release-mode base class with
+  only the underlying, unsafe, release-mode iterators that the base
+  class exports.</p>
+
+<p> The debugging version of <code>std::list</code> will have the
+  following basic structure:</p>
+
+<pre>
+template&lt;typename _Tp, typename _Allocator = std::allocator&lt;_Tp&gt;
+  class debug-list :
+    public release-list&lt;_Tp, _Allocator&gt;,
+    public __gnu_debug::_Safe_sequence&lt;debug-list&lt;_Tp, _Allocator&gt; &gt;
+  {
+    typedef release-list&lt;_Tp, _Allocator&gt; _Base;
+    typedef debug-list&lt;_Tp, _Allocator&gt;   _Self;
+
+  public:
+    typedef __gnu_debug::_Safe_iterator&lt;typename _Base::iterator, _Self&gt;       iterator;
+    typedef __gnu_debug::_Safe_iterator&lt;typename _Base::const_iterator, _Self&gt; const_iterator;
+
+    // duplicate std::list interface with debugging semantics
+  };
+</pre>
+
+<h3><a name="precondition">Precondition checking</a></h3>
+<p>The debug mode operates primarily by checking the preconditions of
+  all standard library operations that it supports. Preconditions that
+  are always checked (regardless of whether or not we are in debug
+  mode) are checked via the <code>__check_xxx</code> macros defined
+  and documented in the source
+  file <code>include/debug/debug.h</code>. Preconditions that may or
+  may not be checked, depending on the debug-mode
+  macro <code>_GLIBCXX_DEBUG</code>, are checked via
+  the <code>__requires_xxx</code> macros defined and documented in the
+  same source file. Preconditions are validated using any additional
+  information available at run-time, e.g., the containers that are
+  associated with a particular iterator, the position of the iterator
+  within those containers, the distance between two iterators that may
+  form a valid range, etc. In the absence of suitable information,
+  e.g., an input iterator that is not a safe iterator, these
+  precondition checks will silently succeed.</p>
+
+<p>The majority of precondition checks use the aforementioned macros,
+  which have the secondary benefit of having prewritten debug
+  messages that use information about the current status of the
+  objects involved (e.g., whether an iterator is singular or what
+  sequence it is attached to) along with some static information
+  (e.g., the names of the function parameters corresponding to the
+  objects involved). When not using these macros, the debug mode uses
+  either the debug-mode assertion
+  macro <code>_GLIBCXX_DEBUG_ASSERT</code> , its pedantic
+  cousin <code>_GLIBCXX_DEBUG_PEDASSERT</code>, or the assertion
+  check macro that supports more advance formulation of error
+  messages, <code>_GLIBCXX_DEBUG_VERIFY</code>. These macros are
+  documented more thoroughly in the debug mode source code.</p>
+
+<h3><a name="coexistence">Release- and debug-mode coexistence</a></h3>
+<p>The libstdc++ debug mode is the first debug mode we know of that
+  is able to provide the "Per-use recompilation" (4) guarantee, that
+  allows release-compiled and debug-compiled code to be linked and
+  executed together without causing unpredictable behavior. This
+  guarantee minimizes the recompilation that users are required to
+  perform, shortening the detect-compile-debug bughunting cycle
+  and making the debug mode easier to incorporate into development
+  environments by minimizing dependencies.</p>
+
+<p>Achieving link- and run-time coexistence is not a trivial
+  implementation task. To achieve this goal we required a small
+  extension to the GNU C++ compiler (described in the section on
+  <a href="#mixing">link- and run-time coexistence</a>) and complex
+  organization of debug- and release-modes. The end result is that we
+  have achieved per-use recompilation but have had to give up some
+  checking of the <code>std::basic_string</code> class template
+  (namely, safe iterators).
+
+<h4><a name="compile_coexistence">Compile-time coexistence of release- and
+    debug-mode components</a></h4>
+<p>Both the release-mode components and the debug-mode
+  components need to exist within a single translation unit so that
+  the debug versions can wrap the release versions. However, only one
+  of these components should be user-visible at any particular
+  time with the standard name, e.g., <code>std::list</code>. In
+  release mode, we define only the release-mode version of the
+  component with its standard name and do not include the debugging
+  component at all (except, perhaps, in <code>__gnu_debug</code>, if
+  requested via the separate debugging headers). This method leaves the
+  behavior of release mode completely unchanged from its behavior
+  prior to the introduction of the libstdc++ debug mode.</p>
+
+<p>In debug mode we include the release-mode container into its
+  natural namespace but perform renaming to an implementation-defined
+  name using preprocessor macros. Thus the
+  release-mode <code>std::list</code> will be renamed
+  to <code>std::_Release_list</code> during debug mode, and we will
+  automatically include the debugging version with the
+  name <code>std::list</code> for users to reference. This method
+  allows the debug- and release-mode versions of the same component to
+  coexist at compile-time without causing an unreasonable maintenance
+  burden.</p>
+
+<h4><a name="mixing">Link- and run-time coexistence of release- and
+    debug-mode components</a></h4>
+<p>There is a problem with the simple compile-time coexistence
+  mechanism: if a user compiles some modules with release mode and
+  some modules with debug mode, the debuggable components will differ
+  in different translation units, violating the C++ One Definition
+  Rule (ODR). This violation will likely be detected at link time,
+  because the sizes of debug-mode containers will differ from the
+  sizes of release-mode containers, although in some cases (such as
+  dynamic linking) the error may be detected much later (or not at
+  all!).</p>
+
+<p>Unfortunately, it is not possible to avoid violating the ODR with
+  most debug mode designs (see the section on <a
+  href="#coexistence_alt">alternatives for coexistence</a>), so the
+  philosophy of the libstdc++ debug mode is to acknowledge that there
+  is an unavoidable ODR violation in this case but to ensure that the
+  ODR violation does not affect execution. To accomplish this, the
+  libstdc++ debug mode uses the aforementioned preprocessor renaming
+  scheme but includes an additional renaming scheme that happens at
+  compile-time that essentially reverses the preprocessor
+  renaming <em>from the linker's point of view</em>. Thus, in debug
+  mode, the release-mode <code>list</code> container is
+  named <code>std::_Release_list</code> but will be mangled with the
+  name <code>std::list</code> (as it was in release mode). Similarly,
+  the debug-mode <code>list</code> is named <code>std::list</code>
+  (in debug mode) but will be mangled
+  as <code>std::_Debug_list</code>. Thus the
+  release-mode <code>list</code> always compiles down to code that
+  uses the name <code>std::list</code>, and the
+  debug-mode <code>list</code> always compiles down to code that uses
+  the name <code>std::_Debug_list</code>, independent of the use of
+  debug mode. This has several positive effects:</p>
+
+<ul>
+  <li>No linking conflicts between debug/release objects: because the
+  names of the debug- and release-mode containers are different in the
+  compiled object files, there are no link-time conflicts between the
+  two.</li>
+
+  <li>Release-mode code is shared: the release-mode code can be shared
+  within a program, even with it is compiled partly in release-mode
+  and partly in debug-mode, because the release-mode code is unchanged
+  in name and function. This can decrease the size of mixed
+  debug/release binaries.</li>
+
+  <li>Able to catch <em>most</em> invalid debug/release combinations:
+  because the names of debug- and release-mode containers are
+  different in the compiled object files, if a debug/release
+  interaction cannot occur (e.g., because a container a translation
+  unit compiled in debug mode is passed to a routine in a translation
+  unit compiled in release mode) the result will be an undefined
+  symbol at link time. The undefined symbol occurs because the mangled
+  name of the definition will contain the release-mode container type
+  and the mangled name of the reference will contain the debug-mode
+  container type. However, we cannot detect these collisions if the
+  only use of the container is in the return type, because the return
+  type is not part of the mangled name of a function.</li>
+</ul>
+
+<p>The new <code>link_name</code> class attribute facilities
+  renaming. It may be attached to any class type (or any class
+  template) to override the name of the class used for name
+  mangling. For instance, a class named <code>bar</code> would
+  generally mangle as <code>3bar</code>; if the class has
+  a <code>link_name</code> attribute that specifies the string
+  "wibble", then it would mangle as <code>6wibble</code>.</p>
+
+<p>Note that although we have hidden the ODR violation, it still
+  exists. For this reason we cannot easily provide safe iterators for
+  the <code>std::basic_string</code> class template, as it is present
+  throughout the C++ standard library. For instance, locale facets
+  define typedefs that include <code>basic_string</code>: in a mixed
+  debug/release program, should that typedef be based on the
+  debug-mode <code>basic_string</code> or the
+  release-mode <code>basic_string</code>? While the answer could be
+  "both", and the difference hidden via renaming a la the
+  debug/release containers, we must note two things about locale
+  facets:</p>
+
+<ol>
+  <li>They exist as shared state: one can create a facet in one
+  translation unit and access the facet via the same type name in a
+  different translation unit. This means that we cannot have two
+  different versions of locale facets, because the types would not be
+  the same across debug/release-mode translation unit barriers.</li>
+
+  <li>They have virtual functions returning strings: these functions
+  mangle in the same way regardless of the mangling of their return
+  types (see above), and their precise signatures can be relied upon
+  by users because they may be overridden in derived classes.
+</ol>
+
+<p>With the design of libstdc++ debug mode, we cannot effectively hide
+  the differences between debug and release-mode strings from the
+  user. Failure to hide the differences may result in unpredictable
+  behavior, and for this reason we have opted to only
+  perform <code>basic_string</code> changes that do not require ABI
+  changes. The effect on users is expected to be minimal, as there are
+  simple alternatives (e.g., <code>__gnu_debug::basic_string</code>),
+  and the usability benefit we gain from the ability to mix debug- and
+  release-compiled translation units is enormous.</p>
+
+<h4><a name="coexistence_alt">Alternatives for Coexistence</a></h4>
+<p>The coexistence scheme was chosen over many alternatives,
+  including language-only solutions and solutions that also required
+  extensions to the C++ front end. The following is a partial list of
+  solutions, with justifications for our rejection of each.</p>
+
+<ul>
+  <li><em>Completely separate debug/release libraries</em>: This is by
+  far the simplest implementation option, where we do not allow any
+  coexistence of debug- and release-compiled translation units in a
+  program. This solution has an extreme negative affect on usability,
+  because it is quite likely that some libraries an application
+  depends on cannot be recompiled easily. This would not meet
+  our <b>usability</b> or <b>minimize recompilation</b> criteria
+  well.</li>
+
+  <li><em>Add a <code>Debug</code> boolean template parameter</em>:
+  Partial specialization could be used to select the debug
+  implementation when <code>Debug == true</code>, and the state
+  of <code>_GLIBCXX_DEBUG</code> could decide whether the
+  default <code>Debug</code> argument is <code>true</code>
+  or <code>false</code>. This option would break conformance with the
+  C++ standard in both debug <em>and</em> release modes. This would
+  not meet our <b>correctness</b> criteria. </li>
+
+  <li><em>Packaging a debug flag in the allocators</em>: We could
+    reuse the <code>Allocator</code> template parameter of containers
+    by adding a sentinel wrapper <code>debug&lt;&gt;</code> that
+    signals the user's intention to use debugging, and pick up
+    the <code>debug&lr;&gt;</code> allocator wrapper in a partial
+    specialization. However, this has two drawbacks: first, there is a
+    conformance issue because the default allocator would not be the
+    standard-specified <code>std::allocator&lt;T&gt;</code>. Secondly
+    (and more importantly), users that specify allocators instead of
+    implicitly using the default allocator would not get debugging
+    containers. Thus this solution fails the <b>correctness</b>
+    criteria.</li>
+
+  <li><em>Define debug containers in another namespace, and employ
+      a <code>using</code> declaration (or directive)</em>: This is an
+      enticing option, because it would eliminate the need for
+      the <code>link_name</code> extension by aliasing the
+      templates. However, there is no true template aliasing mechanism
+      is C++, because both <code>using</code> directives and using
+      declarations disallow specialization. This method fails
+      the <b>correctness</b> criteria.</li>
+
+  <li><em>Extension: allow template aliasing/renaming</em>: This is
+    the runner-up to the <code>link_name</code> solution, eliminated
+    only because it requires more extensive compiler changes
+    than <code>link_name</code>. In this model, we would define the
+    debug containers in a different namespace
+    (e.g., <code>__gnu_debug</code>) and then import them (e.g., with
+    an extended <code>using</code> declaration that aliases templates,
+    such as that of <a
+    href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1449.pdf">template
+    aliases</a> proposal). This solution is workable, and in fact
+    would be desirable in the long run, but requires a sizeable change
+    to the C++ compiler front-end that is not within the scope of
+    this project.</li>
+
+  <li><em>Extension: allow reopening on namespaces</em>: This would
+    allow the debug mode to effectively alias the
+    namespace <code>std</code> to an internal namespace, such
+    as <code>__gnu_std_debug</code>, so that it is completely
+    separate from the release-mode <code>std</code> namespace. While
+    this will solve some renaming problems and ensure that
+    debug- and release-compiled code cannot be mixed unsafely, it ensures that
+    debug- and release-compiled code cannot be mixed at all. For
+    instance, the program would have two <code>std::cout</code>
+    objects! This solution would fails the <b>minimize
+    recompilation</b> requirement, because we would only be able to
+    support option (1) or (2).</li>
+  </li>
+</ul>
+
+<p>Other options may exist for implementing the debug mode, many of
+  which have probably been considered and others that may still be
+  lurking. This list may be expanded over time to include other
+  options that we could have implemented, but in all cases the full
+  ramifications of the approach (as measured against the design goals
+  for a libstdc++ debug mode) should be considered first. The DejaGNU
+  testsuite includes some testcases that check for known problems with
+  some solutions (e.g., the <code>using</code> declaration solution
+  that breaks user specialization), and additional testcases will be
+  added as we are able to identify other typical problem cases. These
+  test cases will serve as a benchmark by which we can compare debug
+  mode implementations.</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 07d585f..6fb2c3a 100644 (file)
@@ -34,6 +34,7 @@
    <li><a href="#util">Utilities: abicheck and libv3test</a></li>
    <li><a href="#new">How to write a new test case</a></li>
    <li><a href="#check">Options for running the tests</a></li>
+   <li><a href="#debug">Running debug-mode tests</a></li>
    <li><a href="#future">Future</a></li>
    <li><a href="#internals">DejaGNU internals</a></li>
 </ul>
@@ -544,6 +545,19 @@ make check-target-libstdc++-v3 RUNTESTFLAGS="--target_board=arm-sim"
       for which files to examine.
    </p>
 
+<hr/>
+<h2><a name="debug">Running debug-mode tests</a></h2>
+<p>To run the libstdc++ test suite under the <a
+  href="debug.html#safe">debug mode</a>,
+  edit <code>libstdc++/scripts/testsuite_flags</code> to add the
+  compile-time flag <code>-D_GLIBCXX_DEBUG</code> to the result
+  printed by the <code>--build-cxx</code> option. Additionally, add
+  the <code>-D_GLIBCXX_DEBUG_PEDANTIC</code> flag to turn on pedantic
+  checking. The libstdc++ test suite should produce precisely the same
+  results under debug mode that it does under release mode: any
+  deviation indicates an error in either the library or the test
+  suite.</p>
+
 <hr />
 <h2><a name="future">Future</a></h2>
 
index 862b0a3..3af38b3 100644 (file)
@@ -224,7 +224,6 @@ ext_headers = \
        ${ext_srcdir}/hash_fun.h \
        ${ext_srcdir}/hashtable.h
 
-
 # This is the common subset of files that all three "C" header models use.
 c_base_srcdir = $(C_INCLUDE_DIR)
 c_base_builddir = .
@@ -290,6 +289,34 @@ c_compatibility_headers = \
        ${c_compatibility_srcdir}/wchar.h \
        ${c_compatibility_srcdir}/wctype.h
 
+# Debug mode headers
+debug_srcdir = ${glibcxx_srcdir}/include/debug
+debug_builddir = ./debug
+debug_headers = \
+       ${debug_srcdir}/bitset \
+       ${debug_srcdir}/debug.h \
+       ${debug_srcdir}/deque \
+       ${debug_srcdir}/formatter.h \
+       ${debug_srcdir}/hash_map \
+       ${debug_srcdir}/hash_map.h \
+       ${debug_srcdir}/hash_multimap.h \
+       ${debug_srcdir}/hash_multiset.h \
+       ${debug_srcdir}/hash_set \
+       ${debug_srcdir}/hash_set.h \
+       ${debug_srcdir}/list \
+       ${debug_srcdir}/map \
+       ${debug_srcdir}/map.h \
+       ${debug_srcdir}/multimap.h \
+       ${debug_srcdir}/multiset.h \
+       ${debug_srcdir}/safe_base.h \
+       ${debug_srcdir}/safe_iterator.h \
+       ${debug_srcdir}/safe_iterator.tcc \
+       ${debug_srcdir}/safe_sequence.h \
+       ${debug_srcdir}/set \
+       ${debug_srcdir}/set.h \
+       ${debug_srcdir}/string \
+       ${debug_srcdir}/vector
+
 # Some of the different "C" header models need extra files.
 # Some "C" header schemes require the "C" compatibility headers.
 # For --enable-cheaders=c_std
@@ -350,7 +377,7 @@ endif
 # CLEANFILES and all-local are kept up-to-date.
 allstamped = \
        stamp-std stamp-bits stamp-c_base stamp-c_compatibility \
-       stamp-backward stamp-ext stamp-host
+       stamp-backward stamp-ext stamp-debug stamp-host
 
 # List of all files that are created by explicit building, editing, or
 # catenation.
@@ -429,6 +456,15 @@ stamp-ext: ${ext_headers}
        fi ;\
        $(STAMP) stamp-ext
 
+stamp-debug: ${debug_headers}
+       @if [ ! -d "${debug_builddir}" ]; then \
+         mkdir -p ${debug_builddir} ;\
+       fi ;\
+       if [ ! -f stamp-debug ]; then \
+         (cd ${debug_builddir} && @LN_S@ $? . || true) ;\
+       fi ;\
+       $(STAMP) stamp-debug
+
 stamp-${host_alias}:
        @if [ ! -d ${host_builddir} ]; then \
          mkdir -p ${host_builddir} ;\
@@ -556,6 +592,9 @@ install-headers:
        $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${std_builddir}
        for file in ${std_headers_rename}; do \
          $(INSTALL_DATA) ${std_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${std_builddir}; done
+       $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${debug_builddir}
+       for file in ${debug_headers}; do \
+         $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${debug_builddir}; done
        $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${host_builddir}
        for file in ${host_headers} ${host_headers_extra} \
         ${thread_host_headers}; do \
index 1db9bfc..cf40dcf 100644 (file)
@@ -491,11 +491,40 @@ c_compatibility_headers = \
        ${c_compatibility_srcdir}/wctype.h
 
 
+# Debug mode headers
+debug_srcdir = ${glibcxx_srcdir}/include/debug
+debug_builddir = ./debug
+debug_headers = \
+       ${debug_srcdir}/bitset \
+       ${debug_srcdir}/debug.h \
+       ${debug_srcdir}/deque \
+       ${debug_srcdir}/formatter.h \
+       ${debug_srcdir}/hash_map \
+       ${debug_srcdir}/hash_map.h \
+       ${debug_srcdir}/hash_multimap.h \
+       ${debug_srcdir}/hash_multiset.h \
+       ${debug_srcdir}/hash_set \
+       ${debug_srcdir}/hash_set.h \
+       ${debug_srcdir}/list \
+       ${debug_srcdir}/map \
+       ${debug_srcdir}/map.h \
+       ${debug_srcdir}/multimap.h \
+       ${debug_srcdir}/multiset.h \
+       ${debug_srcdir}/safe_base.h \
+       ${debug_srcdir}/safe_iterator.h \
+       ${debug_srcdir}/safe_iterator.tcc \
+       ${debug_srcdir}/safe_sequence.h \
+       ${debug_srcdir}/set \
+       ${debug_srcdir}/set.h \
+       ${debug_srcdir}/string \
+       ${debug_srcdir}/vector
+
+@GLIBCXX_C_HEADERS_C_STD_FALSE@c_base_headers_extra = 
+
 # Some of the different "C" header models need extra files.
 # Some "C" header schemes require the "C" compatibility headers.
 # For --enable-cheaders=c_std
 @GLIBCXX_C_HEADERS_C_STD_TRUE@c_base_headers_extra = ${c_base_srcdir}/cmath.tcc
-@GLIBCXX_C_HEADERS_C_STD_FALSE@c_base_headers_extra = 
 @GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE@c_compatibility_headers_extra = 
 
 @GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE@c_compatibility_headers_extra = ${c_compatibility_headers}
@@ -546,7 +575,7 @@ PCHFLAGS = -Winvalid-pch -Wno-deprecated -x c++-header $(CXXFLAGS)
 # CLEANFILES and all-local are kept up-to-date.
 allstamped = \
        stamp-std stamp-bits stamp-c_base stamp-c_compatibility \
-       stamp-backward stamp-ext stamp-host
+       stamp-backward stamp-ext stamp-debug stamp-host
 
 
 # List of all files that are created by explicit building, editing, or
@@ -783,6 +812,15 @@ stamp-ext: ${ext_headers}
        fi ;\
        $(STAMP) stamp-ext
 
+stamp-debug: ${debug_headers}
+       @if [ ! -d "${debug_builddir}" ]; then \
+         mkdir -p ${debug_builddir} ;\
+       fi ;\
+       if [ ! -f stamp-debug ]; then \
+         (cd ${debug_builddir} && @LN_S@ $? . || true) ;\
+       fi ;\
+       $(STAMP) stamp-debug
+
 stamp-${host_alias}:
        @if [ ! -d ${host_builddir} ]; then \
          mkdir -p ${host_builddir} ;\
@@ -904,6 +942,9 @@ install-headers:
        $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${std_builddir}
        for file in ${std_headers_rename}; do \
          $(INSTALL_DATA) ${std_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${std_builddir}; done
+       $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${debug_builddir}
+       for file in ${debug_headers}; do \
+         $(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${debug_builddir}; done
        $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${host_builddir}
        for file in ${host_headers} ${host_headers_extra} \
         ${thread_host_headers}; do \
index 44df752..7b1ba5c 100644 (file)
@@ -43,6 +43,7 @@
 #pragma GCC system_header
 
 #include <bits/atomicity.h>
+#include <debug/debug.h>
 
 namespace std
 {
@@ -608,7 +609,10 @@ namespace std
        */
       const_reference
       operator[] (size_type __pos) const
-      { return _M_data()[__pos]; }
+      { 
+       _GLIBCXX_DEBUG_ASSERT(__pos <= size());
+       return _M_data()[__pos]; 
+      }
 
       /**
        *  @brief  Subscript access to the data contained in the %string.
@@ -623,6 +627,7 @@ namespace std
       reference
       operator[](size_type __pos)
       {
+       _GLIBCXX_DEBUG_ASSERT(__pos < size());
        _M_leak();
        return _M_data()[__pos];
       }
@@ -729,7 +734,10 @@ namespace std
        */
       basic_string&
       append(const _CharT* __s)
-      { return this->append(__s, traits_type::length(__s)); }
+      { 
+       __glibcxx_requires_string(__s);
+       return this->append(__s, traits_type::length(__s)); 
+      }
 
       /**
        *  @brief  Append multiple characters.
@@ -810,7 +818,10 @@ namespace std
        */
       basic_string&
       assign(const _CharT* __s)
-      { return this->assign(__s, traits_type::length(__s)); }
+      { 
+       __glibcxx_requires_string(__s);
+       return this->assign(__s, traits_type::length(__s)); 
+      }
 
       /**
        *  @brief  Set value to multiple characters.
@@ -942,7 +953,10 @@ namespace std
       */
       basic_string&
       insert(size_type __pos, const _CharT* __s)
-      { return this->insert(__pos, __s, traits_type::length(__s)); }
+      { 
+       __glibcxx_requires_string(__s);
+       return this->insert(__pos, __s, traits_type::length(__s)); 
+      }
 
       /**
        *  @brief  Insert multiple characters.
@@ -983,6 +997,7 @@ namespace std
       iterator
       insert(iterator __p, _CharT __c)
       {
+       _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
        const size_type __pos = __p - _M_ibegin();
        this->insert(_M_check(__pos), size_type(1), __c);
        _M_rep()->_M_set_leaked();
@@ -1043,6 +1058,8 @@ namespace std
       iterator
       erase(iterator __position)
       {
+       _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin() 
+                                && __position < _M_iend());
        const size_type __i = __position - _M_ibegin();
         this->replace(__position, __position + 1, _M_data(), _M_data());
        _M_rep()->_M_set_leaked();
@@ -1064,6 +1081,8 @@ namespace std
       iterator
       erase(iterator __first, iterator __last)
       {
+       _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last
+                                && __last <= _M_iend());
         const size_type __i = __first - _M_ibegin();
        this->replace(__first, __last, _M_data(), _M_data());
        _M_rep()->_M_set_leaked();
@@ -1150,7 +1169,10 @@ namespace std
       */
       basic_string&
       replace(size_type __pos, size_type __n1, const _CharT* __s)
-      { return this->replace(__pos, __n1, __s, traits_type::length(__s)); }
+      { 
+       __glibcxx_requires_string(__s);
+       return this->replace(__pos, __n1, __s, traits_type::length(__s)); 
+      }
 
       /**
        *  @brief  Replace characters with multiple characters.
@@ -1187,7 +1209,11 @@ namespace std
       */
       basic_string&
       replace(iterator __i1, iterator __i2, const basic_string& __str)
-      { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
+      { 
+       _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+                                && __i2 <= _M_iend());
+       return this->replace(__i1, __i2, __str._M_data(), __str.size()); 
+      }
 
       /**
        *  @brief  Replace range of characters with C substring.
@@ -1205,7 +1231,7 @@ namespace std
       */
       basic_string&
       replace(iterator __i1, iterator __i2,
-                           const _CharT* __s, size_type __n)
+             const _CharT* __s, size_type __n)
       { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); }
 
       /**
@@ -1223,7 +1249,12 @@ namespace std
       */
       basic_string&
       replace(iterator __i1, iterator __i2, const _CharT* __s)
-      { return this->replace(__i1, __i2, __s, traits_type::length(__s)); }
+      { 
+       _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+                                && __i2 <= _M_iend());
+       __glibcxx_requires_string(__s);
+       return this->replace(__i1, __i2, __s, traits_type::length(__s)); 
+      }
 
       /**
        *  @brief  Replace range of characters with multiple characters
@@ -1241,7 +1272,11 @@ namespace std
       */
       basic_string&
       replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
-      { return _M_replace_aux(__i1, __i2, __n, __c); }
+      { 
+       _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+                                && __i2 <= _M_iend());
+       return _M_replace_aux(__i1, __i2, __n, __c); 
+      }
 
       /**
        *  @brief  Replace range of characters with range.
@@ -1261,30 +1296,55 @@ namespace std
         basic_string&
         replace(iterator __i1, iterator __i2,
                _InputIterator __k1, _InputIterator __k2)
-        { typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
-         return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral()); }
+        { 
+         _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+                                  && __i2 <= _M_iend());
+         __glibcxx_requires_valid_range(__k1, __k2);
+         typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+         return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral()); 
+       }
 
       // Specializations for the common case of pointer and iterator:
       // useful to avoid the overhead of temporary buffering in _M_replace.
       basic_string&
-      replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2)
-        { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
-                              __k1, __k2 - __k1); }
+        replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2)
+        { 
+         _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+                                  && __i2 <= _M_iend());
+         __glibcxx_requires_valid_range(__k1, __k2);
+         return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+                              __k1, __k2 - __k1); 
+       }
 
       basic_string&
-      replace(iterator __i1, iterator __i2, const _CharT* __k1, const _CharT* __k2)
-        { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
-                              __k1, __k2 - __k1); }
+        replace(iterator __i1, iterator __i2, 
+               const _CharT* __k1, const _CharT* __k2)
+        { 
+         _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+                                  && __i2 <= _M_iend());
+         __glibcxx_requires_valid_range(__k1, __k2);
+         return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+                              __k1, __k2 - __k1); 
+       }
 
       basic_string&
-      replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)
-        { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+        replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)
+        { 
+         _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+                                  && __i2 <= _M_iend());
+         __glibcxx_requires_valid_range(__k1, __k2);
+         return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
                               __k1.base(), __k2 - __k1);
        }
 
       basic_string&
-      replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2)
-        { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+        replace(iterator __i1, iterator __i2, 
+               const_iterator __k1, const_iterator __k2)
+        { 
+         _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+                                  && __i2 <= _M_iend());
+         __glibcxx_requires_valid_range(__k1, __k2);
+         return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
                               __k1.base(), __k2 - __k1);
        }
 
@@ -1459,7 +1519,10 @@ namespace std
       */
       size_type
       find(const _CharT* __s, size_type __pos = 0) const
-      { return this->find(__s, __pos, traits_type::length(__s)); }
+      { 
+       __glibcxx_requires_string(__s);
+       return this->find(__s, __pos, traits_type::length(__s)); 
+      }
 
       /**
        *  @brief  Find position of a character.
@@ -1514,7 +1577,10 @@ namespace std
       */
       size_type
       rfind(const _CharT* __s, size_type __pos = npos) const
-      { return this->rfind(__s, __pos, traits_type::length(__s)); }
+      { 
+       __glibcxx_requires_string(__s);
+       return this->rfind(__s, __pos, traits_type::length(__s)); 
+      }
 
       /**
        *  @brief  Find last position of a character.
@@ -1569,7 +1635,10 @@ namespace std
       */
       size_type
       find_first_of(const _CharT* __s, size_type __pos = 0) const
-      { return this->find_first_of(__s, __pos, traits_type::length(__s)); }
+      { 
+       __glibcxx_requires_string(__s);
+       return this->find_first_of(__s, __pos, traits_type::length(__s)); 
+      }
 
       /**
        *  @brief  Find position of a character.
@@ -1627,7 +1696,10 @@ namespace std
       */
       size_type
       find_last_of(const _CharT* __s, size_type __pos = npos) const
-      { return this->find_last_of(__s, __pos, traits_type::length(__s)); }
+      { 
+       __glibcxx_requires_string(__s);
+       return this->find_last_of(__s, __pos, traits_type::length(__s)); 
+      }
 
       /**
        *  @brief  Find last position of a character.
@@ -1686,7 +1758,10 @@ namespace std
       */
       size_type
       find_first_not_of(const _CharT* __s, size_type __pos = 0) const
-      { return this->find_first_not_of(__s, __pos, traits_type::length(__s)); }
+      { 
+       __glibcxx_requires_string(__s);
+       return this->find_first_not_of(__s, __pos, traits_type::length(__s)); 
+      }
 
       /**
        *  @brief  Find position of a different character.
@@ -1742,7 +1817,10 @@ namespace std
       */
       size_type
       find_last_not_of(const _CharT* __s, size_type __pos = npos) const
-      { return this->find_last_not_of(__s, __pos, traits_type::length(__s)); }
+      { 
+       __glibcxx_requires_string(__s);
+       return this->find_last_not_of(__s, __pos, traits_type::length(__s)); 
+      }
 
       /**
        *  @brief  Find last position of a different character.
@@ -2197,7 +2275,6 @@ namespace std
             const basic_string<_CharT, _Traits, _Alloc>& __rhs)
     { return __rhs.compare(__lhs) <= 0; }
 
-
   /**
    *  @brief  Swap contents of two strings.
    *  @param lhs  First string.
index ecd8f71..34a373c 100644 (file)
 
 namespace std
 {
+  template<typename _Type>
+    inline bool
+    __is_null_pointer(_Type* __ptr)
+    { return __ptr == 0; }
+
+  template<typename _Type>
+    inline bool
+    __is_null_pointer(const _Type&)
+    { return false; }
+
   template<typename _CharT, typename _Traits, typename _Alloc>
     const typename basic_string<_CharT, _Traits, _Alloc>::size_type 
     basic_string<_CharT, _Traits, _Alloc>::
@@ -141,8 +151,8 @@ namespace std
        if (__beg == __end && __a == _Alloc())
          return _S_empty_rep()._M_refdata();
 
-       // NB: Not required, but considered best practice.
-       if (__builtin_expect(__beg == _InIterator(), 0))
+       // NB: Not required, but considered best practice. 
+       if (__builtin_expect(__is_null_pointer(__beg), 0))
          __throw_logic_error("basic_string::_S_construct NULL not valid");
 
        const size_type __dnew = static_cast<size_type>(std::distance(__beg, __end));
@@ -215,12 +225,14 @@ namespace std
                               __str._M_fold(__pos, __n), __a), __a)
     { }
 
+  // TBD: DPG annotate
   template<typename _CharT, typename _Traits, typename _Alloc>
     basic_string<_CharT, _Traits, _Alloc>::
     basic_string(const _CharT* __s, size_type __n, const _Alloc& __a)
     : _M_dataplus(_S_construct(__s, __s + __n, __a), __a)
     { }
 
+  // TBD: DPG annotate
   template<typename _CharT, typename _Traits, typename _Alloc>
     basic_string<_CharT, _Traits, _Alloc>::
     basic_string(const _CharT* __s, const _Alloc& __a)
@@ -233,7 +245,8 @@ namespace std
     basic_string(size_type __n, _CharT __c, const _Alloc& __a)
     : _M_dataplus(_S_construct(__n, __c, __a), __a)
     { }
+
+  // TBD: DPG annotate 
   template<typename _CharT, typename _Traits, typename _Alloc>
     template<typename _InputIterator>
     basic_string<_CharT, _Traits, _Alloc>::
@@ -275,6 +288,7 @@ namespace std
      basic_string<_CharT, _Traits, _Alloc>::
      assign(const _CharT* __s, size_type __n)
      {
+       __glibcxx_requires_string_len(__s, __n);
        if (__n > this->max_size())
         __throw_length_error("basic_string::assign");
        if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
@@ -313,6 +327,7 @@ namespace std
      basic_string<_CharT, _Traits, _Alloc>::
      insert(size_type __pos, const _CharT* __s, size_type __n)
      {
+       __glibcxx_requires_string_len(__s, __n);
        const size_type __size = this->size();
        if (__pos > __size)
          __throw_out_of_range("basic_string::insert");
@@ -350,6 +365,7 @@ namespace std
      replace(size_type __pos, size_type __n1, const _CharT* __s,
             size_type __n2)
      {
+       __glibcxx_requires_string_len(__s, __n2);
        const size_type __size = this->size();
        if (__pos > __size)
          __throw_out_of_range("basic_string::replace");
@@ -727,6 +743,7 @@ namespace std
     basic_string<_CharT, _Traits, _Alloc>::
     append(const _CharT* __s, size_type __n)
     {
+      __glibcxx_requires_string_len(__s, __n);
       const size_type __len = __n + this->size();
       if (__len > this->capacity())
        this->reserve(__len);
@@ -749,6 +766,7 @@ namespace std
     operator+(const _CharT* __lhs,
              const basic_string<_CharT, _Traits, _Alloc>& __rhs)
     {
+      __glibcxx_requires_string(__lhs);
       typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
       typedef typename __string_type::size_type          __size_type;
       const __size_type __len = _Traits::length(__lhs);
@@ -783,6 +801,8 @@ namespace std
       
       if (__n > this->size() - __pos)
        __n = this->size() - __pos;
+
+      __glibcxx_requires_string_len(__s, __n);
       
       traits_type::copy(__s, _M_data() + __pos, __n);
       // 21.3.5.7 par 3: do not append null.  (good.)
@@ -794,6 +814,8 @@ namespace std
     basic_string<_CharT, _Traits, _Alloc>::
     find(const _CharT* __s, size_type __pos, size_type __n) const
     {
+      __glibcxx_requires_string_len(__s, __n);
+
       const size_type __size = this->size();
       size_t __xpos = __pos;
       const _CharT* __data = _M_data();
@@ -827,6 +849,8 @@ namespace std
     basic_string<_CharT, _Traits, _Alloc>::
     rfind(const _CharT* __s, size_type __pos, size_type __n) const
     {
+      __glibcxx_requires_string_len(__s, __n);
+
       const size_type __size = this->size();
       if (__n <= __size)
        {
@@ -866,6 +890,8 @@ namespace std
     basic_string<_CharT, _Traits, _Alloc>::
     find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
     {
+      __glibcxx_requires_string_len(__s, __n);
+
       for (; __n && __pos < this->size(); ++__pos)
        {
          const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]);
@@ -880,6 +906,8 @@ namespace std
     basic_string<_CharT, _Traits, _Alloc>::
     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
     {
+      __glibcxx_requires_string_len(__s, __n);
+
       size_type __size = this->size();
       if (__size && __n)
        { 
@@ -900,6 +928,8 @@ namespace std
     basic_string<_CharT, _Traits, _Alloc>::
     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
     {
+      __glibcxx_requires_string_len(__s, __n);
+
       size_t __xpos = __pos;
       for (; __xpos < this->size(); ++__xpos)
        if (!traits_type::find(__s, __n, _M_data()[__xpos]))
@@ -924,6 +954,8 @@ namespace std
     basic_string<_CharT, _Traits, _Alloc>::
     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
     {
+      __glibcxx_requires_string_len(__s, __n);
+
       size_type __size = this->size();
       if (__size)
        { 
@@ -1004,6 +1036,8 @@ namespace std
     basic_string<_CharT, _Traits, _Alloc>::
     compare(const _CharT* __s) const
     {
+      __glibcxx_requires_string(__s);
+
       const size_type __size = this->size();
       const size_type __osize = traits_type::length(__s);
       const size_type __len = std::min(__size, __osize);
@@ -1019,6 +1053,8 @@ namespace std
     basic_string <_CharT, _Traits, _Alloc>::
     compare(size_type __pos, size_type __n1, const _CharT* __s) const
     {
+      __glibcxx_requires_string(__s);
+
       const size_type __size = this->size();
       if (__pos > __size)
        __throw_out_of_range("basic_string::compare");
@@ -1038,6 +1074,8 @@ namespace std
     compare(size_type __pos, size_type __n1, const _CharT* __s, 
            size_type __n2) const
     {
+      __glibcxx_requires_string_len(__s, __n2);
+
       const size_type __size = this->size();
       if (__pos > __size)
        __throw_out_of_range("basic_string::compare");
index d6ce9ed..6a0fb79 100644 (file)
 # define _GLIBCXX_EXTERN_TEMPLATE 1
 #endif
 
-// To enable older, ARM-style iostreams and other anachronisms use this.
-//#define _GLIBCXX_DEPRECATED 1
+// To enable debug mode.
+namespace __gnu_norm 
+{ 
+  using namespace std; 
+}
 
-// Use corrected code from the committee library group's issues list.
-//#define _GLIBCXX_RESOLVE_LIB_DEFECTS 1
+namespace __gnu_debug_def { }
+
+namespace __gnu_debug 
+{ 
+  using namespace std; 
+  using namespace __gnu_debug_def __attribute__ ((strong));
+}
+
+namespace std
+{
+#ifdef _GLIBCXX_DEBUG
+  using namespace __gnu_debug_def __attribute__ ((strong));
+#else
+  using namespace __gnu_norm __attribute__ ((strong));
+#endif
+}
 
 // The remainder of the prewritten config is automatic; all the
 // user hooks are listed above.
index dedab6a..9f01eed 100644 (file)
@@ -61,7 +61,7 @@
 #ifndef _DEQUE_TCC
 #define _DEQUE_TCC 1
 
-namespace std
+namespace __gnu_norm
 { 
   template <typename _Tp, typename _Alloc>
     deque<_Tp,_Alloc>&
@@ -707,6 +707,6 @@ namespace std
       this->_M_start._M_set_node(__new_nstart);
       this->_M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
     }
-} // namespace std 
+} // namespace __gnu_norm
   
 #endif
index 9c5a0cd..283b0ac 100644 (file)
@@ -61,7 +61,7 @@
 #ifndef _LIST_TCC
 #define _LIST_TCC 1
 
-namespace std
+namespace __gnu_norm
 {
   template<typename _Tp, typename _Alloc>
     void
@@ -409,6 +409,6 @@ namespace std
         swap(__counter[__fill-1]);
       }
     }
-} // namespace std
+} // namespace __gnu_norm
 
 #endif /* _LIST_TCC */
index 70ef219..7cb54eb 100644 (file)
 
 #include <bits/stl_heap.h>
 #include <bits/stl_tempbuf.h>     // for _Temporary_buffer
+#include <debug/debug.h>
 
 // See concept_check.h for the __glibcxx_*_requires macros.
 
 namespace std
 {
-
   /**
    *  @brief Find the median of three values.
    *  @param  a  A value.
@@ -153,6 +153,7 @@ namespace std
     {
       // concept requirements
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
+      __glibcxx_requires_valid_range(__first, __last);
       for ( ; __first != __last; ++__first)
        __f(*__first);
       return __f;
@@ -295,6 +296,7 @@ namespace std
       __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));
     }
 
@@ -315,6 +317,7 @@ namespace std
       __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));
     }
 
@@ -334,6 +337,7 @@ namespace std
       __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;
@@ -365,6 +369,7 @@ namespace std
       __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;
@@ -393,6 +398,7 @@ namespace std
       __glibcxx_function_requires(_EqualityComparableConcept<
            typename iterator_traits<_InputIterator>::value_type >)
       __glibcxx_function_requires(_EqualityComparableConcept<_Tp>)
+      __glibcxx_requires_valid_range(__first, __last);
       typename iterator_traits<_InputIterator>::difference_type __n = 0;
       for ( ; __first != __last; ++__first)
        if (*__first == __value)
@@ -416,6 +422,7 @@ namespace std
       __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))
@@ -458,7 +465,8 @@ namespace std
       __glibcxx_function_requires(_EqualOpConcept<
            typename iterator_traits<_ForwardIterator1>::value_type,
            typename iterator_traits<_ForwardIterator2>::value_type>)
-
+      __glibcxx_requires_valid_range(__first1, __last1);
+      __glibcxx_requires_valid_range(__first2, __last2);
       // Test for empty ranges
       if (__first1 == __last1 || __first2 == __last2)
        return __first1;
@@ -531,6 +539,8 @@ namespace std
       __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
            typename iterator_traits<_ForwardIterator1>::value_type,
            typename iterator_traits<_ForwardIterator2>::value_type>)
+      __glibcxx_requires_valid_range(__first1, __last1);
+      __glibcxx_requires_valid_range(__first2, __last2);
 
       // Test for empty ranges
       if (__first1 == __last1 || __first2 == __last2)
@@ -603,6 +613,7 @@ namespace std
       __glibcxx_function_requires(_EqualityComparableConcept<
            typename iterator_traits<_ForwardIterator>::value_type>)
       __glibcxx_function_requires(_EqualityComparableConcept<_Tp>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__count <= 0)
        return __first;
@@ -651,6 +662,7 @@ namespace std
       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
       __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
            typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__count <= 0)
        return __first;
@@ -708,6 +720,7 @@ namespace std
       __glibcxx_function_requires(_ConvertibleConcept<
            typename iterator_traits<_ForwardIterator2>::value_type,
            typename iterator_traits<_ForwardIterator1>::value_type>)
+      __glibcxx_requires_valid_range(__first1, __last1);
 
       for ( ; __first1 != __last1; ++__first1, ++__first2)
        std::iter_swap(__first1, __first2);
@@ -739,6 +752,7 @@ namespace std
       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
             // "the type returned by a _UnaryOperation"
             __typeof__(__unary_op(*__first))>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       for ( ; __first != __last; ++__first, ++__result)
        *__result = __unary_op(*__first);
@@ -775,6 +789,7 @@ namespace std
       __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);
@@ -804,6 +819,7 @@ namespace std
            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)
@@ -833,6 +849,7 @@ namespace std
            typename iterator_traits<_ForwardIterator>::value_type>)
       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
            typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       for ( ; __first != __last; ++__first)
        if (__pred(*__first))
@@ -865,6 +882,7 @@ namespace std
            typename iterator_traits<_InputIterator>::value_type>)
       __glibcxx_function_requires(_EqualOpConcept<
            typename iterator_traits<_InputIterator>::value_type, _Tp>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       for ( ; __first != __last; ++__first, ++__result)
        *__result = *__first == __old_value ? __new_value : *__first;
@@ -898,6 +916,7 @@ namespace std
            typename iterator_traits<_InputIterator>::value_type>)
       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
            typename iterator_traits<_InputIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       for ( ; __first != __last; ++__first, ++__result)
        *__result = __pred(*__first) ? __new_value : *__first;
@@ -923,6 +942,7 @@ namespace std
       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
       __glibcxx_function_requires(_GeneratorConcept<_Generator,
            typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       for ( ; __first != __last; ++__first)
        *__first = __gen();
@@ -977,6 +997,7 @@ namespace std
            typename iterator_traits<_InputIterator>::value_type>)
       __glibcxx_function_requires(_EqualOpConcept<
            typename iterator_traits<_InputIterator>::value_type, _Tp>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       for ( ; __first != __last; ++__first)
        if (!(*__first == __value)) {
@@ -1011,6 +1032,7 @@ namespace std
            typename iterator_traits<_InputIterator>::value_type>)
       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
            typename iterator_traits<_InputIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       for ( ; __first != __last; ++__first)
        if (!__pred(*__first)) {
@@ -1047,6 +1069,7 @@ namespace std
            typename iterator_traits<_ForwardIterator>::value_type>)
       __glibcxx_function_requires(_EqualOpConcept<
            typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       __first = std::find(__first, __last, __value);
       _ForwardIterator __i = __first;
@@ -1079,6 +1102,7 @@ namespace std
       __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIterator>)
       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
            typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       __first = std::find_if(__first, __last, __pred);
       _ForwardIterator __i = __first;
@@ -1207,6 +1231,7 @@ namespace std
            typename iterator_traits<_InputIterator>::value_type>)
       __glibcxx_function_requires(_EqualityComparableConcept<
            typename iterator_traits<_InputIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       typedef typename iterator_traits<_OutputIterator>::iterator_category _IterType;
 
@@ -1239,6 +1264,7 @@ namespace std
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
            typename iterator_traits<_InputIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       typedef typename iterator_traits<_OutputIterator>::iterator_category _IterType;
 
@@ -1266,7 +1292,8 @@ namespace std
       // concept requirements
       __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIterator>)
       __glibcxx_function_requires(_EqualityComparableConcept<
-           typename iterator_traits<_ForwardIterator>::value_type>)
+                    typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       // Skip the beginning, if already unique.
       __first = std::adjacent_find(__first, __last);
@@ -1306,6 +1333,7 @@ namespace std
       __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
                typename iterator_traits<_ForwardIterator>::value_type,
                typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       // Skip the beginning, if already unique.
       __first = std::adjacent_find(__first, __last, __binary_pred);
@@ -1371,7 +1399,8 @@ namespace std
     {
       // concept requirements
       __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
-               _BidirectionalIterator>)
+                   _BidirectionalIterator>)
+      __glibcxx_requires_valid_range(__first, __last);
       std::__reverse(__first, __last, std::__iterator_category(__first));
     }
 
@@ -1399,6 +1428,7 @@ namespace std
       __glibcxx_function_requires(_BidirectionalIteratorConcept<_BidirectionalIterator>)
       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
                typename iterator_traits<_BidirectionalIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       while (__first != __last) {
        --__last;
@@ -1583,6 +1613,8 @@ namespace std
     {
       // 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());
@@ -1614,6 +1646,8 @@ namespace std
       __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, copy(__middle, __last, __result));
     }
@@ -1657,6 +1691,7 @@ namespace std
       // concept requirements
       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
            _RandomAccessIterator>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first == __last) return;
       for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
@@ -1684,6 +1719,7 @@ namespace std
       // concept requirements
       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
            _RandomAccessIterator>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first == __last) return;
       for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
@@ -1773,6 +1809,7 @@ namespace std
       __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIterator>)
       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
            typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       return std::__partition(__first, __last, __pred, std::__iterator_category(__first));
     }
@@ -1873,6 +1910,7 @@ namespace std
       __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIterator>)
       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
            typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first == __last)
        return __first;
@@ -2139,6 +2177,8 @@ namespace std
       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
            _RandomAccessIterator>)
       __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
+      __glibcxx_requires_valid_range(__first, __middle);
+      __glibcxx_requires_valid_range(__middle, __last);
 
       std::make_heap(__first, __middle);
       for (_RandomAccessIterator __i = __middle; __i < __last; ++__i)
@@ -2179,6 +2219,8 @@ namespace std
            _RandomAccessIterator>)
       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
                                                          _ValueType, _ValueType>)
+      __glibcxx_requires_valid_range(__first, __middle);
+      __glibcxx_requires_valid_range(__middle, __last);
 
       std::make_heap(__first, __middle, __comp);
       for (_RandomAccessIterator __i = __middle; __i < __last; ++__i)
@@ -2219,6 +2261,8 @@ namespace std
       __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, _OutputValueType>)
       __glibcxx_function_requires(_LessThanComparableConcept<_OutputValueType>)
       __glibcxx_function_requires(_LessThanComparableConcept<_InputValueType>)
+      __glibcxx_requires_valid_range(__first, __last);
+      __glibcxx_requires_valid_range(__result_first, __result_last);
 
       if (__result_first == __result_last) return __result_last;
       _RandomAccessIterator __result_real_last = __result_first;
@@ -2275,6 +2319,8 @@ namespace std
       __glibcxx_function_requires(_ConvertibleConcept<_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;
@@ -2375,6 +2421,7 @@ namespace std
       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
            _RandomAccessIterator>)
       __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first != __last) {
        std::__introsort_loop(__first, __last, __lg(__last - __first) * 2);
@@ -2406,6 +2453,7 @@ namespace std
       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
            _RandomAccessIterator>)
       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType, _ValueType>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first != __last) {
        std::__introsort_loop(__first, __last, __lg(__last - __first) * 2, __comp);
@@ -2438,6 +2486,7 @@ namespace std
       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
       __glibcxx_function_requires(_SameTypeConcept<_Tp, _ValueType>)
       __glibcxx_function_requires(_LessThanComparableConcept<_Tp>)
+      __glibcxx_requires_partitioned(__first, __last, __val);
 
       _DistanceType __len = std::distance(__first, __last);
       _DistanceType __half;
@@ -2483,6 +2532,7 @@ namespace std
       // 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;
@@ -2525,6 +2575,7 @@ namespace std
       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
       __glibcxx_function_requires(_SameTypeConcept<_Tp, _ValueType>)
       __glibcxx_function_requires(_LessThanComparableConcept<_Tp>)
+      __glibcxx_requires_partitioned(__first, __last, __val);
 
       _DistanceType __len = std::distance(__first, __last);
       _DistanceType __half;
@@ -2570,6 +2621,7 @@ namespace std
       // 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;
@@ -2755,6 +2807,8 @@ namespace std
            typename iterator_traits<_InputIterator2>::value_type>)
       __glibcxx_function_requires(_LessThanComparableConcept<
            typename iterator_traits<_InputIterator1>::value_type>)
+      __glibcxx_requires_sorted(__first1, __last1);
+      __glibcxx_requires_sorted(__first2, __last2);
 
       while (__first1 != __last1 && __first2 != __last2) {
        if (*__first2 < *__first1) {
@@ -2808,6 +2862,8 @@ namespace std
       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
            typename iterator_traits<_InputIterator1>::value_type,
            typename iterator_traits<_InputIterator2>::value_type>)
+      __glibcxx_requires_sorted_pred(__first1, __last1, __comp);
+      __glibcxx_requires_sorted_pred(__first2, __last2, __comp);
 
       while (__first1 != __last1 && __first2 != __last2) {
        if (__comp(*__first2, *__first1)) {
@@ -3170,6 +3226,8 @@ namespace std
       __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<
            _BidirectionalIterator>)
       __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
+      __glibcxx_requires_sorted(__first, __middle);
+      __glibcxx_requires_sorted(__middle, __last);
 
       if (__first == __middle || __middle == __last)
        return;
@@ -3223,6 +3281,8 @@ namespace std
            _BidirectionalIterator>)
       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
            _ValueType, _ValueType>)
+      __glibcxx_requires_sorted_pred(__first, __middle, __comp);
+      __glibcxx_requires_sorted_pred(__middle, __last, __comp);
 
       if (__first == __middle || __middle == __last)
        return;
@@ -3309,6 +3369,7 @@ namespace std
       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
            _RandomAccessIterator>)
       __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       _Temporary_buffer<_RandomAccessIterator, _ValueType> buf(__first, __last);
       if (buf.begin() == 0)
@@ -3346,6 +3407,7 @@ namespace std
            _RandomAccessIterator>)
       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
                                                          _ValueType, _ValueType>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       _Temporary_buffer<_RandomAccessIterator, _ValueType> buf(__first, __last);
       if (buf.begin() == 0)
@@ -3381,6 +3443,8 @@ namespace std
       // concept requirements
       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<_RandomAccessIterator>)
       __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
+      __glibcxx_requires_valid_range(__first, __nth);
+      __glibcxx_requires_valid_range(__nth, __last);
 
       while (__last - __first > 3) {
        _RandomAccessIterator __cut =
@@ -3425,6 +3489,8 @@ namespace std
       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<_RandomAccessIterator>)
       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
                                  _ValueType, _ValueType>)
+      __glibcxx_requires_valid_range(__first, __nth);
+      __glibcxx_requires_valid_range(__nth, __last);
 
       while (__last - __first > 3) {
        _RandomAccessIterator __cut =
@@ -3469,6 +3535,7 @@ namespace std
       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
       __glibcxx_function_requires(_SameTypeConcept<_Tp, _ValueType>)
       __glibcxx_function_requires(_LessThanComparableConcept<_Tp>)
+      __glibcxx_requires_partitioned(__first, __last, __val);
 
       _DistanceType __len = std::distance(__first, __last);
       _DistanceType __half;
@@ -3524,6 +3591,7 @@ namespace std
       __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;
@@ -3572,6 +3640,7 @@ namespace std
       __glibcxx_function_requires(_SameTypeConcept<_Tp,
                typename iterator_traits<_ForwardIterator>::value_type>)
       __glibcxx_function_requires(_LessThanComparableConcept<_Tp>)
+      __glibcxx_requires_partitioned(__first, __last, __val);
 
       _ForwardIterator __i = std::lower_bound(__first, __last, __val);
       return __i != __last && !(__val < *__i);
@@ -3603,6 +3672,7 @@ namespace std
                typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _Tp,
                typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp);
 
       _ForwardIterator __i = std::lower_bound(__first, __last, __val, __comp);
       return __i != __last && !__comp(__val, *__i);
@@ -3642,6 +3712,8 @@ namespace std
            typename iterator_traits<_InputIterator2>::value_type>)
       __glibcxx_function_requires(_LessThanComparableConcept<
            typename iterator_traits<_InputIterator1>::value_type>)
+      __glibcxx_requires_sorted(__first1, __last1);
+      __glibcxx_requires_sorted(__first2, __last2);
 
       while (__first1 != __last1 && __first2 != __last2)
        if (*__first2 < *__first1)
@@ -3687,6 +3759,8 @@ namespace std
       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
            typename iterator_traits<_InputIterator1>::value_type,
            typename iterator_traits<_InputIterator2>::value_type>)
+      __glibcxx_requires_sorted_pred(__first1, __last1, __comp);
+      __glibcxx_requires_sorted_pred(__first2, __last2, __comp);
 
       while (__first1 != __last1 && __first2 != __last2)
        if (__comp(*__first2, *__first1))
@@ -3732,6 +3806,8 @@ namespace std
            typename iterator_traits<_InputIterator2>::value_type>)
       __glibcxx_function_requires(_LessThanComparableConcept<
            typename iterator_traits<_InputIterator1>::value_type>)
+      __glibcxx_requires_sorted(__first1, __last1);
+      __glibcxx_requires_sorted(__first2, __last2);
 
       while (__first1 != __last1 && __first2 != __last2) {
        if (*__first1 < *__first2) {
@@ -3788,6 +3864,8 @@ namespace std
       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
            typename iterator_traits<_InputIterator1>::value_type,
            typename iterator_traits<_InputIterator2>::value_type>)
+      __glibcxx_requires_sorted_pred(__first1, __last1, __comp);
+      __glibcxx_requires_sorted_pred(__first2, __last2, __comp);
 
       while (__first1 != __last1 && __first2 != __last2) {
        if (__comp(*__first1, *__first2)) {
@@ -3840,6 +3918,8 @@ namespace std
            typename iterator_traits<_InputIterator2>::value_type>)
       __glibcxx_function_requires(_LessThanComparableConcept<
            typename iterator_traits<_InputIterator1>::value_type>)
+      __glibcxx_requires_sorted(__first1, __last1);
+      __glibcxx_requires_sorted(__first2, __last2);
 
       while (__first1 != __last1 && __first2 != __last2)
        if (*__first1 < *__first2)
@@ -3892,6 +3972,8 @@ namespace std
       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
            typename iterator_traits<_InputIterator1>::value_type,
            typename iterator_traits<_InputIterator2>::value_type>)
+      __glibcxx_requires_sorted_pred(__first1, __last1, __comp);
+      __glibcxx_requires_sorted_pred(__first2, __last2, __comp);
 
       while (__first1 != __last1 && __first2 != __last2)
        if (__comp(*__first1, *__first2))
@@ -3941,6 +4023,8 @@ namespace std
            typename iterator_traits<_InputIterator2>::value_type>)
       __glibcxx_function_requires(_LessThanComparableConcept<
            typename iterator_traits<_InputIterator1>::value_type>)
+      __glibcxx_requires_sorted(__first1, __last1);
+      __glibcxx_requires_sorted(__first2, __last2);
 
       while (__first1 != __last1 && __first2 != __last2)
        if (*__first1 < *__first2) {
@@ -3996,6 +4080,8 @@ namespace std
       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
            typename iterator_traits<_InputIterator1>::value_type,
            typename iterator_traits<_InputIterator2>::value_type>)
+      __glibcxx_requires_sorted_pred(__first1, __last1, __comp);
+      __glibcxx_requires_sorted_pred(__first2, __last2, __comp);
 
       while (__first1 != __last1 && __first2 != __last2)
        if (__comp(*__first1, *__first2)) {
@@ -4044,6 +4130,8 @@ namespace std
            typename iterator_traits<_InputIterator2>::value_type>)
       __glibcxx_function_requires(_LessThanComparableConcept<
            typename iterator_traits<_InputIterator1>::value_type>)
+      __glibcxx_requires_sorted(__first1, __last1);
+      __glibcxx_requires_sorted(__first2, __last2);
 
       while (__first1 != __last1 && __first2 != __last2)
        if (*__first1 < *__first2) {
@@ -4101,6 +4189,8 @@ namespace std
       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
            typename iterator_traits<_InputIterator1>::value_type,
            typename iterator_traits<_InputIterator2>::value_type>)
+      __glibcxx_requires_sorted_pred(__first1, __last1, __comp);
+      __glibcxx_requires_sorted_pred(__first2, __last2, __comp);
 
       while (__first1 != __last1 && __first2 != __last2)
        if (__comp(*__first1, *__first2)) {
@@ -4137,6 +4227,7 @@ namespace std
       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
       __glibcxx_function_requires(_LessThanComparableConcept<
            typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first == __last) return __first;
       _ForwardIterator __result = __first;
@@ -4164,6 +4255,7 @@ namespace std
       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
            typename iterator_traits<_ForwardIterator>::value_type,
            typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first == __last) return __first;
       _ForwardIterator __result = __first;
@@ -4186,6 +4278,7 @@ namespace std
       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
       __glibcxx_function_requires(_LessThanComparableConcept<
            typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first == __last) return __first;
       _ForwardIterator __result = __first;
@@ -4213,6 +4306,7 @@ namespace std
       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
            typename iterator_traits<_ForwardIterator>::value_type,
            typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first == __last) return __first;
       _ForwardIterator __result = __first;
@@ -4244,6 +4338,7 @@ namespace std
       __glibcxx_function_requires(_BidirectionalIteratorConcept<_BidirectionalIterator>)
       __glibcxx_function_requires(_LessThanComparableConcept<
            typename iterator_traits<_BidirectionalIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first == __last)
        return false;
@@ -4296,6 +4391,7 @@ namespace std
       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
            typename iterator_traits<_BidirectionalIterator>::value_type,
            typename iterator_traits<_BidirectionalIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first == __last)
        return false;
@@ -4344,6 +4440,7 @@ namespace std
       __glibcxx_function_requires(_BidirectionalIteratorConcept<_BidirectionalIterator>)
       __glibcxx_function_requires(_LessThanComparableConcept<
            typename iterator_traits<_BidirectionalIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first == __last)
        return false;
@@ -4396,6 +4493,7 @@ namespace std
       __glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
            typename iterator_traits<_BidirectionalIterator>::value_type,
            typename iterator_traits<_BidirectionalIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first == __last)
        return false;
@@ -4451,6 +4549,8 @@ namespace std
       __glibcxx_function_requires(_EqualOpConcept<
            typename iterator_traits<_InputIterator>::value_type,
            typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first1, __last1);
+      __glibcxx_requires_valid_range(__first2, __last2);
 
       for ( ; __first1 != __last1; ++__first1)
        for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter)
@@ -4489,6 +4589,8 @@ namespace std
       __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
            typename iterator_traits<_InputIterator>::value_type,
            typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first1, __last1);
+      __glibcxx_requires_valid_range(__first2, __last2);
 
       for ( ; __first1 != __last1; ++__first1)
        for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter)
@@ -4649,6 +4751,8 @@ namespace std
       __glibcxx_function_requires(_EqualOpConcept<
            typename iterator_traits<_ForwardIterator1>::value_type,
            typename iterator_traits<_ForwardIterator2>::value_type>)
+      __glibcxx_requires_valid_range(__first1, __last1);
+      __glibcxx_requires_valid_range(__first2, __last2);
 
       return std::__find_end(__first1, __last1, __first2, __last2,
                             std::__iterator_category(__first1),
@@ -4694,6 +4798,8 @@ namespace std
       __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),
index 73b1359..3e1a7c6 100644 (file)
@@ -74,6 +74,7 @@
 #include <bits/stl_iterator_base_funcs.h>
 #include <bits/stl_iterator.h>
 #include <bits/concept_check.h>
+#include <debug/debug.h>
 
 namespace std
 {
@@ -333,6 +334,7 @@ namespace std
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
            typename iterator_traits<_InputIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
        typedef typename _Is_normal_iterator<_InputIterator>::_Normal __Normal;
        return std::__copy_ni1(__first, __last, __result, __Normal());
@@ -471,6 +473,7 @@ namespace std
       __glibcxx_function_requires(_ConvertibleConcept<
            typename iterator_traits<_BI1>::value_type,
            typename iterator_traits<_BI2>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       typedef typename _Is_normal_iterator<_BI1>::_Normal __Normal;
       return std::__copy_backward_input_normal_iterator(__first, __last, __result,
@@ -495,6 +498,7 @@ namespace std
     {
       // concept requirements
       __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIterator>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       for ( ; __first != __last; ++__first)
        *__first = __value;
@@ -527,6 +531,7 @@ namespace std
   inline void
   fill(unsigned char* __first, unsigned char* __last, const unsigned char& __c)
   {
+    __glibcxx_requires_valid_range(__first, __last);
     unsigned char __tmp = __c;
     std::memset(__first, __tmp, __last - __first);
   }
@@ -534,6 +539,7 @@ namespace std
   inline void
   fill(signed char* __first, signed char* __last, const signed char& __c)
   {
+    __glibcxx_requires_valid_range(__first, __last);
     signed char __tmp = __c;
     std::memset(__first, static_cast<unsigned char>(__tmp), __last - __first);
   }
@@ -541,6 +547,7 @@ namespace std
   inline void
   fill(char* __first, char* __last, const char& __c)
   {
+    __glibcxx_requires_valid_range(__first, __last);
     char __tmp = __c;
     std::memset(__first, static_cast<unsigned char>(__tmp), __last - __first);
   }
@@ -594,6 +601,7 @@ namespace std
            typename iterator_traits<_InputIterator1>::value_type>)
       __glibcxx_function_requires(_EqualityComparableConcept<
            typename iterator_traits<_InputIterator2>::value_type>)
+      __glibcxx_requires_valid_range(__first1, __last1);
 
       while (__first1 != __last1 && *__first1 == *__first2)
         {
@@ -625,6 +633,7 @@ namespace std
       // concept requirements
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
+      __glibcxx_requires_valid_range(__first1, __last1);
 
       while (__first1 != __last1 && __binary_pred(*__first1, *__first2))
         {
@@ -655,6 +664,7 @@ namespace std
       __glibcxx_function_requires(_EqualOpConcept<
            typename iterator_traits<_InputIterator1>::value_type,
            typename iterator_traits<_InputIterator2>::value_type>)
+      __glibcxx_requires_valid_range(__first1, __last1);
 
       for ( ; __first1 != __last1; ++__first1, ++__first2)
        if (!(*__first1 == *__first2))
@@ -684,6 +694,7 @@ namespace std
       // concept requirements
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
+      __glibcxx_requires_valid_range(__first1, __last1);
 
       for ( ; __first1 != __last1; ++__first1, ++__first2)
        if (!__binary_pred(*__first1, *__first2))
@@ -717,6 +728,8 @@ namespace std
            typename iterator_traits<_InputIterator1>::value_type>)
       __glibcxx_function_requires(_LessThanComparableConcept<
            typename iterator_traits<_InputIterator2>::value_type>)
+      __glibcxx_requires_valid_range(__first1, __last1);
+      __glibcxx_requires_valid_range(__first2, __last2);
 
       for (;__first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) 
        {
@@ -749,6 +762,8 @@ namespace std
       // concept requirements
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
+      __glibcxx_requires_valid_range(__first1, __last1);
+      __glibcxx_requires_valid_range(__first2, __last2);
 
       for ( ; __first1 != __last1 && __first2 != __last2
            ; ++__first1, ++__first2) 
@@ -767,6 +782,9 @@ namespace std
                          const unsigned char* __first2, 
                          const unsigned char* __last2)
   {
+    __glibcxx_requires_valid_range(__first1, __last1);
+    __glibcxx_requires_valid_range(__first2, __last2);
+
     const size_t __len1 = __last1 - __first1;
     const size_t __len2 = __last2 - __first2;
     const int __result = std::memcmp(__first1, __first2, std::min(__len1, __len2));
@@ -777,6 +795,9 @@ namespace std
   lexicographical_compare(const char* __first1, const char* __last1,
                          const char* __first2, const char* __last2)
   {
+    __glibcxx_requires_valid_range(__first1, __last1);
+    __glibcxx_requires_valid_range(__first2, __last2);
+
 #if CHAR_MAX == SCHAR_MAX
     return std::lexicographical_compare((const signed char*) __first1,
                                        (const signed char*) __last1,
index 15e0f57..d05f607 100644 (file)
@@ -61,7 +61,7 @@
 #ifndef _BVECTOR_H
 #define _BVECTOR_H 1
 
-namespace std
+namespace __gnu_norm
 { 
   typedef unsigned long _Bit_type;
   enum { _S_word_bit = int(CHAR_BIT * sizeof(_Bit_type)) };
@@ -334,13 +334,12 @@ public:
   ~_Bvector_base() { _Base::_M_deallocate(); }
 };
 
-} // namespace std
+} // namespace __gnu_norm
 
 // Declare a partial specialization of vector<T, Alloc>.
 #include <bits/stl_vector.h>
-namespace std
+namespace __gnu_norm
 {
-
 template <typename _Alloc> 
   class vector<bool, _Alloc> : public _Bvector_base<_Alloc> 
   {
@@ -723,13 +722,8 @@ template <typename _Alloc>
     void clear() { erase(begin(), end()); }
   };
 
-// This typedef is non-standard.  It is provided for backward compatibility.
-typedef vector<bool, __alloc> bit_vector;
-
-} // namespace std 
+  // This typedef is non-standard.  It is provided for backward compatibility.
+  typedef vector<bool, __alloc> bit_vector;
+} // namespace __gnu_norm
 
 #endif /* _BVECTOR_H */
-
-// Local Variables:
-// mode:C++
-// End:
index b573343..2498bb6 100644 (file)
@@ -65,7 +65,7 @@
 #include <bits/stl_iterator_base_types.h>
 #include <bits/stl_iterator_base_funcs.h>
 
-namespace std
+namespace __gnu_norm
 { 
   /**
    *  @if maint
@@ -96,7 +96,7 @@ namespace std
    *  All the functions are op overloads except for _M_set_node.
    *  @endif
   */
-  template <typename _Tp, typename _Ref, typename _Ptr>
+  template<typename _Tp, typename _Ref, typename _Ptr>
     struct _Deque_iterator
   {
     typedef _Deque_iterator<_Tp, _Tp&, _Tp*>             iterator;
@@ -205,7 +205,7 @@ namespace std
   // Note: we also provide overloads whose operands are of the same type in
   // order to avoid ambiguous overload resolution when std::rel_ops operators
   // are in scope (for additional details, see libstdc++/3628)
-  template <typename _Tp, typename _Ref, typename _Ptr>
+  template<typename _Tp, typename _Ref, typename _Ptr>
   inline bool
   operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
           const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
@@ -213,7 +213,7 @@ namespace std
     return __x._M_cur == __y._M_cur;
   }
   
-  template <typename _Tp, typename _RefL, typename _PtrL,
+  template<typename _Tp, typename _RefL, typename _PtrL,
                           typename _RefR, typename _PtrR>
   inline bool
   operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
@@ -222,7 +222,7 @@ namespace std
     return __x._M_cur == __y._M_cur;
   }
   
-  template <typename _Tp, typename _Ref, typename _Ptr>
+  template<typename _Tp, typename _Ref, typename _Ptr>
   inline bool
   operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
           const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
@@ -230,7 +230,7 @@ namespace std
     return !(__x == __y);
   }
   
-  template <typename _Tp, typename _RefL, typename _PtrL,
+  template<typename _Tp, typename _RefL, typename _PtrL,
                           typename _RefR, typename _PtrR>
   inline bool
   operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
@@ -239,7 +239,7 @@ namespace std
     return !(__x == __y);
   }
   
-  template <typename _Tp, typename _Ref, typename _Ptr>
+  template<typename _Tp, typename _Ref, typename _Ptr>
   inline bool
   operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
           const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
@@ -248,7 +248,7 @@ namespace std
       (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node);
   }
   
-  template <typename _Tp, typename _RefL, typename _PtrL,
+  template<typename _Tp, typename _RefL, typename _PtrL,
                           typename _RefR, typename _PtrR>
   inline bool
   operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
@@ -258,7 +258,7 @@ namespace std
       (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node);
   }
   
-  template <typename _Tp, typename _Ref, typename _Ptr>
+  template<typename _Tp, typename _Ref, typename _Ptr>
   inline bool
   operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
           const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
@@ -266,7 +266,7 @@ namespace std
     return __y < __x;
   }
   
-  template <typename _Tp, typename _RefL, typename _PtrL,
+  template<typename _Tp, typename _RefL, typename _PtrL,
                           typename _RefR, typename _PtrR>
   inline bool
   operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
@@ -275,7 +275,7 @@ namespace std
     return __y < __x;
   }
   
-  template <typename _Tp, typename _Ref, typename _Ptr>
+  template<typename _Tp, typename _Ref, typename _Ptr>
   inline bool
   operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
           const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
@@ -283,7 +283,7 @@ namespace std
     return !(__y < __x);
   }
   
-  template <typename _Tp, typename _RefL, typename _PtrL,
+  template<typename _Tp, typename _RefL, typename _PtrL,
                           typename _RefR, typename _PtrR>
   inline bool
   operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
@@ -292,7 +292,7 @@ namespace std
     return !(__y < __x);
   }
   
-  template <typename _Tp, typename _Ref, typename _Ptr>
+  template<typename _Tp, typename _Ref, typename _Ptr>
   inline bool
   operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
           const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
@@ -300,7 +300,7 @@ namespace std
     return !(__x < __y);
   }
   
-  template <typename _Tp, typename _RefL, typename _PtrL,
+  template<typename _Tp, typename _RefL, typename _PtrL,
                           typename _RefR, typename _PtrR>
   inline bool
   operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
@@ -313,7 +313,7 @@ namespace std
   // According to the resolution of DR179 not only the various comparison
   // operators but also operator- must accept mixed iterator/const_iterator
   // parameters.
-  template <typename _Tp, typename _RefL, typename _PtrL,
+  template<typename _Tp, typename _RefL, typename _PtrL,
                           typename _RefR, typename _PtrR>
   inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
   operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
@@ -325,7 +325,7 @@ namespace std
       (__y._M_last - __y._M_cur);
   }
   
-  template <typename _Tp, typename _Ref, typename _Ptr>
+  template<typename _Tp, typename _Ref, typename _Ptr>
   inline _Deque_iterator<_Tp, _Ref, _Ptr>
   operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x)
   {
@@ -345,7 +345,7 @@ namespace std
    *  instanceless allocators.
    *  @endif
   */
-  template <typename _Tp, typename _Alloc, bool __is_static>
+  template<typename _Tp, typename _Alloc, bool __is_static>
     class _Deque_alloc_base
   {
   public:
@@ -388,7 +388,7 @@ namespace std
   };
   
   /// @if maint Specialization for instanceless allocators.  @endif
-  template <typename _Tp, typename _Alloc>
+  template<typename _Tp, typename _Alloc>
     class _Deque_alloc_base<_Tp, _Alloc, true>
   {
   public:
@@ -439,7 +439,7 @@ namespace std
    *  here.
    *  @endif
   */
-  template <typename _Tp, typename _Alloc>
+  template<typename _Tp, typename _Alloc>
     class _Deque_base
     : public _Deque_alloc_base<_Tp,_Alloc,
                                 _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
@@ -470,7 +470,7 @@ namespace std
   };
   
   
-  template <typename _Tp, typename _Alloc>
+  template<typename _Tp, typename _Alloc>
   _Deque_base<_Tp,_Alloc>::~_Deque_base()
   {
     if (this->_M_map)
@@ -490,7 +490,7 @@ namespace std
    *  The initial underlying memory layout is a bit complicated...
    *  @endif
   */
-  template <typename _Tp, typename _Alloc>
+  template<typename _Tp, typename _Alloc>
   void
   _Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements)
   {
@@ -525,7 +525,7 @@ namespace std
                        __num_elements % __deque_buf_size(sizeof(_Tp));
   }
   
-  template <typename _Tp, typename _Alloc>
+  template<typename _Tp, typename _Alloc>
   void _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish)
   {
     _Tp** __cur;
@@ -541,7 +541,7 @@ namespace std
       }
   }
   
-  template <typename _Tp, typename _Alloc>
+  template<typename _Tp, typename _Alloc>
   void
   _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
   {
@@ -634,7 +634,7 @@ namespace std
    *  and we can use other standard algorithms as well.
    *  @endif
   */
-  template <typename _Tp, typename _Alloc = allocator<_Tp> >
+  template<typename _Tp, typename _Alloc = allocator<_Tp> >
     class deque : protected _Deque_base<_Tp, _Alloc>
   {
     // concept requirements
@@ -1227,13 +1227,13 @@ namespace std
      *  push_back on each value from the iterator.
      *  @endif
     */
-    template <typename _InputIterator>
+    template<typename _InputIterator>
       void
       _M_range_initialize(_InputIterator __first, _InputIterator __last,
                           input_iterator_tag);
   
     // called by the second initialize_dispatch above
-    template <typename _ForwardIterator>
+    template<typename _ForwardIterator>
       void
       _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
                           forward_iterator_tag);
@@ -1278,13 +1278,13 @@ namespace std
       }
   
     // called by the second assign_dispatch above
-    template <typename _InputIterator>
+    template<typename _InputIterator>
       void
       _M_assign_aux(_InputIterator __first, _InputIterator __last,
                     input_iterator_tag);
   
     // called by the second assign_dispatch above
-    template <typename _ForwardIterator>
+    template<typename _ForwardIterator>
       void
       _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
                     forward_iterator_tag)
@@ -1357,13 +1357,13 @@ namespace std
       }
   
     // called by the second insert_dispatch above
-    template <typename _InputIterator>
+    template<typename _InputIterator>
       void
       _M_range_insert_aux(iterator __pos, _InputIterator __first,
                           _InputIterator __last, input_iterator_tag);
   
     // called by the second insert_dispatch above
-    template <typename _ForwardIterator>
+    template<typename _ForwardIterator>
       void
       _M_range_insert_aux(iterator __pos, _ForwardIterator __first,
                           _ForwardIterator __last, forward_iterator_tag);
@@ -1383,7 +1383,7 @@ namespace std
     _M_insert_aux(iterator __pos, size_type __n, const value_type& __x);
   
     // called by range_insert_aux for forward iterators
-    template <typename _ForwardIterator>
+    template<typename _ForwardIterator>
       void
       _M_insert_aux(iterator __pos, 
                     _ForwardIterator __first, _ForwardIterator __last,
@@ -1464,7 +1464,7 @@ namespace std
    *  deques.  Deques are considered equivalent if their sizes are equal,
    *  and if corresponding elements compare equal.
   */
-  template <typename _Tp, typename _Alloc>
+  template<typename _Tp, typename _Alloc>
   inline bool operator==(const deque<_Tp, _Alloc>& __x,
                          const deque<_Tp, _Alloc>& __y)
   {
@@ -1483,7 +1483,7 @@ namespace std
    *
    *  See std::lexicographical_compare() for how the determination is made.
   */
-  template <typename _Tp, typename _Alloc>
+  template<typename _Tp, typename _Alloc>
   inline bool operator<(const deque<_Tp, _Alloc>& __x,
                         const deque<_Tp, _Alloc>& __y)
   {
@@ -1492,39 +1492,39 @@ namespace std
   }
   
   /// Based on operator==
-  template <typename _Tp, typename _Alloc>
+  template<typename _Tp, typename _Alloc>
   inline bool operator!=(const deque<_Tp, _Alloc>& __x,
                          const deque<_Tp, _Alloc>& __y) {
     return !(__x == __y);
   }
   
   /// Based on operator<
-  template <typename _Tp, typename _Alloc>
+  template<typename _Tp, typename _Alloc>
   inline bool operator>(const deque<_Tp, _Alloc>& __x,
                         const deque<_Tp, _Alloc>& __y) {
     return __y < __x;
   }
   
   /// Based on operator<
-  template <typename _Tp, typename _Alloc>
+  template<typename _Tp, typename _Alloc>
   inline bool operator<=(const deque<_Tp, _Alloc>& __x,
                          const deque<_Tp, _Alloc>& __y) {
     return !(__y < __x);
   }
   
   /// Based on operator<
-  template <typename _Tp, typename _Alloc>
+  template<typename _Tp, typename _Alloc>
   inline bool operator>=(const deque<_Tp, _Alloc>& __x,
                          const deque<_Tp, _Alloc>& __y) {
     return !(__x < __y);
   }
   
   /// See std::deque::swap().
-  template <typename _Tp, typename _Alloc>
+  template<typename _Tp, typename _Alloc>
   inline void swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y)
   {
     __x.swap(__y);
   }
-} // namespace std 
+} // namespace __gnu_norm
   
 #endif /* _DEQUE_H */
index 697f2c6..c16cbe0 100644 (file)
 #ifndef _STL_HEAP_H
 #define _STL_HEAP_H 1
 
+#include <debug/debug.h>
+
 namespace std
 {
+  // is_heap, a predicate testing whether or not a range is
+  // a heap.  This function is an extension, not part of the C++
+  // standard.
+  template<typename _RandomAccessIterator, typename _Distance>
+    bool
+    __is_heap(_RandomAccessIterator __first, _Distance __n)
+    {
+      _Distance __parent = 0;
+      for (_Distance __child = 1; __child < __n; ++__child) {
+       if (__first[__parent] < __first[__child]) 
+         return false;
+       if ((__child & 1) == 0)
+         ++__parent;
+      }
+      return true;
+    }
+
+  template<typename _RandomAccessIterator, typename _Distance,
+           typename _StrictWeakOrdering>
+    bool
+    __is_heap(_RandomAccessIterator __first, _StrictWeakOrdering __comp,
+             _Distance __n)
+    {
+      _Distance __parent = 0;
+      for (_Distance __child = 1; __child < __n; ++__child) {
+       if (__comp(__first[__parent], __first[__child]))
+         return false;
+       if ((__child & 1) == 0)
+         ++__parent;
+      }
+      return true;
+    }
+
+  template<typename _RandomAccessIterator>
+    bool
+    __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
+    { return std::__is_heap(__first, std::distance(__first, __last)); }
+
+  template<typename _RandomAccessIterator, typename _StrictWeakOrdering>
+    bool
+    __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
+           _StrictWeakOrdering __comp)
+    { return std::__is_heap(__first, __comp, std::distance(__first, __last)); }
 
   // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap.
 
@@ -101,6 +146,8 @@ namespace std
       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
            _RandomAccessIterator>)
       __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
+      __glibcxx_requires_valid_range(__first, __last);
+      //      __glibcxx_requires_heap(__first, __last - 1);
 
       std::__push_heap(__first, _DistanceType((__last - __first) - 1), _DistanceType(0), 
                       _ValueType(*(__last - 1)));
@@ -145,6 +192,8 @@ namespace std
       // concept requirements
       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
            _RandomAccessIterator>)
+      __glibcxx_requires_valid_range(__first, __last);
+      __glibcxx_requires_heap_pred(__first, __last - 1, __comp);
 
       std::__push_heap(__first, _DistanceType((__last - __first) - 1), _DistanceType(0), 
                       _ValueType(*(__last - 1)), __comp);
@@ -200,6 +249,8 @@ namespace std
       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
            _RandomAccessIterator>)
       __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
+      __glibcxx_requires_valid_range(__first, __last);
+      __glibcxx_requires_heap(__first, __last);
 
       std::__pop_heap(__first, __last - 1, __last - 1, _ValueType(*(__last - 1)));
     }
@@ -256,6 +307,8 @@ namespace std
       // concept requirements
       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
            _RandomAccessIterator>)
+      __glibcxx_requires_valid_range(__first, __last);
+      __glibcxx_requires_heap_pred(__first, __last, __comp);
 
       typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType;
       std::__pop_heap(__first, __last - 1, __last - 1, _ValueType(*(__last - 1)), __comp);
@@ -282,6 +335,7 @@ namespace std
       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
            _RandomAccessIterator>)
       __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__last - __first < 2) return;
       _DistanceType __len = __last - __first;
@@ -317,7 +371,8 @@ namespace std
       // concept requirements
       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
            _RandomAccessIterator>)
-
+      __glibcxx_requires_valid_range(__first, __last);
+      
       if (__last - __first < 2) return;
       _DistanceType __len = __last - __first;
       _DistanceType __parent = (__len - 2)/2;
@@ -347,6 +402,8 @@ namespace std
            _RandomAccessIterator>)
       __glibcxx_function_requires(_LessThanComparableConcept<
            typename iterator_traits<_RandomAccessIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
+      //      __glibcxx_requires_heap(__first, __last);
 
       while (__last - __first > 1)
        std::pop_heap(__first, __last--);
@@ -370,6 +427,8 @@ namespace std
       // concept requirements
       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
            _RandomAccessIterator>)
+      __glibcxx_requires_valid_range(__first, __last);
+      __glibcxx_requires_heap_pred(__first, __last, __comp);
 
       while (__last - __first > 1)
        std::pop_heap(__first, __last--, __comp);
index 4533aee..4524e9e 100644 (file)
@@ -63,7 +63,7 @@
 
 #include <bits/concept_check.h>
 
-namespace std
+namespace __gnu_norm
 {
   // Supporting structures are split into common and templated types; the
   // latter publicly inherits from the former in an effort to reduce code
@@ -89,9 +89,9 @@ namespace std
    *  @if maint
    *  @brief Common part of a list::iterator.
    *
-   *  A simple type to walk a doubly-linked list.  All operations here should
-   *  be self-explanatory after taking any decent introductory data structures
-   *  course.
+   *  A simple type to walk a doubly-linked list.  All operations here
+   *  should be self-explanatory after taking any decent introductory
+   *  data structures course.
    *  @endif
   */
   struct _List_iterator_base
@@ -233,17 +233,20 @@ namespace std
     { _M_node_allocator.deallocate(__p, 1); }
   
     // NOTA BENE
-    // The stored instance is not actually of "allocator_type"'s type.  Instead
-    // we rebind the type to Allocator<List_node<Tp>>, which according to
-    // [20.1.5]/4 should probably be the same.  List_node<Tp> is not the same
-    // size as Tp (it's two pointers larger), and specializations on Tp may go
-    // unused because List_node<Tp> is being bound instead.
+    // The stored instance is not actually of "allocator_type"'s type.
+    // Instead we rebind the type to Allocator<List_node<Tp>>, which
+    // according to [20.1.5]/4 should probably be the same.
+    // List_node<Tp> is not the same size as Tp (it's two pointers
+    // larger), and specializations on Tp may go unused because
+    // List_node<Tp> is being bound instead.
     //
-    // We put this to the test in get_allocator above; if the two types are
-    // actually different, there had better be a conversion between them.
+    // We put this to the test in get_allocator above; if the two
+    // types are actually different, there had better be a conversion
+    // between them.
     //
-    // None of the predefined allocators shipped with the library (as of 3.1)
-    // use this instantiation anyhow; they're all instanceless.
+    // None of the predefined allocators shipped with the library (as
+    // of 3.1) use this instantiation anyhow; they're all
+    // instanceless.
     typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type
              _M_node_allocator;
   
@@ -329,36 +332,37 @@ namespace std
    *  <a href="tables.html#68">optional sequence requirements</a> with the
    *  %exception of @c at and @c operator[].
    *
-   *  This is a @e doubly @e linked %list.  Traversal up and down the %list
-   *  requires linear time, but adding and removing elements (or @e nodes) is
-   *  done in constant time, regardless of where the change takes place.
-   *  Unlike std::vector and std::deque, random-access iterators are not
-   *  provided, so subscripting ( @c [] ) access is not allowed.  For algorithms
-   *  which only need sequential access, this lack makes no difference.
+   *  This is a @e doubly @e linked %list.  Traversal up and down the
+   *  %list requires linear time, but adding and removing elements (or
+   *  @e nodes) is done in constant time, regardless of where the
+   *  change takes place.  Unlike std::vector and std::deque,
+   *  random-access iterators are not provided, so subscripting ( @c
+   *  [] ) access is not allowed.  For algorithms which only need
+   *  sequential access, this lack makes no difference.
    *
-   *  Also unlike the other standard containers, std::list provides specialized 
-   *  algorithms %unique to linked lists, such as splicing, sorting, and
-   *  in-place reversal.
+   *  Also unlike the other standard containers, std::list provides
+   *  specialized algorithms %unique to linked lists, such as
+   *  splicing, sorting, and in-place reversal.
    *
    *  @if maint
    *  A couple points on memory allocation for list<Tp>:
    *
-   *  First, we never actually allocate a Tp, we allocate List_node<Tp>'s
-   *  and trust [20.1.5]/4 to DTRT.  This is to ensure that after elements from
-   *  %list<X,Alloc1> are spliced into %list<X,Alloc2>, destroying the memory of
-   *  the second %list is a valid operation, i.e., Alloc1 giveth and Alloc2
-   *  taketh away.
+   *  First, we never actually allocate a Tp, we allocate
+   *  List_node<Tp>'s and trust [20.1.5]/4 to DTRT.  This is to ensure
+   *  that after elements from %list<X,Alloc1> are spliced into
+   *  %list<X,Alloc2>, destroying the memory of the second %list is a
+   *  valid operation, i.e., Alloc1 giveth and Alloc2 taketh away.
    *
    *  Second, a %list conceptually represented as
    *  @code
    *    A <---> B <---> C <---> D
    *  @endcode
-   *  is actually circular; a link exists between A and D.  The %list class
-   *  holds (as its only data member) a private list::iterator pointing to
-   *  @e D, not to @e A!  To get to the head of the %list, we start at the tail
-   *  and move forward by one.  When this member iterator's next/previous
-   *  pointers refer to itself, the %list is %empty.
-   *  @endif
+   *  is actually circular; a link exists between A and D.  The %list
+   *  class holds (as its only data member) a private list::iterator
+   *  pointing to @e D, not to @e A!  To get to the head of the %list,
+   *  we start at the tail and move forward by one.  When this member
+   *  iterator's next/previous pointers refer to itself, the %list is
+   *  %empty.  @endif
   */
   template<typename _Tp, typename _Alloc = allocator<_Tp> >
     class list : protected _List_base<_Tp, _Alloc>
@@ -505,18 +509,19 @@ namespace std
       { this->insert(begin(), __first, __last); }
   
     /**
-     *  No explicit dtor needed as the _Base dtor takes care of things.
-     *  The _Base dtor only erases the elements, and note that if the elements
-     *  themselves are pointers, the pointed-to memory is not touched in any
-     *  way.  Managing the pointer is the user's responsibilty.
+     *  No explicit dtor needed as the _Base dtor takes care of
+     *  things.  The _Base dtor only erases the elements, and note
+     *  that if the elements themselves are pointers, the pointed-to
+     *  memory is not touched in any way.  Managing the pointer is the
+     *  user's responsibilty.
     */
   
     /**
      *  @brief  %List assignment operator.
      *  @param  x  A %list of identical element and allocator types.
      * 
-     *  All the elements of @a x are copied, but unlike the copy constructor,
-     *  the allocator object is not copied.
+     *  All the elements of @a x are copied, but unlike the copy
+     *  constructor, the allocator object is not copied.
     */
     list&
     operator=(const list& __x);
@@ -526,13 +531,14 @@ namespace std
      *  @param  n  Number of elements to be assigned.
      *  @param  val  Value to be assigned.
      *
-     *  This function fills a %list with @a n copies of the given value.
-     *  Note that the assignment completely changes the %list and that the
-     *  resulting %list's size is the same as the number of elements assigned.
-     *  Old data may be lost.
+     *  This function fills a %list with @a n copies of the given
+     *  value.  Note that the assignment completely changes the %list
+     *  and that the resulting %list's size is the same as the number
+     *  of elements assigned.  Old data may be lost.
     */
     void
-    assign(size_type __n, const value_type& __val) { _M_fill_assign(__n, __val); }
+    assign(size_type __n, const value_type& __val) 
+    { _M_fill_assign(__n, __val); }
   
     /**
      *  @brief  Assigns a range to a %list.
@@ -568,44 +574,50 @@ namespace std
     begin() { return static_cast<_Node*>(this->_M_node._M_next); }
   
     /**
-     *  Returns a read-only (constant) iterator that points to the first element
-     *  in the %list.  Iteration is done in ordinary element order.
+     *  Returns a read-only (constant) iterator that points to the
+     *  first element in the %list.  Iteration is done in ordinary
+     *  element order.
     */
     const_iterator
     begin() const { return static_cast<_Node*>(this->_M_node._M_next); }
   
     /**
-     *  Returns a read/write iterator that points one past the last element in
-     *  the %list.  Iteration is done in ordinary element order.
+     *  Returns a read/write iterator that points one past the last
+     *  element in the %list.  Iteration is done in ordinary element
+     *  order.
     */
     iterator
     end() { return static_cast<_Node*>(&this->_M_node); }
   
     /**
-     *  Returns a read-only (constant) iterator that points one past the last
-     *  element in the %list.  Iteration is done in ordinary element order.
+     *  Returns a read-only (constant) iterator that points one past
+     *  the last element in the %list.  Iteration is done in ordinary
+     *  element order.
     */
     const_iterator
-    end() const { return const_cast<_Node *>(static_cast<const _Node*>(&this->_M_node)); }
+    end() const 
+    { return const_cast<_Node *>(static_cast<const _Node*>(&this->_M_node)); }
   
     /**
-     *  Returns a read/write reverse iterator that points to the last element in
-     *  the %list.  Iteration is done in reverse element order.
+     *  Returns a read/write reverse iterator that points to the last
+     *  element in the %list.  Iteration is done in reverse element
+     *  order.
     */
     reverse_iterator
     rbegin() { return reverse_iterator(end()); }
   
     /**
-     *  Returns a read-only (constant) reverse iterator that points to the last
-     *  element in the %list.  Iteration is done in reverse element order.
+     *  Returns a read-only (constant) reverse iterator that points to
+     *  the last element in the %list.  Iteration is done in reverse
+     *  element order.
     */
     const_reverse_iterator
     rbegin() const { return const_reverse_iterator(end()); }
   
     /**
-     *  Returns a read/write reverse iterator that points to one before the
-     *  first element in the %list.  Iteration is done in reverse element
-     *  order.
+     *  Returns a read/write reverse iterator that points to one
+     *  before the first element in the %list.  Iteration is done in
+     *  reverse element order.
     */
     reverse_iterator
     rend() { return reverse_iterator(begin()); }
@@ -621,7 +633,8 @@ namespace std
   
     // [23.2.2.2] capacity
     /**
-     *  Returns true if the %list is empty.  (Thus begin() would equal end().)
+     *  Returns true if the %list is empty.  (Thus begin() would equal
+     *  end().)
     */
     bool
     empty() const { return this->_M_node._M_next == &this->_M_node; }
@@ -635,14 +648,14 @@ namespace std
     max_size() const { return size_type(-1); }
   
     /**
-     *  @brief  Resizes the %list to the specified number of elements.
-     *  @param  new_size  Number of elements the %list should contain.
-     *  @param  x  Data with which new elements should be populated.
+     *  @brief Resizes the %list to the specified number of elements.
+     *  @param new_size Number of elements the %list should contain.
+     *  @param x Data with which new elements should be populated.
      *
-     *  This function will %resize the %list to the specified number of
-     *  elements.  If the number is smaller than the %list's current size the
-     *  %list is truncated, otherwise the %list is extended and new elements
-     *  are populated with given data.
+     *  This function will %resize the %list to the specified number
+     *  of elements.  If the number is smaller than the %list's
+     *  current size the %list is truncated, otherwise the %list is
+     *  extended and new elements are populated with given data.
     */
     void
     resize(size_type __new_size, const value_type& __x);
@@ -652,9 +665,9 @@ namespace std
      *  @param  new_size  Number of elements the %list should contain.
      *
      *  This function will resize the %list to the specified number of
-     *  elements.  If the number is smaller than the %list's current size the
-     *  %list is truncated, otherwise the %list is extended and new elements
-     *  are default-constructed.
+     *  elements.  If the number is smaller than the %list's current
+     *  size the %list is truncated, otherwise the %list is extended
+     *  and new elements are default-constructed.
     */
     void
     resize(size_type __new_size) { this->resize(__new_size, value_type()); }
@@ -675,8 +688,8 @@ namespace std
     front() const { return *begin(); }
   
     /**
-     *  Returns a read/write reference to the data at the last element of the
-     *  %list.
+     *  Returns a read/write reference to the data at the last element
+     *  of the %list.
     */
     reference
     back() { return *(--end()); }
@@ -693,10 +706,11 @@ namespace std
      *  @brief  Add data to the front of the %list.
      *  @param  x  Data to be added.
      *
-     *  This is a typical stack operation.  The function creates an element at
-     *  the front of the %list and assigns the given data to it.  Due to the
-     *  nature of a %list this operation can be done in constant time, and
-     *  does not invalidate iterators and references.
+     *  This is a typical stack operation.  The function creates an
+     *  element at the front of the %list and assigns the given data
+     *  to it.  Due to the nature of a %list this operation can be
+     *  done in constant time, and does not invalidate iterators and
+     *  references.
     */
     void
     push_front(const value_type& __x) { this->insert(begin(), __x); }
@@ -704,13 +718,14 @@ namespace std
     /**
      *  @brief  Removes first element.
      *
-     *  This is a typical stack operation.  It shrinks the %list by one.
-     *  Due to the nature of a %list this operation can be done in constant
-     *  time, and only invalidates iterators/references to the element being
-     *  removed.
+     *  This is a typical stack operation.  It shrinks the %list by
+     *  one.  Due to the nature of a %list this operation can be done
+     *  in constant time, and only invalidates iterators/references to
+     *  the element being removed.
      *
-     *  Note that no data is returned, and if the first element's data is
-     *  needed, it should be retrieved before pop_front() is called.
+     *  Note that no data is returned, and if the first element's data
+     *  is needed, it should be retrieved before pop_front() is
+     *  called.
     */
     void
     pop_front() { this->erase(begin()); }
@@ -719,10 +734,11 @@ namespace std
      *  @brief  Add data to the end of the %list.
      *  @param  x  Data to be added.
      *
-     *  This is a typical stack operation.  The function creates an element at
-     *  the end of the %list and assigns the given data to it.  Due to the
-     *  nature of a %list this operation can be done in constant time, and
-     *  does not invalidate iterators and references.
+     *  This is a typical stack operation.  The function creates an
+     *  element at the end of the %list and assigns the given data to
+     *  it.  Due to the nature of a %list this operation can be done
+     *  in constant time, and does not invalidate iterators and
+     *  references.
     */
     void
     push_back(const value_type& __x) { this->insert(end(), __x); }
@@ -730,13 +746,13 @@ namespace std
     /**
      *  @brief  Removes last element.
      *
-     *  This is a typical stack operation.  It shrinks the %list by one.
-     *  Due to the nature of a %list this operation can be done in constant
-     *  time, and only invalidates iterators/references to the element being
-     *  removed.
+     *  This is a typical stack operation.  It shrinks the %list by
+     *  one.  Due to the nature of a %list this operation can be done
+     *  in constant time, and only invalidates iterators/references to
+     *  the element being removed.
      *
-     *  Note that no data is returned, and if the last element's data is
-     *  needed, it should be retrieved before pop_back() is called.
+     *  Note that no data is returned, and if the last element's data
+     *  is needed, it should be retrieved before pop_back() is called.
     */
     void
     pop_back()
@@ -751,10 +767,10 @@ namespace std
      *  @param  x  Data to be inserted.
      *  @return  An iterator that points to the inserted data.
      *
-     *  This function will insert a copy of the given value before the specified
-     *  location.
-     *  Due to the nature of a %list this operation can be done in constant
-     *  time, and does not invalidate iterators and references.
+     *  This function will insert a copy of the given value before the
+     *  specified location.  Due to the nature of a %list this
+     *  operation can be done in constant time, and does not
+     *  invalidate iterators and references.
     */
     iterator
     insert(iterator __position, const value_type& __x);
@@ -765,11 +781,12 @@ namespace std
      *  @param  n  Number of elements to be inserted.
      *  @param  x  Data to be inserted.
      *
-     *  This function will insert a specified number of copies of the given data
-     *  before the location specified by @a position.
+     *  This function will insert a specified number of copies of the
+     *  given data before the location specified by @a position.
      *
-     *  Due to the nature of a %list this operation can be done in constant
-     *  time, and does not invalidate iterators and references.
+     *  Due to the nature of a %list this operation can be done in
+     *  constant time, and does not invalidate iterators and
+     *  references.
     */
     void
     insert(iterator __position, size_type __n, const value_type& __x)
@@ -781,16 +798,17 @@ namespace std
      *  @param  first  An input iterator.
      *  @param  last   An input iterator.
      *
-     *  This function will insert copies of the data in the range
-     *  [@a first,@a last) into the %list before the location specified by @a
-     *  position.
+     *  This function will insert copies of the data in the range [@a
+     *  first,@a last) into the %list before the location specified by
+     *  @a position.
      *
      *  Due to the nature of a %list this operation can be done in constant
      *  time, and does not invalidate iterators and references.
     */
     template<typename _InputIterator>
       void
-      insert(iterator __position, _InputIterator __first, _InputIterator __last)
+      insert(iterator __position, _InputIterator __first, 
+            _InputIterator __last)
       {
         // Check whether it's an integral type.  If so, it's not an iterator.
         typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
@@ -805,13 +823,12 @@ namespace std
      *  This function will erase the element at the given position and thus
      *  shorten the %list by one.
      *
-     *  Due to the nature of a %list this operation can be done in constant
-     *  time, and only invalidates iterators/references to the element being
-     *  removed.
-     *  The user is also cautioned that
-     *  this function only erases the element, and that if the element is itself
-     *  a pointer, the pointed-to memory is not touched in any way.  Managing
-     *  the pointer is the user's responsibilty.
+     *  Due to the nature of a %list this operation can be done in
+     *  constant time, and only invalidates iterators/references to
+     *  the element being removed.  The user is also cautioned that
+     *  this function only erases the element, and that if the element
+     *  is itself a pointer, the pointed-to memory is not touched in
+     *  any way.  Managing the pointer is the user's responsibilty.
     */
     iterator
     erase(iterator __position);
@@ -824,16 +841,16 @@ namespace std
      *  @return  An iterator pointing to the element pointed to by @a last
      *           prior to erasing (or end()).
      *
-     *  This function will erase the elements in the range @a [first,last) and
-     *  shorten the %list accordingly.
+     *  This function will erase the elements in the range @a
+     *  [first,last) and shorten the %list accordingly.
      *
-     *  Due to the nature of a %list this operation can be done in constant
-     *  time, and only invalidates iterators/references to the element being
-     *  removed.
-     *  The user is also cautioned that
-     *  this function only erases the elements, and that if the elements
-     *  themselves are pointers, the pointed-to memory is not touched in any
-     *  way.  Managing the pointer is the user's responsibilty.
+     *  Due to the nature of a %list this operation can be done in
+     *  constant time, and only invalidates iterators/references to
+     *  the element being removed.  The user is also cautioned that
+     *  this function only erases the elements, and that if the
+     *  elements themselves are pointers, the pointed-to memory is not
+     *  touched in any way.  Managing the pointer is the user's
+     *  responsibilty.
     */
     iterator
     erase(iterator __first, iterator __last)
@@ -847,18 +864,19 @@ namespace std
      *  @brief  Swaps data with another %list.
      *  @param  x  A %list of the same element and allocator types.
      *
-     *  This exchanges the elements between two lists in constant time.
-     *  Note that the global std::swap() function is specialized such that
-     *  std::swap(l1,l2) will feed to this function.
+     *  This exchanges the elements between two lists in constant
+     *  time.  Note that the global std::swap() function is
+     *  specialized such that std::swap(l1,l2) will feed to this
+     *  function.
     */
     void
     swap(list& __x);
   
     /**
-     *  Erases all the elements.  Note that this function only erases the
-     *  elements, and that if the elements themselves are pointers, the
-     *  pointed-to memory is not touched in any way.  Managing the pointer is
-     *  the user's responsibilty.
+     *  Erases all the elements.  Note that this function only erases
+     *  the elements, and that if the elements themselves are
+     *  pointers, the pointed-to memory is not touched in any way.
+     *  Managing the pointer is the user's responsibilty.
     */
     void
     clear() { _Base::__clear(); }
@@ -869,8 +887,9 @@ namespace std
      *  @param  position  Iterator referencing the element to insert before.
      *  @param  x  Source list.
      *
-     *  The elements of @a x are inserted in constant time in front of the
-     *  element referenced by @a position.  @a x becomes an empty list.
+     *  The elements of @a x are inserted in constant time in front of
+     *  the element referenced by @a position.  @a x becomes an empty
+     *  list.
     */
     void
     splice(iterator __position, list& __x)
@@ -885,8 +904,8 @@ namespace std
      *  @param  x  Source list.
      *  @param  i  Iterator referencing the element to move.
      *
-     *  Removes the element in list @a x referenced by @a i and inserts it into the
-     *  current list before @a position.
+     *  Removes the element in list @a x referenced by @a i and
+     *  inserts it into the current list before @a position.
     */
     void
     splice(iterator __position, list&, iterator __i)
@@ -904,8 +923,8 @@ namespace std
      *  @param  first  Iterator referencing the start of range in x.
      *  @param  last  Iterator referencing the end of range in x.
      *
-     *  Removes elements in the range [first,last) and inserts them before
-     *  @a position in constant time.
+     *  Removes elements in the range [first,last) and inserts them
+     *  before @a position in constant time.
      *
      *  Undefined if @a position is in [first,last).
    */
@@ -920,11 +939,11 @@ namespace std
      *  @brief  Remove all elements equal to value.
      *  @param  value  The value to remove.
      *
-     *  Removes every element in the list equal to @a value.  Remaining
-     *  elements stay in list order.  Note that this function only erases the
-     *  elements, and that if the elements themselves are pointers, the
-     *  pointed-to memory is not touched in any way.  Managing the pointer is
-     *  the user's responsibilty.
+     *  Removes every element in the list equal to @a value.
+     *  Remaining elements stay in list order.  Note that this
+     *  function only erases the elements, and that if the elements
+     *  themselves are pointers, the pointed-to memory is not touched
+     *  in any way.  Managing the pointer is the user's responsibilty.
     */
     void
     remove(const _Tp& __value);
@@ -933,11 +952,12 @@ namespace std
      *  @brief  Remove all elements satisfying a predicate.
      *  @param  Predicate  Unary predicate function or object.
      *
-     *  Removes every element in the list for which the predicate returns
-     *  true.  Remaining elements stay in list order.  Note that this function
-     *  only erases the elements, and that if the elements themselves are
-     *  pointers, the pointed-to memory is not touched in any way.  Managing
-     *  the pointer is the user's responsibilty.
+     *  Removes every element in the list for which the predicate
+     *  returns true.  Remaining elements stay in list order.  Note
+     *  that this function only erases the elements, and that if the
+     *  elements themselves are pointers, the pointed-to memory is not
+     *  touched in any way.  Managing the pointer is the user's
+     *  responsibilty.
     */
     template<typename _Predicate>
       void
@@ -946,11 +966,12 @@ namespace std
     /**
      *  @brief  Remove consecutive duplicate elements.
      *
-     *  For each consecutive set of elements with the same value, remove all
-     *  but the first one.  Remaining elements stay in list order.  Note that
-     *  this function only erases the elements, and that if the elements
-     *  themselves are pointers, the pointed-to memory is not touched in any
-     *  way.  Managing the pointer is the user's responsibilty.
+     *  For each consecutive set of elements with the same value,
+     *  remove all but the first one.  Remaining elements stay in list
+     *  order.  Note that this function only erases the elements, and
+     *  that if the elements themselves are pointers, the pointed-to
+     *  memory is not touched in any way.  Managing the pointer is the
+     *  user's responsibilty.
     */
     void
     unique();
@@ -960,11 +981,12 @@ namespace std
      *  @param  BinaryPredicate  Binary predicate function or object.
      *
      *  For each consecutive set of elements [first,last) that satisfy
-     *  predicate(first,i) where i is an iterator in [first,last), remove all
-     *  but the first one.  Remaining elements stay in list order.  Note that
-     *  this function only erases the elements, and that if the elements
-     *  themselves are pointers, the pointed-to memory is not touched in any
-     *  way.  Managing the pointer is the user's responsibilty.
+     *  predicate(first,i) where i is an iterator in [first,last),
+     *  remove all but the first one.  Remaining elements stay in list
+     *  order.  Note that this function only erases the elements, and
+     *  that if the elements themselves are pointers, the pointed-to
+     *  memory is not touched in any way.  Managing the pointer is the
+     *  user's responsibilty.
     */
     template<typename _BinaryPredicate>
       void
@@ -975,9 +997,9 @@ namespace std
      *  @param  x  Sorted list to merge.
      *
      *  Assumes that both @a x and this list are sorted according to
-     *  operator<().  Merges elements of @a x into this list in sorted order,
-     *  leaving @a x empty when complete.  Elements in this list precede
-     *  elements in @a x that are equal.
+     *  operator<().  Merges elements of @a x into this list in sorted
+     *  order, leaving @a x empty when complete.  Elements in this
+     *  list precede elements in @a x that are equal.
     */
     void
     merge(list& __x);
@@ -988,9 +1010,10 @@ namespace std
      *  @param  StrictWeakOrdering  Comparison function definining sort order.
      *
      *  Assumes that both @a x and this list are sorted according to
-     *  StrictWeakOrdering.  Merges elements of @a x into this list in sorted
-     *  order, leaving @a x empty when complete.  Elements in this list precede
-     *  elements in @a x that are equivalent according to StrictWeakOrdering().
+     *  StrictWeakOrdering.  Merges elements of @a x into this list in
+     *  sorted order, leaving @a x empty when complete.  Elements in
+     *  this list precede elements in @a x that are equivalent
+     *  according to StrictWeakOrdering().
     */
     template<typename _StrictWeakOrdering>
       void
@@ -1007,8 +1030,8 @@ namespace std
     /**
      *  @brief  Sort the elements.
      *
-     *  Sorts the elements of this list in NlogN time.  Equivalent elements
-     *  remain in list order.
+     *  Sorts the elements of this list in NlogN time.  Equivalent
+     *  elements remain in list order.
     */
     void
     sort();
@@ -1016,8 +1039,8 @@ namespace std
     /**
      *  @brief  Sort the elements according to comparison function.
      *
-     *  Sorts the elements of this list in NlogN time.  Equivalent elements
-     *  remain in list order.
+     *  Sorts the elements of this list in NlogN time.  Equivalent
+     *  elements remain in list order.
     */
     template<typename _StrictWeakOrdering>
       void
@@ -1026,7 +1049,7 @@ namespace std
   protected:
     // Internal assign functions follow.
   
-    // called by the range assign to implement [23.1.1]/9
+    // Called by the range assign to implement [23.1.1]/9
     template<typename _Integer>
       void
       _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
@@ -1035,20 +1058,21 @@ namespace std
                        static_cast<value_type>(__val));
       }
   
-    // called by the range assign to implement [23.1.1]/9
+    // Called by the range assign to implement [23.1.1]/9
     template<typename _InputIterator>
       void
-      _M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type);
+      _M_assign_dispatch(_InputIterator __first, _InputIterator __last, 
+                        __false_type);
   
-    // Called by assign(n,t), and the range assign when it turns out to be the
-    // same thing.
+    // Called by assign(n,t), and the range assign when it turns out
+    // to be the same thing.
     void
     _M_fill_assign(size_type __n, const value_type& __val);
   
   
     // Internal insert functions follow.
   
-    // called by the range insert to implement [23.1.1]/9
+    // Called by the range insert to implement [23.1.1]/9
     template<typename _Integer>
       void
       _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
@@ -1058,7 +1082,7 @@ namespace std
                        static_cast<value_type>(__x));
       }
   
-    // called by the range insert to implement [23.1.1]/9
+    // Called by the range insert to implement [23.1.1]/9
     template<typename _InputIterator>
       void
       _M_insert_dispatch(iterator __pos,
@@ -1069,8 +1093,8 @@ namespace std
           insert(__pos, *__first);
       }
   
-    // Called by insert(p,n,x), and the range insert when it turns out to be
-    // the same thing.
+    // Called by insert(p,n,x), and the range insert when it turns out
+    // to be the same thing.
     void
     _M_fill_insert(iterator __pos, size_type __n, const value_type& __x)
     {
@@ -1105,9 +1129,9 @@ namespace std
    *  @param  y  A %list of the same type as @a x.
    *  @return  True iff the size and elements of the lists are equal.
    *
-   *  This is an equivalence relation.  It is linear in the size of the
-   *  lists.  Lists are considered equivalent if their sizes are equal,
-   *  and if corresponding elements compare equal.
+   *  This is an equivalence relation.  It is linear in the size of
+   *  the lists.  Lists are considered equivalent if their sizes are
+   *  equal, and if corresponding elements compare equal.
   */
   template<typename _Tp, typename _Alloc>
   inline bool
@@ -1174,6 +1198,6 @@ namespace std
     inline void
     swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
     { __x.swap(__y); }
-} // namespace std
+} // namespace __gnu_norm
 
 #endif /* _LIST_H */
index 7b15dcc..9895cad 100644 (file)
@@ -63,7 +63,7 @@
 
 #include <bits/concept_check.h>
 
-namespace std
+namespace __gnu_norm
 {
   /**
    *  @brief A standard container made up of (key,value) pairs, which can be
@@ -653,6 +653,6 @@ namespace std
     inline void
     swap(map<_Key,_Tp,_Compare,_Alloc>& __x, map<_Key,_Tp,_Compare,_Alloc>& __y)
     { __x.swap(__y); }
-} // namespace std
+} // namespace __gnu_norm
 
 #endif /* _MAP_H */
index ebc7ff9..4d89228 100644 (file)
@@ -63,7 +63,7 @@
 
 #include <bits/concept_check.h>
 
-namespace std
+namespace __gnu_norm
 {
   // Forward declaration of operators < and ==, needed for friend declaration.
   
@@ -632,6 +632,6 @@ namespace std
     swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x,
          multimap<_Key,_Tp,_Compare,_Alloc>& __y)
     { __x.swap(__y); }
-} // namespace std
+} // namespace __gnu_norm
 
 #endif /* _MULTIMAP_H */
index 49d8c4e..d85c910 100644 (file)
@@ -63,7 +63,7 @@
 
 #include <bits/concept_check.h>
 
-namespace std
+namespace __gnu_norm
 {
 
 // Forward declaration of operators < and ==, needed for friend declaration.
@@ -256,6 +256,6 @@ inline void swap(multiset<_Key,_Compare,_Alloc>& __x,
   __x.swap(__y);
 }
 
-} // namespace std
+} // namespace __gnu_norm
 
 #endif /* _MULTISET_H */
index 4aa92ed..7b901a5 100644 (file)
@@ -61,6 +61,8 @@
 #ifndef _STL_NUMERIC_H
 #define _STL_NUMERIC_H 1
 
+#include <debug/debug.h>
+
 namespace std
 {
 
@@ -70,6 +72,7 @@ namespace std
     {
       // concept requirements
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       for ( ; __first != __last; ++__first)
        __init = __init + *__first;
@@ -83,6 +86,7 @@ namespace std
     {
       // concept requirements
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       for ( ; __first != __last; ++__first)
        __init = __binary_op(__init, *__first);
@@ -97,6 +101,7 @@ namespace std
       // concept requirements
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
+      __glibcxx_requires_valid_range(__first1, __last1);
 
       for ( ; __first1 != __last1; ++__first1, ++__first2)
        __init = __init + (*__first1 * *__first2);
@@ -114,6 +119,7 @@ namespace std
       // concept requirements
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
+      __glibcxx_requires_valid_range(__first1, __last1);
 
       for ( ; __first1 != __last1; ++__first1, ++__first2)
        __init = __binary_op1(__init, __binary_op2(*__first1, *__first2));
@@ -130,6 +136,7 @@ namespace std
       // concept requirements
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first == __last) return __result;
       *__result = *__first;
@@ -151,6 +158,7 @@ namespace std
       // concept requirements
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first == __last) return __result;
       *__result = *__first;
@@ -172,6 +180,7 @@ namespace std
       // concept requirements
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first == __last) return __result;
       *__result = *__first;
@@ -194,6 +203,7 @@ namespace std
       // concept requirements
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first == __last) return __result;
       *__result = *__first;
index 0bb41ac..441fc55 100644 (file)
 #define _QUEUE_H 1
 
 #include <bits/concept_check.h>
+#include <debug/debug.h>
 
 namespace std
 {
   // Forward declarations of operators < and ==, needed for friend declaration.
+  template<typename _Tp, typename _Sequence = deque<_Tp> >
+    class queue;
   
-  template <typename _Tp, typename _Sequence = deque<_Tp> >
-  class queue;
-  
-  template <typename _Tp, typename _Seq>
-  inline bool operator==(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&);
-  
-  template <typename _Tp, typename _Seq>
-  inline bool operator<(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&);
+  template<typename _Tp, typename _Seq>
+    inline bool 
+    operator==(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&);
   
+  template<typename _Tp, typename _Seq>
+    inline bool 
+    operator<(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&);
   
   /**
    *  @brief  A standard container giving FIFO behavior.
@@ -101,111 +102,133 @@ namespace std
    *  which is a typedef for the second Sequence parameter, and @c push and
    *  @c pop, which are standard %queue/FIFO operations.
   */
-  template <typename _Tp, typename _Sequence>
+  template<typename _Tp, typename _Sequence>
     class queue
-  {
-    // concept requirements
-    typedef typename _Sequence::value_type _Sequence_value_type;
-    __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
-    __glibcxx_class_requires(_Sequence, _FrontInsertionSequenceConcept)
-    __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept)
-    __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
-  
-    template <typename _Tp1, typename _Seq1>
-    friend bool operator== (const queue<_Tp1, _Seq1>&,
-                            const queue<_Tp1, _Seq1>&);
-    template <typename _Tp1, typename _Seq1>
-    friend bool operator< (const queue<_Tp1, _Seq1>&,
-                           const queue<_Tp1, _Seq1>&);
-  
-  public:
-    typedef typename _Sequence::value_type                value_type;
-    typedef typename _Sequence::reference                 reference;
-    typedef typename _Sequence::const_reference           const_reference;
-    typedef typename _Sequence::size_type                 size_type;
-    typedef          _Sequence                            container_type;
-  
-  protected:
-    /**
-     *  'c' is the underlying container.  Maintainers wondering why this isn't
-     *  uglified as per style guidelines should note that this name is
-     *  specified in the standard, [23.2.3.1].  (Why?  Presumably for the same
-     *  reason that it's protected instead of private:  to allow derivation.
-     *  But none of the other containers allow for derivation.  Odd.)
-    */
-    _Sequence c;
-  
-  public:
-    /**
-     *  @brief  Default constructor creates no elements.
-    */
-    explicit
-    queue(const _Sequence& __c = _Sequence())
-    : c(__c) {}
-  
-    /**
-     *  Returns true if the %queue is empty.
-    */
-    bool
-    empty() const { return c.empty(); }
-  
-    /**  Returns the number of elements in the %queue.  */
-    size_type
-    size() const { return c.size(); }
-  
-    /**
-     *  Returns a read/write reference to the data at the first element of the
-     *  %queue.
-    */
-    reference
-    front() { return c.front(); }
-  
-    /**
-     *  Returns a read-only (constant) reference to the data at the first
-     *  element of the %queue.
-    */
-    const_reference
-    front() const { return c.front(); }
-  
-    /**
-     *  Returns a read/write reference to the data at the last element of the
-     *  %queue.
-    */
-    reference
-    back() { return c.back(); }
-  
-    /**
-     *  Returns a read-only (constant) reference to the data at the last
-     *  element of the %queue.
-    */
-    const_reference
-    back() const { return c.back(); }
-  
-    /**
-     *  @brief  Add data to the end of the %queue.
-     *  @param  x  Data to be added.
-     *
-     *  This is a typical %queue operation.  The function creates an element at
-     *  the end of the %queue and assigns the given data to it.
-     *  The time complexity of the operation depends on the underlying
-     *  sequence.
-    */
-    void
-    push(const value_type& __x) { c.push_back(__x); }
-  
-    /**
-     *  @brief  Removes first element.
-     *
-     *  This is a typical %queue operation.  It shrinks the %queue by one.
-     *  The time complexity of the operation depends on the underlying
-     *  sequence.
-     *
-     *  Note that no data is returned, and if the first element's data is
-     *  needed, it should be retrieved before pop() is called.
-    */
-    void
-    pop() { c.pop_front(); }
-  };
+    {
+      // concept requirements
+      typedef typename _Sequence::value_type _Sequence_value_type;
+      __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
+      __glibcxx_class_requires(_Sequence, _FrontInsertionSequenceConcept)
+      __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept)
+      __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
+  
+       template<typename _Tp1, typename _Seq1>
+          friend bool 
+          operator==(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
+
+      template<typename _Tp1, typename _Seq1>
+        friend bool 
+        operator<(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&);
+  
+    public:
+      typedef typename _Sequence::value_type                value_type;
+      typedef typename _Sequence::reference                 reference;
+      typedef typename _Sequence::const_reference           const_reference;
+      typedef typename _Sequence::size_type                 size_type;
+      typedef          _Sequence                            container_type;
+      
+    protected:
+      /**
+       *  'c' is the underlying container.  Maintainers wondering why
+       *  this isn't uglified as per style guidelines should note that
+       *  this name is specified in the standard, [23.2.3.1].  (Why?
+       *  Presumably for the same reason that it's protected instead
+       *  of private: to allow derivation.  But none of the other
+       *  containers allow for derivation.  Odd.)
+       */
+      _Sequence c;
+      
+    public:
+      /**
+       *  @brief  Default constructor creates no elements.
+       */
+      explicit
+      queue(const _Sequence& __c = _Sequence()) : c(__c) {}
+      
+      /**
+       *  Returns true if the %queue is empty.
+       */
+      bool
+      empty() const { return c.empty(); }
+      
+      /**  Returns the number of elements in the %queue.  */
+      size_type
+      size() const { return c.size(); }
+      
+      /**
+       *  Returns a read/write reference to the data at the first
+       *  element of the %queue.
+       */
+      reference
+      front() 
+      { 
+       __glibcxx_requires_nonempty();
+       return c.front(); 
+      }
+      
+      /**
+       *  Returns a read-only (constant) reference to the data at the first
+       *  element of the %queue.
+       */
+      const_reference
+      front() const 
+      { 
+       __glibcxx_requires_nonempty();
+       return c.front(); 
+      }
+      
+      /**
+       *  Returns a read/write reference to the data at the last
+       *  element of the %queue.
+       */
+      reference
+      back() 
+      {
+       __glibcxx_requires_nonempty();
+       return c.back(); 
+      }
+      
+      /**
+       *  Returns a read-only (constant) reference to the data at the last
+       *  element of the %queue.
+       */
+      const_reference
+      back() const 
+      {
+       __glibcxx_requires_nonempty();
+       return c.back(); 
+      }
+      
+      /**
+       *  @brief  Add data to the end of the %queue.
+       *  @param  x  Data to be added.
+       *
+       *  This is a typical %queue operation.  The function creates an
+       *  element at the end of the %queue and assigns the given data
+       *  to it.  The time complexity of the operation depends on the
+       *  underlying sequence.
+       */
+      void
+      push(const value_type& __x) { c.push_back(__x); }
+      
+      /**
+       *  @brief  Removes first element.
+       *
+       *  This is a typical %queue operation.  It shrinks the %queue by one.
+       *  The time complexity of the operation depends on the underlying
+       *  sequence.
+       *
+       *  Note that no data is returned, and if the first element's
+       *  data is needed, it should be retrieved before pop() is
+       *  called.
+       */
+      void
+      pop() 
+      { 
+       __glibcxx_requires_nonempty();
+       c.pop_front(); 
+      }
+    };
   
   
   /**
@@ -219,9 +242,10 @@ namespace std
    *  linear in the size of the sequences, and queues are considered equivalent
    *  if their sequences compare equal.
   */
-  template <typename _Tp, typename _Sequence>
+  template<typename _Tp, typename _Sequence>
     inline bool 
-    operator==(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y)
+    operator==(const queue<_Tp,_Sequence>& __x, 
+              const queue<_Tp,_Sequence>& __y)
     { return __x.c == __y.c; }
   
   /**
@@ -230,39 +254,43 @@ namespace std
    *  @param  y  A %queue of the same type as @a x.
    *  @return  True iff @a x is lexicographically less than @a y.
    *
-   *  This is an total ordering relation.  Complexity and semantics depend on
-   *  the underlying sequence type, but the expected rules are:  this relation
-   *  is linear in the size of the sequences, the elements must be comparable
-   *  with @c <, and std::lexicographical_compare() is usually used to make the
+   *  This is an total ordering relation.  Complexity and semantics
+   *  depend on the underlying sequence type, but the expected rules
+   *  are: this relation is linear in the size of the sequences, the
+   *  elements must be comparable with @c <, and
+   *  std::lexicographical_compare() is usually used to make the
    *  determination.
   */
-  template <typename _Tp, typename _Sequence>
+  template<typename _Tp, typename _Sequence>
     inline bool
     operator<(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y)
     { return __x.c < __y.c; }
   
   /// Based on operator==
-  template <typename _Tp, typename _Sequence>
+  template<typename _Tp, typename _Sequence>
     inline bool
-    operator!=(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y)
+    operator!=(const queue<_Tp,_Sequence>& __x, 
+              const queue<_Tp,_Sequence>& __y)
     { return !(__x == __y); }
   
   /// Based on operator<
-  template <typename _Tp, typename _Sequence>
+  template<typename _Tp, typename _Sequence>
     inline bool 
     operator>(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y)
     { return __y < __x; }
   
   /// Based on operator<
-  template <typename _Tp, typename _Sequence>
+  template<typename _Tp, typename _Sequence>
     inline bool 
-    operator<=(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y)
+    operator<=(const queue<_Tp,_Sequence>& __x, 
+              const queue<_Tp,_Sequence>& __y)
     { return !(__y < __x); }
   
   /// Based on operator<
-  template <typename _Tp, typename _Sequence>
+  template<typename _Tp, typename _Sequence>
     inline bool 
-    operator>=(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y)
+    operator>=(const queue<_Tp,_Sequence>& __x, 
+              const queue<_Tp,_Sequence>& __y)
     { return !(__x < __y); }
   
   
@@ -272,157 +300,169 @@ namespace std
    *  @ingroup Containers
    *  @ingroup Sequences
    *
-   *  This is not a true container, but an @e adaptor.  It holds another
-   *  container, and provides a wrapper interface to that container.  The
-   *  wrapper is what enforces sorting and first-in-first-out %queue behavior.
-   *  Very few of the standard container/sequence interface requirements are
-   *  met (e.g., iterators).
+   *  This is not a true container, but an @e adaptor.  It holds
+   *  another container, and provides a wrapper interface to that
+   *  container.  The wrapper is what enforces sorting and
+   *  first-in-first-out %queue behavior.  Very few of the standard
+   *  container/sequence interface requirements are met (e.g.,
+   *  iterators).
    *
    *  The second template parameter defines the type of the underlying
-   *  sequence/container.  It defaults to std::vector, but it can be any type
-   *  that supports @c front(), @c push_back, @c pop_back, and random-access
-   *  iterators, such as std::deque or an appropriate user-defined type.
+   *  sequence/container.  It defaults to std::vector, but it can be
+   *  any type that supports @c front(), @c push_back, @c pop_back,
+   *  and random-access iterators, such as std::deque or an
+   *  appropriate user-defined type.
    *
-   *  The third template parameter supplies the means of making priority
-   *  comparisons.  It defaults to @c less<value_type> but can be anything
-   *  defining a strict weak ordering.
+   *  The third template parameter supplies the means of making
+   *  priority comparisons.  It defaults to @c less<value_type> but
+   *  can be anything defining a strict weak ordering.
    *
    *  Members not found in "normal" containers are @c container_type,
-   *  which is a typedef for the second Sequence parameter, and @c push,
-   *  @c pop, and @c top, which are standard %queue/FIFO operations.
+   *  which is a typedef for the second Sequence parameter, and @c
+   *  push, @c pop, and @c top, which are standard %queue/FIFO
+   *  operations.
    *
-   *  @note  No equality/comparison operators are provided for %priority_queue.
+   *  @note No equality/comparison operators are provided for
+   *  %priority_queue.
    *
-   *  @note  Sorting of the elements takes place as they are added to, and
-   *         removed from, the %priority_queue using the %priority_queue's
-   *         member functions.  If you access the elements by other means, and
-   *         change their data such that the sorting order would be different,
-   *         the %priority_queue will not re-sort the elements for you.  (How
-   *         could it know to do so?)
+   *  @note Sorting of the elements takes place as they are added to,
+   *  and removed from, the %priority_queue using the
+   *  %priority_queue's member functions.  If you access the elements
+   *  by other means, and change their data such that the sorting
+   *  order would be different, the %priority_queue will not re-sort
+   *  the elements for you.  (How could it know to do so?)
   */
-  template <typename _Tp, typename _Sequence = vector<_Tp>,
+  template<typename _Tp, typename _Sequence = vector<_Tp>,
             typename _Compare  = less<typename _Sequence::value_type> >
     class priority_queue
-  {
-    // concept requirements
-    typedef typename _Sequence::value_type _Sequence_value_type;
-    __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
-    __glibcxx_class_requires(_Sequence, _SequenceConcept)
-    __glibcxx_class_requires(_Sequence, _RandomAccessContainerConcept)
-    __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
-    __glibcxx_class_requires4(_Compare, bool, _Tp, _Tp, _BinaryFunctionConcept)
-  
-  public:
-    typedef typename _Sequence::value_type                value_type;
-    typedef typename _Sequence::reference                 reference;
-    typedef typename _Sequence::const_reference           const_reference;
-    typedef typename _Sequence::size_type                 size_type;
-    typedef          _Sequence                            container_type;
-  
-  protected:
-    //  See queue::c for notes on these names.
-    _Sequence  c;
-    _Compare   comp;
-  
-  public:
-    /**
-     *  @brief  Default constructor creates no elements.
-    */
-    explicit
-    priority_queue(const _Compare& __x = _Compare(),
-                   const _Sequence& __s = _Sequence()) 
-    : c(__s), comp(__x) 
-    { std::make_heap(c.begin(), c.end(), comp); }
-  
-    /**
-     *  @brief  Builds a %queue from a range.
-     *  @param  first  An input iterator.
-     *  @param  last  An input iterator.
-     *  @param  x  A comparison functor describing a strict weak ordering.
-     *  @param  s  An initial sequence with which to start.
-     * 
-     *  Begins by copying @a s, inserting a copy of the elements from
-     *  @a [first,last) into the copy of @a s, then ordering the copy
-     *  according to @a x.
-     *
-     *  For more information on function objects, see the documentation on
-     *  @link s20_3_1_base functor base classes@endlink.
-    */
-    template <typename _InputIterator>
-      priority_queue(_InputIterator __first, _InputIterator __last,
-                     const _Compare& __x = _Compare(),
-                     const _Sequence& __s = _Sequence())
-      : c(__s), comp(__x)
-      { 
-        c.insert(c.end(), __first, __last);
-        std::make_heap(c.begin(), c.end(), comp);
-      }
-  
-    /**
-     *  Returns true if the %queue is empty.
-    */
-    bool
-    empty() const { return c.empty(); }
-  
-    /**  Returns the number of elements in the %queue.  */
-    size_type
-    size() const { return c.size(); }
-  
-    /**
-     *  Returns a read-only (constant) reference to the data at the first
-     *  element of the %queue.
-    */
-    const_reference
-    top() const { return c.front(); }
-  
-    /**
-     *  @brief  Add data to the %queue.
-     *  @param  x  Data to be added.
-     *
-     *  This is a typical %queue operation.
-     *  The time complexity of the operation depends on the underlying
-     *  sequence.
-    */
-    void 
-    push(const value_type& __x) 
     {
-      try 
+      // concept requirements
+      typedef typename _Sequence::value_type _Sequence_value_type;
+      __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
+      __glibcxx_class_requires(_Sequence, _SequenceConcept)
+      __glibcxx_class_requires(_Sequence, _RandomAccessContainerConcept)
+      __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
+      __glibcxx_class_requires4(_Compare, bool, _Tp,_Tp,_BinaryFunctionConcept)
+  
+       public:
+      typedef typename _Sequence::value_type                value_type;
+      typedef typename _Sequence::reference                 reference;
+      typedef typename _Sequence::const_reference           const_reference;
+      typedef typename _Sequence::size_type                 size_type;
+      typedef          _Sequence                            container_type;
+      
+    protected:
+      //  See queue::c for notes on these names.
+      _Sequence  c;
+      _Compare   comp;
+      
+    public:
+      /**
+       *  @brief  Default constructor creates no elements.
+       */
+      explicit
+      priority_queue(const _Compare& __x = _Compare(), 
+                    const _Sequence& __s = _Sequence()) 
+      : c(__s), comp(__x) 
+      { std::make_heap(c.begin(), c.end(), comp); }
+  
+      /**
+       *  @brief  Builds a %queue from a range.
+       *  @param  first  An input iterator.
+       *  @param  last  An input iterator.
+       *  @param  x  A comparison functor describing a strict weak ordering.
+       *  @param  s  An initial sequence with which to start.
+       * 
+       *  Begins by copying @a s, inserting a copy of the elements
+       *  from @a [first,last) into the copy of @a s, then ordering
+       *  the copy according to @a x.
+       *
+       *  For more information on function objects, see the
+       *  documentation on @link s20_3_1_base functor base
+       *  classes@endlink.
+       */
+      template<typename _InputIterator>
+        priority_queue(_InputIterator __first, _InputIterator __last,
+                      const _Compare& __x = _Compare(),
+                      const _Sequence& __s = _Sequence())
+       : c(__s), comp(__x)
+        { 
+         __glibcxx_requires_valid_range(__first, __last);
+         c.insert(c.end(), __first, __last);
+         std::make_heap(c.begin(), c.end(), comp);
+       }
+      
+      /**
+       *  Returns true if the %queue is empty.
+       */
+      bool
+      empty() const { return c.empty(); }
+      
+      /**  Returns the number of elements in the %queue.  */
+      size_type
+      size() const { return c.size(); }
+      
+      /**
+       *  Returns a read-only (constant) reference to the data at the first
+       *  element of the %queue.
+       */
+      const_reference
+      top() const 
+      {
+       __glibcxx_requires_nonempty();
+       return c.front(); 
+      }
+      
+      /**
+       *  @brief  Add data to the %queue.
+       *  @param  x  Data to be added.
+       *
+       *  This is a typical %queue operation.
+       *  The time complexity of the operation depends on the underlying
+       *  sequence.
+       */
+      void 
+      push(const value_type& __x) 
+      {
+       try 
         {
           c.push_back(__x); 
           std::push_heap(c.begin(), c.end(), comp);
         }
-      catch(...)
+       catch(...)
         {
           c.clear();
           __throw_exception_again; 
         }
-    }
-  
-    /**
-     *  @brief  Removes first element.
-     *
-     *  This is a typical %queue operation.  It shrinks the %queue by one.
-     *  The time complexity of the operation depends on the underlying
-     *  sequence.
-     *
-     *  Note that no data is returned, and if the first element's data is
-     *  needed, it should be retrieved before pop() is called.
-    */
-    void 
-    pop() 
-    {
-      try 
+      }
+      
+      /**
+       *  @brief  Removes first element.
+       *
+       *  This is a typical %queue operation.  It shrinks the %queue
+       *  by one.  The time complexity of the operation depends on the
+       *  underlying sequence.
+       *
+       *  Note that no data is returned, and if the first element's
+       *  data is needed, it should be retrieved before pop() is
+       *  called.
+       */
+      void 
+      pop() 
+      {
+       __glibcxx_requires_nonempty();
+       try 
         {
           std::pop_heap(c.begin(), c.end(), comp);
           c.pop_back();
         }
-      catch(...)
+       catch(...)
         {
           c.clear();
           __throw_exception_again; 
         }
-    }
-  };
+      }
+    };
   
   // No equality/comparison operators are provided for priority_queue.
 } // namespace std
index fa8c6cf..d1494b9 100644 (file)
 
 #include <bits/concept_check.h>
 
-namespace std
+namespace __gnu_norm
 {
-
-// Forward declarations of operators < and ==, needed for friend declaration.
-
-template <class _Key, class _Compare = less<_Key>,
-          class _Alloc = allocator<_Key> >
-class set;
-
-template <class _Key, class _Compare, class _Alloc>
-inline bool operator==(const set<_Key,_Compare,_Alloc>& __x, 
-                       const set<_Key,_Compare,_Alloc>& __y);
-
-template <class _Key, class _Compare, class _Alloc>
-inline bool operator<(const set<_Key,_Compare,_Alloc>& __x, 
-                      const set<_Key,_Compare,_Alloc>& __y);
-
-
-template <class _Key, class _Compare, class _Alloc>
-class set
-{
-  // concept requirements
-  __glibcxx_class_requires(_Key, _SGIAssignableConcept)
-  __glibcxx_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept)
-
-public:
-  // typedefs:
-  typedef _Key     key_type;
-  typedef _Key     value_type;
-  typedef _Compare key_compare;
-  typedef _Compare value_compare;
+  // Forward declarations of operators < and ==, needed for friend declaration.
+  template<class _Key, class _Compare = less<_Key>, 
+          class _Alloc = allocator<_Key> >
+  class set;
+
+  template<class _Key, class _Compare, class _Alloc>
+    inline bool 
+    operator==(const set<_Key,_Compare,_Alloc>& __x, 
+              const set<_Key,_Compare,_Alloc>& __y);
+
+  template<class _Key, class _Compare, class _Alloc>
+    inline bool 
+    operator<(const set<_Key,_Compare,_Alloc>& __x, 
+             const set<_Key,_Compare,_Alloc>& __y);
+
+  template<class _Key, class _Compare, class _Alloc>
+    class set
+    {
+      // concept requirements
+      __glibcxx_class_requires(_Key, _SGIAssignableConcept)
+      __glibcxx_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept)
+       
+       public:
+      // typedefs:
+      typedef _Key     key_type;
+      typedef _Key     value_type;
+      typedef _Compare key_compare;
+      typedef _Compare value_compare;
 private:
   typedef _Rb_tree<key_type, value_type, 
                   _Identity<value_type>, key_compare, _Alloc> _Rep_type;
@@ -118,12 +117,12 @@ public:
                const allocator_type& __a = allocator_type())
     : _M_t(__comp, __a) {}
 
-  template <class _InputIterator>
+  template<class _InputIterator>
   set(_InputIterator __first, _InputIterator __last)
     : _M_t(_Compare(), allocator_type())
     { _M_t.insert_unique(__first, __last); }
 
-  template <class _InputIterator>
+  template<class _InputIterator>
   set(_InputIterator __first, _InputIterator __last, const _Compare& __comp,
       const allocator_type& __a = allocator_type())
     : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); }
@@ -159,7 +158,7 @@ public:
     typedef typename _Rep_type::iterator _Rep_iterator;
     return _M_t.insert_unique((_Rep_iterator&)__position, __x);
   }
-  template <class _InputIterator>
+  template<class _InputIterator>
   void insert(_InputIterator __first, _InputIterator __last) {
     _M_t.insert_unique(__first, __last);
   }
@@ -205,54 +204,54 @@ public:
     return _M_t.equal_range(__x);
   }
 
-  template <class _K1, class _C1, class _A1>
+  template<class _K1, class _C1, class _A1>
   friend bool operator== (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&);
-  template <class _K1, class _C1, class _A1>
+  template<class _K1, class _C1, class _A1>
   friend bool operator< (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&);
 };
 
-template <class _Key, class _Compare, class _Alloc>
+template<class _Key, class _Compare, class _Alloc>
 inline bool operator==(const set<_Key,_Compare,_Alloc>& __x, 
                        const set<_Key,_Compare,_Alloc>& __y) {
   return __x._M_t == __y._M_t;
 }
 
-template <class _Key, class _Compare, class _Alloc>
+template<class _Key, class _Compare, class _Alloc>
 inline bool operator<(const set<_Key,_Compare,_Alloc>& __x, 
                       const set<_Key,_Compare,_Alloc>& __y) {
   return __x._M_t < __y._M_t;
 }
 
-template <class _Key, class _Compare, class _Alloc>
+template<class _Key, class _Compare, class _Alloc>
 inline bool operator!=(const set<_Key,_Compare,_Alloc>& __x, 
                        const set<_Key,_Compare,_Alloc>& __y) {
   return !(__x == __y);
 }
 
-template <class _Key, class _Compare, class _Alloc>
+template<class _Key, class _Compare, class _Alloc>
 inline bool operator>(const set<_Key,_Compare,_Alloc>& __x, 
                       const set<_Key,_Compare,_Alloc>& __y) {
   return __y < __x;
 }
 
-template <class _Key, class _Compare, class _Alloc>
+template<class _Key, class _Compare, class _Alloc>
 inline bool operator<=(const set<_Key,_Compare,_Alloc>& __x, 
                        const set<_Key,_Compare,_Alloc>& __y) {
   return !(__y < __x);
 }
 
-template <class _Key, class _Compare, class _Alloc>
+template<class _Key, class _Compare, class _Alloc>
 inline bool operator>=(const set<_Key,_Compare,_Alloc>& __x, 
                        const set<_Key,_Compare,_Alloc>& __y) {
   return !(__x < __y);
 }
 
-template <class _Key, class _Compare, class _Alloc>
+template<class _Key, class _Compare, class _Alloc>
 inline void swap(set<_Key,_Compare,_Alloc>& __x, 
                  set<_Key,_Compare,_Alloc>& __y) {
   __x.swap(__y);
 }
 
-} // namespace std
+} // namespace __gnu_norm
 
 #endif /* _SET_H */
index b9847ce..d72755a 100644 (file)
 #define _STACK_H 1
 
 #include <bits/concept_check.h>
+#include <debug/debug.h>
 
 namespace std
 {
-  // Forward declarations of operators == and <, needed for friend declaration.
+  // Forward declarations of operators == and <, needed for friend
+  // declaration.
+  template<typename _Tp, typename _Sequence = deque<_Tp> >
+    class stack;
   
-  template <typename _Tp, typename _Sequence = deque<_Tp> >
-  class stack;
+  template<typename _Tp, typename _Seq>
+    inline bool 
+    operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y);
   
-  template <typename _Tp, typename _Seq>
-  inline bool operator==(const stack<_Tp,_Seq>& __x,
-                        const stack<_Tp,_Seq>& __y);
-  
-  template <typename _Tp, typename _Seq>
-  inline bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y);
+  template<typename _Tp, typename _Seq>
+    inline bool 
+    operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y);
   
   
   /**
@@ -89,104 +91,120 @@ namespace std
    *  but does not define anything to do with iterators.  Very few of the
    *  other standard container interfaces are defined.
    *
-   *  This is not a true container, but an @e adaptor.  It holds another
-   *  container, and provides a wrapper interface to that container.  The
-   *  wrapper is what enforces strict first-in-last-out %stack behavior.
+   *  This is not a true container, but an @e adaptor.  It holds
+   *  another container, and provides a wrapper interface to that
+   *  container.  The wrapper is what enforces strict
+   *  first-in-last-out %stack behavior.
    *
    *  The second template parameter defines the type of the underlying
-   *  sequence/container.  It defaults to std::deque, but it can be any type
-   *  that supports @c back, @c push_back, and @c pop_front, such as
-   *  std::list, std::vector, or an appropriate user-defined type.
+   *  sequence/container.  It defaults to std::deque, but it can be
+   *  any type that supports @c back, @c push_back, and @c pop_front,
+   *  such as std::list, std::vector, or an appropriate user-defined
+   *  type.
    *
    *  Members not found in "normal" containers are @c container_type,
-   *  which is a typedef for the second Sequence parameter, and @c push,
-   *  @c pop, and @c top, which are standard %stack/FILO operations.
+   *  which is a typedef for the second Sequence parameter, and @c
+   *  push, @c pop, and @c top, which are standard %stack/FILO
+   *  operations.
   */
-  template <typename _Tp, typename _Sequence>
+  template<typename _Tp, typename _Sequence>
     class stack
-  {
-    // concept requirements
-    typedef typename _Sequence::value_type _Sequence_value_type;
-    __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
-    __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept)
-    __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
-  
-    template <typename _Tp1, typename _Seq1>
-    friend bool operator== (const stack<_Tp1, _Seq1>&,
-                            const stack<_Tp1, _Seq1>&);
-    template <typename _Tp1, typename _Seq1>
-    friend bool operator< (const stack<_Tp1, _Seq1>&,
-                           const stack<_Tp1, _Seq1>&);
-  
-  public:
-    typedef typename _Sequence::value_type                value_type;
-    typedef typename _Sequence::reference                 reference;
-    typedef typename _Sequence::const_reference           const_reference;
-    typedef typename _Sequence::size_type                 size_type;
-    typedef          _Sequence                            container_type;
-  
-  protected:
-    //  See queue::c for notes on this name.
-    _Sequence c;
-  
-  public:
-    // XXX removed old def ctor, added def arg to this one to match 14882
-    /**
-     *  @brief  Default constructor creates no elements.
-    */
-    explicit
-    stack(const _Sequence& __c = _Sequence())
-    : c(__c) {}
+    {
+      // concept requirements
+      typedef typename _Sequence::value_type _Sequence_value_type;
+      __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
+      __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept)
+      __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
   
-    /**
-     *  Returns true if the %stack is empty.
-    */
-    bool
-    empty() const { return c.empty(); }
-  
-    /**  Returns the number of elements in the %stack.  */
-    size_type
-    size() const { return c.size(); }
-  
-    /**
-     *  Returns a read/write reference to the data at the first element of the
-     *  %stack.
-    */
-    reference
-    top() { return c.back(); }
-  
-    /**
-     *  Returns a read-only (constant) reference to the data at the first
-     *  element of the %stack.
-    */
-    const_reference
-    top() const { return c.back(); }
+       template<typename _Tp1, typename _Seq1>
+          friend bool 
+          operator==(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&);
+
+      template<typename _Tp1, typename _Seq1>
+        friend bool 
+        operator<(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&);
   
-    /**
-     *  @brief  Add data to the top of the %stack.
-     *  @param  x  Data to be added.
-     *
-     *  This is a typical %stack operation.  The function creates an element at
-     *  the top of the %stack and assigns the given data to it.
-     *  The time complexity of the operation depends on the underlying
-     *  sequence.
-    */
-    void
-    push(const value_type& __x) { c.push_back(__x); }
+    public:
+      typedef typename _Sequence::value_type                value_type;
+      typedef typename _Sequence::reference                 reference;
+      typedef typename _Sequence::const_reference           const_reference;
+      typedef typename _Sequence::size_type                 size_type;
+      typedef          _Sequence                            container_type;
+      
+    protected:
+      //  See queue::c for notes on this name.
+      _Sequence c;
+      
+    public:
+      // XXX removed old def ctor, added def arg to this one to match 14882
+      /**
+       *  @brief  Default constructor creates no elements.
+       */
+      explicit
+      stack(const _Sequence& __c = _Sequence()) : c(__c) {}
+      
+      /**
+       *  Returns true if the %stack is empty.
+       */
+      bool
+      empty() const { return c.empty(); }
+      
+      /**  Returns the number of elements in the %stack.  */
+      size_type
+      size() const { return c.size(); }
+      
+      /**
+       *  Returns a read/write reference to the data at the first
+       *  element of the %stack.
+       */
+      reference
+      top() 
+      { 
+       __glibcxx_requires_nonempty();
+       return c.back(); 
+      }
+      
+      /**
+       *  Returns a read-only (constant) reference to the data at the first
+       *  element of the %stack.
+       */
+      const_reference
+      top() const 
+      {
+       __glibcxx_requires_nonempty();
+       return c.back(); 
+      }
+      
+      /**
+       *  @brief  Add data to the top of the %stack.
+       *  @param  x  Data to be added.
+       *
+       *  This is a typical %stack operation.  The function creates an
+       *  element at the top of the %stack and assigns the given data
+       *  to it.  The time complexity of the operation depends on the
+       *  underlying sequence.
+       */
+      void
+      push(const value_type& __x) { c.push_back(__x); }
   
-    /**
-     *  @brief  Removes first element.
-     *
-     *  This is a typical %stack operation.  It shrinks the %stack by one.
-     *  The time complexity of the operation depends on the underlying
-     *  sequence.
-     *
-     *  Note that no data is returned, and if the first element's data is
-     *  needed, it should be retrieved before pop() is called.
-    */
-    void
-    pop() { c.pop_back(); }
-  };
+      /**
+       *  @brief  Removes first element.
+       *
+       *  This is a typical %stack operation.  It shrinks the %stack
+       *  by one.  The time complexity of the operation depends on the
+       *  underlying sequence.
+       *
+       *  Note that no data is returned, and if the first element's
+       *  data is needed, it should be retrieved before pop() is
+       *  called.
+       */
+      void
+      pop() 
+      {
+       __glibcxx_requires_nonempty();
+       c.pop_back(); 
+      }
+    };
   
   
   /**
@@ -195,12 +213,13 @@ namespace std
    *  @param  y  A %stack of the same type as @a x.
    *  @return  True iff the size and elements of the stacks are equal.
    *
-   *  This is an equivalence relation.  Complexity and semantics depend on the
-   *  underlying sequence type, but the expected rules are:  this relation is
-   *  linear in the size of the sequences, and stacks are considered equivalent
-   *  if their sequences compare equal.
+   *  This is an equivalence relation.  Complexity and semantics
+   *  depend on the underlying sequence type, but the expected rules
+   *  are: this relation is linear in the size of the sequences, and
+   *  stacks are considered equivalent if their sequences compare
+   *  equal.
   */
-  template <typename _Tp, typename _Seq>
+  template<typename _Tp, typename _Seq>
     inline bool
     operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
     { return __x.c == __y.c; }
@@ -211,37 +230,38 @@ namespace std
    *  @param  y  A %stack of the same type as @a x.
    *  @return  True iff @a x is lexicographically less than @a y.
    *
-   *  This is an total ordering relation.  Complexity and semantics depend on
-   *  the underlying sequence type, but the expected rules are:  this relation
-   *  is linear in the size of the sequences, the elements must be comparable
-   *  with @c <, and std::lexicographical_compare() is usually used to make the
+   *  This is an total ordering relation.  Complexity and semantics
+   *  depend on the underlying sequence type, but the expected rules
+   *  are: this relation is linear in the size of the sequences, the
+   *  elements must be comparable with @c <, and
+   *  std::lexicographical_compare() is usually used to make the
    *  determination.
   */
-  template <typename _Tp, typename _Seq>
+  template<typename _Tp, typename _Seq>
     inline bool
     operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
     { return __x.c < __y.c; }
   
   /// Based on operator==
-  template <typename _Tp, typename _Seq>
+  template<typename _Tp, typename _Seq>
     inline bool
     operator!=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
     { return !(__x == __y); }
   
   /// Based on operator<
-  template <typename _Tp, typename _Seq>
+  template<typename _Tp, typename _Seq>
     inline bool
     operator>(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
     { return __y < __x; }
   
   /// Based on operator<
-  template <typename _Tp, typename _Seq>
+  template<typename _Tp, typename _Seq>
     inline bool
     operator<=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
     { return !(__y < __x); }
   
   /// Based on operator<
-  template <typename _Tp, typename _Seq>
+  template<typename _Tp, typename _Seq>
     inline bool
     operator>=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
     { return !(__x < __y); }
index e911697..94d6a4a 100644 (file)
@@ -65,7 +65,7 @@
 #include <bits/functexcept.h>
 #include <bits/concept_check.h>
 
-namespace std
+namespace __gnu_norm
 {
   /// @if maint Primary default version.  @endif
   /**
@@ -966,6 +966,6 @@ namespace std
     inline void
     swap(vector<_Tp,_Alloc>& __x, vector<_Tp,_Alloc>& __y)
     { __x.swap(__y); }
-} // namespace std
+} // namespace __gnu_norm
 
 #endif /* _VECTOR_H */
index dcbf9f0..cc67505 100644 (file)
@@ -37,6 +37,8 @@
 
 #pragma GCC system_header
 
+#include <debug/debug.h>
+
 namespace std
 {
   template<typename _Tp, typename _CharT = char, 
@@ -65,18 +67,33 @@ namespace std
       { }
 
       const _Tp&
-      operator*() const { return _M_value; }
+      operator*() const 
+      { 
+       __glibcxx_requires_cond(_M_ok,
+                               _M_message(__gnu_debug::__msg_deref_istream)
+                               ._M_iterator(*this));
+       return _M_value;
+      }
 
       const _Tp*
       operator->() const { return &(operator*()); }
 
       istream_iterator& 
       operator++() 
-      { _M_read(); return *this; }
+      { 
+       __glibcxx_requires_cond(_M_ok,
+                               _M_message(__gnu_debug::__msg_inc_istream)
+                               ._M_iterator(*this));
+       _M_read(); 
+       return *this; 
+      }
 
       istream_iterator 
       operator++(int)  
       {
+       __glibcxx_requires_cond(_M_ok,
+                               _M_message(__gnu_debug::__msg_inc_istream)
+                               ._M_iterator(*this)); 
        istream_iterator __tmp = *this;
        _M_read();
        return __tmp;
@@ -138,6 +155,9 @@ namespace std
       ostream_iterator& 
       operator=(const _Tp& __value) 
       { 
+       __glibcxx_requires_cond(_M_stream != 0,
+                               _M_message(__gnu_debug::__msg_output_ostream)
+                               ._M_iterator(*this));
        *_M_stream << __value;
        if (_M_string) *_M_stream << _M_string;
        return *this;
index 51d8384..d193de2 100644 (file)
@@ -39,6 +39,7 @@
 #pragma GCC system_header
 
 #include <streambuf>
+#include <debug/debug.h>
 
 // NB: Should specialize copy, find algorithms for streambuf iterators.
 
@@ -82,11 +83,23 @@ namespace std
       // NB: The result of operator*() on an end of stream is undefined.
       char_type 
       operator*() const
-      { return traits_type::to_char_type(_M_get()); }
+      { 
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+       // Dereferencing a past-the-end istreambuf_iterator is a
+       // libstdc++ extension
+       __glibcxx_requires_cond(!_M_at_eof(),
+                               _M_message(__gnu_debug::__msg_deref_istreambuf)
+                               ._M_iterator(*this)); 
+#endif
+       return traits_type::to_char_type(_M_get()); 
+      }
        
       istreambuf_iterator& 
       operator++()
       { 
+       __glibcxx_requires_cond(!_M_at_eof(),
+                               _M_message(__gnu_debug::__msg_inc_istreambuf)
+                               ._M_iterator(*this)); 
        const int_type __eof = traits_type::eof();
        if (_M_sbuf && traits_type::eq_int_type(_M_sbuf->sbumpc(), __eof))
          _M_sbuf = 0;
@@ -98,6 +111,10 @@ namespace std
       istreambuf_iterator
       operator++(int)
       {
+       __glibcxx_requires_cond(!_M_at_eof(),
+                               _M_message(__gnu_debug::__msg_inc_istreambuf)
+                               ._M_iterator(*this)); 
+
        const int_type __eof = traits_type::eof();
        istreambuf_iterator __old = *this;
        if (_M_sbuf
@@ -116,8 +133,8 @@ namespace std
       equal(const istreambuf_iterator& __b) const
       {
        const int_type __eof = traits_type::eof();
-       bool __thiseof = traits_type::eq_int_type(_M_get(), __eof);
-       bool __beof = traits_type::eq_int_type(__b._M_get(), __eof);
+       bool __thiseof = _M_at_eof();
+       bool __beof = __b._M_at_eof();
        return (__thiseof && __beof || (!__thiseof && !__beof));
       }
 
@@ -137,6 +154,13 @@ namespace std
          }
        return __ret;
       }
+
+      bool 
+      _M_at_eof() const
+      {
+       const int_type __eof = traits_type::eof();
+       return traits_type::eq_int_type(_M_get(), __eof);
+      }
     };
 
   template<typename _CharT, typename _Traits>
index 181b359..6342743 100644 (file)
@@ -61,7 +61,7 @@
 #ifndef _VECTOR_TCC
 #define _VECTOR_TCC 1
 
-namespace std
+namespace __gnu_norm
 {
   template<typename _Tp, typename _Alloc>
     void
@@ -432,7 +432,8 @@ namespace std
             {
               __new_finish = std::uninitialized_copy(iterator(this->_M_start),
                                                     __position, __new_start);
-              __new_finish = std::uninitialized_copy(__first, __last, __new_finish);
+              __new_finish = std::uninitialized_copy(__first, __last, 
+                                                    __new_finish);
               __new_finish = std::uninitialized_copy(__position,
                                                     iterator(this->_M_finish),
                                                     __new_finish);
@@ -452,6 +453,6 @@ namespace std
         }
       }
     }
-} // namespace std
+} // namespace __gnu_norm
 
 #endif /* _VECTOR_TCC */
diff --git a/libstdc++-v3/include/debug/bitset b/libstdc++-v3/include/debug/bitset
new file mode 100644 (file)
index 0000000..3c474cf
--- /dev/null
@@ -0,0 +1,298 @@
+// Debugging bitset implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_BITSET
+#define _GLIBCXX_DEBUG_BITSET
+
+#include <bitset>
+#include <debug/safe_sequence.h>
+#include <debug/safe_iterator.h>
+
+namespace __gnu_debug_def
+{ 
+  template<size_t _Nb> 
+    class bitset
+    : public __gnu_norm::bitset<_Nb>, public __gnu_debug::_Safe_sequence_base
+    {
+      typedef  __gnu_norm::bitset<_Nb>                 _Base;
+      typedef __gnu_debug::_Safe_sequence_base  _Safe_base;
+
+    public:
+      // bit reference:
+      class reference 
+      : private _Base::reference, public __gnu_debug::_Safe_iterator_base
+      {
+       typedef typename _Base::reference _Base_ref;
+
+       friend class bitset;
+       reference();
+       
+       reference(const _Base_ref& __base, bitset* __seq) 
+       : _Base_ref(__base), _Safe_iterator_base(__seq, false)
+       { }
+
+      public:
+       reference(const reference& __x)
+       : _Base_ref(__x), _Safe_iterator_base(__x, false)
+       { }
+
+       reference& 
+       operator=(bool __x)
+       {
+         _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
+                             _M_message(::__gnu_debug::__msg_bad_bitset_write)
+                               ._M_iterator(*this));
+         *static_cast<_Base_ref*>(this) = __x;
+         return *this;
+       }
+
+       reference& 
+       operator=(const reference& __x)
+       {
+         _GLIBCXX_DEBUG_VERIFY(! __x._M_singular(),
+                              _M_message(::__gnu_debug::__msg_bad_bitset_read)
+                               ._M_iterator(__x));
+         _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
+                             _M_message(::__gnu_debug::__msg_bad_bitset_write)
+                               ._M_iterator(*this));
+         *static_cast<_Base_ref*>(this) = __x;
+         return *this;
+       }
+       
+       bool 
+       operator~() const
+       {
+         _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
+                              _M_message(::__gnu_debug::__msg_bad_bitset_read)
+                               ._M_iterator(*this));
+         return ~(*static_cast<const _Base_ref*>(this));
+       }
+       
+       operator bool() const
+       {
+         _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
+                             _M_message(::__gnu_debug::__msg_bad_bitset_read)
+                               ._M_iterator(*this));
+         return *static_cast<const _Base_ref*>(this);
+       }
+       
+       reference& 
+       flip()
+       {
+         _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
+                             _M_message(::__gnu_debug::__msg_bad_bitset_flip)
+                               ._M_iterator(*this));
+         _Base_ref::flip();
+         return *this;
+       }
+      };
+
+      // 23.3.5.1 constructors:
+      bitset() : _Base() { }
+      
+      bitset(unsigned long __val) : _Base(__val) { }
+      
+      template<typename _CharT, typename _Traits, typename _Allocator>
+        explicit 
+        bitset(const std::basic_string<_CharT,_Traits,_Allocator>& __str,
+              typename std::basic_string<_CharT,_Traits,_Allocator>::size_type
+              __pos = 0,
+              typename std::basic_string<_CharT,_Traits,_Allocator>::size_type
+              __n = (std::basic_string<_CharT,_Traits,_Allocator>::npos))
+       : _Base(__str, __pos, __n) { }
+
+      bitset(const _Base& __x) : _Base(__x), _Safe_base() { }
+
+      // 23.3.5.2 bitset operations:
+      bitset<_Nb>& 
+      operator&=(const bitset<_Nb>& __rhs)
+      {
+       _M_base() &= __rhs;
+       return *this;
+      }
+      
+      bitset<_Nb>& 
+      operator|=(const bitset<_Nb>& __rhs)
+      {
+       _M_base() != __rhs;
+       return *this;
+      }
+      
+      bitset<_Nb>& 
+      operator^=(const bitset<_Nb>& __rhs)
+      {
+       _M_base() ^= __rhs;
+       return *this;
+      }
+      
+      bitset<_Nb>& 
+      operator<<=(size_t __pos)
+      {
+       _M_base() <<= __pos;
+       return *this;
+      }
+      
+      bitset<_Nb>& 
+      operator>>=(size_t __pos)
+      {
+       _M_base() >>= __pos;
+       return *this;
+      }
+      
+      bitset<_Nb>& 
+      set()
+      {
+       _Base::set();
+       return *this;
+      }
+      
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 186. bitset::set() second parameter should be bool 
+      bitset<_Nb>& 
+      set(size_t __pos, bool __val = true)
+      {
+       _Base::set(__pos, __val);
+       return *this;
+      }
+      
+      bitset<_Nb>& 
+      reset()
+      {
+       _Base::reset();
+       return *this;
+      }
+      
+      bitset<_Nb>& 
+      reset(size_t __pos)
+      {
+       _Base::reset(__pos);
+       return *this;
+      }
+      
+      bitset<_Nb> operator~() const { return bitset(~_M_base()); }
+      
+      bitset<_Nb>& 
+      flip()
+      {
+       _Base::flip();
+       return *this;
+      }
+      
+      bitset<_Nb>& 
+      flip(size_t __pos)
+      {
+       _Base::flip(__pos);
+       return *this;
+      }
+      
+      // element access:
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 11. Bitset minor problems 
+      reference 
+      operator[](size_t __pos)
+      { 
+       __glibcxx_check_subscript(__pos);
+       return reference(_M_base()[__pos], this); 
+      }
+      
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 11. Bitset minor problems 
+      bool 
+      operator[](size_t __pos) const 
+      { 
+       __glibcxx_check_subscript(__pos);
+       return _M_base()[__pos]; 
+      }
+      
+      using _Base::to_ulong;
+      
+      template <typename _CharT, typename _Traits, typename _Allocator>
+        std::basic_string<_CharT, _Traits, _Allocator> 
+        to_string() const
+        { return _M_base().template to_string<_CharT, _Traits, _Allocator>(); }
+      
+      using _Base::count;
+      using _Base::size;
+      
+      bool 
+      operator==(const bitset<_Nb>& __rhs) const
+      { return _M_base() == __rhs; }
+
+      bool 
+      operator!=(const bitset<_Nb>& __rhs) const
+      { return _M_base() != __rhs; }
+      
+      using _Base::test;
+      using _Base::any;
+      using _Base::none;
+      
+      bitset<_Nb> 
+      operator<<(size_t __pos) const
+      { return bitset<_Nb>(_M_base() << __pos); }
+      
+      bitset<_Nb> 
+      operator>>(size_t __pos) const
+      { return bitset<_Nb>(_M_base() >> __pos); }
+      
+      _Base&       
+      _M_base() { return *this; }
+
+      const _Base& 
+      _M_base() const { return *this; }
+    };
+  template<size_t _Nb>
+    bitset<_Nb> 
+    operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
+    { return bitset<_Nb>(__x) &= __y; }
+  
+  template<size_t _Nb>
+    bitset<_Nb> 
+    operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
+    { return bitset<_Nb>(__x) |= __y; }
+
+  template<size_t _Nb>
+    bitset<_Nb> 
+    operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y)
+    { return bitset<_Nb>(__x) ^= __y; }
+
+  template<typename _CharT, typename _Traits, size_t _Nb>
+    std::basic_istream<_CharT, _Traits>&
+    operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x)
+    { return __is >> __x._M_base(); }
+
+  template<typename _CharT, typename _Traits, size_t _Nb>
+    std::basic_ostream<_CharT, _Traits>&
+    operator<<(std::basic_ostream<_CharT, _Traits>& __os, 
+              const bitset<_Nb>& __x)
+    { return __os << __x._M_base(); }
+} // namespace __gnu_debug_def
+
+#endif
diff --git a/libstdc++-v3/include/debug/debug.h b/libstdc++-v3/include/debug/debug.h
new file mode 100644 (file)
index 0000000..edb19aa
--- /dev/null
@@ -0,0 +1,531 @@
+// Debugging support implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_DEBUG_H
+#define _GLIBCXX_DEBUG_DEBUG_H 1
+
+/**
+ * Macros used by the implementation to verify certain
+ * properties. These macros may only be used directly by the debug
+ * wrappers. Note that these are macros (instead of the more obviously
+ * "correct" choice of making them functions) because we need line and
+ * file information at the call site, to minimize the distance between
+ * the user error and where the error is reported.
+ *
+ */
+#define _GLIBCXX_DEBUG_VERIFY(_Condition,_ErrorMessage)                \
+  do {                                                                 \
+    if (! (_Condition))                                                        \
+      ::__gnu_debug::_Error_formatter::_M_at(__FILE__, __LINE__)       \
+         ._ErrorMessage._M_error();                                    \
+  } while (false)
+
+// Verify that [_First, _Last) forms a valid iterator range.
+#define __glibcxx_check_valid_range(_First,_Last)                      \
+_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__valid_range(_First, _Last),     \
+                     _M_message(::__gnu_debug::__msg_valid_range)      \
+                     ._M_iterator(_First, #_First)                     \
+                     ._M_iterator(_Last, #_Last))
+
+/** Verify that we can insert into *this with the iterator _Position.
+ *  Insertion into a container at a specific position requires that
+ *  the iterator be nonsingular (i.e., either dereferenceable or
+ *  past-the-end) and that it reference the sequence we are inserting
+ *  into. Note that this macro is only valid when the container is a
+ *  _Safe_sequence and the iterator is a _Safe_iterator.
+*/
+#define __glibcxx_check_insert(_Position)                              \
+_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(),                                \
+                     _M_message(::__gnu_debug::__msg_insert_singular) \
+                     ._M_sequence(*this, "this")                       \
+                     ._M_iterator(_Position, #_Position));             \
+_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this),                  \
+                     _M_message(::__gnu_debug::__msg_insert_different) \
+                     ._M_sequence(*this, "this")                       \
+                     ._M_iterator(_Position, #_Position))
+
+/** Verify that we can insert the values in the iterator range
+ *  [_First, _Last) into *this with the iterator _Position.  Insertion
+ *  into a container at a specific position requires that the iterator
+ *  be nonsingular (i.e., either dereferenceable or past-the-end),
+ *  that it reference the sequence we are inserting into, and that the
+ *  iterator range [_First, Last) is a valid (possibly empty)
+ *  range. Note that this macro is only valid when the container is a
+ *  _Safe_sequence and the iterator is a _Safe_iterator.
+ *
+ *  @tbd We would like to be able to check for noninterference of
+ *  _Position and the range [_First, _Last), but that can't (in
+ *  general) be done.
+*/
+#define __glibcxx_check_insert_range(_Position,_First,_Last)           \
+__glibcxx_check_valid_range(_First,_Last);                             \
+_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(),                                \
+                     _M_message(::__gnu_debug::__msg_insert_singular) \
+                      ._M_sequence(*this, "this")                      \
+                     ._M_iterator(_Position, #_Position));             \
+_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this),                  \
+                     _M_message(::__gnu_debug::__msg_insert_different) \
+                     ._M_sequence(*this, "this")                       \
+                     ._M_iterator(_Position, #_Position))
+
+/** Verify that we can erase the element referenced by the iterator
+ * _Position. We can erase the element if the _Position iterator is
+ * dereferenceable and references this sequence.
+*/
+#define __glibcxx_check_erase(_Position)                               \
+_GLIBCXX_DEBUG_VERIFY(_Position._M_dereferenceable(),                  \
+                     _M_message(::__gnu_debug::__msg_erase_bad)        \
+                      ._M_sequence(*this, "this")                      \
+                     ._M_iterator(_Position, #_Position));             \
+_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this),                  \
+                     _M_message(::__gnu_debug::__msg_erase_different) \
+                     ._M_sequence(*this, "this")                       \
+                     ._M_iterator(_Position, #_Position))
+
+/** Verify that we can erase the elements in the iterator range
+ *  [_First, _Last). We can erase the elements if [_First, _Last) is a
+ *  valid iterator range within this sequence.
+*/
+#define __glibcxx_check_erase_range(_First,_Last)                      \
+__glibcxx_check_valid_range(_First,_Last);                             \
+_GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this),                     \
+                     _M_message(::__gnu_debug::__msg_erase_different) \
+                      ._M_sequence(*this, "this")                      \
+                     ._M_iterator(_First, #_First)                     \
+                     ._M_iterator(_Last, #_Last))
+
+// Verify that the subscript _N is less than the container's size.
+#define __glibcxx_check_subscript(_N)                                  \
+_GLIBCXX_DEBUG_VERIFY(_N < this->size(),                               \
+                     _M_message(::__gnu_debug::__msg_subscript_oob) \
+                      ._M_sequence(*this, "this")                      \
+                     ._M_integer(_N, #_N)                              \
+                     ._M_integer(this->size(), "size"))
+
+// Verify that the container is nonempty
+#define __glibcxx_check_nonempty()                                     \
+_GLIBCXX_DEBUG_VERIFY(! this->empty(),                                 \
+                     _M_message(::__gnu_debug::__msg_empty)    \
+                      ._M_sequence(*this, "this"))
+
+// Verify that the < operator for elements in the sequence is a
+// StrictWeakOrdering by checking that it is irreflexive.
+#define __glibcxx_check_strict_weak_ordering(_First,_Last)     \
+_GLIBCXX_DEBUG_ASSERT(_First == _Last || !(*_First < *_First))
+
+// Verify that the predicate is StrictWeakOrdering by checking that it
+// is irreflexive.
+#define __glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred)  \
+_GLIBCXX_DEBUG_ASSERT(_First == _Last || !_Pred(*_First, *_First))
+
+
+// Verify that the iterator range [_First, _Last) is sorted
+#define __glibcxx_check_sorted(_First,_Last)                           \
+__glibcxx_check_valid_range(_First,_Last);                             \
+__glibcxx_check_strict_weak_ordering(_First,_Last);                    \
+_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last),    \
+                     _M_message(::__gnu_debug::__msg_unsorted) \
+                      ._M_iterator(_First, #_First)                    \
+                     ._M_iterator(_Last, #_Last))
+
+/** Verify that the iterator range [_First, _Last) is sorted by the
+    predicate _Pred. */
+#define __glibcxx_check_sorted_pred(_First,_Last,_Pred)                        \
+__glibcxx_check_valid_range(_First,_Last);                             \
+__glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred);         \
+_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last, _Pred), \
+                     _M_message(::__gnu_debug::__msg_unsorted_pred) \
+                      ._M_iterator(_First, #_First)                    \
+                     ._M_iterator(_Last, #_Last)                       \
+                     ._M_string(#_Pred))
+
+/** Verify that the iterator range [_First, _Last) is partitioned
+    w.r.t. the value _Value. */
+#define __glibcxx_check_partitioned(_First,_Last,_Value)               \
+__glibcxx_check_valid_range(_First,_Last);                             \
+_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last,        \
+                                                        _Value),       \
+                     _M_message(::__gnu_debug::__msg_unpartitioned) \
+                     ._M_iterator(_First, #_First)                     \
+                     ._M_iterator(_Last, #_Last)                       \
+                     ._M_string(#_Value))
+
+/** Verify that the iterator range [_First, _Last) is partitioned
+    w.r.t. the value _Value and predicate _Pred. */
+#define __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred)    \
+__glibcxx_check_valid_range(_First,_Last);                             \
+_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last,        \
+                                                        _Value, _Pred), \
+                     _M_message(::__gnu_debug::__msg_unpartitioned_pred) \
+                     ._M_iterator(_First, #_First)                     \
+                     ._M_iterator(_Last, #_Last)                       \
+                     ._M_string(#_Pred)                                \
+                      ._M_string(#_Value))
+
+// Verify that the iterator range [_First, _Last) is a heap
+#define __glibcxx_check_heap(_First,_Last)                             \
+__glibcxx_check_valid_range(_First,_Last);                             \
+_GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last),         \
+                     _M_message(::__gnu_debug::__msg_not_heap) \
+                     ._M_iterator(_First, #_First)                     \
+                     ._M_iterator(_Last, #_Last))
+
+/** Verify that the iterator range [_First, _Last) is a heap
+    w.r.t. the predicate _Pred. */
+#define __glibcxx_check_heap_pred(_First,_Last,_Pred)                  \
+__glibcxx_check_valid_range(_First,_Last);                             \
+_GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last, _Pred),          \
+                     _M_message(::__gnu_debug::__msg_not_heap_pred) \
+                      ._M_iterator(_First, #_First)                    \
+                     ._M_iterator(_Last, #_Last)                       \
+                     ._M_string(#_Pred))
+
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+#  define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0)
+#  define __glibcxx_check_string_len(_String,_Len) \
+       _GLIBCXX_DEBUG_ASSERT(_String != 0 || _Len == 0)
+#else
+#  define __glibcxx_check_string(_String)
+#  define __glibcxx_check_string_len(_String,_Len)
+#endif
+
+/** Macros used by the implementation outside of debug wrappers to
+ *  verify certain properties. The __glibcxx_requires_xxx macros are
+ *  merely wrappers around the __glibcxx_check_xxx wrappers when we
+ *  are compiling with debug mode, but disappear when we are in
+ *  release mode so that there is no checking performed in, e.g., the
+ *  standard library algorithms.
+*/
+#ifdef _GLIBCXX_DEBUG
+#  define _GLIBCXX_DEBUG_ASSERT(_Condition) assert(_Condition)
+
+#  ifdef _GLIBXX_DEBUG_PEDANTIC
+#    define _GLIBCXX_DEBUG_PEDASSERT(_Condition) assert(_Condition)
+#  else
+#    define _GLIBCXX_DEBUG_PEDASSERT(_Condition)
+#  endif
+
+#  define __glibcxx_requires_cond(_Cond,_Msg) _GLIBCXX_DEBUG_VERIFY(_Cond,_Msg)
+#  define __glibcxx_requires_valid_range(_First,_Last) \
+     __glibcxx_check_valid_range(_First,_Last)
+#  define __glibcxx_requires_sorted(_First,_Last) \
+     __glibcxx_check_sorted(_First,_Last)
+#  define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) \
+     __glibcxx_check_sorted_pred(_First,_Last,_Pred)
+#  define __glibcxx_requires_partitioned(_First,_Last,_Value)  \
+     __glibcxx_check_partitioned(_First,_Last,_Value)
+#  define __glibcxx_requires_partitioned_pred(_First,_Last,_Value,_Pred) \
+     __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred)
+#  define __glibcxx_requires_heap(_First,_Last) \
+     __glibcxx_check_heap(_First,_Last)
+#  define __glibcxx_requires_heap_pred(_First,_Last,_Pred) \
+     __glibcxx_check_heap_pred(_First,_Last,_Pred)
+#  define __glibcxx_requires_nonempty() __glibcxx_check_nonempty()
+#  define __glibcxx_requires_string(_String) __glibcxx_check_string(_String)
+#  define __glibcxx_requires_string_len(_String,_Len)  \
+     __glibcxx_check_string_len(_String,_Len)
+#  define __glibcxx_requires_subscript(_N) __glibcxx_check_subscript(_N)
+#else
+#  define _GLIBCXX_DEBUG_ASSERT(_Condition)
+#  define _GLIBCXX_DEBUG_PEDASSERT(_Condition)
+#  define __glibcxx_requires_cond(_Cond,_Msg)
+#  define __glibcxx_requires_valid_range(_First,_Last)
+#  define __glibcxx_requires_sorted(_First,_Last)
+#  define __glibcxx_requires_sorted_pred(_First,_Last,_Pred)
+#  define __glibcxx_requires_partitioned(_First,_Last,_Value)
+#  define __glibcxx_requires_partitioned_pred(_First,_Last,_Value,_Pred)
+#  define __glibcxx_requires_heap(_First,_Last)
+#  define __glibcxx_requires_heap_pred(_First,_Last,_Pred)
+#  define __glibcxx_requires_nonempty()
+#  define __glibcxx_requires_string(_String)
+#  define __glibcxx_requires_string_len(_String,_Len)
+#  define __glibcxx_requires_subscript(_N)
+#endif 
+
+#include <cassert> // TBD: temporary
+
+#include <stddef.h>                       // for ptrdiff_t
+#include <bits/stl_iterator_base_types.h> // for iterator_traits, categories
+#include <bits/type_traits.h>             // for _Is_integer
+
+namespace __gnu_debug
+{
+  template<typename _Iterator, typename _Sequence> 
+    class _Safe_iterator;
+
+  // An arbitrary iterator pointer is not singular.
+  inline bool 
+  __check_singular_aux(const void*) { return false; }
+
+  // We may have an iterator that derives from _Safe_iterator_base but isn't
+  // a _Safe_iterator.
+  template<typename _Iterator>
+    inline bool
+    __check_singular(_Iterator& __x)
+    { return __gnu_debug::__check_singular_aux(&__x); }
+
+  /** Non-NULL pointers are nonsingular. */
+  template<typename _Tp>
+    inline bool
+    __check_singular(const _Tp* __ptr)
+    { return __ptr == 0; }
+
+  /** Safe iterators know if they are singular. */
+  template<typename _Iterator, typename _Sequence>
+    inline bool
+    __check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x)
+    { return __x._M_singular(); }
+
+  /** Assume that some arbitrary iterator is dereferenceable, because we
+      can't prove that it isn't. */
+  template<typename _Iterator>
+    inline bool
+    __check_dereferenceable(_Iterator&)
+    { return true; }
+
+  /** Non-NULL pointers are dereferenceable. */
+  template<typename _Tp>
+    inline bool
+    __check_dereferenceable(const _Tp* __ptr)
+    { return __ptr; }
+
+  /** Safe iterators know if they are singular. */
+  template<typename _Iterator, typename _Sequence>
+    inline bool
+    __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x)
+    { return __x._M_dereferenceable(); }
+
+  /** If the distance between two random access iterators is
+   *  nonnegative, assume the range is valid. 
+  */
+  template<typename _RandomAccessIterator>
+    inline bool
+    __valid_range_aux2(const _RandomAccessIterator& __first, 
+                      const _RandomAccessIterator& __last,
+                      std::random_access_iterator_tag)
+    { return __last - __first >= 0; }
+
+  /** Can't test for a valid range with input iterators, because
+   *  iteration may be destructive. So we just assume that the range
+   *  is valid.
+  */
+  template<typename _InputIterator>
+    inline bool
+    __valid_range_aux2(const _InputIterator&, const _InputIterator&,
+                      std::input_iterator_tag)
+    { return true; }
+
+  /** We say that integral types for a valid range, and defer to other
+   *  routines to realize what to do with integral types instead of
+   *  iterators. 
+  */
+  template<typename _Integral>
+    inline bool
+    __valid_range_aux(const _Integral&, const _Integral&, __true_type)
+    { return true; }
+
+  /** We have iterators, so figure out what kind of iterators that are
+   *  to see if we can check the range ahead of time.
+  */
+  template<typename _InputIterator>
+    inline bool
+    __valid_range_aux(const _InputIterator& __first, 
+                     const _InputIterator& __last, __false_type)
+  {
+    typedef typename std::iterator_traits<_InputIterator>::iterator_category
+      _Category;
+    return __gnu_debug::__valid_range_aux2(__first, __last, _Category()); 
+  }
+
+  /** Don't know what these iterators are, or if they are even
+   *  iterators (we may get an integral type for InputIterator), so
+   *  see if they are integral and pass them on to the next phase
+   *  otherwise.
+  */
+  template<typename _InputIterator>
+    inline bool
+    __valid_range(const _InputIterator& __first, const _InputIterator& __last)
+    { 
+      typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+      return __gnu_debug::__valid_range_aux(__first, __last, _Integral());
+    }
+
+  /** Safe iterators know how to check if they form a valid range. */
+  template<typename _Iterator, typename _Sequence>
+    inline bool 
+    __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first,
+                 const _Safe_iterator<_Iterator, _Sequence>& __last)
+    { return __first._M_valid_range(__last); }
+
+  /* Checks that [first, last) is a valid range, and then returns
+   * __first. This routine is useful when we can't use a separate
+   * assertion statement because, e.g., we are in a constructor. 
+  */
+  template<typename _InputIterator>
+    inline _InputIterator
+    __check_valid_range(const _InputIterator& __first, 
+                       const _InputIterator& __last)
+    {
+      _GLIBCXX_DEBUG_ASSERT(__gnu_debug::__valid_range(__first, __last));
+      return __first;
+    }
+
+  /** Checks that __s is non-NULL or __n == 0, and then returns __s. */
+  template<typename _CharT, typename _Integer>
+    inline const _CharT*
+    __check_string(const _CharT* __s, const _Integer& __n)
+    {
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+      _GLIBCXX_DEBUG_ASSERT(__s != 0 || __n == 0);
+#endif
+      return __s;
+    }
+
+  /** Checks that __s is non-NULL and then returns __s. */
+  template<typename _CharT>
+    inline const _CharT*
+    __check_string(const _CharT* __s)
+    {
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+      _GLIBCXX_DEBUG_ASSERT(__s != 0);
+#endif
+      return __s;
+    }
+
+  // Can't check if an input iterator sequence is sorted, because we
+  // can't step through the sequence.
+  template<typename _InputIterator>
+    inline bool 
+    __check_sorted_aux(const _InputIterator&, const _InputIterator&,
+                       std::input_iterator_tag)
+    { return true; }
+
+  // Can verify if a forward iterator sequence is in fact sorted using
+  // std::__is_sorted
+  template<typename _ForwardIterator>
+    inline bool
+    __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
+                       std::forward_iterator_tag)
+    { 
+      if (__first == __last)
+        return true;
+
+      _ForwardIterator __next = __first;
+      for (++__next; __next != __last; __first = __next, ++__next) {
+        if (*__next < *__first)
+          return false;
+      }
+
+      return true;
+    }
+
+  // Can't check if an input iterator sequence is sorted, because we can't step
+  // through the sequence.
+  template<typename _InputIterator, typename _Predicate>
+    inline bool 
+    __check_sorted_aux(const _InputIterator&, const _InputIterator&,
+                       _Predicate, std::input_iterator_tag)
+    { return true; }
+
+  // Can verify if a forward iterator sequence is in fact sorted using
+  // std::__is_sorted
+  template<typename _ForwardIterator, typename _Predicate>
+    inline bool
+    __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, 
+                       _Predicate __pred, std::forward_iterator_tag)
+    { 
+      if (__first == __last)
+        return true;
+
+      _ForwardIterator __next = __first;
+      for (++__next; __next != __last; __first = __next, ++__next) {
+        if (__pred(*__next, *__first))
+          return false;
+      }
+
+      return true;
+    }
+
+  // Determine if a sequence is sorted.
+  template<typename _InputIterator>
+    inline bool
+    __check_sorted(const _InputIterator& __first, const _InputIterator& __last)
+    { 
+      typedef typename std::iterator_traits<_InputIterator>::iterator_category 
+        _Category;
+      return __gnu_debug::__check_sorted_aux(__first, __last, _Category());
+    }
+
+  template<typename _InputIterator, typename _Predicate>
+    inline bool
+    __check_sorted(const _InputIterator& __first, const _InputIterator& __last,
+                   _Predicate __pred)
+    { 
+      typedef typename std::iterator_traits<_InputIterator>::iterator_category 
+        _Category;
+      return __gnu_debug::__check_sorted_aux(__first, __last, __pred,
+                                            _Category());
+    }
+
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 270. Binary search requirements overly strict 
+  // Determine if a sequence is partitioned w.r.t. this element.
+  template<typename _ForwardIterator, typename _Tp>
+    inline bool
+    __check_partitioned(_ForwardIterator __first, _ForwardIterator __last,
+                       const _Tp& __value)
+    {
+      while (__first != __last && *__first < __value)
+       ++__first;
+      while (__first != __last && !(*__first < __value))
+       ++__first;
+      return __first == __last;
+    }
+
+  // Determine if a sequence is partitioned w.r.t. this element.
+  template<typename _ForwardIterator, typename _Tp, typename _Pred>
+    inline bool
+    __check_partitioned(_ForwardIterator __first, _ForwardIterator __last,
+                       const _Tp& __value, _Pred __pred)
+    {
+      while (__first != __last && __pred(*__first, __value))
+       ++__first;
+      while (__first != __last && !__pred(*__first, __value))
+       ++__first;
+      return __first == __last;
+    }
+} // namespace __gnu_debug
+
+#ifdef _GLIBCXX_DEBUG
+// We need the error formatter
+#  include <debug/formatter.h>
+#endif
+
+#endif 
diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque
new file mode 100644 (file)
index 0000000..b9d68af
--- /dev/null
@@ -0,0 +1,386 @@
+// Debugging deque implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_DEQUE
+#define _GLIBCXX_DEBUG_DEQUE 1
+
+#include <deque>
+#include <debug/safe_sequence.h>
+#include <debug/safe_iterator.h>
+
+namespace __gnu_debug_def
+{
+  template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
+    class deque 
+    : public  __gnu_norm::deque<_Tp, _Allocator>,
+    public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> >
+    {
+      typedef  __gnu_norm::deque<_Tp, _Allocator> _Base;
+      typedef __gnu_debug::_Safe_sequence<deque> _Safe_base;
+
+    public:
+      typedef typename _Allocator::reference        reference;
+      typedef typename _Allocator::const_reference  const_reference;
+      
+      typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,deque> 
+                                                   iterator;
+      typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,deque>
+                                                    const_iterator;
+      
+      typedef typename _Base::size_type             size_type;
+      typedef typename _Base::difference_type       difference_type;
+      
+      typedef _Tp                                  value_type;
+      typedef _Allocator                           allocator_type;
+      typedef typename _Allocator::pointer          pointer;
+      typedef typename _Allocator::const_pointer    const_pointer;
+      typedef std::reverse_iterator<iterator>       reverse_iterator;
+      typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+      // 23.2.1.1 construct/copy/destroy:
+      explicit deque(const _Allocator& __a = _Allocator())
+      : _Base(__a) { }
+
+      explicit deque(size_type __n, const _Tp& __value = _Tp(),
+                    const _Allocator& __a = _Allocator())
+      : _Base(__n, __value, __a) { }
+
+      template<class _InputIterator>
+        deque(_InputIterator __first, _InputIterator __last,
+             const _Allocator& __a = _Allocator())
+       : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a)
+        { }
+
+      deque(const deque<_Tp,_Allocator>& __x) : _Base(__x), _Safe_base() { }
+
+      deque(const _Base& __x) : _Base(__x), _Safe_base() { }
+      
+      ~deque() { }
+      
+      deque<_Tp,_Allocator>& 
+      operator=(const deque<_Tp,_Allocator>& __x)
+      {
+       *static_cast<_Base*>(this) = __x;
+       this->_M_invalidate_all();
+       return *this;
+      }
+      
+      template<class _InputIterator>
+        void 
+        assign(_InputIterator __first, _InputIterator __last)
+        {
+         __glibcxx_check_valid_range(__first, __last);
+         _Base::assign(__first, __last);
+         this->_M_invalidate_all();
+       }
+
+      void 
+      assign(size_type __n, const _Tp& __t)
+      {
+       _Base::assign(__n, __t);
+       this->_M_invalidate_all();
+      }
+      
+      using _Base::get_allocator;
+      
+      // iterators:
+      iterator 
+      begin() 
+      { return iterator(_Base::begin(), this); }
+      
+      const_iterator 
+      begin() const 
+      { return const_iterator(_Base::begin(), this); }
+      
+      iterator 
+      end() 
+      { return iterator(_Base::end(), this); }
+      
+      const_iterator 
+      end() const 
+      { return const_iterator(_Base::end(), this); }
+      
+      reverse_iterator 
+      rbegin() 
+      { return reverse_iterator(end()); }
+      
+      const_reverse_iterator 
+      rbegin() const
+      { return const_reverse_iterator(end()); }
+      
+      reverse_iterator 
+      rend() 
+      { return reverse_iterator(begin()); }
+      
+      const_reverse_iterator 
+      rend() const
+      { return const_reverse_iterator(begin()); }
+      
+      // 23.2.1.2 capacity:
+      using _Base::size;
+      using _Base::max_size;
+      
+      void 
+      resize(size_type __sz, _Tp __c = _Tp())
+      {
+       typedef typename _Base::const_iterator _Base_const_iterator;
+       typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
+       
+       bool __invalidate_all = __sz > this->size();
+       if (__sz < this->size())
+         this->_M_invalidate_if(_After_nth(__sz, _M_base().begin()));
+       
+       _Base::resize(__sz, __c);
+       
+       if (__invalidate_all)
+         this->_M_invalidate_all();
+      }
+      
+      using _Base::empty;
+      
+      // element access:
+      reference 
+      operator[](size_type __n)
+      {
+       __glibcxx_check_subscript(__n);
+       return _M_base()[__n];
+      }
+      
+      const_reference 
+      operator[](size_type __n) const
+      {
+       __glibcxx_check_subscript(__n);
+       return _M_base()[__n];
+      }
+      
+      using _Base::at;
+      
+      reference 
+      front()
+      {
+       __glibcxx_check_nonempty();
+       return _Base::front();
+      }
+      
+      const_reference 
+      front() const
+      {
+       __glibcxx_check_nonempty();
+       return _Base::front();
+      }
+      
+      reference 
+      back()
+      {
+       __glibcxx_check_nonempty();
+       return _Base::back();
+      }
+      
+      const_reference 
+      back() const
+      {
+       __glibcxx_check_nonempty();
+       return _Base::back();
+      }
+      
+      // 23.2.1.3 modifiers:
+      void 
+      push_front(const _Tp& __x)
+      {
+       _Base::push_front(__x);
+       this->_M_invalidate_all();
+      }
+      
+      void 
+      push_back(const _Tp& __x)
+      {
+       _Base::push_back(__x);
+       this->_M_invalidate_all();
+      }
+      
+      iterator 
+      insert(iterator __position, const _Tp& __x)
+      {
+       __glibcxx_check_insert(__position);
+       typename _Base::iterator __res = _Base::insert(__position.base(), __x);
+       this->_M_invalidate_all();
+       return iterator(__res, this);
+      }
+      
+      void 
+      insert(iterator __position, size_type __n, const _Tp& __x)
+      {
+       __glibcxx_check_insert(__position);
+       _Base::insert(__position.base(), __n, __x);
+       this->_M_invalidate_all();
+      }
+      
+      template<class _InputIterator>
+        void 
+        insert(iterator __position, 
+              _InputIterator __first, _InputIterator __last)
+        {
+         __glibcxx_check_insert_range(__position, __first, __last);
+         _Base::insert(__position.base(), __first, __last);
+         this->_M_invalidate_all();
+       }
+      
+      void 
+      pop_front()
+      {
+       __glibcxx_check_nonempty();
+       iterator __victim = begin();
+       __victim._M_invalidate();
+       _Base::pop_front();
+      }
+      
+      void 
+      pop_back()
+      {
+       __glibcxx_check_nonempty();
+       iterator __victim = end();
+       --__victim;
+       __victim._M_invalidate();
+       _Base::pop_back();
+      }
+      
+      iterator 
+      erase(iterator __position)
+      {
+       __glibcxx_check_erase(__position);
+       if (__position == begin() || __position == end()-1)
+         {
+           __position._M_invalidate();
+           return iterator(_Base::erase(__position.base()), this);
+         }
+       else
+         {
+           typename _Base::iterator __res = _Base::erase(__position.base());
+           this->_M_invalidate_all();
+           return iterator(__res, this);
+         }
+      }
+      
+      iterator 
+      erase(iterator __first, iterator __last)
+      {
+       // _GLIBCXX_RESOLVE_LIB_DEFECTS
+       // 151. can't currently clear() empty container
+       __glibcxx_check_erase_range(__first, __last);
+       if (__first == begin() || __last == end()-1)
+         {
+           this->_M_detach_singular();
+           for (iterator __position = __first; __position != __last; )
+             {
+               iterator __victim = __position++;
+               __victim._M_invalidate();
+             }
+           try 
+             { 
+               return iterator(_Base::erase(__first.base(), __last.base()),
+                               this); 
+             }
+           catch (...)
+             {
+               this->_M_revalidate_singular();
+               __throw_exception_again;
+             }
+         }
+       else
+         {
+           typename _Base::iterator __res = _Base::erase(__first.base(), 
+                                                         __last.base());
+           this->_M_invalidate_all();
+           return iterator(__res, this);
+         }
+      }
+      
+      void 
+      swap(deque<_Tp,_Allocator>& __x)
+      {
+       _Base::swap(__x);
+       this->_M_swap(__x);
+      }
+      
+      void 
+      clear()
+      {
+       _Base::clear();
+       this->_M_invalidate_all();
+      }
+      
+      _Base&       
+      _M_base()       { return *this; }
+
+      const _Base& 
+      _M_base() const { return *this; }
+    };
+
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator==(const deque<_Tp, _Alloc>& __lhs, 
+              const deque<_Tp, _Alloc>& __rhs)
+    { return __lhs._M_base() == __rhs._M_base(); }
+
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator!=(const deque<_Tp, _Alloc>& __lhs, 
+              const deque<_Tp, _Alloc>& __rhs)
+    { return __lhs._M_base() != __rhs._M_base(); }
+
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator<(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs)
+    { return __lhs._M_base() < __rhs._M_base(); }
+
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator<=(const deque<_Tp, _Alloc>& __lhs, 
+              const deque<_Tp, _Alloc>& __rhs)
+    { return __lhs._M_base() <= __rhs._M_base(); }
+
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator>=(const deque<_Tp, _Alloc>& __lhs, 
+              const deque<_Tp, _Alloc>& __rhs)
+    { return __lhs._M_base() >= __rhs._M_base(); }
+
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator>(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs)
+    { return __lhs._M_base() > __rhs._M_base(); }
+
+  template<typename _Tp, typename _Alloc>
+    inline void
+    swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs)
+    { __lhs.swap(__rhs); }
+} // namespace __gnu_debug_def
+
+#endif
diff --git a/libstdc++-v3/include/debug/formatter.h b/libstdc++-v3/include/debug/formatter.h
new file mode 100644 (file)
index 0000000..317ce21
--- /dev/null
@@ -0,0 +1,385 @@
+// Debug-mode error formatting implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_FORMATTER_H
+#define _GLIBCXX_DEBUG_FORMATTER_H 1
+
+#include <typeinfo>
+#include <debug/debug.h>
+
+namespace __gnu_debug
+{
+  /** Determine if the two types are the same. */
+  template<typename _Type1, typename _Type2>
+    struct __is_same
+    {
+      static const bool value = false;
+    };
+
+  template<typename _Type>
+    struct __is_same<_Type, _Type>
+    {
+      static const bool value = true;
+    };
+
+  template<bool> struct __truth { };
+
+  class _Safe_sequence_base;
+
+  template<typename _Iterator, typename _Sequence> 
+    class _Safe_iterator;
+
+  template<typename _Sequence> 
+    class _Safe_sequence;
+
+  enum _Debug_msg_id
+  {
+    // General checks
+    __msg_valid_range,
+    __msg_insert_singular,
+    __msg_insert_different,
+    __msg_erase_bad,
+    __msg_erase_different,
+    __msg_subscript_oob,
+    __msg_empty,
+    __msg_unpartitioned,
+    __msg_unpartitioned_pred,
+    __msg_unsorted,
+    __msg_unsorted_pred,
+    __msg_not_heap,
+    __msg_not_heap_pred,
+    // std::bitset checks
+    __msg_bad_bitset_write,
+    __msg_bad_bitset_read,
+    __msg_bad_bitset_flip,
+    // std::list checks
+    __msg_self_splice,
+    __msg_splice_alloc,
+    __msg_splice_bad,
+    __msg_splice_other,
+    __msg_splice_overlap,
+    // iterator checks
+    __msg_init_singular,
+    __msg_init_copy_singular,
+    __msg_init_const_singular,
+    __msg_copy_singular,
+    __msg_bad_deref,
+    __msg_bad_inc,
+    __msg_bad_dec,
+    __msg_iter_subscript_oob,
+    __msg_advance_oob,
+    __msg_retreat_oob,
+    __msg_iter_compare_bad,
+    __msg_compare_different,
+    __msg_iter_order_bad,
+    __msg_order_different,
+    __msg_distance_bad,
+    __msg_distance_different,
+    // istream_iterator
+    __msg_deref_istream,
+    __msg_inc_istream,
+    // ostream_iterator
+    __msg_output_ostream,
+    // istreambuf_iterator
+    __msg_deref_istreambuf,
+    __msg_inc_istreambuf
+  };
+
+  class _Error_formatter
+  {
+    /// Whether an iterator is constant, mutable, or unknown
+    enum _Constness
+    {
+      __unknown_constness,
+      __const_iterator,
+      __mutable_iterator,
+      __last_constness
+    }; 
+
+    // The state of the iterator (fine-grained), if we know it.
+    enum _Iterator_state
+    {
+      __unknown_state,
+      __singular,      // singular, may still be attached to a sequence
+      __begin,         // dereferenceable, and at the beginning
+      __middle,        // dereferenceable, not at the beginning
+      __end,           // past-the-end, may be at beginning if sequence empty
+      __last_state
+    };
+
+    // Tags denoting the type of parameter for construction
+    struct _Is_iterator { };
+    struct _Is_sequence { };
+
+    // A parameter that may be referenced by an error message
+    struct _Parameter
+    {
+      enum 
+      { 
+       __unused_param, 
+       __iterator, 
+       __sequence, 
+       __integer,
+       __string
+      } _M_kind;
+      
+      union
+      {
+       // When _M_kind == __iterator
+       struct 
+       {
+         const char*      _M_name;      
+         const void*      _M_address;   
+         const type_info* _M_type;   
+         _Constness       _M_constness;
+         _Iterator_state  _M_state;
+         const void*      _M_sequence;  
+         const type_info* _M_seq_type;
+       } _M_iterator;
+       
+       // When _M_kind == __sequence
+       struct
+       {
+         const char*      _M_name;
+         const void*      _M_address;
+         const type_info* _M_type;
+       } _M_sequence;
+
+       // When _M_kind == __integer
+       struct
+       {
+         const char* _M_name;
+         long        _M_value;
+       } _M_integer;
+
+       // When _M_kind == __string
+       struct
+       {
+         const char* _M_name;
+         const char* _M_value;
+       } _M_string;
+      } _M_variant;
+
+      _Parameter() : _M_kind(__unused_param) { }
+      
+      _Parameter(long __value, const char* __name) 
+      : _M_kind(__integer)
+      { 
+       _M_variant._M_integer._M_name = __name;
+       _M_variant._M_integer._M_value = __value; 
+      }
+
+      _Parameter(const char* __value, const char* __name)
+      : _M_kind(__string)
+      {
+       _M_variant._M_string._M_name = __name;
+       _M_variant._M_string._M_value = __value; 
+      }
+
+      template<typename _Iterator, typename _Sequence>
+        _Parameter(const _Safe_iterator<_Iterator, _Sequence>& __it,
+                  const char* __name, _Is_iterator)
+       : _M_kind(__iterator)
+        {
+         _M_variant._M_iterator._M_name = __name;
+         _M_variant._M_iterator._M_address = &__it;
+         _M_variant._M_iterator._M_type = &typeid(__it);
+         _M_variant._M_iterator._M_constness = 
+           __is_same<_Safe_iterator<_Iterator, _Sequence>,
+                                typename _Sequence::iterator>::
+             value? __mutable_iterator : __const_iterator;
+         _M_variant._M_iterator._M_sequence = __it._M_get_sequence();
+         _M_variant._M_iterator._M_seq_type = &typeid(_Sequence);
+
+         if (__it._M_singular())
+           _M_variant._M_iterator._M_state = __singular;
+         else
+           {
+             bool __is_begin = __it._M_is_begin();
+             bool __is_end = __it._M_is_end();
+             if (__is_end)
+               _M_variant._M_iterator._M_state = __end;
+             else if (__is_begin)
+               _M_variant._M_iterator._M_state = __begin;
+             else
+               _M_variant._M_iterator._M_state = __middle;
+           }
+       }
+
+      template<typename _Type>
+        _Parameter(const _Type*& __it, const char* __name, _Is_iterator)
+       : _M_kind(__iterator)
+        {
+         _M_variant._M_iterator._M_name = __name;
+         _M_variant._M_iterator._M_address = &__it;
+         _M_variant._M_iterator._M_type = &typeid(__it);
+         _M_variant._M_iterator._M_constness = __mutable_iterator;
+         _M_variant._M_iterator._M_state = __it? __unknown_state : __singular;
+         _M_variant._M_iterator._M_sequence = 0;
+         _M_variant._M_iterator._M_seq_type = 0;
+       }
+
+      template<typename _Type>
+        _Parameter(_Type*& __it, const char* __name, _Is_iterator)
+        : _M_kind(__iterator)
+        {
+         _M_variant._M_iterator._M_name = __name;
+         _M_variant._M_iterator._M_address = &__it;
+         _M_variant._M_iterator._M_type = &typeid(__it);
+         _M_variant._M_iterator._M_constness = __const_iterator;
+         _M_variant._M_iterator._M_state = __it? __unknown_state : __singular;
+         _M_variant._M_iterator._M_sequence = 0;
+         _M_variant._M_iterator._M_seq_type = 0;
+       }
+      
+      template<typename _Iterator>
+        _Parameter(const _Iterator& __it, const char* __name, _Is_iterator)
+       : _M_kind(__iterator)
+        {
+         _M_variant._M_iterator._M_name = __name;
+         _M_variant._M_iterator._M_address = &__it;
+         _M_variant._M_iterator._M_type = &typeid(__it);
+         _M_variant._M_iterator._M_constness = __unknown_constness;
+         _M_variant._M_iterator._M_state = 
+           __gnu_debug::__check_singular(__it)? __singular : __unknown_state;
+         _M_variant._M_iterator._M_sequence = 0;
+         _M_variant._M_iterator._M_seq_type = 0;
+       }
+
+      template<typename _Sequence>
+        _Parameter(const _Safe_sequence<_Sequence>& __seq,
+                  const char* __name, _Is_sequence)
+       : _M_kind(__sequence)
+        {
+         _M_variant._M_sequence._M_name = __name;
+         _M_variant._M_sequence._M_address = 
+           static_cast<const _Sequence*>(&__seq);
+         _M_variant._M_sequence._M_type = &typeid(_Sequence);
+       }
+
+      template<typename _Sequence>
+        _Parameter(const _Sequence& __seq, const char* __name, _Is_sequence)
+       : _M_kind(__sequence)
+        {
+         _M_variant._M_sequence._M_name = __name;
+         _M_variant._M_sequence._M_address = &__seq;
+         _M_variant._M_sequence._M_type = &typeid(_Sequence);
+       }
+      
+      void
+      _M_print_field(const _Error_formatter* __formatter, 
+                    const char* __name) const;
+                                        
+      void
+      _M_print_description(const _Error_formatter* __formatter) const;
+    };
+
+    friend struct _Parameter;
+
+  public:    
+    template<typename _Iterator>
+      const _Error_formatter&
+      _M_iterator(const _Iterator& __it, const char* __name = 0)  const
+      {
+       if (_M_num_parameters < __max_parameters)
+         _M_parameters[_M_num_parameters++] = _Parameter(__it, __name,
+                                                         _Is_iterator());
+       return *this;
+      }
+
+    const _Error_formatter&
+    _M_integer(long __value, const char* __name = 0) const
+    {
+      if (_M_num_parameters < __max_parameters)
+       _M_parameters[_M_num_parameters++] = _Parameter(__value, __name);
+      return *this;
+    }
+
+    const _Error_formatter&
+    _M_string(const char* __value, const char* __name = 0) const
+    {
+      if (_M_num_parameters < __max_parameters)
+       _M_parameters[_M_num_parameters++] = _Parameter(__value, __name);
+      return *this;
+    }
+
+    template<typename _Sequence>
+      const _Error_formatter&
+      _M_sequence(const _Sequence& __seq, const char* __name = 0) const
+      {
+       if (_M_num_parameters < __max_parameters)
+         _M_parameters[_M_num_parameters++] = _Parameter(__seq, __name, 
+                                                         _Is_sequence());
+       return *this;
+      }
+
+    const _Error_formatter&
+    _M_message(const char* __text) const
+    { _M_text = __text; return *this; }
+
+    const _Error_formatter&
+    _M_message(_Debug_msg_id __id) const;
+
+    void 
+    _M_error() const;
+
+  private:
+    _Error_formatter(const char* __file, size_t __line)
+    : _M_file(__file), _M_line(__line), _M_num_parameters(0), _M_text(0),
+      _M_max_length(78), _M_column(1), _M_first_line(true), _M_wordwrap(false)
+    { }
+
+    void 
+    _M_print_word(const char* __word) const;
+
+    void 
+    _M_print_string(const char* __string) const;
+
+    enum { __max_parameters = 9 };
+
+    const char*         _M_file;
+    size_t              _M_line;
+    mutable _Parameter  _M_parameters[__max_parameters];
+    mutable size_t      _M_num_parameters;
+    mutable const char* _M_text;
+    mutable size_t      _M_max_length;
+    enum { _M_indent = 4 } ;
+    mutable size_t      _M_column;
+    mutable bool        _M_first_line;
+    mutable bool        _M_wordwrap;
+
+  public:
+    static _Error_formatter
+    _M_at(const char* __file, size_t __line)
+    { return _Error_formatter(__file, __line); }
+  };
+} // namespace __gnu_debug
+
+#endif 
diff --git a/libstdc++-v3/include/debug/hash_map b/libstdc++-v3/include/debug/hash_map
new file mode 100644 (file)
index 0000000..570a9af
--- /dev/null
@@ -0,0 +1,38 @@
+// Debugging hash_map/hash_multimap implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_HASH_MAP
+#define _GLIBCXX_DEBUG_HASH_MAP 1
+
+#include <hash_map>
+#include <debug/dbg_hash_map.h>
+#include <debug/dbg_hash_multimap.h>
+
+#endif
diff --git a/libstdc++-v3/include/debug/hash_map.h b/libstdc++-v3/include/debug/hash_map.h
new file mode 100644 (file)
index 0000000..5ca102a
--- /dev/null
@@ -0,0 +1,270 @@
+// Debugging hash_map implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_HASH_MAP_H
+#define _GLIBCXX_DEBUG_HASH_MAP_H 1
+
+#include <debug/safe_sequence.h>
+#include <debug/safe_iterator.h>
+
+namespace __gnu_debug_def
+{
+  template<typename _Value, typename _Tp,
+          typename _HashFcn  = __gnu_cxx::hash<_Value>,
+          typename _EqualKey = std::equal_to<_Value>,
+          typename _Alloc = std::allocator<_Value> >
+    class hash_map
+    : public __gnu_cxx::hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>,
+      public __gnu_debug::_Safe_sequence<hash_map<_Value, _Tp, _HashFcn,
+                                                _EqualKey, _Alloc> >
+    {
+      typedef __gnu_cxx::hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc> 
+                                                       _Base;
+      typedef __gnu_debug::_Safe_sequence<hash_map>    _Safe_base;
+
+    public:
+      typedef typename _Base::key_type        key_type;
+      typedef typename _Base::data_type       data_type;
+      typedef typename _Base::mapped_type     mapped_type;
+      typedef typename _Base::value_type      value_type;
+      typedef typename _Base::hasher          hasher;
+      typedef typename _Base::key_equal       key_equal;
+      typedef typename _Base::size_type       size_type;
+      typedef typename _Base::difference_type difference_type;
+      typedef typename _Base::pointer         pointer;
+      typedef typename _Base::const_pointer   const_pointer;
+      typedef typename _Base::reference       reference;
+      typedef typename _Base::const_reference const_reference;
+      
+      typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, hash_map>
+                                             iterator;
+      typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, 
+                                         hash_map>
+                                             const_iterator;
+      
+      typedef typename _Base::allocator_type  allocator_type;
+
+      using _Base::hash_funct;
+      using _Base::key_eq;
+      using _Base::get_allocator;
+      
+      hash_map() { }
+      
+      explicit hash_map(size_type __n) : _Base(__n) { }
+      
+      hash_map(size_type __n, const hasher& __hf) : _Base(__n, __hf) { }
+
+      hash_map(size_type __n, const hasher& __hf, const key_equal& __eql,
+              const allocator_type& __a = allocator_type())
+      : _Base(__n, __hf, __eql, __a) { }
+    
+      template<typename _InputIterator>
+        hash_map(_InputIterator __f, _InputIterator __l)
+        : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { }
+
+      template<typename _InputIterator>
+        hash_map(_InputIterator __f, _InputIterator __l, size_type __n)
+       : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { }
+
+      template<typename _InputIterator>
+        hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
+                const hasher& __hf)
+        : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { }
+
+      template<typename _InputIterator>
+        hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
+                const hasher& __hf, const key_equal& __eql,
+                const allocator_type& __a = allocator_type())
+       : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf,
+               __eql, __a) { }
+
+      hash_map(const _Base& __x) : _Base(__x), _Safe_base() { }
+
+      using _Base::size;
+      using _Base::max_size;
+      using _Base::empty;
+      
+      void 
+      swap(hash_map& __x)
+      {
+       _Base::swap(__x);
+       this->_M_swap(__x);
+      }
+      
+      iterator 
+      begin() { return iterator(_Base::begin(), this); }
+
+      iterator 
+      end() { return iterator(_Base::end(),   this); }
+      
+      const_iterator 
+      begin() const 
+      { return const_iterator(_Base::begin(), this); }
+      
+      const_iterator 
+      end() const 
+      { return const_iterator(_Base::end(),   this); }
+      
+      std::pair<iterator, bool> 
+      insert(const value_type& __obj)
+      { 
+       std::pair<typename _Base::iterator, bool> __res = _Base::insert(__obj);
+       return std::make_pair(iterator(__res.first, this), __res.second);
+      }
+      
+      template <typename _InputIterator>
+        void 
+        insert(_InputIterator __first, _InputIterator __last) 
+        {
+         __glibcxx_check_valid_range(__first, __last);
+         _Base::insert(__first.base(), __last.base());
+       }
+
+
+      std::pair<iterator, bool> 
+      insert_noresize(const value_type& __obj)
+      { 
+       std::pair<typename _Base::iterator, bool> __res = 
+                                               _Base::insert_noresize(__obj);
+       return std::make_pair(iterator(__res.first, this), __res.second);
+      }
+      
+      iterator 
+      find(const key_type& __key)
+      { return iterator(_Base::find(__key), this); }
+      
+      const_iterator 
+      find(const key_type& __key) const 
+      { return const_iterator(_Base::find(__key), this); }
+      
+      using _Base::operator[];
+      using _Base::count;
+      
+      std::pair<iterator, iterator> 
+      equal_range(const key_type& __key)
+      { 
+       typedef typename _Base::iterator _Base_iterator;
+       std::pair<_Base_iterator, _Base_iterator> __res = 
+                         _Base::equal_range(__key);
+       return std::make_pair(iterator(__res.first, this),
+                             iterator(__res.second, this));
+      }
+      
+      std::pair<const_iterator, const_iterator> 
+      equal_range(const key_type& __key) const
+      { 
+       typedef typename _Base::const_iterator _Base_iterator;
+       std::pair<_Base_iterator, _Base_iterator> __res = 
+       _Base::equal_range(__key);
+       return std::make_pair(const_iterator(__res.first, this),
+                             const_iterator(__res.second, this));
+      }
+      
+      size_type 
+      erase(const key_type& __key) 
+      {
+       iterator __victim(_Base::find(__key), this);
+       if (__victim != end())
+         return this->erase(__victim), 1;
+       else
+         return 0;
+      }
+      
+      void 
+      erase(iterator __it) 
+      {
+       __glibcxx_check_erase(__it);
+       __it._M_invalidate();
+       _Base::erase(__it.base());
+      }
+      
+      void 
+      erase(iterator __first, iterator __last)
+      {
+       __glibcxx_check_erase_range(__first, __last);
+       for (iterator __tmp = __first; __tmp != __last;)
+       {
+         iterator __victim = __tmp++;
+         __victim._M_invalidate();
+       }
+       _Base::erase(__first.base(), __last.base());
+      }
+      
+      void 
+      clear() 
+      { 
+       _Base::clear();
+       this->_M_invalidate_all(); 
+      }
+      
+      using _Base::resize;
+      using _Base::bucket_count;
+      using _Base::max_bucket_count;
+      using _Base::elems_in_bucket;
+      
+      _Base&       
+      _M_base()       { return *this; }
+
+      const _Base& 
+      _M_base() const { return *this; }
+      
+    private:
+      void 
+      _M_invalidate_all()
+      {
+       typedef typename _Base::const_iterator _Base_const_iterator;
+       typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
+       this->_M_invalidate_if(_Not_equal(_M_base().end()));
+      }
+    };
+  
+  template<typename _Value, typename _Tp, typename _HashFcn, 
+          typename _EqualKey, typename _Alloc>
+    inline bool
+    operator==(const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x,
+              const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y)
+    { return __x._M_base() == __y._M_base(); }
+
+  template<typename _Value, typename _Tp, typename _HashFcn, 
+          typename _EqualKey, typename _Alloc>
+    inline bool
+    operator!=(const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x,
+              const hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y)
+    { return __x._M_base() != __y._M_base(); }
+
+  template<typename _Value, typename _Tp, typename _HashFcn, 
+          typename _EqualKey, typename _Alloc>
+    inline void
+    swap(hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x,
+        hash_map<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y)
+    { __x.swap(__y); }
+} // namespace __gnu_debug_def
+
+#endif 
diff --git a/libstdc++-v3/include/debug/hash_multimap.h b/libstdc++-v3/include/debug/hash_multimap.h
new file mode 100644 (file)
index 0000000..dd453d6
--- /dev/null
@@ -0,0 +1,261 @@
+// Debugging hash_multimap implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_HASH_MULTIMAP_H
+#define _GLIBCXX_DEBUG_HASH_MULTIMAP_H 1
+
+#include <debug/safe_sequence.h>
+#include <debug/safe_iterator.h>
+
+namespace __gnu_debug_def
+{
+  template<typename _Value, typename _Tp,
+          typename _HashFcn  = __gnu_cxx::hash<_Value>,
+          typename _EqualKey = std::equal_to<_Value>,
+          typename _Alloc =  std::allocator<_Value> >
+    class hash_multimap
+    : public __gnu_cxx::hash_multimap<_Value,_Tp,_HashFcn, _EqualKey,_Alloc>,
+      public __gnu_debug::_Safe_sequence<hash_multimap<_Value, _Tp, _HashFcn,
+                                                      _EqualKey, _Alloc> >
+    {
+      typedef __gnu_cxx::hash_multimap<_Value,_Tp,_HashFcn, _EqualKey,_Alloc>
+                                                       _Base;
+      typedef __gnu_debug::_Safe_sequence<hash_multimap> _Safe_base;
+
+  public:
+      typedef typename _Base::key_type                 key_type;
+      typedef typename _Base::data_type                data_type;
+      typedef typename _Base::mapped_type              mapped_type;
+      typedef typename _Base::value_type               value_type;
+      typedef typename _Base::hasher                   hasher;
+      typedef typename _Base::key_equal                key_equal;
+      typedef typename _Base::size_type                size_type;
+      typedef typename _Base::difference_type          difference_type;
+      typedef typename _Base::pointer                  pointer;
+      typedef typename _Base::const_pointer            const_pointer;
+      typedef typename _Base::reference                reference;
+      typedef typename _Base::const_reference          const_reference;
+
+      typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, 
+                                         hash_multimap> iterator;
+      typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
+                                         hash_multimap> const_iterator;
+
+      typedef typename _Base::allocator_type              allocator_type;
+
+      using _Base::hash_funct;
+      using _Base::key_eq;
+      using _Base::get_allocator;
+      
+      hash_multimap() { }
+      
+      explicit hash_multimap(size_type __n) : _Base(__n) { }
+      
+      hash_multimap(size_type __n, const hasher& __hf) : _Base(__n, __hf) { }
+
+      hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql,
+                   const allocator_type& __a = allocator_type())
+      : _Base(__n, __hf, __eql, __a) { }
+    
+      template<typename _InputIterator>
+        hash_multimap(_InputIterator __f, _InputIterator __l)
+       : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { }
+
+      template<typename _InputIterator>
+        hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n)
+        : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { }
+
+      template<typename _InputIterator>
+        hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
+                     const hasher& __hf)
+       : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { }
+
+      template<typename _InputIterator>
+        hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
+                     const hasher& __hf, const key_equal& __eql,
+                     const allocator_type& __a = allocator_type())
+       : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf,
+               __eql, __a) { }
+
+      using _Base::size;
+      using _Base::max_size;
+      using _Base::empty;
+      
+      void 
+      swap(hash_multimap& __x)
+      {
+       _Base::swap(__x);
+       this->_M_swap(__x);
+      }
+      
+      iterator 
+      begin() { return iterator(_Base::begin(), this); }
+
+      iterator 
+      end()   { return iterator(_Base::end(),   this); }
+      
+      const_iterator 
+      begin() const 
+      { return const_iterator(_Base::begin(), this); }
+      
+      const_iterator 
+      end() const 
+      { return const_iterator(_Base::end(),   this); }
+      
+      iterator
+      insert(const value_type& __obj)
+      { return iterator(_Base::insert(__obj), this); }
+      
+      template <typename _InputIterator>
+        void 
+        insert(_InputIterator __first, _InputIterator __last) 
+        {
+         __glibcxx_check_valid_range(__first, __last);
+         _Base::insert(__first.base(), __last.base());
+       }
+      
+      iterator
+      insert_noresize(const value_type& __obj)
+      { return iterator(_Base::insert_noresize(__obj), this); }
+      
+      iterator 
+      find(const key_type& __key)
+      { return iterator(_Base::find(__key), this); }
+      
+      const_iterator 
+      find(const key_type& __key) const 
+      { return const_iterator(_Base::find(__key), this); }
+      
+      using _Base::count;
+      
+      std::pair<iterator, iterator> 
+      equal_range(const key_type& __key)
+      { 
+       typedef typename _Base::iterator _Base_iterator;
+       std::pair<_Base_iterator, _Base_iterator> __res = 
+                                                    _Base::equal_range(__key);
+       return std::make_pair(iterator(__res.first, this),
+                             iterator(__res.second, this));
+      }
+      
+      std::pair<const_iterator, const_iterator> 
+      equal_range(const key_type& __key) const
+      { 
+       typedef typename _Base::const_iterator _Base_iterator;
+       std::pair<_Base_iterator, _Base_iterator> __res = 
+        _Base::equal_range(__key);
+       return std::make_pair(const_iterator(__res.first, this),
+                             const_iterator(__res.second, this));
+      }
+      
+      size_type 
+      erase(const key_type& __key) 
+      {
+       std::pair<iterator, iterator> __victims = this->equal_range(__key);
+       size_t __num_victims = 0;
+       while (__victims.first != __victims.second) 
+       {
+         this->erase(__victims.first++);
+         ++__num_victims;
+       }
+       return __num_victims;
+      }
+    
+      void 
+      erase(iterator __it) 
+      {
+       __glibcxx_check_erase(__it);
+       __it._M_invalidate();
+       _Base::erase(__it.base());
+      }
+      
+      void 
+      erase(iterator __first, iterator __last)
+      {
+       __glibcxx_check_erase_range(__first, __last);
+       for (iterator __tmp = __first; __tmp != __last;)
+       {
+         iterator __victim = __tmp++;
+         __victim._M_invalidate();
+       }
+       _Base::erase(__first.base(), __last.base());
+      }
+      
+      void 
+      clear() 
+      { 
+       _Base::clear();
+       this->_M_invalidate_all(); 
+      }
+      
+      using _Base::resize;
+      using _Base::bucket_count;
+      using _Base::max_bucket_count;
+      using _Base::elems_in_bucket;
+      
+      _Base&       
+      _M_base()       { return *this; }
+
+      const _Base& 
+      _M_base() const { return *this; }
+      
+    private:
+      void 
+      _M_invalidate_all()
+      {
+       typedef typename _Base::const_iterator _Base_const_iterator;
+       typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
+       this->_M_invalidate_if(_Not_equal(_M_base().end()));
+      }
+    };
+  
+  template<typename _Value, typename _Tp, typename _HashFcn, 
+          typename _EqualKey, typename _Alloc>
+    inline bool
+    operator==(const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __x,
+              const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __y)
+    { return __x._M_base() == __y._M_base(); }
+
+  template<typename _Value, typename _Tp, typename _HashFcn, 
+          typename _EqualKey, typename _Alloc>
+    inline bool
+    operator!=(const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __x,
+              const hash_multimap<_Value,_Tp,_HashFcn,_EqualKey,_Alloc>& __y)
+    { return __x._M_base() != __y._M_base(); }
+  
+  template<typename _Value, typename _Tp, typename _HashFcn, 
+          typename _EqualKey, typename _Alloc>
+    inline void
+    swap(hash_multimap<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __x,
+        hash_multimap<_Value, _Tp, _HashFcn, _EqualKey, _Alloc>& __y)
+    { __x.swap(__y); }
+} // namespace __gnu_debug_def
+
+#endif
diff --git a/libstdc++-v3/include/debug/hash_multiset.h b/libstdc++-v3/include/debug/hash_multiset.h
new file mode 100644 (file)
index 0000000..cacad03
--- /dev/null
@@ -0,0 +1,236 @@
+// Debugging hash_multiset implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_HASH_MULTISET_H
+#define _GLIBCXX_DEBUG_HASH_MULTISET_H 1
+
+#include <debug/safe_sequence.h>
+#include <debug/safe_iterator.h>
+
+namespace __gnu_debug_def
+{
+  template<typename _Value,
+          typename _HashFcn  = __gnu_cxx::hash<_Value>,
+          typename _EqualKey = std::equal_to<_Value>,
+          typename _Alloc =  std::allocator<_Value> >
+    class hash_multiset
+    : public __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>,
+      public __gnu_debug::_Safe_sequence<hash_multiset<_Value, _HashFcn,
+                                                      _EqualKey, _Alloc> >
+    {
+      typedef __gnu_cxx:: hash_multiset<_Value,_HashFcn, _EqualKey,_Alloc>
+                                                       _Base;
+      typedef __gnu_debug::_Safe_sequence<hash_multiset> _Safe_base;
+
+  public:
+    typedef typename _Base::key_type                   key_type;
+    typedef typename _Base::value_type                 value_type;
+    typedef typename _Base::hasher                     hasher;
+    typedef typename _Base::key_equal                  key_equal;
+    typedef typename _Base::size_type                  size_type;
+    typedef typename _Base::difference_type            difference_type;
+    typedef typename _Base::pointer                    pointer;
+    typedef typename _Base::const_pointer              const_pointer;
+    typedef typename _Base::reference                  reference;
+    typedef typename _Base::const_reference            const_reference;
+
+    typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, 
+                                        hash_multiset> iterator;
+    typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
+                                        hash_multiset> const_iterator;
+
+    typedef typename _Base::allocator_type              allocator_type;
+
+    using _Base::hash_funct;
+    using _Base::key_eq;
+    using _Base::get_allocator;
+
+    hash_multiset() { }
+
+    explicit hash_multiset(size_type __n) : _Base(__n) { }
+
+    hash_multiset(size_type __n, const hasher& __hf) : _Base(__n, __hf) { }
+
+    hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql,
+                 const allocator_type& __a = allocator_type())
+    : _Base(__n, __hf, __eql, __a)
+    { }
+    
+    template<typename _InputIterator>
+      hash_multiset(_InputIterator __f, _InputIterator __l)
+      : _Base(__gnu_debug::__check_valid_range(__f, __l), __l)
+      { }
+
+    template<typename _InputIterator>
+      hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n)
+      : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n)
+      { }
+
+    template<typename _InputIterator>
+      hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
+                   const hasher& __hf)
+      : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf)
+      { }
+
+    template<typename _InputIterator>
+      hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
+                   const hasher& __hf, const key_equal& __eql,
+                   const allocator_type& __a = allocator_type())
+      : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf,
+             __eql, __a)
+      { }
+
+    hash_multiset(const _Base& __x) : _Base(__x), _Safe_base() { }
+
+    using _Base::size;
+    using _Base::max_size;
+    using _Base::empty;
+
+    void 
+    swap(hash_multiset& __x)
+    {
+      _Base::swap(__x);
+      this->_M_swap(__x);
+    }
+
+    iterator begin() const { return iterator(_Base::begin(), this); }
+    iterator end() const   { return iterator(_Base::end(),   this); }
+
+    iterator
+    insert(const value_type& __obj)
+    { return iterator(_Base::insert(__obj), this); }
+
+    template <typename _InputIterator>
+      void 
+      insert(_InputIterator __first, _InputIterator __last) 
+      {
+       __glibcxx_check_valid_range(__first, __last);
+       _Base::insert(__first.base(), __last.base());
+      }
+
+
+    iterator
+    insert_noresize(const value_type& __obj)
+    { return iterator(_Base::insert_noresize(__obj), this); }
+
+    iterator 
+    find(const key_type& __key) const 
+    { return iterator(_Base::find(__key), this); }
+
+    using _Base::count;
+    
+    std::pair<iterator, iterator> 
+    equal_range(const key_type& __key) const
+    { 
+      typedef typename _Base::iterator _Base_iterator;
+      std::pair<_Base_iterator, _Base_iterator> __res = 
+       _Base::equal_range(__key);
+      return std::make_pair(iterator(__res.first, this),
+                           iterator(__res.second, this));
+    }
+
+    size_type 
+    erase(const key_type& __key) 
+    {
+      size_type __count = 0;
+      std::pair<iterator, iterator> __victims = this->equal_range(__key);
+      while (__victims.first != __victims.second)
+       {
+         this->erase(__victims++);
+         ++__count;
+       }
+      return __count;
+    }
+    
+    void 
+    erase(iterator __it) 
+    {
+      __glibcxx_check_erase(__it);
+      __it._M_invalidate();
+      _Base::erase(__it.base());
+    }
+
+    void 
+    erase(iterator __first, iterator __last)
+    {
+      __glibcxx_check_erase_range(__first, __last);
+      for (iterator __tmp = __first; __tmp != __last;)
+       {
+         iterator __victim = __tmp++;
+         __victim._M_invalidate();
+       }
+      _Base::erase(__first.base(), __last.base());
+    }
+
+    void 
+    clear() 
+    { 
+      _Base::clear();
+      this->_M_invalidate_all(); 
+    }
+
+    using _Base::resize;
+    using _Base::bucket_count;
+    using _Base::max_bucket_count;
+    using _Base::elems_in_bucket;
+
+    _Base&       _M_base()       { return *this; }
+    const _Base& _M_base() const { return *this; }
+
+  private:
+    void 
+    _M_invalidate_all()
+    {
+      typedef typename _Base::const_iterator _Base_const_iterator;
+      typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
+      this->_M_invalidate_if(_Not_equal(_M_base().end()));
+    }
+  };
+
+template<typename _Value, typename _HashFcn, typename _EqualKey, typename _Alloc>
+  inline bool
+  operator==(const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x,
+            const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y)
+  { return __x._M_base() == __y._M_base(); }
+
+template<typename _Value, typename _HashFcn, typename _EqualKey, typename _Alloc>
+  inline bool
+  operator!=(const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x,
+            const hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y)
+  { return __x._M_base() != __y._M_base(); }
+
+template<typename _Value, typename _HashFcn, typename _EqualKey, typename _Alloc>
+  inline void
+  swap(hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __x,
+       hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>& __y)
+  { __x.swap(__y); }
+} // namespace __gnu_debug_def
+
+#endif
diff --git a/libstdc++-v3/include/debug/hash_set b/libstdc++-v3/include/debug/hash_set
new file mode 100644 (file)
index 0000000..13d879d
--- /dev/null
@@ -0,0 +1,38 @@
+// Debugging hash_set/hash_multiset implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_HASH_SET
+#define _GLIBCXX_DEBUG_HASH_SET 1
+
+#include <hash_set>
+#include <debug/dbg_hash_set.h>
+#include <debug/dbg_hash_multiset.h>
+
+#endif 
diff --git a/libstdc++-v3/include/debug/hash_set.h b/libstdc++-v3/include/debug/hash_set.h
new file mode 100644 (file)
index 0000000..88afb90
--- /dev/null
@@ -0,0 +1,245 @@
+// Debugging hash_set implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_HASH_SET_H
+#define _GLIBCXX_DEBUG_HASH_SET_H 1
+
+#include <debug/safe_sequence.h>
+#include <debug/safe_iterator.h>
+
+namespace __gnu_debug_def
+{
+  template<typename _Value,
+          typename _HashFcn  = __gnu_cxx::hash<_Value>,
+          typename _EqualKey = std::equal_to<_Value>,
+          typename _Alloc =  std::allocator<_Value> >
+    class hash_set
+    : public __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc>,
+      public __gnu_debug::_Safe_sequence<hash_set<_Value, _HashFcn, _EqualKey,
+                                                 _Alloc> >
+    {
+      typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> _Base;
+      typedef __gnu_debug::_Safe_sequence<hash_set> _Safe_base;
+      
+    public:
+      typedef typename _Base::key_type        key_type;
+      typedef typename _Base::value_type      value_type;
+      typedef typename _Base::hasher          hasher;
+      typedef typename _Base::key_equal       key_equal;
+      typedef typename _Base::size_type       size_type;
+      typedef typename _Base::difference_type difference_type;
+      typedef typename _Base::pointer         pointer;
+      typedef typename _Base::const_pointer   const_pointer;
+      typedef typename _Base::reference       reference;
+      typedef typename _Base::const_reference const_reference;
+
+      typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, hash_set>
+                                              iterator;
+      typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
+                                         hash_set>
+                                              const_iterator;
+
+      typedef typename _Base::allocator_type allocator_type;
+      
+      using _Base::hash_funct;
+      using _Base::key_eq;
+      using _Base::get_allocator;
+      
+      hash_set() { }
+      
+      explicit hash_set(size_type __n) : _Base(__n) { }
+      
+      hash_set(size_type __n, const hasher& __hf) : _Base(__n, __hf) { }
+      
+      hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
+              const allocator_type& __a = allocator_type())
+      : _Base(__n, __hf, __eql, __a) { }
+    
+      template<typename _InputIterator>
+        hash_set(_InputIterator __f, _InputIterator __l)
+        : _Base(__gnu_debug::__check_valid_range(__f, __l), __l) { }
+
+      template<typename _InputIterator>
+        hash_set(_InputIterator __f, _InputIterator __l, size_type __n)
+       : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n) { }
+
+      template<typename _InputIterator>
+        hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
+                const hasher& __hf)
+       : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf) { }
+
+      template<typename _InputIterator>
+        hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
+                const hasher& __hf, const key_equal& __eql,
+                const allocator_type& __a = allocator_type())
+       : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n, __hf,
+               __eql, __a) { }
+
+      hash_set(const _Base& __x) : _Base(__x), _Safe_base() { }
+      
+      using _Base::size;
+      using _Base::max_size;
+      using _Base::empty;
+      
+      void 
+      swap(hash_set& __x)
+      {
+       _Base::swap(__x);
+       this->_M_swap(__x);
+      }
+      
+      iterator 
+      begin() const { return iterator(_Base::begin(), this); }
+
+      iterator 
+      end() const   { return iterator(_Base::end(),   this); }
+
+      std::pair<iterator, bool> 
+      insert(const value_type& __obj)
+      {                    
+       std::pair<typename _Base::iterator, bool> __res =
+        _Base::insert(__obj);
+       return std::make_pair(iterator(__res.first, this), __res.second);
+      }
+      
+      template <typename _InputIterator>
+        void 
+        insert(_InputIterator __first, _InputIterator __last) 
+        {
+         __glibcxx_check_valid_range(__first, __last);
+         _Base::insert(__first.base(), __last.base());
+       }
+      
+
+      std::pair<iterator, bool> 
+      insert_noresize(const value_type& __obj)
+      {
+       std::pair<typename _Base::iterator, bool> __res =
+        _Base::insert_noresize(__obj);
+       return std::make_pair(iterator(__res.first, this), __res.second);
+      }
+      
+      iterator 
+      find(const key_type& __key) const 
+      { return iterator(_Base::find(__key), this); }
+      
+      using _Base::count;
+      
+      std::pair<iterator, iterator> 
+      equal_range(const key_type& __key) const
+      { 
+       typedef typename _Base::iterator _Base_iterator;
+       std::pair<_Base_iterator, _Base_iterator> __res = 
+         _Base::equal_range(__key);
+       return std::make_pair(iterator(__res.first, this),
+                             iterator(__res.second, this));
+      }
+      
+      size_type 
+      erase(const key_type& __key) 
+      {
+       iterator __victim(_Base::find(__key), this);
+       if (__victim != end())
+         return this->erase(__victim), 1;
+       else
+         return 0;
+      }
+    
+      void 
+      erase(iterator __it) 
+      {
+       __glibcxx_check_erase(__it);
+       __it._M_invalidate();
+       _Base::erase(__it.base());
+      }
+      
+      void 
+      erase(iterator __first, iterator __last)
+      {
+       __glibcxx_check_erase_range(__first, __last);
+       for (iterator __tmp = __first; __tmp != __last;)
+       {
+         iterator __victim = __tmp++;
+         __victim._M_invalidate();
+       }
+       _Base::erase(__first.base(), __last.base());
+      }
+      
+      void 
+      clear() 
+      { 
+       _Base::clear();
+       this->_M_invalidate_all(); 
+      }
+      
+      using _Base::resize;
+      using _Base::bucket_count;
+      using _Base::max_bucket_count;
+      using _Base::elems_in_bucket;
+      
+      _Base&       
+      _M_base()       { return *this; }
+
+      const _Base& 
+      _M_base() const { return *this; }
+
+    private:
+      void 
+      _M_invalidate_all()
+      {
+       typedef typename _Base::const_iterator _Base_const_iterator;
+       typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
+       this->_M_invalidate_if(_Not_equal(_M_base().end()));
+      }
+    };
+
+  template<typename _Value, typename _HashFcn, typename _EqualKey, 
+          typename _Alloc>
+    inline bool
+    operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x,
+              const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y)
+    { return __x._M_base() == __y._M_base(); }
+
+  template<typename _Value, typename _HashFcn, typename _EqualKey, 
+          typename _Alloc>
+    inline bool
+    operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x,
+              const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y)
+    { return __x._M_base() != __y._M_base(); }
+
+  template<typename _Value, typename _HashFcn, typename _EqualKey, 
+          typename _Alloc>
+    inline void
+    swap(hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __x,
+        hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __y)
+    { __x.swap(__y); }
+} // namespace __gnu_debug_def
+
+#endif
diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list
new file mode 100644 (file)
index 0000000..79dcb1d
--- /dev/null
@@ -0,0 +1,505 @@
+// Debugging list implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_LIST
+#define _GLIBCXX_DEBUG_LIST 1
+
+#include <list>
+#include <bits/stl_algo.h>
+#include <debug/safe_sequence.h>
+#include <debug/safe_iterator.h>
+
+namespace __gnu_debug_def
+{
+  template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
+    class list
+    : public __gnu_norm::list<_Tp, _Allocator>,
+      public __gnu_debug::_Safe_sequence<list<_Tp, _Allocator> >
+    {
+      typedef __gnu_norm::list<_Tp, _Allocator> _Base;
+      typedef __gnu_debug::_Safe_sequence<list>  _Safe_base;
+
+    public:
+      typedef typename _Allocator::reference        reference;
+      typedef typename _Allocator::const_reference  const_reference;
+      
+      typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, list> 
+                                                   iterator;
+      typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, list>
+                                                   const_iterator;
+
+      typedef typename _Base::size_type             size_type;
+      typedef typename _Base::difference_type       difference_type;
+      
+      typedef _Tp                                  value_type;
+      typedef _Allocator                           allocator_type;
+      typedef typename _Allocator::pointer          pointer;
+      typedef typename _Allocator::const_pointer    const_pointer;
+      typedef std::reverse_iterator<iterator>       reverse_iterator;
+      typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+      // 23.2.2.1 construct/copy/destroy:
+      explicit list(const _Allocator& __a = _Allocator())
+      : _Base(__a) { }
+
+      explicit list(size_type __n, const _Tp& __value = _Tp(),
+                   const _Allocator& __a = _Allocator())
+      : _Base(__n, __value, __a) { }
+
+      template<class _InputIterator>
+      list(_InputIterator __first, _InputIterator __last,
+          const _Allocator& __a = _Allocator())
+       : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a)
+      { }
+      
+
+      list(const list& __x) : _Base(__x), _Safe_base() { }
+      
+      list(const _Base& __x) : _Base(__x), _Safe_base() { }
+      
+      ~list() { }
+      
+      list& 
+      operator=(const list& __x)
+      {
+       static_cast<_Base&>(*this) = __x;
+       this->_M_invalidate_all();
+       return *this;
+      }
+      
+      template<class _InputIterator>
+        void 
+        assign(_InputIterator __first, _InputIterator __last)
+        {
+         __glibcxx_check_valid_range(__first, __last);
+         _Base::assign(__first, __last);
+         this->_M_invalidate_all();
+       }
+      
+      void 
+      assign(size_type __n, const _Tp& __t)
+      {
+       _Base::assign(__n, __t);
+       this->_M_invalidate_all();
+      }
+      
+      using _Base::get_allocator;
+      
+      // iterators:
+      iterator       
+      begin()       
+      { return iterator(_Base::begin(), this); }
+      
+      const_iterator 
+      begin() const 
+      { return const_iterator(_Base::begin(), this); }
+      
+      iterator 
+      end() 
+      { return iterator(_Base::end(), this); }
+      
+      const_iterator 
+      end() const   
+      { return const_iterator(_Base::end(), this); }
+      
+      reverse_iterator 
+      rbegin() 
+      { return reverse_iterator(end()); }
+      
+      const_reverse_iterator 
+      rbegin() const
+      { return const_reverse_iterator(end()); }
+      
+      reverse_iterator 
+      rend() 
+      { return reverse_iterator(begin()); }
+      
+      const_reverse_iterator 
+      rend() const 
+      { return const_reverse_iterator(begin()); }
+      
+      // 23.2.2.2 capacity:
+      using _Base::empty;
+      using _Base::size;
+      using _Base::max_size;
+      
+      void 
+      resize(size_type __sz, _Tp __c = _Tp())
+      {
+       this->_M_detach_singular();
+       
+       // if __sz < size(), invalidate all iterators in [begin+__sz, end())
+       iterator __victim = begin();
+       iterator __end = end();
+       for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
+         ++__victim;
+       
+       while (__victim != __end)
+         {
+           iterator __real_victim = __victim++;
+           __real_victim._M_invalidate();
+         }
+       
+       try 
+         {
+           _Base::resize(__sz, __c);
+         }
+       catch(...)
+         {
+           this->_M_revalidate_singular();
+           __throw_exception_again;
+         }
+      }
+      
+      // element access:
+      reference 
+      front()
+      {
+       __glibcxx_check_nonempty();
+       return _Base::front();
+      }
+      
+      const_reference 
+      front() const
+      {
+       __glibcxx_check_nonempty();
+       return _Base::front();
+      }
+      
+      reference 
+      back()
+      {
+       __glibcxx_check_nonempty();
+       return _Base::back();
+      }
+      
+      const_reference 
+      back() const
+      {
+       __glibcxx_check_nonempty();
+       return _Base::back();
+      }
+      
+      // 23.2.2.3 modifiers:
+      using _Base::push_front;
+      
+      void 
+      pop_front()
+      {
+       __glibcxx_check_nonempty();
+       iterator __victim = begin();
+       __victim._M_invalidate();
+       _Base::pop_front();
+      }
+      
+      using _Base::push_back;
+      
+      void 
+      pop_back()
+      {
+       __glibcxx_check_nonempty();
+       iterator __victim = end();
+       --__victim;
+       __victim._M_invalidate();
+       _Base::pop_back();
+      }
+      
+      iterator 
+      insert(iterator __position, const _Tp& __x)
+      {
+       __glibcxx_check_insert(__position);
+       return iterator(_Base::insert(__position.base(), __x), this);
+      }
+      
+      void 
+      insert(iterator __position, size_type __n, const _Tp& __x)
+      {
+       __glibcxx_check_insert(__position);
+       _Base::insert(__position.base(), __n, __x);
+      }
+      
+      template<class _InputIterator>
+        void 
+        insert(iterator __position, _InputIterator __first,
+              _InputIterator __last)
+        {
+         __glibcxx_check_insert_range(__position, __first, __last);
+         _Base::insert(__position.base(), __first, __last);
+       }
+      
+      iterator 
+      erase(iterator __position)
+      {
+       __glibcxx_check_erase(__position);
+       __position._M_invalidate();
+       return iterator(_Base::erase(__position.base()), this);
+      }
+      
+      iterator 
+      erase(iterator __position, iterator __last)
+      {
+       // _GLIBCXX_RESOLVE_LIB_DEFECTS
+       // 151. can't currently clear() empty container
+       __glibcxx_check_erase_range(__position, __last);
+       for (iterator __victim = __position; __victim != __last; )
+         {
+           iterator __old = __victim;
+           ++__victim;
+           __old._M_invalidate();
+         }
+       return iterator(_Base::erase(__position.base(), __last.base()), this);
+      }
+      
+      void 
+      swap(list& __x)
+      {
+       _Base::swap(__x);
+       this->_M_swap(__x);
+      }
+      
+      void 
+      clear()
+      {
+       _Base::clear();
+       this->_M_invalidate_all();
+      }
+      
+      // 23.2.2.4 list operations:
+      void 
+      splice(iterator __position, list& __x)
+      {
+       _GLIBCXX_DEBUG_VERIFY(&__x != this,
+                             _M_message(::__gnu_debug::__msg_self_splice)
+                             ._M_sequence(*this, "this"));
+       this->splice(__position, __x, __x.begin(), __x.end());
+      }
+      
+      void 
+      splice(iterator __position, list& __x, iterator __i)
+      {
+       __glibcxx_check_insert(__position);
+       _GLIBCXX_DEBUG_VERIFY(__x.get_allocator() == this->get_allocator(),
+                             _M_message(::__gnu_debug::__msg_splice_alloc)
+                           ._M_sequence(*this)._M_sequence(__x, "__x"));
+       _GLIBCXX_DEBUG_VERIFY(__i._M_dereferenceable(),
+                             _M_message(::__gnu_debug::__msg_splice_bad)
+                             ._M_iterator(__i, "__i"));
+       _GLIBCXX_DEBUG_VERIFY(__i._M_attached_to(&__x),
+                             _M_message(::__gnu_debug::__msg_splice_other)
+                            ._M_iterator(__i, "__i")._M_sequence(__x, "__x"));
+       
+       // _GLIBCXX_RESOLVE_LIB_DEFECTS
+       // 250. splicing invalidates iterators
+       this->_M_transfer_iter(__i);
+       _Base::splice(__position.base(), __x._M_base(), __i.base());
+      }
+      
+      void 
+      splice(iterator __position, list& __x, iterator __first, iterator __last)
+      {
+       __glibcxx_check_insert(__position);
+       __glibcxx_check_valid_range(__first, __last);
+       _GLIBCXX_DEBUG_VERIFY(__first._M_attached_to(&__x),
+                             _M_message(::__gnu_debug::__msg_splice_other)
+                             ._M_sequence(__x, "x")
+                             ._M_iterator(__first, "first"));
+       _GLIBCXX_DEBUG_VERIFY(__x.get_allocator() == this->get_allocator(),
+                             _M_message(::__gnu_debug::__msg_splice_alloc)
+                             ._M_sequence(*this)._M_sequence(__x));
+       
+       for (iterator __tmp = __first; __tmp != __last; )
+         {
+           _GLIBCXX_DEBUG_VERIFY(&__x != this || __tmp != __position,
+                               _M_message(::__gnu_debug::__msg_splice_overlap)
+                                 ._M_iterator(__tmp, "position")
+                                 ._M_iterator(__first, "first")
+                                 ._M_iterator(__last, "last"));
+           iterator __victim = __tmp++;
+           // _GLIBCXX_RESOLVE_LIB_DEFECTS
+           // 250. splicing invalidates iterators
+           this->_M_transfer_iter(__victim);
+         }
+       
+       _Base::splice(__position.base(), __x._M_base(), __first.base(),
+                     __last.base());
+      }
+      
+      void 
+      remove(const _Tp& __value)
+      {
+       for (iterator __x = begin(); __x.base() != _Base::end(); )
+         {
+           if (*__x == __value)
+             __x = erase(__x);
+           else
+             ++__x;
+         }
+      }
+      
+      template<class _Predicate> 
+        void 
+        remove_if(_Predicate __pred)
+        {
+         for (iterator __x = begin(); __x.base() != _Base::end(); )
+           {
+             if (__pred(*__x))
+               __x = erase(__x);
+             else
+               ++__x;
+           }
+       }
+      
+      void 
+      unique()
+      {
+       iterator __first = begin();
+       iterator __last = end();
+       if (__first == __last) 
+         return;
+       iterator __next = __first;
+       while (++__next != __last)
+         {
+           if (*__first == *__next)
+             erase(__next);
+           else
+             __first = __next;
+           __next = __first;
+         }
+      }
+      
+      template<class _BinaryPredicate>
+        void 
+        unique(_BinaryPredicate __binary_pred)
+        {
+         iterator __first = begin();
+         iterator __last = end();
+         if (__first == __last) 
+           return;
+         iterator __next = __first;
+         while (++__next != __last)
+           {
+             if (__binary_pred(*__first, *__next))
+               erase(__next);
+             else
+               __first = __next;
+             __next = __first;
+           }
+       }
+      
+      void 
+      merge(list& __x)
+      {
+       __glibcxx_check_sorted(_Base::begin(), _Base::end());
+       __glibcxx_check_sorted(__x.begin().base(), __x.end().base());
+       for (iterator __tmp = __x.begin(); __tmp != __x.end(); )
+         {
+           iterator __victim = __tmp++;
+           __victim._M_attach(&__x);
+         }
+       _Base::merge(__x._M_base());
+      }
+      
+      template<class _Compare> 
+        void 
+        merge(list& __x, _Compare __comp)
+        {
+         __glibcxx_check_sorted_pred(_Base::begin(), _Base::end(), __comp);
+         __glibcxx_check_sorted_pred(__x.begin().base(), __x.end().base(), 
+                                     __comp);
+         for (iterator __tmp = __x.begin(); __tmp != __x.end(); )
+           {
+             iterator __victim = __tmp++;
+             __victim._M_attach(&__x);
+           }
+         _Base::merge(__x._M_base(), __comp);
+       }
+      
+      void 
+      sort() { _Base::sort(); }
+      
+      template<typename _StrictWeakOrdering>
+        void 
+        sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); }
+      
+      using _Base::reverse;
+      
+      _Base&       
+      _M_base()       { return *this; }
+
+      const _Base& 
+      _M_base() const { return *this; }
+
+    private:
+      void 
+      _M_invalidate_all()
+      {
+       typedef typename _Base::const_iterator _Base_const_iterator;
+       typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
+       this->_M_invalidate_if(_Not_equal(_M_base().end()));
+      }
+    };
+  
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator==(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs)
+    { return __lhs._M_base() == __rhs._M_base(); }
+
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator!=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs)
+    { return __lhs._M_base() != __rhs._M_base(); }
+  
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator<(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs)
+    { return __lhs._M_base() < __rhs._M_base(); }
+  
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator<=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs)
+    { return __lhs._M_base() <= __rhs._M_base(); }
+
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator>=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs)
+    { return __lhs._M_base() >= __rhs._M_base(); }
+  
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator>(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs)
+    { return __lhs._M_base() > __rhs._M_base(); }
+  
+  template<typename _Tp, typename _Alloc>
+    inline void
+    swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs)
+    { __lhs.swap(__rhs); }
+} // namespace __gnu_debug_def
+
+#endif
diff --git a/libstdc++-v3/include/debug/map b/libstdc++-v3/include/debug/map
new file mode 100644 (file)
index 0000000..2c38404
--- /dev/null
@@ -0,0 +1,38 @@
+// Debugging map/multimap implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_MAP
+#define _GLIBCXX_DEBUG_MAP 1
+
+#include <map>
+#include <debug/map.h>
+#include <debug/multimap.h>
+
+#endif
diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h
new file mode 100644 (file)
index 0000000..d8609bd
--- /dev/null
@@ -0,0 +1,323 @@
+// Debugging map implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_MAP_H
+#define _GLIBCXX_DEBUG_MAP_H 1
+
+#include <debug/safe_sequence.h>
+#include <debug/safe_iterator.h>
+#include <utility>
+
+namespace __gnu_debug_def
+{
+  template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
+          typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
+    class map
+    : public __gnu_norm::map<_Key, _Tp, _Compare, _Allocator>,
+      public __gnu_debug::_Safe_sequence<map<_Key, _Tp, _Compare, _Allocator> >
+    {
+      typedef __gnu_norm::map<_Key, _Tp, _Compare, _Allocator> _Base;
+      typedef __gnu_debug::_Safe_sequence<map> _Safe_base;
+
+    public:
+      // types:
+      typedef _Key                                  key_type;
+      typedef _Tp                                   mapped_type;
+      typedef std::pair<const _Key, _Tp>            value_type;
+      typedef _Compare                              key_compare;
+      typedef _Allocator                            allocator_type;
+      typedef typename _Allocator::reference        reference;
+      typedef typename _Allocator::const_reference  const_reference;
+      
+      typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, map> 
+                                                    iterator;
+      typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, map>
+                                                    const_iterator;
+
+      typedef typename _Base::size_type             size_type;
+      typedef typename _Base::difference_type       difference_type;
+      typedef typename _Allocator::pointer          pointer;
+      typedef typename _Allocator::const_pointer    const_pointer;
+      typedef std::reverse_iterator<iterator>       reverse_iterator;
+      typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+      
+      using _Base::value_compare;
+      
+      // 23.3.1.1 construct/copy/destroy:
+      explicit map(const _Compare& __comp = _Compare(), 
+                  const _Allocator& __a = _Allocator())
+      : _Base(__comp, __a) { }
+
+      template<typename _InputIterator>
+        map(_InputIterator __first, _InputIterator __last,
+           const _Compare& __comp = _Compare(), 
+           const _Allocator& __a = _Allocator())
+       : _Base(__gnu_debug::__check_valid_range(__first, __last), __last,
+               __comp, __a), _Safe_base() { }
+
+      map(const map<_Key,_Tp,_Compare,_Allocator>& __x) 
+      : _Base(__x), _Safe_base() { } 
+      
+      map(const _Base& __x) : _Base(__x), _Safe_base() { }
+
+      ~map() { }
+      
+      map<_Key,_Tp,_Compare,_Allocator>&
+      operator=(const map<_Key,_Tp,_Compare,_Allocator>& __x)
+      {
+       *static_cast<_Base*>(this) = __x;
+       this->_M_invalidate_all();
+       return *this;
+      }
+      
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 133. map missing get_allocator()
+      using _Base::get_allocator;
+      
+      // iterators:
+      iterator       
+      begin()  
+      { return iterator(_Base::begin(), this); }
+      
+      const_iterator 
+      begin() const 
+      { return const_iterator(_Base::begin(), this); }
+      
+      iterator       
+      end()         
+      { return iterator(_Base::end(), this); }
+      
+      const_iterator 
+      end() const   
+      { return const_iterator(_Base::end(), this); }
+      
+      reverse_iterator 
+      rbegin() 
+      { return reverse_iterator(end()); }
+      
+      const_reverse_iterator 
+      rbegin() const
+      { return const_reverse_iterator(end()); }
+      
+      reverse_iterator 
+      rend() 
+      { return reverse_iterator(begin()); }
+      
+      const_reverse_iterator 
+      rend() const 
+      { return const_reverse_iterator(begin()); }
+      
+      // capacity:
+      using _Base::empty;
+      using _Base::size;
+      using _Base::max_size;
+      
+      // 23.3.1.2 element access:
+      using _Base::operator[];
+      
+      // modifiers:
+      std::pair<iterator, bool> 
+      insert(const value_type& __x)
+      {
+       typedef typename _Base::iterator _Base_iterator;
+       std::pair<_Base_iterator, bool> __res = _Base::insert(__x);
+       return std::pair<iterator, bool>(iterator(__res.first, this), 
+                                        __res.second);
+      }
+      
+      iterator 
+      insert(iterator __position, const value_type& __x)
+      {
+       __glibcxx_check_insert(__position);
+       return iterator(_Base::insert(__position.base(), __x), this);
+      }
+      
+      template<typename _InputIterator>
+        void 
+        insert(_InputIterator __first, _InputIterator __last)
+        {
+         __glibcxx_valid_range(__first, __last);
+         _Base::insert(__first, __last);
+       }
+      
+      void 
+      erase(iterator __position)
+      {
+       __glibcxx_check_erase(__position);
+       __position._M_invalidate();
+       _Base::erase(__position.base());
+      }
+      
+      size_type 
+      erase(const key_type& __x)
+      {
+       iterator __victim = find(__x);
+       if (__victim == end())
+         return 0;
+       else
+       {
+         __victim._M_invalidate();
+         _Base::erase(__victim.base());
+         return 1;
+       }
+      }
+      
+      void 
+      erase(iterator __first, iterator __last)
+      {
+       // _GLIBCXX_RESOLVE_LIB_DEFECTS
+       // 151. can't currently clear() empty container
+       __glibcxx_check_erase_range(__first, __last);
+       while (__first != __last)
+         this->erase(__first++);
+      }
+      
+      void 
+      swap(map<_Key,_Tp,_Compare,_Allocator>& __x)
+      {
+       _Base::swap(__x);
+       this->_M_swap(__x);
+      }
+      
+      void 
+      clear()
+      { this->erase(begin(), end()); }
+      
+      // observers:
+      using _Base::key_comp;
+      using _Base::value_comp;
+      
+      // 23.3.1.3 map operations:
+      iterator 
+      find(const key_type& __x)
+      { return iterator(_Base::find(__x), this); }
+      
+      const_iterator 
+      find(const key_type& __x) const
+      { return const_iterator(_Base::find(__x), this); }
+      
+      using _Base::count;
+      
+      iterator 
+      lower_bound(const key_type& __x)
+      { return iterator(_Base::lower_bound(__x), this); }
+      
+      const_iterator 
+      lower_bound(const key_type& __x) const
+      { return const_iterator(_Base::lower_bound(__x), this); }
+      
+      iterator 
+      upper_bound(const key_type& __x)
+      { return iterator(_Base::upper_bound(__x), this); }
+      
+      const_iterator 
+      upper_bound(const key_type& __x) const
+      { return const_iterator(_Base::upper_bound(__x), this); }
+      
+      std::pair<iterator,iterator>
+      equal_range(const key_type& __x)
+      {
+       typedef typename _Base::iterator _Base_iterator;
+       std::pair<_Base_iterator, _Base_iterator> __res =
+       _Base::equal_range(__x);
+       return std::make_pair(iterator(__res.first, this),
+                             iterator(__res.second, this));
+      }
+      
+      std::pair<const_iterator,const_iterator>
+      equal_range(const key_type& __x) const
+      {
+       typedef typename _Base::const_iterator _Base_const_iterator;
+       std::pair<_Base_const_iterator, _Base_const_iterator> __res =
+       _Base::equal_range(__x);
+       return std::make_pair(const_iterator(__res.first, this),
+                             const_iterator(__res.second, this));
+      }
+      
+      _Base&       
+      _M_base() { return *this; }
+
+      const _Base& 
+      _M_base() const { return *this; }
+      
+    private:
+      void 
+      _M_invalidate_all()
+      {
+       typedef typename _Base::const_iterator _Base_const_iterator;
+       typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
+       this->_M_invalidate_if(_Not_equal(_M_base().end()));
+      }
+    };
+
+  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator> 
+    inline bool
+    operator==(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, 
+              const map<_Key,_Tp,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() == __rhs._M_base(); }
+
+  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+    inline bool
+    operator!=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, 
+              const map<_Key,_Tp,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() != __rhs._M_base(); }
+
+  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+    inline bool
+    operator<(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, 
+             const map<_Key,_Tp,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() < __rhs._M_base(); }
+
+  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+    inline bool
+    operator<=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, 
+              const map<_Key,_Tp,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() <= __rhs._M_base(); }
+
+  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+    inline bool
+    operator>=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, 
+              const map<_Key,_Tp,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() >= __rhs._M_base(); }
+
+  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+    inline bool
+    operator>(const map<_Key,_Tp,_Compare,_Allocator>& __lhs, 
+             const map<_Key,_Tp,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() > __rhs._M_base(); }
+
+  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+    inline void
+    swap(map<_Key,_Tp,_Compare,_Allocator>& __lhs, 
+        map<_Key,_Tp,_Compare,_Allocator>& __rhs)
+    { __lhs.swap(__rhs); }
+} // namespace __gnu_debug_def
+
+#endif 
diff --git a/libstdc++-v3/include/debug/multimap.h b/libstdc++-v3/include/debug/multimap.h
new file mode 100644 (file)
index 0000000..8c3bd31
--- /dev/null
@@ -0,0 +1,314 @@
+// Debugging multimap implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_MULTIMAP_H
+#define _GLIBCXX_DEBUG_MULTIMAP_H 1
+
+#include <debug/safe_sequence.h>
+#include <debug/safe_iterator.h>
+#include <utility>
+
+namespace __gnu_debug_def
+{
+  template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
+          typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
+    class multimap 
+    : public __gnu_norm::multimap<_Key, _Tp, _Compare, _Allocator>,
+    public __gnu_debug::_Safe_sequence<multimap<_Key,_Tp,_Compare,_Allocator> >
+    {
+      typedef __gnu_norm::multimap<_Key, _Tp, _Compare, _Allocator> _Base;
+      typedef __gnu_debug::_Safe_sequence<multimap> _Safe_base;
+      
+    public:
+      // types:
+      typedef _Key                                  key_type;
+      typedef _Tp                                   mapped_type;
+      typedef std::pair<const _Key, _Tp>             value_type;
+      typedef _Compare                               key_compare;
+      typedef _Allocator                             allocator_type;
+      typedef typename _Allocator::reference         reference;
+      typedef typename _Allocator::const_reference   const_reference;
+      
+      typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, multimap> 
+                                                     iterator;
+      typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
+                                           multimap> const_iterator;
+
+      typedef typename _Base::size_type              size_type;
+      typedef typename _Base::difference_type        difference_type;
+      typedef typename _Allocator::pointer           pointer;
+      typedef typename _Allocator::const_pointer     const_pointer;
+      typedef std::reverse_iterator<iterator>        reverse_iterator;
+      typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
+      
+      using _Base::value_compare;
+      
+      // 23.3.1.1 construct/copy/destroy:
+      explicit multimap(const _Compare& __comp = _Compare(),
+                       const _Allocator& __a = _Allocator())
+      : _Base(__comp, __a) { }
+
+      template<typename _InputIterator>
+      multimap(_InputIterator __first, _InputIterator __last,
+              const _Compare& __comp = _Compare(), 
+              const _Allocator& __a = _Allocator())
+      : _Base(__gnu_debug::__check_valid_range(__first, __last), __last,
+             __comp, __a) { }
+
+      multimap(const multimap<_Key,_Tp,_Compare,_Allocator>& __x)
+      : _Base(__x), _Safe_base() { } 
+
+      multimap(const _Base& __x) : _Base(__x), _Safe_base() { }
+
+      ~multimap() { }
+
+      multimap<_Key,_Tp,_Compare,_Allocator>&
+      operator=(const multimap<_Key,_Tp,_Compare,_Allocator>& __x)
+      {
+       *static_cast<_Base*>(this) = __x;
+       this->_M_invalidate_all();
+       return *this;
+      }
+
+      using _Base::get_allocator;
+
+      // iterators:
+      iterator       
+      begin() 
+      { return iterator(_Base::begin(), this); }
+
+      const_iterator 
+      begin() const 
+      { return const_iterator(_Base::begin(), this); }
+
+      iterator       
+      end() 
+      { return iterator(_Base::end(), this); }
+
+      const_iterator 
+      end() const   
+      { return const_iterator(_Base::end(), this); }
+
+      reverse_iterator 
+      rbegin() 
+      { return reverse_iterator(end()); }
+
+      const_reverse_iterator 
+      rbegin() const
+      { return const_reverse_iterator(end()); }
+
+      reverse_iterator 
+      rend() 
+      { return reverse_iterator(begin()); }
+
+      const_reverse_iterator 
+      rend() const 
+      { return const_reverse_iterator(begin()); }
+
+      // capacity:
+      using _Base::empty;
+      using _Base::size;
+      using _Base::max_size;
+
+      // modifiers:
+      iterator 
+      insert(const value_type& __x)
+      { return iterator(_Base::insert(__x), this); }
+
+      iterator 
+      insert(iterator __position, const value_type& __x)
+      {
+       __glibcxx_check_insert(__position);
+       return iterator(_Base::insert(__position.base(), __x), this);
+      }
+
+      template<typename _InputIterator>
+        void 
+        insert(_InputIterator __first, _InputIterator __last)
+        {
+         __glibcxx_check_valid_range(__first, __last);
+         _Base::insert(__first, __last);
+       }
+
+      void 
+      erase(iterator __position)
+      {
+       __glibcxx_check_erase(__position);
+       __position._M_invalidate();
+       _Base::erase(__position.base());
+      }
+
+      size_type 
+      erase(const key_type& __x)
+      {
+       std::pair<iterator, iterator> __victims = this->equal_range(__x);
+       size_type __count = 0;
+       while (__victims.first != __victims.second)
+       {
+         iterator __victim = __victims.first++;
+         __victim._M_invalidate();
+         _Base::erase(__victim.base());
+         ++__count;
+       }
+       return __count;
+      }
+
+      void 
+      erase(iterator __first, iterator __last)
+      {
+       // _GLIBCXX_RESOLVE_LIB_DEFECTS
+       // 151. can't currently clear() empty container
+       __glibcxx_check_erase_range(__first, __last);
+       while (__first != __last)
+       this->erase(__first++);
+      }
+
+      void 
+      swap(multimap<_Key,_Tp,_Compare,_Allocator>& __x)
+      {
+       _Base::swap(__x);
+       this->_M_swap(__x);
+      }
+
+      void 
+      clear()
+      { this->erase(begin(), end()); }
+
+      // observers:
+      using _Base::key_comp;
+      using _Base::value_comp;
+
+      // 23.3.1.3 multimap operations:
+      iterator 
+      find(const key_type& __x)
+      { return iterator(_Base::find(__x), this); }
+
+      const_iterator 
+      find(const key_type& __x) const
+      { return const_iterator(_Base::find(__x), this); }
+
+      using _Base::count;
+
+      iterator 
+      lower_bound(const key_type& __x)
+      { return iterator(_Base::lower_bound(__x), this); }
+
+      const_iterator 
+      lower_bound(const key_type& __x) const
+      { return const_iterator(_Base::lower_bound(__x), this); }
+
+      iterator 
+      upper_bound(const key_type& __x)
+      { return iterator(_Base::upper_bound(__x), this); }
+
+      const_iterator 
+      upper_bound(const key_type& __x) const
+      { return const_iterator(_Base::upper_bound(__x), this); }
+
+      std::pair<iterator,iterator>
+      equal_range(const key_type& __x)
+      {
+       typedef typename _Base::iterator _Base_iterator;
+       std::pair<_Base_iterator, _Base_iterator> __res =
+       _Base::equal_range(__x);
+       return std::make_pair(iterator(__res.first, this),
+                             iterator(__res.second, this));
+      }
+
+      std::pair<const_iterator,const_iterator>
+      equal_range(const key_type& __x) const
+      {
+       typedef typename _Base::const_iterator _Base_const_iterator;
+       std::pair<_Base_const_iterator, _Base_const_iterator> __res =
+       _Base::equal_range(__x);
+       return std::make_pair(const_iterator(__res.first, this),
+                             const_iterator(__res.second, this));
+      }
+
+      _Base&       
+      _M_base() { return *this; }
+
+      const _Base& 
+      _M_base() const { return *this; }
+
+    private:
+      void 
+      _M_invalidate_all()
+      {
+       typedef typename _Base::const_iterator _Base_const_iterator;
+       typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
+       this->_M_invalidate_if(_Not_equal(_M_base().end()));
+      }
+    };
+
+  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+    inline bool
+    operator==(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, 
+              const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() == __rhs._M_base(); }
+
+  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+    inline bool
+    operator!=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, 
+              const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() != __rhs._M_base(); }
+
+  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+    inline bool
+    operator<(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, 
+             const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() < __rhs._M_base(); }
+
+  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+    inline bool
+    operator<=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, 
+              const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() <= __rhs._M_base(); }
+
+  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+    inline bool
+    operator>=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, 
+              const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() >= __rhs._M_base(); }
+
+  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+    inline bool
+    operator>(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, 
+             const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() > __rhs._M_base(); }
+
+  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+    inline void
+    swap(multimap<_Key,_Tp,_Compare,_Allocator>& __lhs, 
+        multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
+    { __lhs.swap(__rhs); }
+} // namespace __gnu_debug_def
+
+#endif 
diff --git a/libstdc++-v3/include/debug/multiset.h b/libstdc++-v3/include/debug/multiset.h
new file mode 100644 (file)
index 0000000..083c8fb
--- /dev/null
@@ -0,0 +1,320 @@
+// Debugging multiset implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_MULTISET_H
+#define _GLIBCXX_DEBUG_MULTISET_H 1
+
+#include <debug/safe_sequence.h>
+#include <debug/safe_iterator.h>
+#include <utility>
+
+namespace __gnu_debug_def
+{
+  template<typename _Key, typename _Compare = std::less<_Key>,
+          typename _Allocator = std::allocator<_Key> >
+    class multiset 
+    : public __gnu_norm::multiset<_Key, _Compare, _Allocator>,
+      public __gnu_debug::_Safe_sequence<multiset<_Key, _Compare, _Allocator> >
+    {
+      typedef __gnu_norm::multiset<_Key, _Compare, _Allocator> _Base;
+      typedef __gnu_debug::_Safe_sequence<multiset> _Safe_base;
+
+    public:
+      // types:
+      typedef _Key                                key_type;
+      typedef _Key                                value_type;
+      typedef _Compare                                    key_compare;
+      typedef _Compare                                    value_compare;
+      typedef _Allocator                                  allocator_type;
+      typedef typename _Allocator::reference         reference;
+      typedef typename _Allocator::const_reference   const_reference;
+
+      typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, multiset> 
+      iterator;
+      typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
+                                         multiset> const_iterator;
+
+      typedef typename _Base::size_type              size_type;
+      typedef typename _Base::difference_type        difference_type;
+      typedef typename _Allocator::pointer           pointer;
+      typedef typename _Allocator::const_pointer     const_pointer;
+      typedef std::reverse_iterator<iterator>        reverse_iterator;
+      typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
+
+      // 23.3.3.1 construct/copy/destroy:
+      explicit multiset(const _Compare& __comp = _Compare(),
+                       const _Allocator& __a = _Allocator())
+      : _Base(__comp, __a) { }
+
+      template<typename _InputIterator>
+        multiset(_InputIterator __first, _InputIterator __last,
+                const _Compare& __comp = _Compare(),
+                const _Allocator& __a = _Allocator())
+       : _Base(__gnu_debug::__check_valid_range(__first, __last), __last,
+               __comp, __a) { }
+
+      multiset(const multiset<_Key,_Compare,_Allocator>& __x) 
+      : _Base(__x), _Safe_base() { }
+    
+      multiset(const _Base& __x) : _Base(__x), _Safe_base() { }
+
+      ~multiset() { }
+
+      multiset<_Key,_Compare,_Allocator>& 
+      operator=(const multiset<_Key,_Compare,_Allocator>& __x)
+      {
+       *static_cast<_Base*>(this) = __x;
+       this->_M_invalidate_all();
+       return *this;
+      }
+
+      using _Base::get_allocator;
+
+      // iterators:
+      iterator
+      begin()
+      { return iterator(_Base::begin(), this); }
+
+      const_iterator 
+      begin() const 
+      { return const_iterator(_Base::begin(), this); }
+
+      iterator 
+      end()
+      { return iterator(_Base::end(), this); }
+
+      const_iterator 
+      end() const   
+      { return const_iterator(_Base::end(), this); }
+
+      reverse_iterator 
+      rbegin() 
+      { return reverse_iterator(end()); }
+
+      const_reverse_iterator 
+      rbegin() const
+      { return const_reverse_iterator(end()); }
+
+      reverse_iterator 
+      rend() 
+      { return reverse_iterator(begin()); }
+
+      const_reverse_iterator 
+      rend() const 
+      { return const_reverse_iterator(begin()); }
+
+      // capacity:
+      using _Base::empty;
+      using _Base::size;
+      using _Base::max_size;
+
+      // modifiers:
+      iterator 
+      insert(const value_type& __x)
+      { return iterator(_Base::insert(__x), this); }
+
+      iterator 
+      insert(iterator __position, const value_type& __x)
+      {
+       __glibcxx_check_insert(__position);
+       return iterator(_Base::insert(__position.base(), __x), this);
+      }
+
+      template<typename _InputIterator>
+      void 
+      insert(_InputIterator __first, _InputIterator __last)
+      {
+       __glibcxx_check_valid_range(__first, __last);
+       _Base::insert(__first, __last);
+      }
+
+      void 
+      erase(iterator __position)
+      {
+       __glibcxx_check_erase(__position);
+       __position._M_invalidate();
+       _Base::erase(__position.base());
+      }
+
+      size_type
+      erase(const key_type& __x)
+      {
+       std::pair<iterator, iterator> __victims = this->equal_range(__x);
+       size_type __count = 0;
+       while (__victims.first != __victims.second)
+       {
+         iterator __victim = __victims.first++;
+         __victim._M_invalidate();
+         _Base::erase(__victim.base());
+         ++__count;
+       }
+       return __count;
+      }
+
+      void 
+      erase(iterator __first, iterator __last)
+      {
+       // _GLIBCXX_RESOLVE_LIB_DEFECTS
+       // 151. can't currently clear() empty container
+       __glibcxx_check_erase_range(__first, __last);
+       while (__first != __last)
+       this->erase(__first++);
+      }
+
+      void 
+      swap(multiset<_Key,_Compare,_Allocator>& __x)
+      {
+       _Base::swap(__x);
+       this->_M_swap(__x);
+      }
+
+      void 
+      clear()
+      { this->erase(begin(), end()); }
+
+      // observers:
+      using _Base::key_comp;
+      using _Base::value_comp;
+
+      // multiset operations:
+      iterator 
+      find(const key_type& __x)
+      { return iterator(_Base::find(__x), this); }
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 214. set::find() missing const overload
+      const_iterator 
+      find(const key_type& __x) const
+      { return const_iterator(_Base::find(__x), this); }
+
+      using _Base::count;
+
+      iterator 
+      lower_bound(const key_type& __x)
+      { return iterator(_Base::lower_bound(__x), this); }
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 214. set::find() missing const overload
+      const_iterator 
+      lower_bound(const key_type& __x) const
+      { return const_iterator(_Base::lower_bound(__x), this); }
+
+      iterator 
+      upper_bound(const key_type& __x)
+      { return iterator(_Base::upper_bound(__x), this); }
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 214. set::find() missing const overload
+      const_iterator 
+      upper_bound(const key_type& __x) const
+      { return const_iterator(_Base::upper_bound(__x), this); }
+
+      std::pair<iterator,iterator>
+      equal_range(const key_type& __x)
+      {
+       typedef typename _Base::iterator _Base_iterator;
+       std::pair<_Base_iterator, _Base_iterator> __res =
+        _Base::equal_range(__x);
+       return std::make_pair(iterator(__res.first, this),
+                             iterator(__res.second, this));
+      }
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 214. set::find() missing const overload
+      std::pair<const_iterator,const_iterator>
+      equal_range(const key_type& __x) const
+      {
+       typedef typename _Base::const_iterator _Base_iterator;
+       std::pair<_Base_iterator, _Base_iterator> __res =
+        _Base::equal_range(__x);
+       return std::make_pair(const_iterator(__res.first, this),
+                             const_iterator(__res.second, this));
+      }
+
+      _Base& 
+      _M_base() { return *this; }
+
+      const _Base& 
+      _M_base() const { return *this; }
+      
+    private:
+      void 
+      _M_invalidate_all()
+      {
+       typedef typename _Base::const_iterator _Base_const_iterator;
+       typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
+       this->_M_invalidate_if(_Not_equal(_M_base().end()));
+      }
+    };
+
+  template<typename _Key, typename _Compare, typename _Allocator>
+    inline bool 
+    operator==(const multiset<_Key,_Compare,_Allocator>& __lhs,
+              const multiset<_Key,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() == __rhs._M_base(); }
+
+  template<typename _Key, typename _Compare, typename _Allocator>
+    inline bool 
+    operator!=(const multiset<_Key,_Compare,_Allocator>& __lhs,
+              const multiset<_Key,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() != __rhs._M_base(); }
+
+  template<typename _Key, typename _Compare, typename _Allocator>
+    inline bool 
+    operator<(const multiset<_Key,_Compare,_Allocator>& __lhs,
+             const multiset<_Key,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() < __rhs._M_base(); }
+
+  template<typename _Key, typename _Compare, typename _Allocator>
+    inline bool 
+    operator<=(const multiset<_Key,_Compare,_Allocator>& __lhs,
+              const multiset<_Key,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() <= __rhs._M_base(); }
+
+  template<typename _Key, typename _Compare, typename _Allocator>
+    inline bool 
+    operator>=(const multiset<_Key,_Compare,_Allocator>& __lhs,
+              const multiset<_Key,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() >= __rhs._M_base(); }
+
+  template<typename _Key, typename _Compare, typename _Allocator>
+    inline bool 
+    operator>(const multiset<_Key,_Compare,_Allocator>& __lhs,
+             const multiset<_Key,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() > __rhs._M_base(); }
+
+  template<typename _Key, typename _Compare, typename _Allocator>
+    void
+    swap(multiset<_Key,_Compare,_Allocator>& __x,
+        multiset<_Key,_Compare,_Allocator>& __y)
+    { return __x.swap(__y); }
+} // namespace __gnu_debug_def
+
+#endif
diff --git a/libstdc++-v3/include/debug/safe_base.h b/libstdc++-v3/include/debug/safe_base.h
new file mode 100644 (file)
index 0000000..93b1761
--- /dev/null
@@ -0,0 +1,201 @@
+// Safe sequence/iterator base implementation  -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_SAFE_BASE_H
+#define _GLIBCXX_DEBUG_SAFE_BASE_H 1
+
+namespace __gnu_debug
+{
+  class _Safe_sequence_base;
+
+  /** \brief Basic functionality for a "safe" iterator.
+   *
+   *  The %_Safe_iterator_base base class implements the functionality
+   *  of a safe iterator that is not specific to a particular iterator
+   *  type. It contains a pointer back to the sequence it references
+   *  along with iterator version information and pointers to form a
+   *  doubly-linked list of iterators referenced by the container.
+   *
+   *  This class must not perform any operations that can throw an
+   *  exception, or the exception guarantees of derived iterators will
+   *  be broken.
+   */
+  class _Safe_iterator_base
+  {
+  public:
+    /** The sequence this iterator references; may be NULL to indicate
+       a singular iterator. */
+    _Safe_sequence_base* _M_sequence;
+
+    /** The version number of this iterator. The sentinel value 0 is
+     *  used to indicate an invalidated iterator (i.e., one that is
+     *  singular because of an operation on the container). This
+     *  version number must equal the version number in the sequence
+     *  referenced by _M_sequence for the iterator to be
+     *  non-singular. 
+     */
+    unsigned int         _M_version;
+
+    /** Pointer to the previous iterator in the sequence's list of
+       iterators. Only valid when _M_sequence != NULL. */
+    _Safe_iterator_base* _M_prior;
+
+    /** Pointer to the next iterator in the sequence's list of
+       iterators. Only valid when _M_sequence != NULL. */
+    _Safe_iterator_base* _M_next;
+
+  protected:
+    /** Initializes the iterator and makes it singular. */
+    _Safe_iterator_base() 
+    : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0)
+    { }
+
+    /** Initialize the iterator to reference the sequence pointed to
+     *  by @p__seq. @p __constant is true when we are initializing a
+     *  constant iterator, and false if it is a mutable iterator. Note
+     *  that @p __seq may be NULL, in which case the iterator will be
+     *  singular. Otherwise, the iterator will reference @p __seq and
+     *  be nonsingular. 
+     */
+    _Safe_iterator_base(const _Safe_sequence_base* __seq, bool __constant)
+    : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0)
+    { this->_M_attach(const_cast<_Safe_sequence_base*>(__seq), __constant); }
+
+    /** Initializes the iterator to reference the same sequence that
+       @p __x does. @p __constant is true if this is a constant
+       iterator, and false if it is mutable. */
+    _Safe_iterator_base(const _Safe_iterator_base& __x, bool __constant)
+    : _M_sequence(0), _M_version(0), _M_prior(0), _M_next(0)
+    { this->_M_attach(__x._M_sequence, __constant); }
+
+    ~_Safe_iterator_base() { this->_M_detach(); }
+
+  public:
+    /** Attaches this iterator to the given sequence, detaching it
+     * from whatever sequence it was attached to originally. If the
+     * new sequence is the NULL pointer, the iterator is left
+     * unattached.
+     */ 
+    void _M_attach(_Safe_sequence_base* __seq, bool __constant);
+
+    /** Detach the iterator for whatever sequence it is attached to,
+     * if any. 
+    */
+    void _M_detach();
+
+    /** Determines if we are attached to the given sequence. */
+    bool _M_attached_to(const _Safe_sequence_base* __seq) const
+    { return _M_sequence == __seq; }
+
+    /** Is this iterator singular? */
+    bool _M_singular() const;
+
+    /** Can we compare this iterator to the given iterator @p __x?
+       Returns true if both iterators are nonsingular and reference
+       the same sequence. */
+    bool _M_can_compare(const _Safe_iterator_base& __x) const;
+  };
+
+  /**
+   * @brief Base class that supports tracking of iterators that
+   * reference a sequence.
+   *
+   * The %_Safe_sequence_base class provides basic support for
+   * tracking iterators into a sequence. Sequences that track
+   * iterators must derived from %_Safe_sequence_base publicly, so
+   * that safe iterators (which inherit _Safe_iterator_base) can
+   * attach to them. This class contains two linked lists of
+   * iterators, one for constant iterators and one for mutable
+   * iterators, and a version number that allows very fast
+   * invalidation of all iterators that reference the container.
+   *
+   * This class must ensure that no operation on it may throw an
+   * exception, otherwise "safe" sequences may fail to provide the
+   * exception-safety guarantees required by the C++ standard.
+   */
+  class _Safe_sequence_base
+  {
+  public:
+    /// The list of mutable iterators that reference this container
+    _Safe_iterator_base* _M_iterators;
+    
+    /// The list of constant iterators that reference this container
+    _Safe_iterator_base* _M_const_iterators;
+    
+    /// The container version number. This number may never be 0.
+    mutable unsigned int _M_version;
+    
+  protected:
+    // Initialize with a version number of 1 and no iterators
+    _Safe_sequence_base()
+    : _M_iterators(0), _M_const_iterators(0), _M_version(1)
+    { }
+    
+    /** Notify all iterators that reference this sequence that the
+       sequence is being destroyed. */
+    ~_Safe_sequence_base()
+    { this->_M_detach_all(); }
+    
+    /** Detach all iterators, leaving them singular. */
+    void 
+    _M_detach_all();
+    
+    /** Detach all singular iterators. 
+     *  @post for all iterators i attached to this sequence, 
+     *   i->_M_version == _M_version.
+     */
+    void
+    _M_detach_singular();
+    
+    /** Revalidates all attached singular iterators.  This method may
+     *  be used to validate iterators that were invalidated before
+     *  (but for some reasion, such as an exception, need to become
+     *  valid again).
+     */
+    void
+    _M_revalidate_singular();
+    
+    /** Swap this sequence with the given sequence. This operation
+     *  also swaps ownership of the iterators, so that when the
+     *  operation is complete all iterators that originally referenced
+     *  one container now reference the other container.
+     */
+    void 
+    _M_swap(_Safe_sequence_base& __x);
+      
+  public:
+    /** Invalidates all iterators. */
+    void 
+    _M_invalidate_all() const
+    { if (++_M_version == 0) _M_version = 1; }
+  };
+} // namespace __gnu_debug
+
+#endif 
diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h
new file mode 100644 (file)
index 0000000..5d7ee27
--- /dev/null
@@ -0,0 +1,607 @@
+// Safe iterator implementation  -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H
+#define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1
+
+#include <bits/stl_pair.h>
+#include <debug/debug.h>
+#include <debug/formatter.h>
+#include <debug/safe_base.h>
+
+namespace __gnu_debug
+{
+  /** Iterators that derive from _Safe_iterator_base but that aren't
+   *  _Safe_iterators can be determined singular or non-singular via
+   *  _Safe_iterator_base. 
+   */
+  inline bool __check_singular_aux(const _Safe_iterator_base* __x)
+  { return __x->_M_singular(); }
+  
+  /** \brief Safe iterator wrapper.
+   *  
+   *  The class template %_Safe_iterator is a wrapper around an
+   *  iterator that tracks the iterator's movement among sequences and
+   *  checks that operations performed on the "safe" iterator are
+   *  legal. In additional to the basic iterator operations (which are
+   *  validated, and then passed to the underlying iterator),
+   *  %_Safe_iterator has member functions for iterator invalidation,
+   *  attaching/detaching the iterator from sequences, and querying
+   *  the iterator's state.
+   */
+  template<typename _Iterator, typename _Sequence>
+    class _Safe_iterator : public _Safe_iterator_base
+    {
+      typedef _Safe_iterator _Self;
+
+      /** The precision to which we can calculate the distance between
+       *  two iterators.
+       */
+      enum _Distance_precision
+       {
+         __dp_equality, //< Can compare iterator equality, only
+         __dp_sign,     //< Can determine equality and ordering
+         __dp_exact     //< Can determine distance precisely
+       };
+      
+      /// The underlying iterator
+      _Iterator _M_current;
+
+      /// Determine if this is a constant iterator.
+      bool 
+      _M_constant() const
+      {
+       typedef typename _Sequence::const_iterator const_iterator;
+       return __is_same<const_iterator, _Safe_iterator>::value;
+      }
+
+      typedef iterator_traits<_Iterator> _Traits;
+
+    public:
+      typedef typename _Traits::iterator_category iterator_category;
+      typedef typename _Traits::value_type        value_type;
+      typedef typename _Traits::difference_type   difference_type;
+      typedef typename _Traits::reference         reference;
+      typedef typename _Traits::pointer           pointer;
+
+      /// @post the iterator is singular and unattached
+      _Safe_iterator() : _M_current() { }
+
+      /**
+       * @brief Safe iterator construction from an unsafe iterator and
+       * its sequence.
+       *
+       * @pre @p seq is not NULL
+       * @post this is not singular
+       */
+      _Safe_iterator(const _Iterator& __i, const _Sequence* __seq)
+      : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i)
+      { 
+       _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
+                             _M_message(__msg_init_singular)
+                             ._M_iterator(*this, "this"));
+      }
+
+      /**
+       * @brief Copy construction.
+       * @pre @p x is not singular
+       */
+      _Safe_iterator(const _Safe_iterator& __x)
+      : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current)
+      { 
+       _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(),
+                             _M_message(__msg_init_copy_singular)
+                             ._M_iterator(*this, "this")
+                             ._M_iterator(__x, "other"));
+      }
+
+      /** 
+       *  @brief Converting constructor from a mutable iterator to a
+       *  constant iterator.
+       *
+       *  @pre @p x is not singular
+      */
+      template<typename _MutableIterator>
+        _Safe_iterator(const _Safe_iterator<_MutableIterator, _Sequence>& __x)
+       : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base())
+        { 
+         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(),
+                               _M_message(__msg_init_const_singular)
+                               ._M_iterator(*this, "this")
+                               ._M_iterator(__x, "other"));
+       }
+
+      /**
+       * @brief Copy assignment.
+       * @pre @p x is not singular
+       */
+      _Safe_iterator& 
+      operator=(const _Safe_iterator& __x)
+      {
+       _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(),
+                             _M_message(__msg_copy_singular)
+                             ._M_iterator(*this, "this")
+                             ._M_iterator(__x, "other"));
+       _M_current = __x._M_current;
+       this->_M_attach(static_cast<_Sequence*>(__x._M_sequence));
+       return *this;
+      }
+
+      /**
+       *  @brief Iterator dereference.
+       *  @pre iterator is dereferenceable
+       */
+      reference 
+      operator*() const 
+      {
+
+       _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
+                             _M_message(__msg_bad_deref)
+                             ._M_iterator(*this, "this"));
+       return *_M_current;
+      }
+
+      /**
+       *  @brief Iterator dereference.
+       *  @pre iterator is dereferenceable
+       *  @todo Make this correct w.r.t. iterators that return proxies
+       *  @todo Use addressof() instead of & operator
+       */
+      pointer 
+      operator->() const
+      {
+       _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
+                             _M_message(__msg_bad_deref)
+                             ._M_iterator(*this, "this"));
+       return &*_M_current;
+      }
+
+      // ------ Input iterator requirements ------
+      /**
+       *  @brief Iterator preincrement
+       *  @pre iterator is incrementable
+       */
+      _Safe_iterator& 
+      operator++()
+      {
+       _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
+                             _M_message(__msg_bad_inc)
+                             ._M_iterator(*this, "this"));
+       ++_M_current;
+       return *this;
+      }
+
+      /**
+       *  @brief Iterator postincrement
+       *  @pre iterator is incrementable
+       */
+      _Safe_iterator 
+      operator++(int)
+      {
+       _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
+                             _M_message(__msg_bad_inc)
+                             ._M_iterator(*this, "this"));
+       _Safe_iterator __tmp(*this);
+       ++_M_current;
+       return __tmp;
+      }
+
+      // ------ Bidirectional iterator requirements ------
+      /**
+       *  @brief Iterator predecrement
+       *  @pre iterator is decrementable
+       */
+      _Safe_iterator& 
+      operator--()
+      {
+       _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
+                             _M_message(__msg_bad_dec)
+                             ._M_iterator(*this, "this"));
+       --_M_current;
+       return *this;
+      }
+
+      /**
+       *  @brief Iterator postdecrement
+       *  @pre iterator is decrementable
+       */
+      _Safe_iterator 
+      operator--(int)
+      {
+       _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
+                             _M_message(__msg_bad_dec)
+                             ._M_iterator(*this, "this"));
+       _Safe_iterator __tmp(*this);
+       --_M_current;
+       return __tmp;
+      }
+
+      // ------ Random access iterator requirements ------
+      reference 
+      operator[](const difference_type& __n) const
+      {
+       _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n) 
+                             && this->_M_can_advance(__n+1),
+                             _M_message(__msg_iter_subscript_oob)
+                             ._M_iterator(*this)._M_integer(__n));
+
+       return _M_current[__n];
+      }
+
+      _Safe_iterator& 
+      operator+=(const difference_type& __n)
+      {
+       _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
+                             _M_message(__msg_advance_oob)
+                             ._M_iterator(*this)._M_integer(__n));
+       _M_current += __n;
+       return *this;
+      }
+
+      _Safe_iterator 
+      operator+(const difference_type& __n) const
+      {
+       _Safe_iterator __tmp(*this);
+       __tmp += __n;
+       return __tmp;
+      }
+
+      _Safe_iterator& 
+      operator-=(const difference_type& __n)
+      {
+       _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
+                             _M_message(__msg_retreat_oob)
+                             ._M_iterator(*this)._M_integer(__n));
+       _M_current += -__n;
+       return *this;
+      }
+
+      _Safe_iterator 
+      operator-(const difference_type& __n) const
+      {
+       _Safe_iterator __tmp(*this);
+       __tmp -= __n;
+       return __tmp;
+      }
+
+      // ------ Utilities ------
+      /**
+       * @brief Return the underlying iterator
+       */      
+      _Iterator 
+      base() const { return _M_current; }
+
+      /**
+       * @brief Conversion to underlying non-debug iterator to allow
+       * better interaction with non-debug containers.
+       */
+      operator _Iterator() const { return _M_current; }
+
+      /** Attach iterator to the given sequence. */
+      void 
+      _M_attach(const _Sequence* __seq)
+      { 
+       _Safe_iterator_base::_M_attach(const_cast<_Sequence*>(__seq),
+                                      _M_constant()); 
+      }
+
+      /** Invalidate the iterator, making it singular. */
+      void 
+      _M_invalidate();
+
+      /// Is the iterator dereferenceable?
+      bool 
+      _M_dereferenceable() const
+      { return !this->_M_singular() && !_M_is_end(); }
+
+      /// Is the iterator incrementable?
+      bool 
+      _M_incrementable() const { return this->_M_dereferenceable(); }
+
+      // Is the iterator decrementable?
+      bool 
+      _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
+
+      // Can we advance the iterator @p __n steps (@p __n may be negative)
+      bool 
+      _M_can_advance(const difference_type& __n) const;
+
+      // Is the iterator range [*this, __rhs) valid?
+      template<typename _Other>
+        bool 
+        _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const;
+
+      // The sequence this iterator references.
+      const _Sequence* 
+      _M_get_sequence() const
+      { return static_cast<const _Sequence*>(_M_sequence); }
+
+    /** Determine the distance between two iterators with some known
+     * precision. 
+    */
+    template<typename _Iterator1, typename _Iterator2>
+      static pair<difference_type, _Distance_precision>
+      _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs)
+      {
+        typedef typename iterator_traits<_Iterator1>::iterator_category
+         _Category;
+        return _M_get_distance(__lhs, __rhs, _Category());
+      }
+
+    template<typename _Iterator1, typename _Iterator2>
+      static pair<difference_type, _Distance_precision>
+      _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
+                     std::random_access_iterator_tag)
+      {
+        return std::make_pair(__rhs.base() - __lhs.base(), __dp_exact);
+      }
+
+    template<typename _Iterator1, typename _Iterator2>
+      static pair<difference_type, _Distance_precision>
+      _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
+                   std::forward_iterator_tag)
+      {
+        return std::make_pair(__lhs.base() == __rhs.base()? 0 : 1, 
+                             __dp_equality);
+      }
+
+      /// Is this iterator equal to the sequence's begin() iterator?
+      bool _M_is_begin() const
+      {        return *this == static_cast<const _Sequence*>(_M_sequence)->begin(); }
+
+      /// Is this iterator equal to the sequence's end() iterator?
+      bool _M_is_end() const
+      {        return *this == static_cast<const _Sequence*>(_M_sequence)->end(); }
+    };
+
+  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+    inline bool
+    operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
+              const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
+    { 
+      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+                           _M_message(__msg_iter_compare_bad)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
+                           _M_message(__msg_compare_different)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      return __lhs.base() == __rhs.base(); 
+    }
+
+  template<typename _Iterator, typename _Sequence>
+    inline bool
+    operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
+               const _Safe_iterator<_Iterator, _Sequence>& __rhs)
+    { 
+      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+                           _M_message(__msg_iter_compare_bad)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
+                           _M_message(__msg_compare_different)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      return __lhs.base() == __rhs.base(); 
+    }
+
+  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+    inline bool
+    operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
+              const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
+    { 
+      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+                           _M_message(__msg_iter_compare_bad)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
+                           _M_message(__msg_compare_different)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      return __lhs.base() != __rhs.base(); 
+    }
+
+  template<typename _Iterator, typename _Sequence>
+    inline bool
+    operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
+               const _Safe_iterator<_Iterator, _Sequence>& __rhs)
+    { 
+      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+                           _M_message(__msg_iter_compare_bad)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
+                           _M_message(__msg_compare_different)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      return __lhs.base() != __rhs.base(); 
+    }
+
+  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+    inline bool
+    operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
+             const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
+    { 
+      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+                           _M_message(__msg_iter_order_bad)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
+                           _M_message(__msg_order_different)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      return __lhs.base() < __rhs.base(); 
+    }
+
+  template<typename _Iterator, typename _Sequence>
+    inline bool
+    operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
+             const _Safe_iterator<_Iterator, _Sequence>& __rhs)
+    { 
+      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+                           _M_message(__msg_iter_order_bad)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
+                           _M_message(__msg_order_different)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      return __lhs.base() < __rhs.base(); 
+    }
+
+  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+    inline bool
+    operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
+              const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
+    { 
+      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+                           _M_message(__msg_iter_order_bad)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
+                           _M_message(__msg_order_different)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      return __lhs.base() <= __rhs.base(); 
+    }
+
+  template<typename _Iterator, typename _Sequence>
+    inline bool
+    operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
+               const _Safe_iterator<_Iterator, _Sequence>& __rhs)
+    { 
+      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+                           _M_message(__msg_iter_order_bad)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
+                           _M_message(__msg_order_different)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      return __lhs.base() <= __rhs.base(); 
+    }
+
+  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+    inline bool
+    operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
+             const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
+    { 
+      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+                           _M_message(__msg_iter_order_bad)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
+                           _M_message(__msg_order_different)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      return __lhs.base() > __rhs.base(); 
+    }
+
+  template<typename _Iterator, typename _Sequence>
+    inline bool
+    operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
+             const _Safe_iterator<_Iterator, _Sequence>& __rhs)
+    { 
+      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+                           _M_message(__msg_iter_order_bad)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
+                           _M_message(__msg_order_different)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      return __lhs.base() > __rhs.base(); 
+    }
+
+  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+    inline bool
+    operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
+              const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
+    { 
+      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+                           _M_message(__msg_iter_order_bad)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
+                           _M_message(__msg_order_different)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      return __lhs.base() >= __rhs.base(); 
+    }
+
+  template<typename _Iterator, typename _Sequence>
+    inline bool
+    operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
+               const _Safe_iterator<_Iterator, _Sequence>& __rhs)
+    { 
+      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+                           _M_message(__msg_iter_order_bad)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
+                           _M_message(__msg_order_different)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      return __lhs.base() >= __rhs.base(); 
+    }
+
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // According to the resolution of DR179 not only the various comparison
+  // operators but also operator- must accept mixed iterator/const_iterator
+  // parameters.
+  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
+    inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
+    operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
+             const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
+    { 
+      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+                           _M_message(__msg_distance_bad)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
+                           _M_message(__msg_distance_different)
+                           ._M_iterator(__lhs, "lhs")
+                           ._M_iterator(__rhs, "rhs"));
+      return __lhs.base() - __rhs.base(); 
+    }
+
+  template<typename _Iterator, typename _Sequence>
+    inline _Safe_iterator<_Iterator, _Sequence>
+    operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
+             const _Safe_iterator<_Iterator, _Sequence>& __i)
+    { return __i + __n; }
+} // namespace __gnu_debug
+
+#ifndef _GLIBCXX_EXPORT_TEMPLATE
+#  include <debug/safe_iterator.tcc>
+#endif 
+
+#endif
diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc b/libstdc++-v3/include/debug/safe_iterator.tcc
new file mode 100644 (file)
index 0000000..0af21b9
--- /dev/null
@@ -0,0 +1,140 @@
+// Debugging iterator implementation (out of line) -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/** @file safe_iterator.tcc
+ *  This is an internal header file, included by other library headers.
+ *  You should not attempt to use it directly.
+ */
+
+#ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC
+#define _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC 1
+
+namespace __gnu_debug
+{
+  template<typename _Iterator, typename _Sequence>
+    bool 
+    _Safe_iterator<_Iterator, _Sequence>::
+    _M_can_advance(const difference_type& __n) const
+    {
+      typedef typename _Sequence::const_iterator const_iterator;
+      
+      if (this->_M_singular())
+       return false;
+      if (__n == 0)
+       return true;
+      if (__n < 0) 
+       {
+         const_iterator __begin = 
+           static_cast<const _Sequence*>(_M_sequence)->begin();
+         pair<difference_type, _Distance_precision> __dist =
+           this->_M_get_distance(__begin, *this);
+         bool __ok =  (__dist.second == __dp_exact && __dist.first >= -__n
+                       || __dist.second != __dp_exact && __dist.first > 0);
+         return __ok;
+       }
+      else
+       {
+         const_iterator __end = 
+           static_cast<const _Sequence*>(_M_sequence)->end();
+         pair<difference_type, _Distance_precision> __dist = 
+           this->_M_get_distance(*this, __end);
+         bool __ok = (__dist.second == __dp_exact && __dist.first >= __n
+                      || __dist.second != __dp_exact && __dist.first > 0);
+         return __ok;
+       }
+    }
+  
+  template<typename _Iterator, typename _Sequence>
+    template<typename _Other>
+      bool 
+      _Safe_iterator<_Iterator, _Sequence>::
+      _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const
+      {
+       if (!_M_can_compare(__rhs))
+         return false;
+       
+       /* Determine if we can order the iterators without the help of
+          the container */
+       pair<difference_type, _Distance_precision> __dist = 
+         this->_M_get_distance(*this, __rhs);
+       switch (__dist.second) {
+       case __dp_equality:
+         if (__dist.first == 0)
+           return true;
+         break;
+         
+       case __dp_sign:
+       case __dp_exact:
+         return __dist.first >= 0;
+       }
+       
+       /* We can only test for equality, but check if one of the
+          iterators is at an extreme. */
+       if (_M_is_begin() || __rhs._M_is_end())
+         return true;
+       else if (_M_is_end() || __rhs._M_is_begin())
+         return false;
+       
+       // Assume that this is a valid range; we can't check anything else
+       return true;
+      }
+
+  template<typename _Iterator, typename _Sequence>
+    void
+    _Safe_iterator<_Iterator, _Sequence>::
+    _M_invalidate()
+    {
+      typedef typename _Sequence::iterator iterator;
+      typedef typename _Sequence::const_iterator const_iterator;
+      
+      if (!this->_M_singular())
+       {
+         for (_Safe_iterator_base* iter = _M_sequence->_M_iterators; iter; )
+           {
+             iterator* __victim = static_cast<iterator*>(iter);
+             iter = iter->_M_next;
+             if (this->base() == __victim->base())
+               __victim->_M_version = 0;
+           }
+         for (_Safe_iterator_base* iter = _M_sequence->_M_const_iterators;
+              iter; /* increment in loop */)
+           {
+             const_iterator* __victim = static_cast<const_iterator*>(iter);
+             iter = iter->_M_next;
+             if (this->base() == __victim->base())
+               __victim->_M_version = 0;
+           }
+         _M_version = 0;
+       }
+    }
+} // namespace __gnu_debug
+
+#endif 
+
diff --git a/libstdc++-v3/include/debug/safe_sequence.h b/libstdc++-v3/include/debug/safe_sequence.h
new file mode 100644 (file)
index 0000000..cb2d8ae
--- /dev/null
@@ -0,0 +1,179 @@
+// Safe sequence implementation  -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_SAFE_SEQUENCE_H
+#define _GLIBCXX_DEBUG_SAFE_SEQUENCE_H 1
+
+#include <debug/debug.h>
+#include <debug/safe_base.h>
+
+namespace __gnu_debug
+{
+  template<typename _Iterator, typename _Sequence> 
+    class _Safe_iterator;
+
+  /** A simple function object that returns true if the passed-in
+   *  value is not equal to the stored value. It saves typing over
+   *  using both bind1st and not_equal. 
+   */
+  template<typename _Type>
+    class _Not_equal_to
+    {
+      _Type __value;
+      
+    public:
+      explicit _Not_equal_to(const _Type& __v) : __value(__v) { }
+      
+      bool 
+      operator()(const _Type& __x) const 
+      { return __value != __x; }
+    };
+  
+  /** A function object that returns true when the given random access
+      iterator is at least @c n steps away from the given iterator. */
+  template<typename _Iterator>
+    class _After_nth_from
+    {
+      typedef typename std::iterator_traits<_Iterator>::difference_type
+      difference_type;
+      
+      _Iterator _M_base;
+      difference_type _M_n;
+      
+    public:
+      _After_nth_from(const difference_type& __n, const _Iterator& __base)
+      : _M_base(__base), _M_n(__n) { }
+      
+      bool 
+      operator()(const _Iterator& __x) const
+      { return __x - _M_base >= _M_n; }
+    };
+  
+  /**
+   * @brief Base class for constructing a "safe" sequence type that
+   * tracks iterators that reference it.
+   *
+   * The class template %_Safe_sequence simplifies the construction of
+   * "safe" sequences that track the iterators that reference the
+   * sequence, so that the iterators are notified of changes in the
+   * sequence that may affect their operation, e.g., if the container
+   * invalidates its iterators or is destructed. This class template
+   * may only be used by deriving from it and passing the name of the
+   * derived class as its template parameter via the curiously
+   * recurring template pattern. The derived class must have @c
+   * iterator and @const_iterator types that are instantiations of
+   * class template _Safe_iterator for this sequence. Iterators will
+   * then be tracked automatically.
+   */
+  template<typename _Sequence>
+    class _Safe_sequence : public _Safe_sequence_base
+    {
+    public:
+      /** Invalidates all iterators @c x that reference this sequence,
+         are not singular, and for which @c pred(x) returns @c
+         true. The user of this routine should be careful not to make
+         copies of the iterators passed to @p pred, as the copies may
+         interfere with the invalidation. */
+      template<typename _Predicate> 
+        void 
+        _M_invalidate_if(_Predicate __pred);
+
+      /** Transfers all iterators that reference this memory location
+         to this sequence from whatever sequence they are attached
+         to. */
+      template<typename _Iterator>
+        void
+        _M_transfer_iter(const _Safe_iterator<_Iterator, _Sequence>& __x);
+    };
+
+  template<typename _Sequence>
+    template<typename _Predicate> 
+      void 
+      _Safe_sequence<_Sequence>::
+      _M_invalidate_if(_Predicate __pred)
+      {
+        typedef typename _Sequence::iterator iterator;
+        typedef typename _Sequence::const_iterator const_iterator;
+        
+        for (_Safe_iterator_base* __iter = _M_iterators; __iter; )
+        {
+          iterator* __victim = static_cast<iterator*>(__iter);
+          __iter = __iter->_M_next;
+          if (!__victim->_M_singular()) 
+          {
+           if (__pred(__victim->base()))
+             __victim->_M_invalidate();
+          }
+        }
+
+        for (_Safe_iterator_base* __iter = _M_const_iterators; __iter; )
+        {
+          const_iterator* __victim = static_cast<const_iterator*>(__iter);
+          __iter = __iter->_M_next;
+          if (!__victim->_M_singular()) 
+          {
+           if (__pred(__victim->base()))
+             __victim->_M_invalidate();
+          }
+        }    
+      }
+
+  template<typename _Sequence>
+    template<typename _Iterator>
+      void
+      _Safe_sequence<_Sequence>::
+      _M_transfer_iter(const _Safe_iterator<_Iterator, _Sequence>& __x)
+      {
+       _Safe_sequence_base* __from = __x._M_sequence;
+       if (!__from)
+         return;
+
+        typedef typename _Sequence::iterator iterator;
+        typedef typename _Sequence::const_iterator const_iterator;
+        
+        for (_Safe_iterator_base* __iter = __from->_M_iterators; __iter; )
+        {
+          iterator* __victim = static_cast<iterator*>(__iter);
+          __iter = __iter->_M_next;
+          if (!__victim->_M_singular() && __victim->base() == __x.base())
+           __victim->_M_attach(static_cast<_Sequence*>(this));
+        }
+
+        for (_Safe_iterator_base* __iter = __from->_M_const_iterators; __iter;)
+        {
+          const_iterator* __victim = static_cast<const_iterator*>(__iter);
+          __iter = __iter->_M_next;
+          if (!__victim->_M_singular() && __victim->base() == __x.base())
+           __victim->_M_attach(static_cast<_Sequence*>(this));
+        }
+      }
+} // namespace __gnu_debug
+
+#endif 
diff --git a/libstdc++-v3/include/debug/set b/libstdc++-v3/include/debug/set
new file mode 100644 (file)
index 0000000..a1a69ef
--- /dev/null
@@ -0,0 +1,38 @@
+// Debugging set/multiset implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_SET
+#define _GLIBCXX_DEBUG_SET 1
+
+#include <set>
+#include <debug/set.h>
+#include <debug/multiset.h>
+
+#endif
diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h
new file mode 100644 (file)
index 0000000..861077d
--- /dev/null
@@ -0,0 +1,325 @@
+// Debugging set implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_SET_H
+#define _GLIBCXX_DEBUG_SET_H 1
+
+#include <debug/safe_sequence.h>
+#include <debug/safe_iterator.h>
+#include <utility>
+
+namespace __gnu_debug_def
+{
+  template<typename _Key, typename _Compare = std::less<_Key>,
+          typename _Allocator = std::allocator<_Key> >
+    class set
+    : public __gnu_norm::set<_Key,_Compare,_Allocator>,
+      public __gnu_debug::_Safe_sequence<set<_Key, _Compare, _Allocator> >
+    {
+      typedef __gnu_norm::set<_Key,_Compare,_Allocator> _Base;
+      typedef __gnu_debug::_Safe_sequence<set> _Safe_base;
+      
+    public:
+      // types:
+      typedef _Key                                 key_type;
+      typedef _Key                                 value_type;
+      typedef _Compare                             key_compare;
+      typedef _Compare                             value_compare;
+      typedef _Allocator                           allocator_type;
+      typedef typename _Allocator::reference        reference;
+      typedef typename _Allocator::const_reference  const_reference;
+      
+      typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, set> 
+                                                    iterator;
+      typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, set>
+                                                    const_iterator;
+
+      typedef typename _Base::size_type             size_type;
+      typedef typename _Base::difference_type       difference_type;
+      typedef typename _Allocator::pointer          pointer;
+      typedef typename _Allocator::const_pointer    const_pointer;
+      typedef std::reverse_iterator<iterator>       reverse_iterator;
+      typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+      
+      // 23.3.3.1 construct/copy/destroy:
+      explicit set(const _Compare& __comp = _Compare(),
+                  const _Allocator& __a = _Allocator())
+      : _Base(__comp, __a) { }
+      
+      template<typename _InputIterator>
+        set(_InputIterator __first, _InputIterator __last,
+           const _Compare& __comp = _Compare(),
+           const _Allocator& __a = _Allocator())
+       : _Base(__gnu_debug::__check_valid_range(__first, __last), __last,
+               __comp, __a) { }
+
+      set(const set<_Key,_Compare,_Allocator>& __x) 
+      : _Base(__x), _Safe_base() { }
+    
+      set(const _Base& __x) : _Base(__x), _Safe_base() { }
+      
+      ~set() { }
+      
+      set<_Key,_Compare,_Allocator>& 
+      operator=(const set<_Key,_Compare,_Allocator>& __x)
+      {
+       *static_cast<_Base*>(this) = __x;
+       this->_M_invalidate_all();
+       return *this;
+      }
+      
+      using _Base::get_allocator;
+      
+      // iterators:
+      iterator       
+      begin() 
+      { return iterator(_Base::begin(), this); }
+      
+      const_iterator 
+      begin() const 
+      { return const_iterator(_Base::begin(), this); }
+      
+      iterator       
+      end()
+      { return iterator(_Base::end(), this); }
+      
+      const_iterator 
+      end() const   
+      { return const_iterator(_Base::end(), this); }
+      
+      reverse_iterator 
+      rbegin()
+      { return reverse_iterator(end()); }
+      
+      const_reverse_iterator 
+      rbegin() const
+      { return const_reverse_iterator(end()); }
+      
+      reverse_iterator 
+      rend() 
+      { return reverse_iterator(begin()); }
+      
+      const_reverse_iterator 
+      rend() const 
+      { return const_reverse_iterator(begin()); }
+      
+      // capacity:
+      using _Base::empty;
+      using _Base::size;
+      using _Base::max_size;
+      
+      // modifiers:
+      std::pair<iterator, bool> 
+      insert(const value_type& __x)
+      {
+       typedef typename _Base::iterator _Base_iterator;
+       std::pair<_Base_iterator, bool> __res = _Base::insert(__x);
+       return std::pair<iterator, bool>(iterator(__res.first, this),
+                                        __res.second);
+      }
+      
+      iterator 
+      insert(iterator __position, const value_type& __x)
+      {
+       __glibcxx_check_insert(__position);
+       return iterator(_Base::insert(__position.base(), __x), this);
+      }
+      
+      template <typename _InputIterator>
+        void 
+        insert(_InputIterator __first, _InputIterator __last)
+        {
+         __glibcxx_check_valid_range(__first, __last);
+         _Base::insert(__first, __last);
+       }
+      
+      void 
+      erase(iterator __position)
+      {
+       __glibcxx_check_erase(__position);
+       __position._M_invalidate();
+       _Base::erase(__position.base());
+      }
+      
+      size_type 
+      erase(const key_type& __x)
+      {
+       iterator __victim = find(__x);
+       if (__victim == end())
+          return 0;
+       else
+        {
+         __victim._M_invalidate();
+         _Base::erase(__victim.base());
+         return 1;
+        }
+      }
+      
+      void 
+      erase(iterator __first, iterator __last)
+      {
+       // _GLIBCXX_RESOLVE_LIB_DEFECTS
+       // 151. can't currently clear() empty container
+       __glibcxx_check_erase_range(__first, __last);
+       
+       while (__first != __last)
+        this->erase(__first++);
+      }
+      
+      void 
+      swap(set<_Key,_Compare,_Allocator>& __x)
+      {
+       _Base::swap(__x);
+       this->_M_swap(__x);
+      }
+      
+      void 
+      clear()
+      { this->erase(begin(), end()); }
+      
+      // observers:
+      using _Base::key_comp;
+      using _Base::value_comp;
+      
+      // set operations:
+      iterator 
+      find(const key_type& __x)
+      { return iterator(_Base::find(__x), this); }
+      
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 214. set::find() missing const overload
+      const_iterator 
+      find(const key_type& __x) const
+      { return const_iterator(_Base::find(__x), this); }
+      
+      using _Base::count;
+      
+      iterator 
+      lower_bound(const key_type& __x)
+      { return iterator(_Base::lower_bound(__x), this); }
+      
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 214. set::find() missing const overload
+      const_iterator 
+      lower_bound(const key_type& __x) const
+      { return const_iterator(_Base::lower_bound(__x), this); }
+      
+      iterator 
+      upper_bound(const key_type& __x)
+      { return iterator(_Base::upper_bound(__x), this); }
+      
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 214. set::find() missing const overload
+      const_iterator 
+      upper_bound(const key_type& __x) const
+      { return const_iterator(_Base::upper_bound(__x), this); }
+      
+      std::pair<iterator,iterator>
+      equal_range(const key_type& __x)
+      {
+       typedef typename _Base::iterator _Base_iterator;
+       std::pair<_Base_iterator, _Base_iterator> __res =
+        _Base::equal_range(__x);
+       return std::make_pair(iterator(__res.first, this),
+                             iterator(__res.second, this));
+      }
+      
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 214. set::find() missing const overload
+      std::pair<const_iterator,const_iterator>
+      equal_range(const key_type& __x) const
+      {
+       typedef typename _Base::const_iterator _Base_iterator;
+       std::pair<_Base_iterator, _Base_iterator> __res =
+        _Base::equal_range(__x);
+       return std::make_pair(const_iterator(__res.first, this),
+                             const_iterator(__res.second, this));
+      }
+      
+      _Base&       
+      _M_base() { return *this; }
+
+      const _Base& 
+      _M_base() const { return *this; }
+      
+    private:
+      void 
+      _M_invalidate_all()
+      {
+       typedef typename _Base::const_iterator _Base_const_iterator;
+       typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
+       this->_M_invalidate_if(_Not_equal(_M_base().end()));
+      }
+    };
+  
+  template<typename _Key, typename _Compare, typename _Allocator>
+    inline bool 
+    operator==(const set<_Key,_Compare,_Allocator>& __lhs,
+              const set<_Key,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() == __rhs._M_base(); }
+
+  template<typename _Key, typename _Compare, typename _Allocator>
+    inline bool 
+    operator!=(const set<_Key,_Compare,_Allocator>& __lhs,
+              const set<_Key,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() != __rhs._M_base(); }
+
+  template<typename _Key, typename _Compare, typename _Allocator>
+    inline bool 
+    operator<(const set<_Key,_Compare,_Allocator>& __lhs,
+             const set<_Key,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() < __rhs._M_base(); }
+
+  template<typename _Key, typename _Compare, typename _Allocator>
+    inline bool 
+    operator<=(const set<_Key,_Compare,_Allocator>& __lhs,
+              const set<_Key,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() <= __rhs._M_base(); }
+
+  template<typename _Key, typename _Compare, typename _Allocator>
+    inline bool 
+    operator>=(const set<_Key,_Compare,_Allocator>& __lhs,
+              const set<_Key,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() >= __rhs._M_base(); }
+
+  template<typename _Key, typename _Compare, typename _Allocator>
+    inline bool 
+    operator>(const set<_Key,_Compare,_Allocator>& __lhs,
+             const set<_Key,_Compare,_Allocator>& __rhs)
+    { return __lhs._M_base() > __rhs._M_base(); }
+
+  template<typename _Key, typename _Compare, typename _Allocator>
+    void
+    swap(set<_Key,_Compare,_Allocator>& __x, 
+        set<_Key,_Compare,_Allocator>& __y)
+    { return __x.swap(__y); }
+} // namespace __gnu_debug_def
+
+#endif
diff --git a/libstdc++-v3/include/debug/string b/libstdc++-v3/include/debug/string
new file mode 100644 (file)
index 0000000..5be5da6
--- /dev/null
@@ -0,0 +1,1001 @@
+// Debugging string implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_STRING
+#define _GLIBCXX_DEBUG_STRING 1
+
+#include <string>
+#include <debug/safe_sequence.h>
+#include <debug/safe_iterator.h>
+
+namespace __gnu_debug
+{
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    class basic_string 
+    : public std::basic_string<_CharT, _Traits, _Allocator>,
+      public __gnu_debug::_Safe_sequence<basic_string<_CharT, _Traits,
+                                                     _Allocator> >
+    {
+      typedef std::basic_string<_CharT, _Traits, _Allocator> _Base;
+      typedef __gnu_debug::_Safe_sequence<basic_string>     _Safe_base;
+
+  public:
+    // types:
+    typedef _Traits                                   traits_type;
+    typedef typename _Traits::char_type               value_type;
+    typedef _Allocator                                allocator_type;
+    typedef typename _Allocator::size_type             size_type;
+    typedef typename _Allocator::difference_type       difference_type;
+    typedef typename _Allocator::reference             reference;
+    typedef typename _Allocator::const_reference       const_reference;
+    typedef typename _Allocator::pointer               pointer;
+    typedef typename _Allocator::const_pointer         const_pointer;
+
+    typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, basic_string>
+                                                       iterator;
+    typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, 
+                                         basic_string> const_iterator;
+
+    typedef std::reverse_iterator<iterator>            reverse_iterator;
+    typedef std::reverse_iterator<const_iterator>      const_reverse_iterator;
+
+    using _Base::npos;
+
+    // 21.3.1 construct/copy/destroy:
+    explicit basic_string(const _Allocator& __a = _Allocator())
+    : _Base(__a)
+    { }
+
+    // Provides conversion from a release-mode string to a debug-mode string
+    basic_string(const _Base& __base) : _Base(__base), _Safe_base() { }
+
+    // _GLIBCXX_RESOLVE_LIB_DEFECTS
+    // 42. string ctors specify wrong default allocator 
+    basic_string(const basic_string& __str)
+    : _Base(__str, 0, _Base::npos, __str.get_allocator()), _Safe_base()
+    { }
+
+    // _GLIBCXX_RESOLVE_LIB_DEFECTS
+    // 42. string ctors specify wrong default allocator 
+    basic_string(const basic_string& __str, size_type __pos,
+                  size_type __n = _Base::npos,
+                  const _Allocator& __a = _Allocator())
+    : _Base(__str, __pos, __n, __a)
+    { }
+
+    basic_string(const _CharT* __s, size_type __n,
+                  const _Allocator& __a = _Allocator())
+    : _Base(__gnu_debug::__check_string(__s, __n), __n, __a)
+    { }
+
+    basic_string(const _CharT* __s, const _Allocator& __a = _Allocator())
+    : _Base(__gnu_debug::__check_string(__s), __a)
+    { this->assign(__s); }
+
+    basic_string(size_type __n, _CharT __c,
+                  const _Allocator& __a = _Allocator())
+    : _Base(__n, __c, __a)
+    { }
+
+    template<typename _InputIterator>
+      basic_string(_InputIterator __begin, _InputIterator __end,
+                    const _Allocator& __a = _Allocator())
+      : _Base(__gnu_debug::__check_valid_range(__begin, __end), __end, __a)
+      { }
+
+    ~basic_string() { }
+
+    basic_string& 
+    operator=(const basic_string& __str)
+    {
+      *static_cast<_Base*>(this) = __str;
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    operator=(const _CharT* __s)
+    {
+      __glibcxx_check_string(__s);
+      *static_cast<_Base*>(this) = __s;
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    operator=(_CharT __c)
+    {
+      *static_cast<_Base*>(this) = __c;
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    // 21.3.2 iterators:
+    iterator 
+    begin() 
+    { return iterator(_Base::begin(), this); }
+
+    const_iterator 
+    begin() const 
+    { return const_iterator(_Base::begin(), this); }
+
+    iterator 
+    end() 
+    { return iterator(_Base::end(), this); }
+
+    const_iterator 
+    end() const
+    { return const_iterator(_Base::end(), this); }
+
+    reverse_iterator 
+    rbegin() 
+    { return reverse_iterator(end()); }
+
+    const_reverse_iterator 
+    rbegin() const
+    { return const_reverse_iterator(end()); }
+
+    reverse_iterator
+    rend()
+    { return reverse_iterator(begin()); }
+
+    const_reverse_iterator 
+    rend() const 
+    { return const_reverse_iterator(begin()); }
+
+    // 21.3.3 capacity:
+    using _Base::size;
+    using _Base::length;
+    using _Base::max_size;
+
+    void 
+    resize(size_type __n, _CharT __c)
+    {
+      _Base::resize(__n, __c);
+      this->_M_invalidate_all();
+    }
+
+    void 
+    resize(size_type __n)
+    { this->resize(__n, _CharT()); }
+
+    using _Base::capacity;
+    using _Base::reserve;
+
+    void 
+    clear()
+    {
+      _Base::clear();
+      this->_M_invalidate_all();
+    }
+
+    using _Base::empty;
+
+    // 21.3.4 element access:
+    const_reference 
+    operator[](size_type __pos) const
+    {
+      _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
+                           _M_message(::__gnu_debug::__msg_subscript_oob)
+                           ._M_sequence(*this, "this")
+                           ._M_integer(__pos, "__pos")
+                           ._M_integer(this->size(), "size"));
+      return _M_base()[__pos];
+    }
+
+    reference 
+    operator[](size_type __pos)
+    {
+      __glibcxx_check_subscript(__pos);
+      return _M_base()[__pos];
+    }
+
+    using _Base::at;
+
+    // 21.3.5 modifiers:
+    basic_string& 
+    operator+=(const basic_string& __str)
+    {
+      _M_base() += __str;
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    operator+=(const _CharT* __s)
+    {
+      __glibcxx_check_string(__s);
+      _M_base() += __s;
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    operator+=(_CharT __c)
+    {
+      _M_base() += __c;
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    append(const basic_string& __str)
+    {
+      _Base::append(__str);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    append(const basic_string& __str, size_type __pos, size_type __n)
+    {
+      _Base::append(__str, __pos, __n);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    append(const _CharT* __s, size_type __n)
+    {
+      __glibcxx_check_string_len(__s, __n);
+      _Base::append(__s, __n);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    append(const _CharT* __s)
+    {
+      __glibcxx_check_string(__s);
+      _Base::append(__s);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    append(size_type __n, _CharT __c)
+    {
+      _Base::append(__n, __c);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    template<typename _InputIterator>
+      basic_string& 
+      append(_InputIterator __first, _InputIterator __last)
+      {
+       __glibcxx_check_valid_range(__first, __last);
+       _Base::append(__first, __last);
+       this->_M_invalidate_all();
+       return *this;
+      }
+
+    // _GLIBCXX_RESOLVE_LIB_DEFECTS
+    // 7. string clause minor problems 
+    void 
+    push_back(_CharT __c)
+    {
+      _Base::push_back(__c);
+      this->_M_invalidate_all();
+    }
+
+    basic_string& 
+    assign(const basic_string& __x)
+    {
+      _Base::assign(__x);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    assign(const basic_string& __str, size_type __pos, size_type __n)
+    {
+      _Base::assign(__str, __pos, __n);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    assign(const _CharT* __s, size_type __n)
+    {
+      __glibcxx_check_string_len(__s, __n);
+      _Base::assign(__s, __n);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    assign(const _CharT* __s)
+    {
+      __glibcxx_check_string(__s);
+      _Base::assign(__s);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    assign(size_type __n, _CharT __c)
+    {
+      _Base::assign(__n, __c);
+      this->_M_invalidate_all();
+      return *this;    
+    }
+
+    template<typename _InputIterator>
+      basic_string& 
+      assign(_InputIterator __first, _InputIterator __last)
+      {
+       __glibcxx_check_valid_range(__first, __last);
+       _Base::assign(__first, __last);
+       this->_M_invalidate_all();
+       return *this;   
+      }
+
+    basic_string& 
+    insert(size_type __pos1, const basic_string& __str)
+    {
+      _Base::insert(__pos1, __str);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    insert(size_type __pos1, const basic_string& __str,
+          size_type __pos2, size_type __n)
+    {
+      _Base::insert(__pos1, __str, __pos2, __n);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    insert(size_type __pos, const _CharT* __s, size_type __n)
+    {
+      __glibcxx_check_string(__s);
+      _Base::insert(__pos, __s, __n);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    insert(size_type __pos, const _CharT* __s)
+    {
+      __glibcxx_check_string(__s);
+      _Base::insert(__pos, __s);
+      this->_M_invalidate_all();
+      return *this;    
+    }
+
+    basic_string& 
+    insert(size_type __pos, size_type __n, _CharT __c)
+    {
+      _Base::insert(__pos, __n, __c);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    iterator 
+    insert(iterator __p, _CharT __c)
+    {
+      __glibcxx_check_insert(__p);
+      typename _Base::iterator __res = _Base::insert(__p.base(), __c);
+      this->_M_invalidate_all();
+      return iterator(__res, this);
+    }
+
+    void 
+    insert(iterator __p, size_type __n, _CharT __c)
+    {
+      __glibcxx_check_insert(__p);
+      _Base::insert(__p.base(), __n, __c);
+      this->_M_invalidate_all();
+    }
+
+    template<typename _InputIterator>
+      void 
+      insert(iterator __p, _InputIterator __first, _InputIterator __last)
+      {
+       __glibcxx_check_insert_range(__p, __first, __last);
+       _Base::insert(__p.base(), __first, __last);
+       this->_M_invalidate_all();
+      }
+
+    basic_string& 
+    erase(size_type __pos = 0, size_type __n = _Base::npos)
+    {
+      _Base::erase(__pos, __n);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    iterator 
+    erase(iterator __position)
+    {
+      __glibcxx_check_erase(__position);
+      typename _Base::iterator __res = _Base::erase(__position.base());
+      this->_M_invalidate_all();
+      return iterator(__res, this);
+    }
+
+    iterator 
+    erase(iterator __first, iterator __last)
+    {
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 151. can't currently clear() empty container
+      __glibcxx_check_erase_range(__first, __last);
+      typename _Base::iterator __res = _Base::erase(__first.base(),
+                                                      __last.base());
+      this->_M_invalidate_all();
+      return iterator(__res, this);
+    }
+
+    basic_string& 
+    replace(size_type __pos1, size_type __n1, const basic_string& __str)
+    {
+      _Base::replace(__pos1, __n1, __str);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    replace(size_type __pos1, size_type __n1, const basic_string& __str,
+           size_type __pos2, size_type __n2)
+    {
+      _Base::replace(__pos1, __n1, __str, __pos2, __n2);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    replace(size_type __pos, size_type __n1, const _CharT* __s, 
+           size_type __n2)
+    {
+      __glibcxx_check_string_len(__s, __n2);
+      _Base::replace(__pos, __n1, __s, __n2);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    replace(size_type __pos, size_type __n1, const _CharT* __s)
+    {
+      __glibcxx_check_string(__s);
+      _Base::replace(__pos, __n1, __s);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
+    {
+      _Base::replace(__pos, __n1, __n2, __c);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    replace(iterator __i1, iterator __i2, const basic_string& __str)
+    {
+      __glibcxx_check_erase_range(__i1, __i2);
+      _Base::replace(__i1.base(), __i2.base(), __str);
+      this->_M_invalidate_all();
+      return *this;
+    }
+    
+    basic_string& 
+    replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
+    {
+      __glibcxx_check_erase_range(__i1, __i2);
+      __glibcxx_check_string_len(__s, __n);
+      _Base::replace(__i1.base(), __i2.base(), __s, __n);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    replace(iterator __i1, iterator __i2, const _CharT* __s)
+    {
+      __glibcxx_check_erase_range(__i1, __i2);
+      __glibcxx_check_string(__s);
+      _Base::replace(__i1.base(), __i2.base(), __s);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    basic_string& 
+    replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
+    {
+      __glibcxx_check_erase_range(__i1, __i2);
+      _Base::replace(__i1.base(), __i2.base(), __n, __c);
+      this->_M_invalidate_all();
+      return *this;
+    }
+
+    template<typename _InputIterator>
+      basic_string& 
+      replace(iterator __i1, iterator __i2,
+             _InputIterator __j1, _InputIterator __j2)
+      {
+       __glibcxx_check_erase_range(__i1, __i2);
+       __glibcxx_check_valid_range(__j1, __j2);
+       _Base::replace(__i1.base(), __i2.base(), __j1, __j2);
+       this->_M_invalidate_all();
+       return *this;
+      }
+
+    size_type 
+    copy(_CharT* __s, size_type __n, size_type __pos = 0) const
+    {
+      __glibcxx_check_string_len(__s, __n);
+      return _Base::copy(__s, __n, __pos);
+    }
+
+    void 
+    swap(basic_string<_CharT,_Traits,_Allocator>& __x)
+    {
+      _Base::swap(__x);
+      this->_M_swap(__x);
+      this->_M_invalidate_all();
+      __x._M_invalidate_all();
+    }
+
+    // 21.3.6 string operations:
+    const _CharT* 
+    c_str() const
+    {
+      const _CharT* __res = _Base::c_str();
+      this->_M_invalidate_all();
+      return __res;
+    }
+
+    const _CharT* 
+    data() const
+    {
+      const _CharT* __res = _Base::data();
+      this->_M_invalidate_all();
+      return __res;
+    }
+
+    using _Base::get_allocator;
+
+    size_type 
+    find(const basic_string& __str, size_type __pos = 0) const
+    { return _Base::find(__str, __pos); }
+
+    size_type 
+    find(const _CharT* __s, size_type __pos, size_type __n) const
+    {
+      __glibcxx_check_string(__s);
+      return _Base::find(__s, __pos, __n);
+    }
+
+    size_type 
+    find(const _CharT* __s, size_type __pos = 0) const
+    {
+      __glibcxx_check_string(__s);
+      return _Base::find(__s, __pos);
+    }
+
+    size_type 
+    find(_CharT __c, size_type __pos = 0) const
+    { return _Base::find(__c, __pos); }
+
+    size_type 
+    rfind(const basic_string& __str, size_type __pos = _Base::npos) const
+    { return _Base::rfind(__str, __pos); }
+
+    size_type 
+    rfind(const _CharT* __s, size_type __pos, size_type __n) const
+    { 
+      __glibcxx_check_string_len(__s, __n);
+      return _Base::rfind(__s, __pos, __n);
+    }
+
+    size_type 
+    rfind(const _CharT* __s, size_type __pos = _Base::npos) const
+    {
+      __glibcxx_check_string(__s);
+      return _Base::rfind(__s, __pos);
+    }
+
+    size_type 
+    rfind(_CharT __c, size_type __pos = _Base::npos) const
+    { return _Base::rfind(__c, __pos); }
+       
+    size_type 
+    find_first_of(const basic_string& __str, size_type __pos = 0) const
+    { return _Base::find_first_of(__str, __pos); }
+
+    size_type 
+    find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
+    { 
+      __glibcxx_check_string(__s);
+      return _Base::find_first_of(__s, __pos, __n); 
+    }
+
+    size_type 
+    find_first_of(const _CharT* __s, size_type __pos = 0) const
+    { 
+      __glibcxx_check_string(__s);
+      return _Base::find_first_of(__s, __pos); 
+    }
+
+    size_type 
+    find_first_of(_CharT __c, size_type __pos = 0) const
+    { return _Base::find_first_of(__c, __pos); }
+
+    size_type 
+    find_last_of(const basic_string& __str, size_type __pos = _Base::npos) const
+    { return _Base::find_last_of(__str, __pos); }
+
+    size_type 
+    find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
+    { 
+      __glibcxx_check_string(__s);
+      return _Base::find_last_of(__s, __pos, __n);
+    }
+
+    size_type 
+    find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const
+    { 
+      __glibcxx_check_string(__s);
+      return _Base::find_last_of(__s, __pos);
+    }
+
+    size_type 
+    find_last_of(_CharT __c, size_type __pos = _Base::npos) const
+    { return _Base::find_last_of(__c, __pos); }
+
+    size_type 
+    find_first_not_of(const basic_string& __str, size_type __pos = 0) const
+    { return _Base::find_first_not_of(__str, __pos); }
+
+    size_type 
+    find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
+    {
+      __glibcxx_check_string_len(__s, __n);
+      return _Base::find_first_not_of(__s, __pos, __n);
+    }
+
+    size_type 
+    find_first_not_of(const _CharT* __s, size_type __pos = 0) const
+    {
+      __glibcxx_check_string(__s);
+      return _Base::find_first_not_of(__s, __pos);
+    }
+
+    size_type 
+    find_first_not_of(_CharT __c, size_type __pos = 0) const
+    { return _Base::find_first_not_of(__c, __pos); }
+
+    size_type 
+    find_last_not_of(const basic_string& __str,
+                                 size_type __pos = _Base::npos) const
+    { return _Base::find_last_not_of(__str, __pos); }
+
+    size_type 
+    find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
+    {
+      __glibcxx_check_string(__s);
+      return _Base::find_last_not_of(__s, __pos, __n);
+    }
+
+    size_type 
+    find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const
+    {
+      __glibcxx_check_string(__s);
+      return _Base::find_last_not_of(__s, __pos);
+    }
+
+    size_type 
+    find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const
+    { return _Base::find_last_not_of(__c, __pos); }
+
+    basic_string 
+    substr(size_type __pos = 0, size_type __n = _Base::npos) const
+    { return basic_string(_Base::substr(__pos, __n)); }
+
+    int 
+    compare(const basic_string& __str) const
+    { return _Base::compare(__str); }
+
+    int 
+    compare(size_type __pos1, size_type __n1,
+                 const basic_string& __str) const
+    { return _Base::compare(__pos1, __n1, __str); }
+
+    int 
+    compare(size_type __pos1, size_type __n1, const basic_string& __str,
+             size_type __pos2, size_type __n2) const
+    { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); }
+
+    int 
+    compare(const _CharT* __s) const
+    {
+      __glibcxx_check_string(__s);
+      return _Base::compare(__s);
+    }
+
+    //  _GLIBCXX_RESOLVE_LIB_DEFECTS
+    //  5. string::compare specification questionable
+    int 
+    compare(size_type __pos1, size_type __n1, const _CharT* __s) const
+    {
+      __glibcxx_check_string(__s);
+      return _Base::compare(__pos1, __n1, __s);
+    }
+
+    //  _GLIBCXX_RESOLVE_LIB_DEFECTS
+    //  5. string::compare specification questionable
+    int 
+    compare(size_type __pos1, size_type __n1,const _CharT* __s,
+             size_type __n2) const
+    {
+      __glibcxx_check_string_len(__s, __n2);
+      return _Base::compare(__pos1, __n1, __s, __n2);
+    }
+
+    _Base&       
+    _M_base() { return *this; }
+
+    const _Base& 
+    _M_base() const { return *this; }
+
+    using _Safe_base::_M_invalidate_all;
+  };
+
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline basic_string<_CharT,_Traits,_Allocator>
+    operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
+             const basic_string<_CharT,_Traits,_Allocator>& __rhs)
+    { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
+
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline basic_string<_CharT,_Traits,_Allocator>
+    operator+(const _CharT* __lhs,
+             const basic_string<_CharT,_Traits,_Allocator>& __rhs)
+    { 
+      __glibcxx_check_string(__lhs);
+      return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline basic_string<_CharT,_Traits,_Allocator>
+    operator+(_CharT __lhs, 
+             const basic_string<_CharT,_Traits,_Allocator>& __rhs)
+    { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; }
+
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline basic_string<_CharT,_Traits,_Allocator>
+    operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
+             const _CharT* __rhs)
+    { 
+      __glibcxx_check_string(__rhs);
+      return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; 
+    }
+
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline basic_string<_CharT,_Traits,_Allocator>
+    operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
+             _CharT __rhs)
+    { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
+
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline bool 
+    operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
+              const basic_string<_CharT,_Traits,_Allocator>& __rhs)
+    { return __lhs._M_base() == __rhs._M_base(); }
+  
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline bool
+    operator==(const _CharT* __lhs,
+              const basic_string<_CharT,_Traits,_Allocator>& __rhs)
+    {
+      __glibcxx_check_string(__lhs);
+      return __lhs == __rhs._M_base();
+    }
+
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline bool
+    operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
+              const _CharT* __rhs)
+    {
+      __glibcxx_check_string(__rhs);
+      return __lhs._M_base() == __rhs;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline bool 
+    operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
+              const basic_string<_CharT,_Traits,_Allocator>& __rhs)
+    { return __lhs._M_base() != __rhs._M_base(); }
+  
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline bool
+    operator!=(const _CharT* __lhs,
+              const basic_string<_CharT,_Traits,_Allocator>& __rhs)
+    {
+      __glibcxx_check_string(__lhs);
+      return __lhs != __rhs._M_base();
+    }
+
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline bool
+    operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
+              const _CharT* __rhs)
+    {
+      __glibcxx_check_string(__rhs);
+      return __lhs._M_base() != __rhs;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline bool 
+    operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
+             const basic_string<_CharT,_Traits,_Allocator>& __rhs)
+    { return __lhs._M_base() < __rhs._M_base(); }
+  
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline bool
+    operator<(const _CharT* __lhs,
+             const basic_string<_CharT,_Traits,_Allocator>& __rhs)
+    {
+      __glibcxx_check_string(__lhs);
+      return __lhs < __rhs._M_base();
+    }
+
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline bool
+    operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
+             const _CharT* __rhs)
+    {
+      __glibcxx_check_string(__rhs);
+      return __lhs._M_base() < __rhs;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline bool 
+    operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
+              const basic_string<_CharT,_Traits,_Allocator>& __rhs)
+    { return __lhs._M_base() <= __rhs._M_base(); }
+  
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline bool
+    operator<=(const _CharT* __lhs,
+              const basic_string<_CharT,_Traits,_Allocator>& __rhs)
+    {
+      __glibcxx_check_string(__lhs);
+      return __lhs <= __rhs._M_base();
+    }
+
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline bool
+    operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
+              const _CharT* __rhs)
+    {
+      __glibcxx_check_string(__rhs);
+      return __lhs._M_base() <= __rhs;
+    }
+  
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline bool 
+    operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
+              const basic_string<_CharT,_Traits,_Allocator>& __rhs)
+    { return __lhs._M_base() >= __rhs._M_base(); }
+  
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline bool
+    operator>=(const _CharT* __lhs,
+              const basic_string<_CharT,_Traits,_Allocator>& __rhs)
+    {
+      __glibcxx_check_string(__lhs);
+      return __lhs >= __rhs._M_base();
+    }
+  
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline bool
+    operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
+              const _CharT* __rhs)
+    {
+      __glibcxx_check_string(__rhs);
+      return __lhs._M_base() >= __rhs;
+    }
+  
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline bool 
+    operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
+             const basic_string<_CharT,_Traits,_Allocator>& __rhs)
+    { return __lhs._M_base() > __rhs._M_base(); }
+  
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline bool
+    operator>(const _CharT* __lhs,
+             const basic_string<_CharT,_Traits,_Allocator>& __rhs)
+    {
+      __glibcxx_check_string(__lhs);
+      return __lhs > __rhs._M_base();
+    }
+
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline bool
+    operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
+             const _CharT* __rhs)
+    {
+      __glibcxx_check_string(__rhs);
+      return __lhs._M_base() > __rhs;
+    }
+
+  // 21.3.7.8:
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    inline void 
+    swap(basic_string<_CharT,_Traits,_Allocator>& __lhs,
+        basic_string<_CharT,_Traits,_Allocator>& __rhs)
+    { __lhs.swap(__rhs); }
+
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    std::basic_ostream<_CharT, _Traits>&
+    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+              const basic_string<_CharT, _Traits, _Allocator>& __str)
+    { return __os << __str._M_base(); }
+
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    std::basic_istream<_CharT,_Traits>&
+    operator>>(std::basic_istream<_CharT,_Traits>& __is,
+              basic_string<_CharT,_Traits,_Allocator>& __str)
+    {
+      std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base();
+      __str._M_invalidate_all();
+      return __res;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    std::basic_istream<_CharT,_Traits>&
+    getline(std::basic_istream<_CharT,_Traits>& __is,
+           basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim)
+    {
+      std::basic_istream<_CharT,_Traits>& __res = getline(__is, 
+                                                         __str._M_base(),
+                                                       __delim);
+      __str._M_invalidate_all();
+      return __res;
+    }
+  
+  template<typename _CharT, typename _Traits, typename _Allocator>
+    std::basic_istream<_CharT,_Traits>&
+    getline(std::basic_istream<_CharT,_Traits>& __is,
+           basic_string<_CharT,_Traits,_Allocator>& __str)
+    {
+      std::basic_istream<_CharT,_Traits>& __res = getline(__is, 
+                                                         __str._M_base());
+      __str._M_invalidate_all();
+      return __res;
+    }
+} // namespace __gnu_debug
+
+#endif 
diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector
new file mode 100644 (file)
index 0000000..19249b6
--- /dev/null
@@ -0,0 +1,409 @@
+// Debugging vector implementation -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_DEBUG_VECTOR
+#define _GLIBCXX_DEBUG_VECTOR 1
+
+#include <vector>
+#include <debug/safe_sequence.h>
+#include <debug/safe_iterator.h>
+
+namespace __gnu_debug_def
+{
+  template<typename _Tp, 
+          typename _Allocator = std::allocator<_Tp> >
+    class vector
+    : public __gnu_norm::vector<_Tp, _Allocator>,
+      public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> >
+    {
+      typedef __gnu_norm::vector<_Tp, _Allocator> _Base;
+      typedef __gnu_debug::_Safe_sequence<vector>              _Safe_base;
+
+      typedef typename _Base::const_iterator _Base_const_iterator;
+      typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
+
+    public:
+      typedef typename _Base::reference             reference;
+      typedef typename _Base::const_reference       const_reference;
+
+      typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,vector> 
+      iterator;
+      typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,vector>
+      const_iterator;
+
+      typedef typename _Base::size_type             size_type;
+      typedef typename _Base::difference_type       difference_type;
+
+      typedef _Tp                                  value_type;
+      typedef _Allocator                           allocator_type;
+      typedef typename _Allocator::pointer          pointer;
+      typedef typename _Allocator::const_pointer    const_pointer;
+      typedef std::reverse_iterator<iterator>       reverse_iterator;
+      typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+      // 23.2.4.1 construct/copy/destroy:
+      explicit vector(const _Allocator& __a = _Allocator())
+      : _Base(__a), _M_guaranteed_capacity(0) { }
+
+      explicit vector(size_type __n, const _Tp& __value = _Tp(),
+                     const _Allocator& __a = _Allocator())
+      : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { }
+
+      template<class _InputIterator>
+        vector(_InputIterator __first, _InputIterator __last,
+              const _Allocator& __a = _Allocator())
+       : _Base(__gnu_debug::__check_valid_range(__first, __last), 
+               __last, __a),
+         _M_guaranteed_capacity(0)
+        { _M_update_guaranteed_capacity(); }
+
+      vector(const vector<_Tp,_Allocator>& __x) 
+      : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { }
+
+      /// Construction from a release-mode vector
+      vector(const _Base& __x) 
+      : _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { }
+
+      ~vector() { }
+
+      vector<_Tp,_Allocator>& 
+      operator=(const vector<_Tp,_Allocator>& __x)
+      {
+       static_cast<_Base&>(*this) = __x;
+       this->_M_invalidate_all();
+       _M_update_guaranteed_capacity();
+       return *this;
+      }
+
+      template<typename _InputIterator>
+        void 
+        assign(_InputIterator __first, _InputIterator __last)
+        {
+         __glibcxx_check_valid_range(__first, __last);
+         _Base::assign(__first, __last);
+         this->_M_invalidate_all();
+         _M_update_guaranteed_capacity();
+       }
+
+      void 
+      assign(size_type __n, const _Tp& __u)
+      {
+       _Base::assign(__n, __u);
+       this->_M_invalidate_all();
+       _M_update_guaranteed_capacity();
+      }
+
+      using _Base::get_allocator;
+
+      // iterators:
+      iterator 
+      begin() 
+      { return iterator(_Base::begin(), this); }
+
+      const_iterator 
+      begin() const 
+      { return const_iterator(_Base::begin(), this); }
+
+      iterator 
+      end()
+      { return iterator(_Base::end(), this); }
+
+      const_iterator 
+      end() const
+      { return const_iterator(_Base::end(), this); }
+
+      reverse_iterator 
+      rbegin() 
+      { return reverse_iterator(end()); }
+
+      const_reverse_iterator 
+      rbegin() const
+      { return const_reverse_iterator(end()); }
+
+      reverse_iterator 
+      rend() 
+      { return reverse_iterator(begin()); }
+
+      const_reverse_iterator 
+      rend() const 
+      { return const_reverse_iterator(begin()); }
+
+      // 23.2.4.2 capacity:
+      using _Base::size;
+      using _Base::max_size;
+
+      void 
+      resize(size_type __sz, _Tp __c = _Tp())
+      {
+       bool __realloc = _M_requires_reallocation(__sz);
+       if (__sz < this->size())
+         this->_M_invalidate_if(_After_nth(__sz, _M_base().begin()));
+       _Base::resize(__sz, __c);
+       if (__realloc)
+         this->_M_invalidate_all();
+      }
+
+      using _Base::capacity;
+      using _Base::empty;
+
+      void 
+      reserve(size_type __n)
+      {
+       bool __realloc = _M_requires_reallocation(__n);
+       _Base::reserve(__n);
+       if (__n > _M_guaranteed_capacity)
+         _M_guaranteed_capacity = __n;
+       if (__realloc)
+         this->_M_invalidate_all();
+      }
+
+      // element access:
+      reference 
+      operator[](size_type __n)
+      {
+       __glibcxx_check_subscript(__n);
+       return _M_base()[__n];
+      }
+
+      const_reference 
+      operator[](size_type __n) const
+      {
+       __glibcxx_check_subscript(__n);
+       return _M_base()[__n];
+      }
+
+      using _Base::at;
+
+      reference 
+      front()
+      {
+       __glibcxx_check_nonempty();
+       return _Base::front();
+      }
+
+      const_reference 
+      front() const
+      {
+       __glibcxx_check_nonempty();
+       return _Base::front();
+      }
+
+      reference 
+      back()
+      {
+       __glibcxx_check_nonempty();
+       return _Base::back();
+      }
+
+      const_reference 
+      back() const
+      {
+       __glibcxx_check_nonempty();
+       return _Base::back();
+      }
+
+      // 23.2.4.3 modifiers:
+      void 
+      push_back(const _Tp& __x)
+      {
+       bool __realloc = _M_requires_reallocation(this->size() + 1);
+       _Base::push_back(__x);
+       if (__realloc)
+         this->_M_invalidate_all();
+       _M_update_guaranteed_capacity();
+      }
+
+      void 
+      pop_back()
+      {
+       __glibcxx_check_nonempty();
+       iterator __victim = end() - 1;
+       __victim._M_invalidate();
+       _Base::pop_back();
+      }
+
+      iterator 
+      insert(iterator __position, const _Tp& __x)
+      {
+       __glibcxx_check_insert(__position);
+       bool __realloc = _M_requires_reallocation(this->size() + 1);
+       difference_type __offset = __position - begin();
+       typename _Base::iterator __res = _Base::insert(__position.base(),__x);
+       if (__realloc)
+         this->_M_invalidate_all();
+       else
+         this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
+       _M_update_guaranteed_capacity();
+       return iterator(__res, this);
+      }
+
+      void 
+      insert(iterator __position, size_type __n, const _Tp& __x)
+      {
+       __glibcxx_check_insert(__position);
+       bool __realloc = _M_requires_reallocation(this->size() + __n);
+       difference_type __offset = __position - begin();
+       _Base::insert(__position.base(), __n, __x);
+       if (__realloc)
+         this->_M_invalidate_all();
+       else
+         this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
+       _M_update_guaranteed_capacity();
+      }
+
+      template<class _InputIterator>
+        void 
+        insert(iterator __position, 
+              _InputIterator __first, _InputIterator __last)
+        {
+         __glibcxx_check_insert_range(__position, __first, __last);
+         
+         /* Hard to guess if invalidation will occur, because __last
+            - __first can't be calculated in all cases, so we just
+            punt here by checking if it did occur. */
+         typename _Base::iterator __old_begin = _M_base().begin();
+         difference_type __offset = __position - begin();
+         _Base::insert(__position.base(), __first, __last);
+         
+         if (_M_base().begin() != __old_begin)
+           this->_M_invalidate_all();
+         else
+           this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
+         _M_update_guaranteed_capacity();
+       }
+      
+      iterator 
+      erase(iterator __position)
+      {
+       __glibcxx_check_erase(__position);
+       difference_type __offset = __position - begin();
+       typename _Base::iterator __res = _Base::erase(__position.base());
+       this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
+       return iterator(__res, this);
+      }
+
+      iterator 
+      erase(iterator __first, iterator __last)
+      {
+       // _GLIBCXX_RESOLVE_LIB_DEFECTS
+       // 151. can't currently clear() empty container
+       __glibcxx_check_erase_range(__first, __last);
+      
+       difference_type __offset = __first - begin();
+       typename _Base::iterator __res = _Base::erase(__first.base(), 
+                                                        __last.base());
+       this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
+       return iterator(__res, this);
+      }
+
+      void 
+      swap(vector<_Tp,_Allocator>& __x)
+      {
+       _Base::swap(__x);
+       this->_M_swap(__x);
+      }
+
+      void 
+      clear()
+      {
+       _Base::clear();
+       this->_M_invalidate_all();
+      }
+
+      _Base&       
+      _M_base() { return *this; }
+
+      const _Base& 
+      _M_base() const { return *this; }
+
+    private:
+      size_type _M_guaranteed_capacity;
+
+      bool 
+      _M_requires_reallocation(size_type __elements)
+      {
+#ifdef _GLIBCXX_DEBUG_PEDANTIC
+       return __elements > this->capacity();
+#else
+       return __elements > _M_guaranteed_capacity;
+#endif
+      }
+      
+      void 
+      _M_update_guaranteed_capacity()
+      {
+       if (this->size() > _M_guaranteed_capacity)
+         _M_guaranteed_capacity = this->size();
+      }
+    };
+
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator==(const vector<_Tp, _Alloc>& __lhs,
+              const vector<_Tp, _Alloc>& __rhs)
+    { return __lhs._M_base() == __rhs._M_base(); }
+
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator!=(const vector<_Tp, _Alloc>& __lhs, 
+              const vector<_Tp, _Alloc>& __rhs)
+    { return __lhs._M_base() != __rhs._M_base(); }
+
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator<(const vector<_Tp, _Alloc>& __lhs, 
+             const vector<_Tp, _Alloc>& __rhs)
+    { return __lhs._M_base() < __rhs._M_base(); }
+
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator<=(const vector<_Tp, _Alloc>& __lhs, 
+              const vector<_Tp, _Alloc>& __rhs)
+    { return __lhs._M_base() <= __rhs._M_base(); }
+
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator>=(const vector<_Tp, _Alloc>& __lhs, 
+              const vector<_Tp, _Alloc>& __rhs)
+    { return __lhs._M_base() >= __rhs._M_base(); }
+
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator>(const vector<_Tp, _Alloc>& __lhs, 
+             const vector<_Tp, _Alloc>& __rhs)
+    { return __lhs._M_base() > __rhs._M_base(); }
+
+  template<typename _Tp, typename _Alloc>
+    inline void
+    swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
+    { __lhs.swap(__rhs); }
+} // namespace __gnu_debug_def
+
+#endif 
index 9cccec8..dfb5515 100644 (file)
@@ -208,6 +208,8 @@ namespace __gnu_cxx
            typename iterator_traits<_InputIterator1>::value_type>)
       __glibcxx_function_requires(_LessThanComparableConcept<
            typename iterator_traits<_InputIterator2>::value_type>)
+      __glibcxx_requires_valid_range(__first1, __last1);
+      __glibcxx_requires_valid_range(__first2, __last2);
 
       return __lexicographical_compare_3way(__first1, __last1, __first2, __last2);
     }
@@ -226,6 +228,8 @@ namespace __gnu_cxx
       __glibcxx_function_requires(_EqualityComparableConcept<
            typename iterator_traits<_InputIterator>::value_type >)
       __glibcxx_function_requires(_EqualityComparableConcept<_Tp>)
+      __glibcxx_requires_valid_range(__first, __last);
+
       for ( ; __first != __last; ++__first)
        if (*__first == __value)
          ++__n;
@@ -241,6 +245,8 @@ namespace __gnu_cxx
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
       __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
            typename iterator_traits<_InputIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
+
       for ( ; __first != __last; ++__first)
        if (__pred(*__first))
          ++__n;
@@ -262,6 +268,7 @@ namespace __gnu_cxx
       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
                typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       _Distance __remaining = std::distance(__first, __last);
       _Distance __m = min(__n, __remaining);
@@ -297,6 +304,7 @@ namespace __gnu_cxx
                typename iterator_traits<_ForwardIterator>::value_type>)
       __glibcxx_function_requires(_UnaryFunctionConcept<
                _RandomNumberGenerator, _Distance, _Distance>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       _Distance __remaining = std::distance(__first, __last);
       _Distance __m = min(__n, __remaining);
@@ -378,6 +386,8 @@ namespace __gnu_cxx
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
            _RandomAccessIterator>)
+      __glibcxx_requires_valid_range(__first, __last);
+      __glibcxx_requires_valid_range(__out_first, __out_last);
 
       return __random_sample(__first, __last,
                             __out_first, __out_last - __out_first);
@@ -399,46 +409,14 @@ namespace __gnu_cxx
       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
       __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
            _RandomAccessIterator>)
+      __glibcxx_requires_valid_range(__first, __last);
+      __glibcxx_requires_valid_range(__out_first, __out_last);
 
       return __random_sample(__first, __last,
                             __out_first, __rand,
                             __out_last - __out_first);
     }
   
-  // is_heap, a predicate testing whether or not a range is
-  // a heap.  This function is an extension, not part of the C++
-  // standard.
-
-  template<typename _RandomAccessIterator, typename _Distance>
-    bool
-    __is_heap(_RandomAccessIterator __first, _Distance __n)
-    {
-      _Distance __parent = 0;
-      for (_Distance __child = 1; __child < __n; ++__child) {
-       if (__first[__parent] < __first[__child]) 
-         return false;
-       if ((__child & 1) == 0)
-         ++__parent;
-      }
-      return true;
-    }
-
-  template<typename _RandomAccessIterator, typename _Distance,
-           typename _StrictWeakOrdering>
-    bool
-    __is_heap(_RandomAccessIterator __first, _StrictWeakOrdering __comp,
-             _Distance __n)
-    {
-      _Distance __parent = 0;
-      for (_Distance __child = 1; __child < __n; ++__child) {
-       if (__comp(__first[__parent], __first[__child]))
-         return false;
-       if ((__child & 1) == 0)
-         ++__parent;
-      }
-      return true;
-    }
-
   /**
    *  This is an SGI extension.
    *  @ingroup SGIextensions
@@ -452,8 +430,9 @@ namespace __gnu_cxx
       __glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>)
       __glibcxx_function_requires(_LessThanComparableConcept<
            typename iterator_traits<_RandomAccessIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
-      return __is_heap(__first, __last - __first);
+      return std::__is_heap(__first, __last - __first);
     }
 
   /**
@@ -471,8 +450,9 @@ namespace __gnu_cxx
       __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering,
            typename iterator_traits<_RandomAccessIterator>::value_type, 
            typename iterator_traits<_RandomAccessIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
-      return __is_heap(__first, __comp, __last - __first);
+      return std::__is_heap(__first, __comp, __last - __first);
     }
 
   // is_sorted, a predicated testing whether a range is sorted in
@@ -492,6 +472,7 @@ namespace __gnu_cxx
       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
       __glibcxx_function_requires(_LessThanComparableConcept<
            typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first == __last)
        return true;
@@ -519,6 +500,7 @@ namespace __gnu_cxx
       __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering,
            typename iterator_traits<_ForwardIterator>::value_type, 
            typename iterator_traits<_ForwardIterator>::value_type>)
+      __glibcxx_requires_valid_range(__first, __last);
 
       if (__first == __last)
        return true;
@@ -531,7 +513,6 @@ namespace __gnu_cxx
 
       return true;
     }
-
 } // namespace __gnu_cxx
 
 #endif /* _EXT_ALGORITHM */
index 1d81201..40e6246 100644 (file)
@@ -69,7 +69,3 @@
 #include <bits/stl_algo.h>
 
 #endif /* _GLIBCXX_ALGORITHM */
-
-// Local Variables:
-// mode:C++
-// End:
index ab4ca23..345affc 100644 (file)
 
 #pragma GCC system_header
 
-#include <cstddef>     // for size_t
-#include <cstring>     // for memset
-#include <limits>      // for numeric_limits
+#include <cstddef>     // For size_t
+#include <cstring>     // For memset
+#include <limits>      // For numeric_limits
 #include <string>
-#include <bits/functexcept.h>   // for invalid_argument, out_of_range,
+#include <bits/functexcept.h>   // For invalid_argument, out_of_range,
                                 // overflow_error
-#include <ostream>     // for ostream (operator<<)
-#include <istream>     // for istream (operator>>)
+#include <ostream>     // For ostream (operator<<)
+#include <istream>     // For istream (operator>>)
 
 
 #define _GLIBCXX_BITSET_BITS_PER_WORD  numeric_limits<unsigned long>::digits
 #define _GLIBCXX_BITSET_WORDS(__n) \
  ((__n) < 1 ? 0 : ((__n) + _GLIBCXX_BITSET_BITS_PER_WORD - 1)/_GLIBCXX_BITSET_BITS_PER_WORD)
 
-namespace std
+namespace __gnu_norm
 {
   /**
    *  @if maint
@@ -646,7 +646,7 @@ namespace std
 
       ~reference() { }
 
-      // for b[i] = __x;
+      // For b[i] = __x;
       reference&
       operator=(bool __x)
       {
@@ -657,7 +657,7 @@ namespace std
        return *this;
       }
 
-      // for b[i] = b[__j];
+      // For b[i] = b[__j];
       reference&
       operator=(const reference& __j)
       {
@@ -668,16 +668,16 @@ namespace std
        return *this;
       }
 
-      // flips the bit
+      // Flips the bit
       bool
       operator~() const
       { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) == 0; }
 
-      // for __x = b[i];
+      // For __x = b[i];
       operator bool() const
       { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; }
 
-      // for b[i].flip();
+      // For b[i].flip();
       reference&
       flip()
       {
@@ -1207,9 +1207,13 @@ namespace std
       return __os << __tmp;
     }
   //@}
-} // namespace std
+} // namespace __gnu_norm
 
 #undef _GLIBCXX_BITSET_WORDS
 #undef _GLIBCXX_BITSET_BITS_PER_WORD
 
+#ifdef _GLIBCXX_DEBUG
+# include <debug/bitset>
+#endif
+
 #endif /* _GLIBCXX_BITSET */
index 7200220..80817f6 100644 (file)
@@ -74,4 +74,8 @@
 # include <bits/deque.tcc>
 #endif
 
+#ifdef _GLIBCXX_DEBUG
+# include <debug/deque>
+#endif
+
 #endif /* _GLIBCXX_DEQUE */
index 0330eda..6819f20 100644 (file)
 #define _GLIBCXX_FUNCTIONAL 1
 
 #pragma GCC system_header
+
 #include <bits/c++config.h>
 #include <cstddef>
 #include <bits/stl_function.h>
 
 #endif /* _GLIBCXX_FUNCTIONAL */
-
-// Local Variables:
-// mode:C++
-// End:
-
index 3da3e90..6e3840b 100644 (file)
@@ -62,6 +62,7 @@
 #define _GLIBCXX_ITERATOR 1
 
 #pragma GCC system_header
+
 #include <bits/c++config.h>
 #include <cstddef>
 #include <bits/stl_iterator_base_types.h>
@@ -73,7 +74,3 @@
 #include <bits/streambuf_iterator.h>
 
 #endif /* _GLIBCXX_ITERATOR */
-
-// Local Variables:
-// mode:C++
-// End:
index f882bf7..285a29d 100644 (file)
@@ -74,5 +74,9 @@
 # include <bits/list.tcc>
 #endif
 
+#ifdef _GLIBCXX_DEBUG
+# include <debug/list>
+#endif
+
 #endif /* _GLIBCXX_LIST */
 
index f4e0ca1..4a88ae2 100644 (file)
@@ -67,8 +67,8 @@
 #include <bits/stl_map.h>
 #include <bits/stl_multimap.h>
 
-#endif /* _GLIBCXX_MAP */
+#ifdef _GLIBCXX_DEBUG
+# include <debug/map>
+#endif
 
-// Local Variables:
-// mode:C++
-// End:
+#endif /* _GLIBCXX_MAP */
index 3b7cefa..eb29232 100644 (file)
@@ -57,6 +57,7 @@
 #include <bits/stl_iterator_base_types.h> //for iterator_traits
 #include <bits/stl_uninitialized.h>
 #include <bits/stl_raw_storage_iter.h>
+#include <debug/debug.h>
 
 namespace std
 {
@@ -259,7 +260,11 @@ namespace std
        *  what happens when you dereference one of those...)
        */
       element_type&
-      operator*() const throw() { return *_M_ptr; }
+      operator*() const throw() 
+      {
+       _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
+       return *_M_ptr; 
+      }
       
       /**
        *  @brief  Smart pointer dereferencing.
@@ -268,7 +273,11 @@ namespace std
        *  automatically cause to be dereferenced.
        */
       element_type*
-      operator->() const throw() { return _M_ptr; }
+      operator->() const throw() 
+      {
+       _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
+       return _M_ptr; 
+      }
       
       /**
        *  @brief  Bypassing the smart pointer.
index f461508..88661e9 100644 (file)
@@ -62,6 +62,7 @@
 #define _GLIBCXX_NUMERIC 1
 
 #pragma GCC system_header
+
 #include <bits/c++config.h>
 #include <cstddef>
 #include <iterator>
@@ -69,7 +70,3 @@
 #include <bits/stl_numeric.h>
 
 #endif /* _GLIBCXX_NUMERIC */
-
-// Local Variables:
-// mode:C++
-// End:
index e2e0b84..9a6523b 100644 (file)
 #define _GLIBCXX_QUEUE 1
 
 #pragma GCC system_header
+
 #include <bits/c++config.h>
 #include <bits/functexcept.h>
 #include <bits/stl_algobase.h>
 #include <bits/allocator.h>
 #include <bits/stl_construct.h>
 #include <bits/stl_uninitialized.h>
-#include <bits/stl_vector.h>
 #include <bits/stl_heap.h>
-#include <bits/stl_deque.h>
 #include <bits/stl_function.h>
+#include <deque>
+#include <vector>
 #include <bits/stl_queue.h>
 
-#ifndef _GLIBCXX_EXPORT_TEMPLATE
-#  include <bits/deque.tcc>
-#  include <bits/vector.tcc>
-#endif
-
 #endif /* _GLIBCXX_QUEUE */
index 8dbed18..7ef8c9f 100644 (file)
@@ -67,8 +67,8 @@
 #include <bits/stl_set.h>
 #include <bits/stl_multiset.h>
 
-#endif /* _GLIBCXX_SET */
+#ifdef _GLIBCXX_DEBUG
+# include <debug/set>
+#endif
 
-// Local Variables:
-// mode:C++
-// End:
+#endif /* _GLIBCXX_SET */
index 8017852..70f0456 100644 (file)
 #include <bits/allocator.h>
 #include <bits/stl_construct.h>
 #include <bits/stl_uninitialized.h>
-#include <bits/stl_deque.h>
+#include <deque>
 #include <bits/stl_stack.h>
 
-#ifndef _GLIBCXX_EXPORT_TEMPLATE
-# include <bits/deque.tcc>
-#endif
-
 #endif /* _GLIBCXX_STACK */
index f579342..fe93090 100644 (file)
 #define _GLIBCXX_UTILITY 1
 
 #pragma GCC system_header
+
 #include <bits/c++config.h>
 #include <bits/stl_relops.h>
 #include <bits/stl_pair.h>
 
 #endif /* _GLIBCXX_UTILITY */
-
-// Local Variables:
-// mode:C++
-// End:
index 0936748..7dac89d 100644 (file)
@@ -46,6 +46,7 @@
 #include <cstdlib>
 #include <numeric>
 #include <algorithm>
+#include <debug/debug.h>
 
 namespace std
 {
@@ -221,12 +222,18 @@ namespace std
   template<typename _Tp>
     inline const _Tp&
     valarray<_Tp>::operator[](size_t __i) const
-    { return _M_data[__i]; }
+    { 
+      __glibcxx_requires_subscript(__i);
+      return _M_data[__i]; 
+    }
 
   template<typename _Tp>
     inline _Tp&
     valarray<_Tp>::operator[](size_t __i)
-    { return _M_data[__i]; }
+    { 
+      __glibcxx_requires_subscript(__i);
+      return _M_data[__i]; 
+    }
 
 } // std::
 
@@ -260,7 +267,10 @@ namespace std
     inline
     valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n)
       : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n))
-    { std::__valarray_copy_construct(__p, __p + __n, _M_data); }
+    { 
+      _GLIBCXX_DEBUG_ASSERT(__p != 0 || __n == 0);
+      std::__valarray_copy_construct(__p, __p + __n, _M_data); 
+    }
 
   template<typename _Tp>
     inline
@@ -324,6 +334,7 @@ namespace std
     inline valarray<_Tp>&
     valarray<_Tp>::operator=(const valarray<_Tp>& __v)
     {
+      _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size);
       std::__valarray_copy(__v._M_data, _M_size, _M_data);
       return *this;
     }
@@ -340,6 +351,7 @@ namespace std
     inline valarray<_Tp>&
     valarray<_Tp>::operator=(const slice_array<_Tp>& __sa)
     {
+      _GLIBCXX_DEBUG_ASSERT(_M_size == __sa._M_sz);
       std::__valarray_copy(__sa._M_array, __sa._M_sz,
                           __sa._M_stride, _Array<_Tp>(_M_data));
       return *this;
@@ -349,6 +361,7 @@ namespace std
     inline valarray<_Tp>&
     valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga)
     {
+      _GLIBCXX_DEBUG_ASSERT(_M_size == __ga._M_index.size());
       std::__valarray_copy(__ga._M_array, _Array<size_t>(__ga._M_index),
                           _Array<_Tp>(_M_data), _M_size);
       return *this;
@@ -358,6 +371,7 @@ namespace std
     inline valarray<_Tp>&
     valarray<_Tp>::operator=(const mask_array<_Tp>& __ma)
     {
+      _GLIBCXX_DEBUG_ASSERT(_M_size == __ma._M_sz);
       std::__valarray_copy(__ma._M_array, __ma._M_mask,
                           _Array<_Tp>(_M_data), _M_size);
       return *this;
@@ -367,6 +381,7 @@ namespace std
     inline valarray<_Tp>&
     valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia)
     {
+      _GLIBCXX_DEBUG_ASSERT(_M_size == __ia._M_sz);
       std::__valarray_copy(__ia._M_array, __ia._M_index,
                           _Array<_Tp>(_M_data), _M_size);
       return *this;
@@ -376,6 +391,7 @@ namespace std
     inline valarray<_Tp>&
     valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e)
     {
+      _GLIBCXX_DEBUG_ASSERT(_M_size == __e.size());
       std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data));
       return *this;
     }
@@ -460,6 +476,7 @@ namespace std
     inline _Tp
     valarray<_Tp>::sum() const
     {
+      _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
       return std::__valarray_sum(_M_data, _M_data + _M_size);
     }
 
@@ -540,6 +557,7 @@ namespace std
     inline _Tp
     valarray<_Tp>::min() const
     {
+      _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
       return *std::min_element (_M_data, _M_data+_M_size);
     }
 
@@ -547,6 +565,7 @@ namespace std
     inline _Tp
     valarray<_Tp>::max() const
     {
+      _GLIBCXX_DEBUG_ASSERT(_M_size > 0);
       return *std::max_element (_M_data, _M_data+_M_size);
     }
   
@@ -596,6 +615,7 @@ namespace std
     inline valarray<_Tp>&                                              \
     valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v)           \
     {                                                                  \
+      _GLIBCXX_DEBUG_ASSERT(_M_size == __v._M_size);                    \
       _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size,          \
                               _Array<_Tp>(__v._M_data));               \
       return *this;                                                    \
@@ -643,6 +663,7 @@ _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right)
                  typename __fun<_Name, _Tp>::result_type>               \
     operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w)   \
     {                                                                  \
+      _GLIBCXX_DEBUG_ASSERT(__v.size() == __w.size());                  \
       typedef _BinClos<_Name,_ValArray,_ValArray,_Tp,_Tp> _Closure;     \
       typedef typename __fun<_Name, _Tp>::result_type _Rt;              \
       return _Expr<_Closure, _Rt>(_Closure(__v, __w));                  \
@@ -690,7 +711,3 @@ _DEFINE_BINARY_OPERATOR(>=, __greater_equal)
 } // namespace std
 
 #endif /* _GLIBCXX_VALARRAY */
-
-// Local Variables:
-// mode:c++
-// End:
index 02cf122..16e50a9 100644 (file)
@@ -75,5 +75,9 @@
 # include <bits/vector.tcc>
 #endif
 
+#ifdef _GLIBCXX_DEBUG
+# include <debug/vector>
+#endif
+
 #endif /* _GLIBCXX_VECTOR */
 
index e3e04b5..701d520 100644 (file)
@@ -94,6 +94,7 @@ sources = \
        codecvt.cc \
        complex_io.cc \
        ctype.cc \
+       debug.cc \
        demangle.cc \
        functexcept.cc \
        globals_locale.cc \
index 40d6f8b..08d4af0 100644 (file)
@@ -251,6 +251,7 @@ sources = \
        codecvt.cc \
        complex_io.cc \
        ctype.cc \
+       debug.cc \
        demangle.cc \
        functexcept.cc \
        globals_locale.cc \
@@ -360,7 +361,7 @@ am__objects_1 = codecvt_members.lo collate_members.lo ctype_members.lo \
        messages_members.lo monetary_members.lo numeric_members.lo \
        time_members.lo
 am__objects_2 = basic_file.lo c++locale.lo
-am__objects_3 = codecvt.lo complex_io.lo ctype.lo demangle.lo \
+am__objects_3 = codecvt.lo complex_io.lo ctype.lo debug.lo demangle.lo \
        functexcept.lo globals_locale.lo globals_io.lo ios.lo \
        ios_failure.lo ios_init.lo ios_locale.lo limits.lo locale.lo \
        locale_init.lo locale_facets.lo localename.lo stdexcept.lo \
diff --git a/libstdc++-v3/src/debug.cc b/libstdc++-v3/src/debug.cc
new file mode 100644 (file)
index 0000000..224f8e2
--- /dev/null
@@ -0,0 +1,604 @@
+// Debugging mode support code -*- C++ -*-
+
+// Copyright (C) 2003
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <debug/debug.h>
+#include <debug/safe_sequence.h>
+#include <debug/safe_iterator.h>
+#include <algorithm>
+#include <cstdlib>
+#include <cassert>
+#include <cstring>
+#include <cstdio>
+#include <cctype>
+
+using namespace std;
+
+namespace __gnu_debug
+{
+  const char* _S_debug_messages[] = 
+  {
+    "function requires a valid iterator range [%1.name;, %2.name;)",
+    "attempt to insert into container with a singular iterator",
+    "attempt to insert into container with an iterator from a different container",
+    "attempt to erase from container with a %2.state; iterator",
+    "attempt to erase from container with an iterator from a different container",
+    "attempt to subscript container with out-of-bounds index %2;, but container only holds %3; elements",
+    "attempt to access an element in an empty container",
+    "elements in iterator range [%1.name;, %2.name;) are not partitioned by the value %3;",
+    "elements in iterator range [%1.name;, %2.name;) are not partitioned by the predicate %3; and value %4;",
+    "elements in iterator range [%1.name;, %2.name;) are not sorted",
+    "elements in iterator range [%1.name;, %2.name;) are not sorted according to the predicate %3;",
+    "elements in iterator range [%1.name;, %2.name;) do not form a heap",
+    "elements in iterator range [%1.name;, %2.name;) do not form a heap with respect to the predicate %3;",
+    "attempt to write through a singular bitset reference",
+    "attempt to read from a singular bitset reference",
+    "attempt to flip a singular bitset reference",
+    "attempt to splice a list into itself",
+    "attempt to splice lists with inequal allocators",
+    "attempt to splice elements referenced by a %1.state; iterator",
+    "attempt to splice an iterator from a different container",
+    "splice destination %1.name; occurs within source range [%2.name;, %3.name;)",
+    "attempt to initialize an iterator that will immediately become singular",
+    "attempt to copy-construct an iterator from a singular iterator",
+    "attempt to construct a constant iterator from a singular mutable iterator",
+    "attempt to copy from a singular iterator",
+    "attempt to dereference a %1.state; iterator",
+    "attempt to increment a %1.state; iterator",
+    "attempt to decrement a %1.state; iterator",
+    "attempt to subscript a %1.state; iterator %2; step from its current position, which falls outside its dereferenceable range",
+    "attempt to advance a %1.state; iterator %2; steps, which falls outside its valid range",
+    "attempt to retreat a %1.state; iterator %2; steps, which falls outside its valid range",
+    "attempt to compare a %1.state; iterator to a %2.state; iterator",
+    "attempt to compare iterators from different sequences",
+    "attempt to order a %1.state; iterator to a %2.state; iterator",
+    "attempt to order iterators from different sequences",
+    "attempt to compute the difference between a %1.state; iterator to a %2.state; iterator",
+    "attempt to compute the different between two iterators from different sequences",
+    "attempt to dereference an end-of-stream istream_iterator",
+    "attempt to increment an end-of-stream istream_iterator",
+    "attempt to output via an ostream_iterator with no associated stream",
+    "attempt to dereference an end-of-stream istreambuf_iterator (this is a GNU extension)",
+    "attempt to increment an end-of-stream istreambuf_iterator"
+  };
+
+  void 
+  _Safe_sequence_base::
+  _M_detach_all()
+  {
+    for (_Safe_iterator_base* iter = _M_iterators; iter; )
+    {
+      _Safe_iterator_base* old = iter;
+      iter = iter->_M_next;
+      old->_M_attach(0, false);
+    }
+    
+    for (_Safe_iterator_base* iter = _M_const_iterators; iter; )
+    {
+      _Safe_iterator_base* old = iter;
+      iter = iter->_M_next;
+      old->_M_attach(0, true);
+    }
+  }
+
+  void 
+  _Safe_sequence_base::
+  _M_detach_singular()
+  {
+    for (_Safe_iterator_base* iter = _M_iterators; iter; )
+    {
+      _Safe_iterator_base* old = iter;
+      iter = iter->_M_next;
+      if (old->_M_singular())
+       old->_M_attach(0, false);
+    }
+
+    for (_Safe_iterator_base* iter = _M_const_iterators; iter; )
+    {
+      _Safe_iterator_base* old = iter;
+      iter = iter->_M_next;
+      if (old->_M_singular())
+       old->_M_attach(0, true);
+    }
+  }
+
+  void 
+  _Safe_sequence_base::
+  _M_revalidate_singular()
+  {
+    for (_Safe_iterator_base* iter = _M_iterators; iter;
+        iter = iter->_M_next)
+    {
+      iter->_M_version = _M_version;
+      iter = iter->_M_next;
+    }
+    
+    for (_Safe_iterator_base* iter = _M_const_iterators; iter;
+        iter = iter->_M_next)
+    {
+      iter->_M_version = _M_version;
+      iter = iter->_M_next;
+    }
+  }
+
+  void 
+  _Safe_sequence_base::
+  _M_swap(_Safe_sequence_base& __x)
+  {
+    swap(_M_iterators, __x._M_iterators);
+    swap(_M_const_iterators, __x._M_const_iterators);
+    swap(_M_version, __x._M_version);
+    for (_Safe_iterator_base* iter = _M_iterators; iter; iter = iter->_M_next)
+      iter->_M_sequence = this;
+    for (_Safe_iterator_base* iter = __x._M_iterators; iter; iter = iter->_M_next)
+      iter->_M_sequence = &__x;
+    for (_Safe_iterator_base* iter = _M_const_iterators; iter; iter = iter->_M_next)
+      iter->_M_sequence = this;
+    for (_Safe_iterator_base* iter = __x._M_const_iterators; iter; iter = iter->_M_next)
+      iter->_M_sequence = &__x;
+  }
+  
+  void 
+  _Safe_iterator_base::
+  _M_attach(_Safe_sequence_base* __seq, bool __constant)
+  {
+    _M_detach();
+    
+    // Attach to the new sequence (if there is one)
+    if (__seq)
+    {
+      _M_sequence = __seq;
+      _M_version = _M_sequence->_M_version;
+      _M_prior = 0;
+      if (__constant)
+      {
+       _M_next = _M_sequence->_M_const_iterators;
+       if (_M_next)
+         _M_next->_M_prior = this;
+       _M_sequence->_M_const_iterators = this;
+      }
+      else
+      {
+       _M_next = _M_sequence->_M_iterators;
+       if (_M_next)
+         _M_next->_M_prior = this;
+       _M_sequence->_M_iterators = this;
+      }
+    }
+  }
+
+  void 
+  _Safe_iterator_base::
+  _M_detach()
+  {
+    if (_M_sequence)
+    {
+      // Remove us from this sequence's list
+      if (_M_prior) _M_prior->_M_next = _M_next;
+      if (_M_next)  _M_next->_M_prior = _M_prior;
+      
+      if (_M_sequence->_M_const_iterators == this)
+       _M_sequence->_M_const_iterators = _M_next;
+      if (_M_sequence->_M_iterators == this)
+       _M_sequence->_M_iterators = _M_next;
+    }
+
+    _M_sequence = 0;
+    _M_version = 0;
+    _M_prior = 0;
+    _M_next = 0;
+  }
+  
+  bool
+  _Safe_iterator_base::
+  _M_singular() const
+  { return !_M_sequence || _M_version != _M_sequence->_M_version; }
+    
+  bool
+  _Safe_iterator_base::
+  _M_can_compare(const _Safe_iterator_base& __x) const
+  {
+    return (! _M_singular() && !__x._M_singular()
+           && _M_sequence == __x._M_sequence);
+  }
+
+  void
+  _Error_formatter::_Parameter::
+  _M_print_field(const _Error_formatter* __formatter,
+                const char* __name) const
+  {
+    assert(this->_M_kind != _Parameter::__unused_param);
+    const int bufsize = 64;
+    char buf[bufsize];
+    
+    if (_M_kind == __iterator)
+    {
+      if (strcmp(__name, "name") == 0)
+      {
+       assert(_M_variant._M_iterator._M_name);
+       __formatter->_M_print_word(_M_variant._M_iterator._M_name);
+      }
+      else if (strcmp(__name, "address") == 0)
+      {
+       snprintf(buf, bufsize, "%p", _M_variant._M_iterator._M_address);
+       __formatter->_M_print_word(buf);
+      }
+      else if (strcmp(__name, "type") == 0)
+      {
+       assert(_M_variant._M_iterator._M_type);
+       // TBD: demangle!
+       __formatter->_M_print_word(_M_variant._M_iterator._M_type->name());
+      }
+      else if (strcmp(__name, "constness") == 0)
+      {
+       static const char* __constness_names[__last_constness] =
+       {
+         "<unknown>",
+         "constant",
+         "mutable"
+       };
+       __formatter->_M_print_word(__constness_names[_M_variant._M_iterator._M_constness]);
+      }
+      else if (strcmp(__name, "state") == 0)
+      {
+       static const char* __state_names[__last_state] = 
+       {
+         "<unknown>",
+         "singular",
+         "dereferenceable (start-of-sequence)",
+         "dereferenceable",
+         "past-the-end"
+       };
+       __formatter->_M_print_word(__state_names[_M_variant._M_iterator._M_state]);
+      }
+      else if (strcmp(__name, "sequence") == 0)
+      {
+       assert(_M_variant._M_iterator._M_sequence);
+       snprintf(buf, bufsize, "%p", _M_variant._M_iterator._M_sequence);
+       __formatter->_M_print_word(buf);
+      }
+      else if (strcmp(__name, "seq_type") == 0)
+      {
+       // TBD: demangle!
+       assert(_M_variant._M_iterator._M_seq_type);
+       __formatter->_M_print_word(_M_variant._M_iterator._M_seq_type->name());
+      }
+      else
+       assert(false);
+    }
+    else if (_M_kind == __sequence)
+    {
+      if (strcmp(__name, "name") == 0)
+      {
+       assert(_M_variant._M_sequence._M_name);
+       __formatter->_M_print_word(_M_variant._M_sequence._M_name);
+      }
+      else if (strcmp(__name, "address") == 0)
+      {
+       assert(_M_variant._M_sequence._M_address);
+       snprintf(buf, bufsize, "%p", _M_variant._M_sequence._M_address);
+       __formatter->_M_print_word(buf);
+      }
+      else if (strcmp(__name, "type") == 0)
+      {
+       // TBD: demangle!
+       assert(_M_variant._M_sequence._M_type);
+       __formatter->_M_print_word(_M_variant._M_sequence._M_type->name());
+      }
+      else
+       assert(false);
+    }
+    else if (_M_kind == __integer)
+    {
+      if (strcmp(__name, "name") == 0)
+      {
+       assert(_M_variant._M_integer._M_name);
+       __formatter->_M_print_word(_M_variant._M_integer._M_name);
+      }
+      else
+       assert(false);
+    }
+    else if (_M_kind == __string)
+    {
+      if (strcmp(__name, "name") == 0)
+      {
+       assert(_M_variant._M_string._M_name);
+       __formatter->_M_print_word(_M_variant._M_string._M_name);
+      }
+      else
+       assert(false);
+    }
+    else
+    {
+      assert(false);
+    }
+  }
+
+  void
+  _Error_formatter::_Parameter::
+  _M_print_description(const _Error_formatter* __formatter) const
+  {
+    const int bufsize = 128;
+    char buf[bufsize];
+    
+    if (_M_kind == __iterator)
+    {
+      __formatter->_M_print_word("iterator ");
+      if (_M_variant._M_iterator._M_name)
+      {
+       snprintf(buf, bufsize, "\"%s\" ", 
+                _M_variant._M_iterator._M_name);
+       __formatter->_M_print_word(buf);
+      }
+      
+      snprintf(buf, bufsize, "@ 0x%p {\n", 
+              _M_variant._M_iterator._M_address);
+      __formatter->_M_print_word(buf);
+      if (_M_variant._M_iterator._M_type)
+      {
+       __formatter->_M_print_word("type = ");
+       _M_print_field(__formatter, "type");
+       
+       if (_M_variant._M_iterator._M_constness != __unknown_constness)
+       {
+         __formatter->_M_print_word(" (");
+         _M_print_field(__formatter, "constness");
+         __formatter->_M_print_word(" iterator)");
+       }
+       __formatter->_M_print_word(";\n");
+      }
+      
+      if (_M_variant._M_iterator._M_state != __unknown_state)
+      {
+       __formatter->_M_print_word("  state = ");
+       _M_print_field(__formatter, "state");
+       __formatter->_M_print_word(";\n");
+      }
+
+      if (_M_variant._M_iterator._M_sequence)
+      {
+       __formatter->_M_print_word("  references sequence ");
+       if (_M_variant._M_iterator._M_seq_type)
+       {
+         __formatter->_M_print_word("with type `");
+         _M_print_field(__formatter, "seq_type");
+         __formatter->_M_print_word("' ");
+       }
+       
+       snprintf(buf, bufsize, "@ 0x%p\n", _M_variant._M_sequence._M_address);
+       __formatter->_M_print_word(buf);
+      }
+      __formatter->_M_print_word("}\n");
+    }
+    else if (_M_kind == __sequence)
+    {
+      __formatter->_M_print_word("sequence ");
+      if (_M_variant._M_sequence._M_name)
+      {
+       snprintf(buf, bufsize, "\"%s\" ", 
+                _M_variant._M_sequence._M_name);
+       __formatter->_M_print_word(buf);
+      }
+      
+      snprintf(buf, bufsize, "@ 0x%p {\n", 
+              _M_variant._M_sequence._M_address);
+      __formatter->_M_print_word(buf);
+      
+      if (_M_variant._M_sequence._M_type)
+      {
+       __formatter->_M_print_word("  type = ");
+       _M_print_field(__formatter, "type");
+       __formatter->_M_print_word(";\n");
+      }          
+      __formatter->_M_print_word("}\n");
+    }
+  }
+
+  const _Error_formatter&
+  _Error_formatter::_M_message(_Debug_msg_id __id) const
+  { return this->_M_message(_S_debug_messages[__id]); }
+  
+  void
+  _Error_formatter::_M_error() const
+  {
+    const int bufsize = 128;
+    char buf[bufsize];
+    
+    // Emit file & line number information
+    _M_column = 1;
+    _M_wordwrap = false;
+    if (_M_file)
+    {
+      snprintf(buf, bufsize, "%s:", _M_file);
+      _M_print_word(buf);
+      _M_column += strlen(buf);
+    }
+    
+    if (_M_line > 0)
+    {
+      snprintf(buf, bufsize, "%u:", _M_line);
+      _M_print_word(buf);
+      _M_column += strlen(buf);
+    }
+    
+    _M_wordwrap = true;
+    _M_print_word("error: ");
+    
+    // Print the error message
+    assert(_M_text);
+    _M_print_string(_M_text);
+    _M_print_word(".\n");
+    
+    // Emit descriptions of the objects involved in the operation
+    _M_wordwrap = false;
+    bool has_noninteger_parameters = false;
+    for (unsigned int i = 0; i < _M_num_parameters; ++i)
+    {
+      if (_M_parameters[i]._M_kind == _Parameter::__iterator
+         || _M_parameters[i]._M_kind == _Parameter::__sequence)
+      {
+       if (!has_noninteger_parameters)
+       {
+         _M_first_line = true;
+         _M_print_word("\nObjects involved in the operation:\n");
+         has_noninteger_parameters = true;
+       }
+       _M_parameters[i]._M_print_description(this);
+      }
+    }
+    
+    abort();
+  }
+
+  void 
+  _Error_formatter::_M_print_word(const char* __word) const
+  {
+    if (!_M_wordwrap) 
+    {
+      fprintf(stderr, "%s", __word);
+      return;
+    }
+    
+    size_t __length = strlen(__word);
+    if (__length == 0)
+      return;
+    
+    if ((_M_column + __length < _M_max_length)
+       || (__length >= _M_max_length && _M_column == 1)) 
+    {
+      // If this isn't the first line, indent
+      if (_M_column == 1 && !_M_first_line)
+      {
+       char spacing[_M_indent + 1];
+       for (int i = 0; i < _M_indent; ++i)
+         spacing[i] = ' ';
+       spacing[_M_indent] = '\0';
+       fprintf(stderr, "%s", spacing);
+       _M_column += _M_indent;
+      }
+      
+      fprintf(stderr, "%s", __word);
+      _M_column += __length;
+      
+      if (__word[__length - 1] == '\n') 
+      {
+       _M_first_line = false;
+       _M_column = 1;
+      }
+    }
+    else
+    {
+      _M_column = 1;
+      _M_print_word("\n");
+      _M_print_word(__word);
+    }
+  }
+  
+  void
+  _Error_formatter::
+  _M_print_string(const char* __string) const
+  {
+    const char* __start = __string;
+    const char* __end = __start;
+    const int bufsize = 128;
+    char buf[bufsize];
+
+    while (*__start)
+    {
+      if (*__start != '%')
+      {
+       // [__start, __end) denotes the next word
+       __end = __start;
+       while (isalnum(*__end)) ++__end;
+       if (__start == __end) ++__end;
+       if (isspace(*__end)) ++__end;
+       
+       assert(__end - __start + 1< bufsize);
+       snprintf(buf, __end - __start + 1, "%s", __start);
+       _M_print_word(buf);
+       __start = __end;
+       
+       // Skip extra whitespace
+       while (*__start == ' ') ++__start;
+       
+       continue;
+      } 
+       
+      ++__start;
+      assert(*__start);
+      if (*__start == '%')
+      {
+       _M_print_word("%");
+       ++__start;
+       continue;
+      }
+      
+      // Get the parameter number
+      assert(*__start >= '1' && *__start <= '9');
+      size_t param = *__start - '0';
+      --param;
+      assert(param < _M_num_parameters);
+      
+      // '.' separates the parameter number from the field
+      // name, if there is one.
+      ++__start;
+      if (*__start != '.')
+      {
+       assert(*__start == ';');
+       ++__start;
+       buf[0] = '\0';
+       if (_M_parameters[param]._M_kind == _Parameter::__integer)
+       {
+         snprintf(buf, bufsize, "%ld", 
+                  _M_parameters[param]._M_variant._M_integer._M_value);
+         _M_print_word(buf);
+       }
+       else if (_M_parameters[param]._M_kind == _Parameter::__string)
+         _M_print_string(_M_parameters[param]._M_variant._M_string._M_value);
+       continue;
+      }
+      
+      // Extract the field name we want
+      enum { max_field_len = 16 };
+      char field[max_field_len];
+      int field_idx = 0;
+      ++__start;
+      while (*__start != ';')
+      {
+       assert(*__start);
+       assert(field_idx < max_field_len-1);
+       field[field_idx++] = *__start++;
+      }
+      ++__start;
+      field[field_idx] = 0;
+      
+      _M_parameters[param]._M_print_field(this, field);                  
+    }
+  }
+} // namespace __gnu_debug
index e08ad9f..37a4d3d 100644 (file)
 
 namespace std
 {
+#ifdef _GLIBCXX_INST_ATOMICITY_LOCK
+  template volatile int __Atomicity_lock<0>::_S_atomicity_lock;
+#endif
+
   // string related to iostreams
   template 
     basic_istream<char>& 
@@ -69,12 +73,8 @@ namespace std
     basic_istream<wchar_t>& 
     getline(basic_istream<wchar_t>&, wstring&);
 #endif
-#ifdef _GLIBCXX_INST_ATOMICITY_LOCK
-  template volatile int __Atomicity_lock<0>::_S_atomicity_lock;
-#endif
 } // namespace std
 
-
 namespace __gnu_cxx
 {
 #ifdef _GLIBCXX_NEED_GENERIC_MUTEX
index ec17e54..ab779b8 100644 (file)
@@ -42,7 +42,7 @@
 # define C char
 #endif
 
-namespace std 
+namespace std
 {
   typedef basic_string<C> S;
 
@@ -50,17 +50,7 @@ namespace std
   template S operator+(const C*, const S&);
   template S operator+(C, const S&);
   template S operator+(const S&, const S&);
-} // namespace std
-
-namespace __gnu_cxx
-{
-  using std::S;
-  template bool operator==(const S::iterator&, const S::iterator&);
-  template bool operator==(const S::const_iterator&, const S::const_iterator&);
-}
 
-namespace std
-{
   // Only one template keyword allowed here. 
   // See core issue #46 (NAD)
   // http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_closed.html#46
@@ -100,3 +90,10 @@ namespace std
     S::_S_construct(const C*, const C*, const allocator<C>&,
                    forward_iterator_tag);
 } // namespace std
+
+namespace __gnu_cxx
+{
+  using std::S;
+  template bool operator==(const S::iterator&, const S::iterator&);
+  template bool operator==(const S::const_iterator&, const S::const_iterator&);
+} // namespace __gnu_cxx
index 6f1c629..15a6ae4 100644 (file)
@@ -46,5 +46,5 @@ main()
   test01();
   return 0;
 }
-// { dg-error "candidates" "" { target *-*-* } 216 } 
-// { dg-error "std::auto_ptr" "" { target *-*-* } 338 } 
+// { dg-error "candidates" "" { target *-*-* } 217 } 
+// { dg-error "std::auto_ptr" "" { target *-*-* } 347 } 
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/invalidation/1.cc b/libstdc++-v3/testsuite/23_containers/bitset/invalidation/1.cc
new file mode 100644 (file)
index 0000000..7ca3053
--- /dev/null
@@ -0,0 +1,46 @@
+// Bitset reference invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <debug/bitset>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::bitset;
+
+bool test = true;
+
+// Disappear
+void test01()
+{
+  bitset<32>::reference* i;
+  {
+    bitset<32> bs;
+    bs.flip(7);
+    i = new bitset<32>::reference(bs[7]);
+    VERIFY(*i);
+  }
+  VERIFY(i->_M_singular());
+  delete i;
+}
+
+int main()
+{
+  test01();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/deque/invalidation/1.cc b/libstdc++-v3/testsuite/23_containers/deque/invalidation/1.cc
new file mode 100644 (file)
index 0000000..4529b28
--- /dev/null
@@ -0,0 +1,53 @@
+// Deque iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <debug/deque>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::deque;
+
+bool test = true;
+
+// Assignment
+void test01()
+{
+  deque<int> v1;
+  deque<int> v2;
+
+  deque<int>::iterator i = v1.end();
+  VERIFY(!i._M_dereferenceable() && !i._M_singular());
+
+  v1 = v2;
+  VERIFY(i._M_singular());
+  
+  i = v1.end();
+  v1.assign(v2.begin(), v2.end());
+  VERIFY(i._M_singular());
+
+  i = v1.end();
+  v1.assign(17, 42);
+  VERIFY(i._M_singular());
+}
+
+int main()
+{
+  test01();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/deque/invalidation/2.cc b/libstdc++-v3/testsuite/23_containers/deque/invalidation/2.cc
new file mode 100644 (file)
index 0000000..106c118
--- /dev/null
@@ -0,0 +1,53 @@
+// Deque iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <debug/deque>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::deque;
+
+bool test = true;
+
+// Resize
+void test02()
+{
+  deque<int> v(10, 17);
+
+  deque<int>::iterator before = v.begin() + 6;
+  deque<int>::iterator at = before + 1;
+  deque<int>::iterator after = at + 1;
+
+  // Shrink
+  v.resize(7);
+  VERIFY(before._M_dereferenceable());
+  VERIFY(at._M_singular());
+  VERIFY(after._M_singular());
+
+  // Grow
+  before = v.begin() + 6;
+  v.resize(17);
+  VERIFY(before._M_singular());
+}
+
+int main()
+{
+  test02();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/deque/invalidation/3.cc b/libstdc++-v3/testsuite/23_containers/deque/invalidation/3.cc
new file mode 100644 (file)
index 0000000..60103c1
--- /dev/null
@@ -0,0 +1,62 @@
+// Deque iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <debug/deque>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::deque;
+
+bool test = true;
+
+// Insert
+void test03()
+{
+  deque<int> v(10, 17);
+
+  // Insert a single element
+  deque<int>::iterator before = v.begin() + 6;
+  deque<int>::iterator at = before + 1;
+  deque<int>::iterator after = at;
+  at = v.insert(at, 42);
+  VERIFY(before._M_singular());
+  VERIFY(at._M_dereferenceable());
+  VERIFY(after._M_singular());
+
+  // Insert multiple copies
+  before = v.begin() + 6;
+  at = before + 1;
+  v.insert(at, 3, 42);
+  VERIFY(before._M_singular());
+  VERIFY(at._M_singular());
+
+  // Insert iterator range
+  static int data[] = { 2, 3, 5, 7 };
+  before = v.begin() + 6;
+  at = before + 1;
+  v.insert(at, &data[0], &data[0] + 4);
+  VERIFY(before._M_singular());
+  VERIFY(at._M_singular());
+}
+
+int main()
+{
+  test03();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/deque/invalidation/4.cc b/libstdc++-v3/testsuite/23_containers/deque/invalidation/4.cc
new file mode 100644 (file)
index 0000000..1918737
--- /dev/null
@@ -0,0 +1,69 @@
+// Deque iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <debug/deque>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::deque;
+
+bool test = true;
+
+// Erase
+void test04()
+{
+  deque<int> v(20, 42);
+
+  // Single element erase (middle)
+  deque<int>::iterator before = v.begin();
+  deque<int>::iterator at = before + 3;
+  deque<int>::iterator after = at;
+  at = v.erase(at);
+  VERIFY(before._M_singular());
+  VERIFY(at._M_dereferenceable());
+  VERIFY(after._M_singular());
+
+  // Single element erase (end)
+  before = v.begin();
+  at = before;
+  after = at + 1;
+  at = v.erase(at);
+  VERIFY(before._M_singular());
+  VERIFY(at._M_dereferenceable());
+  VERIFY(after._M_dereferenceable());
+
+  // Multiple element erase
+  before = v.begin();
+  at = before + 3;
+  v.erase(at, at + 3);
+  VERIFY(before._M_singular());
+  VERIFY(at._M_singular());
+
+  // clear()
+  before = v.begin();
+  VERIFY(before._M_dereferenceable());
+  v.clear();
+  VERIFY(before._M_singular());
+}
+
+int main()
+{
+  test04();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/list/invalidation/1.cc b/libstdc++-v3/testsuite/23_containers/list/invalidation/1.cc
new file mode 100644 (file)
index 0000000..86d9031
--- /dev/null
@@ -0,0 +1,60 @@
+// List iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <debug/list>
+#include <iterator>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::list;
+using std::advance;
+
+bool test = true;
+
+// Assignment
+void test01()
+{
+  list<int> v1;
+  list<int> v2;
+
+  v1.push_front(17);
+
+  list<int>::iterator start = v1.begin();
+  list<int>::iterator finish = v1.end();
+  VERIFY(start._M_dereferenceable());
+  VERIFY(!finish._M_dereferenceable() && !finish._M_singular());
+
+  v1 = v2;
+  VERIFY(start._M_singular());
+  VERIFY(!finish._M_dereferenceable() && !finish._M_singular());
+
+  finish = v1.end();
+  v1.assign(v2.begin(), v2.end());
+  VERIFY(!finish._M_dereferenceable() && !finish._M_singular());
+
+  finish = v1.end();
+  v1.assign(17, 42);
+  VERIFY(!finish._M_dereferenceable() && !finish._M_singular());
+}
+
+int main()
+{
+  test01();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/list/invalidation/2.cc b/libstdc++-v3/testsuite/23_containers/list/invalidation/2.cc
new file mode 100644 (file)
index 0000000..117aa61
--- /dev/null
@@ -0,0 +1,55 @@
+// List iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <debug/list>
+#include <iterator>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::list;
+using std::advance;
+
+bool test = true;
+
+// Resize
+void test02()
+{
+  list<int> v(10, 17);
+
+  list<int>::iterator before = v.begin();
+  advance(before, 6);
+  list<int>::iterator at = before;
+  advance(at, 1);
+  list<int>::iterator after = at;
+  advance(after, 1);
+  list<int>::iterator finish = v.end();
+
+  // Shrink
+  v.resize(7);
+  VERIFY(before._M_dereferenceable());
+  VERIFY(at._M_singular());
+  VERIFY(after._M_singular());
+  VERIFY(!finish._M_singular() && !finish._M_dereferenceable());
+}
+
+int main()
+{
+  test02();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/list/invalidation/3.cc b/libstdc++-v3/testsuite/23_containers/list/invalidation/3.cc
new file mode 100644 (file)
index 0000000..59af360
--- /dev/null
@@ -0,0 +1,78 @@
+// List iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <debug/list>
+#include <iterator>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::list;
+using std::advance;
+
+bool test = true;
+
+// Erase
+void test03()
+{
+  list<int> v(20, 42);
+
+  // Single element erase (middle)
+  list<int>::iterator before = v.begin();
+  list<int>::iterator at = before;
+  advance(at, 3);
+  list<int>::iterator after = at;
+  at = v.erase(at);
+  VERIFY(before._M_dereferenceable());
+  VERIFY(at._M_dereferenceable());
+  VERIFY(after._M_singular());
+
+  // Single element erase (end)
+  before = v.begin();
+  at = before;
+  after = at;
+  ++after;
+  at = v.erase(at);
+  VERIFY(before._M_singular());
+  VERIFY(at._M_dereferenceable());
+  VERIFY(after._M_dereferenceable());
+
+  // Multiple element erase
+  before = v.begin();
+  at = before;
+  advance(at, 3);
+  after = at;
+  advance(after, 3);
+  v.erase(at, after);
+  VERIFY(before._M_dereferenceable());
+  VERIFY(at._M_singular());
+
+  // clear()
+  before = v.begin();
+  list<int>::iterator finish = v.end();
+  VERIFY(before._M_dereferenceable());
+  v.clear();
+  VERIFY(before._M_singular());
+  VERIFY(!finish._M_singular() && !finish._M_dereferenceable());
+}
+
+int main()
+{
+  test03();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/list/invalidation/4.cc b/libstdc++-v3/testsuite/23_containers/list/invalidation/4.cc
new file mode 100644 (file)
index 0000000..90f9970
--- /dev/null
@@ -0,0 +1,55 @@
+// List iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <debug/list>
+#include <iterator>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::list;
+using std::advance;
+
+bool test = true;
+
+// Splice
+void test04()
+{
+  list<int> l1(10, 17);
+  list<int> l2(10, 42);
+  
+  list<int>::iterator start2 = l2.begin();
+  list<int>::iterator end2 = start2;
+  advance(end2, 5);
+  list<int>::iterator after2 = end2;
+  advance(after2, 2);
+  
+  l1.splice(l1.begin(), l2, start2, end2);
+  VERIFY(start2._M_dereferenceable());
+  VERIFY(end2._M_dereferenceable());
+  VERIFY(after2._M_dereferenceable());
+  VERIFY(start2._M_attached_to(&l1));
+  VERIFY(end2._M_attached_to(&l2));
+  VERIFY(after2._M_attached_to(&l2));
+}
+
+int main()
+{
+  test04();
+  return !test;
+}
index 5de95b9..bbebfb5 100644 (file)
@@ -76,14 +76,18 @@ test04()
   CompLastLt::reset();
   list0401.merge(list0402, lt);
   VERIFY(list0401 == list0404);
+#ifndef _GLIBCXX_DEBUG
   VERIFY(lt.count() <= (N + M - 1));
+#endif
 
   CompLastEq eq;
 
   CompLastEq::reset();
   list0401.unique(eq);
   VERIFY(list0401 == list0405);
+#ifndef _GLIBCXX_DEBUG
   VERIFY(eq.count() == (N + M - 1));
+#endif
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/23_containers/map/invalidation/1.cc b/libstdc++-v3/testsuite/23_containers/map/invalidation/1.cc
new file mode 100644 (file)
index 0000000..a62a98d
--- /dev/null
@@ -0,0 +1,52 @@
+// Map iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <debug/map>
+#include <iterator>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::map;
+using std::advance;
+
+bool test = true;
+
+// Assignment
+void test01()
+{
+  map<int, int> v1;
+  map<int, int> v2;
+
+  v1[17] = 42;
+
+  map<int, int>::iterator start = v1.begin();
+  map<int, int>::iterator finish = v1.end();
+  VERIFY(start._M_dereferenceable());
+  VERIFY(!finish._M_dereferenceable() && !finish._M_singular());
+
+  v1 = v2;
+  VERIFY(start._M_singular());
+  VERIFY(!finish._M_dereferenceable() && !finish._M_singular());
+}
+
+int main()
+{
+  test01();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/map/invalidation/2.cc b/libstdc++-v3/testsuite/23_containers/map/invalidation/2.cc
new file mode 100644 (file)
index 0000000..0086deb
--- /dev/null
@@ -0,0 +1,71 @@
+// Map iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <debug/map>
+#include <iterator>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::map;
+using std::advance;
+
+bool test = true;
+
+// Erase
+void test02()
+{
+  map<int, int> v;
+  for (int i = 0; i < 20; ++i)
+    v[i] = 20-i;
+
+  // Single element erase (middle)
+  map<int, int>::iterator before = v.begin();
+  map<int, int>::iterator at = before;
+  advance(at, 3);
+  map<int, int>::iterator after = at;
+  ++after;
+  v.erase(at);
+  VERIFY(before._M_dereferenceable());
+  VERIFY(at._M_singular());
+  VERIFY(after._M_dereferenceable());
+
+  // Multiple element erase
+  before = v.begin();
+  at = before;
+  advance(at, 3);
+  after = at;
+  advance(after, 4);
+  v.erase(at, after);
+  VERIFY(before._M_dereferenceable());
+  VERIFY(at._M_singular());
+
+  // clear()
+  before = v.begin();
+  map<int, int>::iterator finish = v.end();
+  VERIFY(before._M_dereferenceable());
+  v.clear();
+  VERIFY(before._M_singular());
+  VERIFY(!finish._M_singular() && !finish._M_dereferenceable());
+}
+
+int main()
+{
+  test02();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/invalidation/1.cc b/libstdc++-v3/testsuite/23_containers/multimap/invalidation/1.cc
new file mode 100644 (file)
index 0000000..71b5385
--- /dev/null
@@ -0,0 +1,53 @@
+// Multimap iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <debug/map>
+#include <iterator>
+#include <testsuite_hooks.h>
+#include <utility>
+
+using __gnu_debug::multimap;
+using std::advance;
+
+bool test = true;
+
+// Assignment
+void test01()
+{
+  multimap<int, int> v1;
+  multimap<int, int> v2;
+
+  v1.insert(std::make_pair(17, 42));
+
+  multimap<int, int>::iterator start = v1.begin();
+  multimap<int, int>::iterator finish = v1.end();
+  VERIFY(start._M_dereferenceable());
+  VERIFY(!finish._M_dereferenceable() && !finish._M_singular());
+
+  v1 = v2;
+  VERIFY(start._M_singular());
+  VERIFY(!finish._M_dereferenceable() && !finish._M_singular());
+}
+
+int main()
+{
+  test01();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/invalidation/2.cc b/libstdc++-v3/testsuite/23_containers/multimap/invalidation/2.cc
new file mode 100644 (file)
index 0000000..c6f659e
--- /dev/null
@@ -0,0 +1,72 @@
+// Multimap iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <debug/map>
+#include <iterator>
+#include <testsuite_hooks.h>
+#include <utility>
+
+using __gnu_debug::multimap;
+using std::advance;
+
+bool test = true;
+
+// Erase
+void test02()
+{
+  multimap<int, int> v;
+  for (int i = 0; i < 20; ++i)
+    v.insert(std::make_pair(i, 20-i));
+
+  // Single element erase (middle)
+  multimap<int, int>::iterator before = v.begin();
+  multimap<int, int>::iterator at = before;
+  advance(at, 3);
+  multimap<int, int>::iterator after = at;
+  ++after;
+  v.erase(at);
+  VERIFY(before._M_dereferenceable());
+  VERIFY(at._M_singular());
+  VERIFY(after._M_dereferenceable());
+
+  // Multiple element erase
+  before = v.begin();
+  at = before;
+  advance(at, 3);
+  after = at;
+  advance(after, 4);
+  v.erase(at, after);
+  VERIFY(before._M_dereferenceable());
+  VERIFY(at._M_singular());
+
+  // clear()
+  before = v.begin();
+  multimap<int, int>::iterator finish = v.end();
+  VERIFY(before._M_dereferenceable());
+  v.clear();
+  VERIFY(before._M_singular());
+  VERIFY(!finish._M_singular() && !finish._M_dereferenceable());
+}
+
+int main()
+{
+  test02();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/invalidation/1.cc b/libstdc++-v3/testsuite/23_containers/multiset/invalidation/1.cc
new file mode 100644 (file)
index 0000000..0d9b76f
--- /dev/null
@@ -0,0 +1,52 @@
+// Multiset iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <debug/set>
+#include <iterator>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::multiset;
+using std::advance;
+
+bool test = true;
+
+// Assignment
+void test01()
+{
+  multiset<int> v1;
+  multiset<int> v2;
+
+  v1.insert(17);
+
+  multiset<int>::iterator start = v1.begin();
+  multiset<int>::iterator finish = v1.end();
+  VERIFY(start._M_dereferenceable());
+  VERIFY(!finish._M_dereferenceable() && !finish._M_singular());
+
+  v1 = v2;
+  VERIFY(start._M_singular());
+  VERIFY(!finish._M_dereferenceable() && !finish._M_singular());
+}
+
+int main()
+{
+  test01();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/invalidation/2.cc b/libstdc++-v3/testsuite/23_containers/multiset/invalidation/2.cc
new file mode 100644 (file)
index 0000000..fbca3c4
--- /dev/null
@@ -0,0 +1,71 @@
+// Multiset iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <debug/set>
+#include <iterator>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::multiset;
+using std::advance;
+
+bool test = true;
+
+// Erase
+void test02()
+{
+  multiset<int> v;
+  for (int i = 0; i < 20; ++i)
+    v.insert(i);
+
+  // Single element erase (middle)
+  multiset<int>::iterator before = v.begin();
+  multiset<int>::iterator at = before;
+  advance(at, 3);
+  multiset<int>::iterator after = at;
+  ++after;
+  v.erase(at);
+  VERIFY(before._M_dereferenceable());
+  VERIFY(at._M_singular());
+  VERIFY(after._M_dereferenceable());
+
+  // Multiple element erase
+  before = v.begin();
+  at = before;
+  advance(at, 3);
+  after = at;
+  advance(after, 4);
+  v.erase(at, after);
+  VERIFY(before._M_dereferenceable());
+  VERIFY(at._M_singular());
+
+  // clear()
+  before = v.begin();
+  multiset<int>::iterator finish = v.end();
+  VERIFY(before._M_dereferenceable());
+  v.clear();
+  VERIFY(before._M_singular());
+  VERIFY(!finish._M_singular() && !finish._M_dereferenceable());
+}
+
+int main()
+{
+  test02();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/invalidation/1.cc b/libstdc++-v3/testsuite/23_containers/set/invalidation/1.cc
new file mode 100644 (file)
index 0000000..5a58f6f
--- /dev/null
@@ -0,0 +1,52 @@
+// Set iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <debug/set>
+#include <iterator>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::set;
+using std::advance;
+
+bool test = true;
+
+// Assignment
+void test01()
+{
+  set<int> v1;
+  set<int> v2;
+
+  v1.insert(17);
+
+  set<int>::iterator start = v1.begin();
+  set<int>::iterator finish = v1.end();
+  VERIFY(start._M_dereferenceable());
+  VERIFY(!finish._M_dereferenceable() && !finish._M_singular());
+
+  v1 = v2;
+  VERIFY(start._M_singular());
+  VERIFY(!finish._M_dereferenceable() && !finish._M_singular());
+}
+
+int main()
+{
+  test01();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/invalidation/2.cc b/libstdc++-v3/testsuite/23_containers/set/invalidation/2.cc
new file mode 100644 (file)
index 0000000..25277d8
--- /dev/null
@@ -0,0 +1,71 @@
+// Set iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <debug/set>
+#include <iterator>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::set;
+using std::advance;
+
+bool test = true;
+
+// Erase
+void test02()
+{
+  set<int> v;
+  for (int i = 0; i < 20; ++i)
+    v.insert(i);
+
+  // Single element erase (middle)
+  set<int>::iterator before = v.begin();
+  set<int>::iterator at = before;
+  advance(at, 3);
+  set<int>::iterator after = at;
+  ++after;
+  v.erase(at);
+  VERIFY(before._M_dereferenceable());
+  VERIFY(at._M_singular());
+  VERIFY(after._M_dereferenceable());
+
+  // Multiple element erase
+  before = v.begin();
+  at = before;
+  advance(at, 3);
+  after = at;
+  advance(after, 4);
+  v.erase(at, after);
+  VERIFY(before._M_dereferenceable());
+  VERIFY(at._M_singular());
+
+  // clear()
+  before = v.begin();
+  set<int>::iterator finish = v.end();
+  VERIFY(before._M_dereferenceable());
+  v.clear();
+  VERIFY(before._M_singular());
+  VERIFY(!finish._M_singular() && !finish._M_dereferenceable());
+}
+
+int main()
+{
+  test02();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/invalidation/1.cc b/libstdc++-v3/testsuite/23_containers/vector/invalidation/1.cc
new file mode 100644 (file)
index 0000000..ccbcb15
--- /dev/null
@@ -0,0 +1,60 @@
+// Vector iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// We need to be pedantic about reallocations for this testcase to be correct.
+// { dg-options "-D_GLIBCXX_DEBUG_PEDANTIC" }
+
+#ifndef _GLIBCXX_DEBUG_PEDANTIC
+#  define _GLIBCXX_DEBUG_PEDANTIC 1
+#endif
+
+#include <debug/vector>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::vector;
+
+bool test = true;
+
+// Assignment
+void test01()
+{
+  vector<int> v1;
+  vector<int> v2;
+
+  vector<int>::iterator i = v1.end();
+  VERIFY(!i._M_dereferenceable() && !i._M_singular());
+
+  v1 = v2;
+  VERIFY(i._M_singular());
+  
+  i = v1.end();
+  v1.assign(v2.begin(), v2.end());
+  VERIFY(i._M_singular());
+
+  i = v1.end();
+  v1.assign(17, 42);
+  VERIFY(i._M_singular());
+}
+
+int main()
+{
+  test01();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/invalidation/2.cc b/libstdc++-v3/testsuite/23_containers/vector/invalidation/2.cc
new file mode 100644 (file)
index 0000000..1f59639
--- /dev/null
@@ -0,0 +1,65 @@
+// Vector iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// We need to be pedantic about reallocations for this testcase to be correct.
+// { dg-options "-D_GLIBCXX_DEBUG_PEDANTIC" }
+
+#ifndef _GLIBCXX_DEBUG_PEDANTIC
+#  define _GLIBCXX_DEBUG_PEDANTIC 1
+#endif
+
+#include <debug/vector>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::vector;
+
+bool test = true;
+
+// Resize
+void test02()
+{
+  vector<int> v(10, 17);
+  v.reserve(20);
+
+  vector<int>::iterator before = v.begin() + 6;
+  vector<int>::iterator at = before + 1;
+  vector<int>::iterator after = at + 1;
+
+  // Shrink
+  v.resize(7);
+  VERIFY(before._M_dereferenceable());
+  VERIFY(at._M_singular());
+  VERIFY(after._M_singular());
+
+  // Grow, without reallocation
+  before = v.begin() + 6;
+  v.resize(17);
+  VERIFY(before._M_dereferenceable());
+
+  // Grow, with reallocation
+  v.resize(42);
+  VERIFY(before._M_singular());
+}
+
+int main()
+{
+  test02();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/invalidation/3.cc b/libstdc++-v3/testsuite/23_containers/vector/invalidation/3.cc
new file mode 100644 (file)
index 0000000..656dd61
--- /dev/null
@@ -0,0 +1,90 @@
+// Vector iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// We need to be pedantic about reallocations for this testcase to be correct.
+// { dg-options "-D_GLIBCXX_DEBUG_PEDANTIC" }
+
+#ifndef _GLIBCXX_DEBUG_PEDANTIC
+#  define _GLIBCXX_DEBUG_PEDANTIC 1
+#endif
+
+#include <debug/vector>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::vector;
+
+bool test = true;
+
+// Insert
+void test03()
+{
+  vector<int> v(10, 17);
+  v.reserve(30);
+
+  // Insert a single element
+  vector<int>::iterator before = v.begin() + 6;
+  vector<int>::iterator at = before + 1;
+  vector<int>::iterator after = at;
+  at = v.insert(at, 42);
+  VERIFY(before._M_dereferenceable());
+  VERIFY(at._M_dereferenceable());
+  VERIFY(after._M_singular());
+
+  // Insert multiple copies
+  before = v.begin() + 6;
+  at = before + 1;
+  v.insert(at, 3, 42);
+  VERIFY(before._M_dereferenceable());
+  VERIFY(at._M_singular());
+
+  // Insert iterator range
+  static int data[] = { 2, 3, 5, 7 };
+  before = v.begin() + 6;
+  at = before + 1;
+  v.insert(at, &data[0], &data[0] + 4);
+  VERIFY(before._M_dereferenceable());
+  VERIFY(at._M_singular());
+
+  // Insert with reallocation
+  before = v.begin() + 6;
+  at = before + 1;
+  v.insert(at, 30, 17);
+  VERIFY(before._M_singular());
+  VERIFY(at._M_singular());
+
+  // Single insert with reallocation
+  vector<int> v2;
+  v2.reserve(100);
+  at = v2.begin();
+  v2.insert(at, 100, 17);
+  at = v2.end() - 1;
+  before = v2.begin();
+  VERIFY(at._M_dereferenceable());
+  VERIFY(before._M_dereferenceable());
+  at = v2.insert(at, 42);
+  VERIFY(at._M_dereferenceable());
+  VERIFY(before._M_singular());
+}
+
+int main()
+{
+  test03();
+  return !test;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/invalidation/4.cc b/libstdc++-v3/testsuite/23_containers/vector/invalidation/4.cc
new file mode 100644 (file)
index 0000000..1492d9c
--- /dev/null
@@ -0,0 +1,67 @@
+// Vector iterator invalidation tests
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// We need to be pedantic about reallocations for this testcase to be correct.
+// { dg-options "-D_GLIBCXX_DEBUG_PEDANTIC" }
+
+#ifndef _GLIBCXX_DEBUG_PEDANTIC
+#  define _GLIBCXX_DEBUG_PEDANTIC 1
+#endif
+
+#include <debug/vector>
+#include <testsuite_hooks.h>
+
+using __gnu_debug::vector;
+
+bool test = true;
+
+// Erase
+void test04()
+{
+  vector<int> v(20, 42);
+
+  // Single element erase
+  vector<int>::iterator before = v.begin();
+  vector<int>::iterator at = before + 3;
+  vector<int>::iterator after = at;
+  at = v.erase(at);
+  VERIFY(before._M_dereferenceable());
+  VERIFY(at._M_dereferenceable());
+  VERIFY(after._M_singular());
+
+  // Multiple element erase
+  before = v.begin();
+  at = before + 3;
+  v.erase(at, at + 3);
+  VERIFY(before._M_dereferenceable());
+  VERIFY(at._M_singular());
+
+  // clear()
+  before = v.begin();
+  VERIFY(before._M_dereferenceable());
+  v.clear();
+  VERIFY(before._M_singular());
+}
+
+int main()
+{
+  test04();
+  return !test;
+}
index a62a9a8..6d564f2 100644 (file)
@@ -95,13 +95,17 @@ test02()
 
     for (int i = 2; i <= N; ++i) {
         std::push_heap(s1, s1 + i, gt);
+#ifndef _GLIBCXX_DEBUG
         VERIFY(gt.count() <= logN);
+#endif
         gt.reset();
     }
 
     for (int i = N; i >= 2; --i) {
         std::pop_heap(s1, s1 + i, gt);
+#ifndef _GLIBCXX_DEBUG
         VERIFY(gt.count() <= 2 * logN);
+#endif
         gt.reset();
     }
 
@@ -113,11 +117,15 @@ test02()
     VERIFY(std::equal(s2, s2 + N, A));
 
     std::make_heap(s2, s2 + N, gt);
+#ifndef _GLIBCXX_DEBUG
     VERIFY(gt.count() <= 3 * N);
+#endif
     gt.reset();
 
     std::sort_heap(s2, s2 + N, gt);
+#ifndef _GLIBCXX_DEBUG
     VERIFY(gt.count() <= N * logN);
+#endif
 
     VERIFY(std::equal(s2, s2 + N, C));
 }