rope (rope(_CharT, const allocator_type&)): Fix to use _Data_allocate.
authorPaolo Carlini <pcarlini@suse.de>
Wed, 16 Jun 2004 17:29:16 +0000 (17:29 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Wed, 16 Jun 2004 17:29:16 +0000 (17:29 +0000)
2004-06-16  Paolo Carlini  <pcarlini@suse.de>

* include/ext/rope (rope(_CharT, const allocator_type&)): Fix
to use _Data_allocate.
* include/ext/ropeimpl.h (rope<>::_S_leaf_concat_char_iter): Likewise.
(rope<>::_S_substring): Likewise.
(rope<>::rope(size_t, _CharT, const allocator_type&)): Likewise.
(rope<>::c_str()): Likewise.
(rope<>::replace_with_c_str()): Likewise.

* include/ext/ropeimpl.h (_Rope_iterator_base<>::_S_setbuf):
Correctly qualify _S_leaf, _S_function, etc., with _Rope_constants::,
not _RopeRep.
(_Rope_iterator_base<>::_S_setcache): Likewise.
(_Rope_iterator_base<>::_S_setcache_for_incr): Likewise.
(rope<>::_S_substring): Likewise.
(rope<>::_S_dump): Likewise.
(rope<>::_S_fetch_ptr): Likewise.
(rope<>::_S_compare): Likewise.
(rope<>::replace_with_c_str()): Likewise.

* testsuite/ext/rope.cc: Rename to testsuite/ext/rope/1.cc.
* testsuite/ext/rope/2.cc: New.

2004-06-16  Paolo Carlini  <pcarlini@suse.de>
    Matt Austern  <austern@apple.com>

* testsuite/ext/rope/3.cc: New.

Co-Authored-By: Matt Austern <austern@apple.com>
From-SVN: r83251

libstdc++-v3/ChangeLog
libstdc++-v3/include/ext/rope
libstdc++-v3/include/ext/ropeimpl.h
libstdc++-v3/testsuite/ext/rope.cc [deleted file]
libstdc++-v3/testsuite/ext/rope/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/ext/rope/2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/ext/rope/3.cc [new file with mode: 0644]

index a6ad3faa1f2a976682339e0aaf461522c45de629..c7f87cc0b3ed0b0bc598c425245edca6ed1a386f 100644 (file)
@@ -1,3 +1,32 @@
+2004-06-16  Paolo Carlini  <pcarlini@suse.de>
+
+       * include/ext/rope (rope(_CharT, const allocator_type&)): Fix
+       to use _Data_allocate.
+       * include/ext/ropeimpl.h (rope<>::_S_leaf_concat_char_iter): Likewise.
+       (rope<>::_S_substring): Likewise.
+       (rope<>::rope(size_t, _CharT, const allocator_type&)): Likewise.
+       (rope<>::c_str()): Likewise.
+       (rope<>::replace_with_c_str()): Likewise.
+
+       * include/ext/ropeimpl.h (_Rope_iterator_base<>::_S_setbuf):
+       Correctly qualify _S_leaf, _S_function, etc., with _Rope_constants::,
+       not _RopeRep.
+       (_Rope_iterator_base<>::_S_setcache): Likewise.
+       (_Rope_iterator_base<>::_S_setcache_for_incr): Likewise.
+       (rope<>::_S_substring): Likewise.
+       (rope<>::_S_dump): Likewise.
+       (rope<>::_S_fetch_ptr): Likewise.
+       (rope<>::_S_compare): Likewise.
+       (rope<>::replace_with_c_str()): Likewise.               
+
+       * testsuite/ext/rope.cc: Rename to testsuite/ext/rope/1.cc.
+       * testsuite/ext/rope/2.cc: New.
+
+2004-06-16  Paolo Carlini  <pcarlini@suse.de>
+           Matt Austern  <austern@apple.com>
+
+       * testsuite/ext/rope/3.cc: New.
+
 2005-06-15  Paolo Bonzini  <bonzini@gnu.org>
 
        * acinclude.m4: Remove useless multilib configury.
index 142c40ed6db1693d39e0d77d9219652e907cf25e..95afd82e0b55900bf70b590c3df89a86d3c5c4ab 100644 (file)
@@ -1540,7 +1540,7 @@ class rope : public _Rope_base<_CharT,_Alloc> {
         rope(_CharT __c, const allocator_type& __a = allocator_type())
         : _Base(__a)
         {
-            _CharT* __buf = __a.allocate(_S_rounded_up_size(1));
+           _CharT* __buf = this->_Data_allocate(_S_rounded_up_size(1));
 
             std::_Construct(__buf, __c);
             try {
index f6160e44cef5f4b0390eda9139ca3d1a236c199f..5eba107bc9d800fa50a2bc1b22a92cd856fbc62a 100644 (file)
@@ -75,14 +75,14 @@ void _Rope_iterator_base<_CharT,_Alloc>::_S_setbuf(
     size_t __pos = __x._M_current_pos;
 
     switch(__leaf->_M_tag) {
-       case _RopeRep::_S_leaf:
+       case _Rope_constants::_S_leaf:
            __x._M_buf_start =
              ((_Rope_RopeLeaf<_CharT,_Alloc>*)__leaf)->_M_data;
            __x._M_buf_ptr = __x._M_buf_start + (__pos - __leaf_pos);
            __x._M_buf_end = __x._M_buf_start + __leaf->_M_size;
            break;
-       case _RopeRep::_S_function:
-       case _RopeRep::_S_substringfn:
+       case _Rope_constants::_S_function:
+       case _Rope_constants::_S_substringfn:
            {
                size_t __len = _S_iterator_buf_len;
                size_t __buf_start_pos = __leaf_pos;
@@ -142,12 +142,12 @@ void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache
        ++__curr_depth;
        __path[__curr_depth] = __curr_rope;
        switch(__curr_rope->_M_tag) {
-         case _RopeRep::_S_leaf:
-         case _RopeRep::_S_function:
-         case _RopeRep::_S_substringfn:
+         case _Rope_constants::_S_leaf:
+         case _Rope_constants::_S_function:
+         case _Rope_constants::_S_substringfn:
            __x._M_leaf_pos = __curr_start_pos;
            goto done;
-         case _RopeRep::_S_concat:
+         case _Rope_constants::_S_concat:
            {
                _Rope_RopeConcatenation<_CharT,_Alloc>* __c =
                        (_Rope_RopeConcatenation<_CharT,_Alloc>*)__curr_rope;
@@ -225,7 +225,7 @@ void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache_for_incr
     __current_node = __c->_M_right;
     __x._M_path_end[++__current_index] = __current_node;
     __dirns |= 1;
-    while (_RopeRep::_S_concat == __current_node->_M_tag) {
+    while (_Rope_constants::_S_concat == __current_node->_M_tag) {
        ++__current_index;
        if (_S_path_cache_len == __current_index) {
            int __i;
@@ -322,7 +322,7 @@ inline void _Rope_RopeRep<_CharT,_Alloc>::_M_free_c_string()
     if (0 != __cstr) {
        size_t __size = this->_M_size + 1;
        _Destroy(__cstr, __cstr + __size);
-       _Data_deallocate(__cstr, __size);
+       this->_Data_deallocate(__cstr, __size);
     }
 }
 
@@ -406,7 +406,7 @@ rope<_CharT,_Alloc>::_S_leaf_concat_char_iter
 {
     size_t __old_len = __r->_M_size;
     _CharT* __new_data = (_CharT*)
-       __r->get_allocator().allocate(_S_rounded_up_size(__old_len + __len));
+      _Data_allocate(_S_rounded_up_size(__old_len + __len));
     _RopeLeaf* __result;
 
     uninitialized_copy_n(__r->_M_data, __old_len, __new_data);
@@ -679,7 +679,7 @@ rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base,
        __adj_endp1 = __endp1;
     }
     switch(__base->_M_tag) {
-       case _RopeRep::_S_concat:
+       case _Rope_constants::_S_concat:
            {
                _RopeConcatenation* __c = (_RopeConcatenation*)__base;
                _RopeRep* __left = __c->_M_left;
@@ -700,7 +700,7 @@ rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base,
                __result = _S_concat(__left_result, __right_result);
                return __result;
            }
-       case _RopeRep::_S_leaf:
+       case _Rope_constants::_S_leaf:
            {
                _RopeLeaf* __l = (_RopeLeaf*)__base;
                _RopeLeaf* __result;
@@ -721,7 +721,7 @@ rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base,
 #               endif
                return __result;
            }
-       case _RopeRep::_S_substringfn:
+       case _Rope_constants::_S_substringfn:
            // Avoid introducing multiple layers of substring nodes.
            {
                _RopeSubstring* __old = (_RopeSubstring*)__base;
@@ -738,7 +738,7 @@ rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base,
 
                } // *** else fall through: ***
            }
-       case _RopeRep::_S_function:
+       case _Rope_constants::_S_function:
            {
                _RopeFunction* __f = (_RopeFunction*)__base;
                _CharT* __section;
@@ -748,7 +748,7 @@ rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base,
 
                if (__result_len > __lazy_threshold) goto lazy;
                __section = (_CharT*)
-               __base->get_allocator().allocate(_S_rounded_up_size(__result_len));
+                 _Data_allocate(_S_rounded_up_size(__result_len));
                try {
                  (*(__f->_M_fn))(__start, __result_len, __section);
                 }
@@ -1010,7 +1010,7 @@ rope<_CharT,_Alloc>::_S_dump(_RopeRep* __r, int __indent)
     if (0 == __r) {
        printf("NULL\n"); return;
     }
-    if (_RopeRep::_S_concat == __r->_M_tag) {
+    if (_Rope_constants::_S_concat == __r->_M_tag) {
        _RopeConcatenation* __c = (_RopeConcatenation*)__r;
        _RopeRep* __left = __c->_M_left;
        _RopeRep* __right = __c->_M_right;
@@ -1031,13 +1031,13 @@ rope<_CharT,_Alloc>::_S_dump(_RopeRep* __r, int __indent)
        char* __kind;
 
        switch (__r->_M_tag) {
-           case _RopeRep::_S_leaf:
+           case _Rope_constants::_S_leaf:
                __kind = "Leaf";
                break;
-           case _RopeRep::_S_function:
+           case _Rope_constants::_S_function:
                __kind = "Function";
                break;
-           case _RopeRep::_S_substringfn:
+           case _Rope_constants::_S_substringfn:
                __kind = "Function representing substring";
                break;
            default:
@@ -1241,7 +1241,7 @@ rope<_CharT,_Alloc>::_S_fetch_ptr(_RopeRep* __r, size_type __i)
     for(;;) {
       if (__r->_M_ref_count > 1) return 0;
       switch(__r->_M_tag) {
-       case _RopeRep::_S_concat:
+        case _Rope_constants::_S_concat:
            {
                _RopeConcatenation* __c = (_RopeConcatenation*)__r;
                _RopeRep* __left = __c->_M_left;
@@ -1256,7 +1256,7 @@ rope<_CharT,_Alloc>::_S_fetch_ptr(_RopeRep* __r, size_type __i)
                }
            }
            break;
-       case _RopeRep::_S_leaf:
+       case _Rope_constants::_S_leaf:
            {
                _RopeLeaf* __l = (_RopeLeaf*)__r;
                if (__l->_M_c_string != __l->_M_data && __l->_M_c_string != 0)
@@ -1269,8 +1269,8 @@ rope<_CharT,_Alloc>::_S_fetch_ptr(_RopeRep* __r, size_type __i)
                }
                return __l->_M_data + __i;
            }
-       case _RopeRep::_S_function:
-       case _RopeRep::_S_substringfn:
+       case _Rope_constants::_S_function:
+       case _Rope_constants::_S_substringfn:
            return 0;
       }
     }
@@ -1293,7 +1293,7 @@ rope<_CharT,_Alloc>::_S_compare (const _RopeRep* __left,
     if (0 == __left) return -1;
     __left_len = __left->_M_size;
     __right_len = __right->_M_size;
-    if (_RopeRep::_S_leaf == __left->_M_tag) {
+    if (_Rope_constants::_S_leaf == __left->_M_tag) {
        _RopeLeaf* __l = (_RopeLeaf*) __left;
        if (_RopeRep::_S_leaf == __right->_M_tag) {
            _RopeLeaf* __r = (_RopeLeaf*) __right;
@@ -1310,7 +1310,7 @@ rope<_CharT,_Alloc>::_S_compare (const _RopeRep* __left,
     } else {
        const_iterator __lstart(__left, 0);
        const_iterator __lend(__left, __left_len);
-       if (_RopeRep::_S_leaf == __right->_M_tag) {
+       if (_Rope_constants::_S_leaf == __right->_M_tag) {
            _RopeLeaf* __r = (_RopeLeaf*) __right;
            return lexicographical_compare_3way(
                                   __lstart, __lend,
@@ -1391,7 +1391,7 @@ rope<_CharT, _Alloc>::rope(size_t __n, _CharT __c,
     if (0 == __rest) {
        __remainder = 0;
     } else {
-       __rest_buffer = __a.allocate(_S_rounded_up_size(__rest));
+        __rest_buffer = this->_Data_allocate(_S_rounded_up_size(__rest));
        uninitialized_fill_n(__rest_buffer, __rest, __c);
        _S_cond_store_eos(__rest_buffer[__rest]);
        try {
@@ -1406,7 +1406,7 @@ rope<_CharT, _Alloc>::rope(size_t __n, _CharT __c,
     __remainder_rope._M_tree_ptr = __remainder;
     if (__exponent != 0) {
        _CharT* __base_buffer =
-         __a.allocate(_S_rounded_up_size(__exponentiate_threshold));
+         this->_Data_allocate(_S_rounded_up_size(__exponentiate_threshold));
        _RopeLeaf* __base_leaf;
        rope __base_rope;
        uninitialized_fill_n(__base_buffer, __exponentiate_threshold, __c);
@@ -1453,7 +1453,7 @@ const _CharT* rope<_CharT,_Alloc>::c_str() const {
     if (0 == __result)
       {
        size_t __s = size();
-       __result = this->get_allocator().allocate(__s + 1);
+       __result = this->_Data_allocate(__s + 1);
        _S_flatten(this->_M_tree_ptr, __result);
        __result[__s] = _S_eos((_CharT*)0);
        this->_M_tree_ptr->_M_c_string = __result;
@@ -1469,12 +1469,12 @@ const _CharT* rope<_CharT,_Alloc>::replace_with_c_str() {
         return _S_empty_c_str;
     }
     __GC_CONST _CharT* __old_c_string = this->_M_tree_ptr->_M_c_string;
-    if (_RopeRep::_S_leaf == this->_M_tree_ptr->_M_tag
+    if (_Rope_constants::_S_leaf == this->_M_tree_ptr->_M_tag
        && 0 != __old_c_string) {
        return(__old_c_string);
     }
     size_t __s = size();
-    _CharT* __result = get_allocator().allocate(_S_rounded_up_size(__s));
+    _CharT* __result = this->_Data_allocate(_S_rounded_up_size(__s));
     _S_flatten(this->_M_tree_ptr, __result);
     __result[__s] = _S_eos((_CharT*)0);
     this->_M_tree_ptr->_M_unref_nonnil();
diff --git a/libstdc++-v3/testsuite/ext/rope.cc b/libstdc++-v3/testsuite/ext/rope.cc
deleted file mode 100644 (file)
index b79e5e9..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-// 2001-10-03 From: Dimitris Vyzovitis <vyzo@media.mit.edu>
-
-// Copyright (C) 2001, 2004 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING.  If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-// USA.
-
-// rope (SGI extension)
-
-#include <ext/rope>
-#include <iostream>
-
-void test01()
-{
-  __gnu_cxx::crope foo;
-  foo += "bar";
-  const char* data = foo.c_str();
-  std::cout << data << std::endl;
-}
-
-#if !__GXX_WEAK__ && _MT_ALLOCATOR_H
-// Explicitly instantiate for systems with no COMDAT or weak support.
-template class __gnu_cxx::__mt_alloc<__gnu_cxx::_Rope_RopeLeaf<char, std::allocator<char> > >;
-template class __gnu_cxx::__mt_alloc<__gnu_cxx::_Rope_RopeFunction<char, std::allocator<char> > >;
-template class __gnu_cxx::__mt_alloc<__gnu_cxx::_Rope_RopeSubstring<char, std::allocator<char> > >;
-template class __gnu_cxx::__mt_alloc<__gnu_cxx::_Rope_RopeConcatenation<char, std::allocator<char> > >;
-#endif
-
-int main()
-{
-  test01();
-  return 0;
-}
diff --git a/libstdc++-v3/testsuite/ext/rope/1.cc b/libstdc++-v3/testsuite/ext/rope/1.cc
new file mode 100644 (file)
index 0000000..b79e5e9
--- /dev/null
@@ -0,0 +1,46 @@
+// 2001-10-03 From: Dimitris Vyzovitis <vyzo@media.mit.edu>
+
+// Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// rope (SGI extension)
+
+#include <ext/rope>
+#include <iostream>
+
+void test01()
+{
+  __gnu_cxx::crope foo;
+  foo += "bar";
+  const char* data = foo.c_str();
+  std::cout << data << std::endl;
+}
+
+#if !__GXX_WEAK__ && _MT_ALLOCATOR_H
+// Explicitly instantiate for systems with no COMDAT or weak support.
+template class __gnu_cxx::__mt_alloc<__gnu_cxx::_Rope_RopeLeaf<char, std::allocator<char> > >;
+template class __gnu_cxx::__mt_alloc<__gnu_cxx::_Rope_RopeFunction<char, std::allocator<char> > >;
+template class __gnu_cxx::__mt_alloc<__gnu_cxx::_Rope_RopeSubstring<char, std::allocator<char> > >;
+template class __gnu_cxx::__mt_alloc<__gnu_cxx::_Rope_RopeConcatenation<char, std::allocator<char> > >;
+#endif
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/rope/2.cc b/libstdc++-v3/testsuite/ext/rope/2.cc
new file mode 100644 (file)
index 0000000..db8519f
--- /dev/null
@@ -0,0 +1,58 @@
+// Copyright (C) 2004 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// rope (SGI extension)
+
+#include <ext/rope>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  using namespace std;
+  using namespace __gnu_cxx;
+  bool test __attribute__((unused)) = true;
+
+  crope r(10000, 'x');
+  crope r2 = r + "abc" + r;
+  crope r3 = r2.substr(10000, 3); 
+  crope r4 = r2.substr(10000, 10000); 
+
+  reverse(r2.mutable_begin(), r2.mutable_end());
+  VERIFY( r2[10000] == 'c' );
+
+  crope r5('a');
+  r5.push_front('b');
+  VERIFY( r5[0] == 'b' );
+  VERIFY( r5[1] == 'a' );
+}
+
+#if !__GXX_WEAK__ && _MT_ALLOCATOR_H
+// Explicitly instantiate for systems with no COMDAT or weak support.
+template class __gnu_cxx::__mt_alloc<__gnu_cxx::_Rope_RopeLeaf<char, std::allocator<char> > >;
+template class __gnu_cxx::__mt_alloc<__gnu_cxx::_Rope_RopeFunction<char, std::allocator<char> > >;
+template class __gnu_cxx::__mt_alloc<__gnu_cxx::_Rope_RopeSubstring<char, std::allocator<char> > >;
+template class __gnu_cxx::__mt_alloc<__gnu_cxx::_Rope_RopeConcatenation<char, std::allocator<char> > >;
+#endif
+
+int main()
+{
+  test01();
+  return 0;
+}
+
diff --git a/libstdc++-v3/testsuite/ext/rope/3.cc b/libstdc++-v3/testsuite/ext/rope/3.cc
new file mode 100644 (file)
index 0000000..eec77d1
--- /dev/null
@@ -0,0 +1,108 @@
+// Copyright (C) 2004 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// rope (SGI extension)
+
+#include <ext/rope>
+#include <testsuite_hooks.h>
+
+const char base[] =
+"Happy families are all alike; every unhappy family is unhappy in   \
+its own way.                                                       \
+                                                                   \
+Everything was in confusion in the Oblonskys' house.  The wife     \
+had discovered that the husband was carrying on an intrigue with    \
+a French girl, who had been a governess in their family, and she    \
+had announced to her husband that she could not go on living in            \
+the same house with him.  This position of affairs had now lasted   \
+three days, and not only the husband and wife themselves, but all   \
+the members of their family and household, were painfully          \
+conscious of it.  Every person in the house felt that there was            \
+so sense in their living together, and that the stray people       \
+brought together by chance in any inn had more in common with one   \
+another than they, the members of the family and household of the   \
+Oblonskys.  The wife did not leave her own room, the husband had    \
+not been at home for three days.  The children ran wild all over    \
+the house; the English governess quarreled with the housekeeper,    \
+and wrote to a friend asking her to look out for a new situation    \
+for her; the man-cook had walked off the day before just at        \
+dinner time; the kitchen-maid, and the coachman had given          \
+warning."                                                      
+  ;
+
+int baselen = sizeof(base) - 1;
+
+template<class StringType>
+StringType
+multiply(const StringType& s, int n)
+{
+  StringType result;
+  while (n > 0)
+    {
+      result += s;
+      --n;
+    }
+  return result;
+}
+
+template <class StringType>
+StringType
+mung_substrings(const StringType& s, int len, int n, int skip)
+{
+  StringType result;
+  int start = 0;
+  while (n > 0)
+    {
+      StringType tmp = s.substr (start, len);
+      result += tmp;
+      --n;
+      start += skip;
+    }
+  return result;
+}
+
+void 
+test01()
+{
+  using namespace __gnu_cxx;
+  bool test __attribute__((unused)) = true;
+
+  crope r;
+  r = multiply(crope(base), 100000);
+
+  crope r1;
+  r1 = mung_substrings(r, 100000, 500, 73);
+
+  VERIFY( r1.size() == 50000000 );
+  VERIFY( r1.substr(88888, 6)[0] == 's' );
+  VERIFY( r1.substr(88888, 6)[2] == 'h' );
+}
+
+#if !__GXX_WEAK__ && _MT_ALLOCATOR_H
+// Explicitly instantiate for systems with no COMDAT or weak support.
+template class __gnu_cxx::__mt_alloc<__gnu_cxx::_Rope_RopeLeaf<char, std::allocator<char> > >;
+template class __gnu_cxx::__mt_alloc<__gnu_cxx::_Rope_RopeFunction<char, std::allocator<char> > >;
+template class __gnu_cxx::__mt_alloc<__gnu_cxx::_Rope_RopeSubstring<char, std::allocator<char> > >;
+template class __gnu_cxx::__mt_alloc<__gnu_cxx::_Rope_RopeConcatenation<char, std::allocator<char> > >;
+#endif
+
+int main()
+{
+  test01();
+  return 0;
+}