Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

MNRope.h

Go to the documentation of this file.
00001 /* 00002 * Copyright (c) 1997 00003 * Silicon Graphics Computer Systems, Inc. 00004 * 00005 * Permission to use, copy, modify, distribute and sell this software 00006 * and its documentation for any purpose is hereby granted without fee, 00007 * provided that the above copyright notice appear in all copies and 00008 * that both that copyright notice and this permission notice appear 00009 * in supporting documentation. Silicon Graphics makes no 00010 * representations about the suitability of this software for any 00011 * purpose. It is provided "as is" without express or implied warranty. 00012 * 00013 * Heavily modified by KOM/Darmstadt University of Technology, 2000 00014 */ 00015 00016 #ifndef ROPE_H 00017 #define ROPE_H 00018 00019 #include <config.h> 00020 00021 #define ITERATORS 00022 00023 #include <sys/types.h> 00024 #include <assert.h> 00025 #include <stdlib.h> 00026 #include "mnstream.h" 00027 00032 // The _S_eos function is used for those functions that 00033 // convert to/from C-like strings to detect the end of the string. 00034 00035 // The end-of-C-string character. 00036 // This is what the draft standard says it should be. 00037 inline uchar_t _S_eos(uchar_t*) { return 0; } 00038 00039 // Store an eos iff _CharT is a basic character type. 00040 // Do not reference _S_eos if it isn't. 00041 inline void _S_cond_store_eos(uchar_t& __c) { __c = 0; } 00042 00043 #include "MNRopeCharProducer.h" 00044 #include "MNRopeCharConsumer.h" 00045 00046 // First a lot of forward declarations. The standard seems to require 00047 // much stricter "declaration before use" than many of the implementations 00048 // that preceded it. 00049 #include "MNSelfDestrPtr.h" 00050 #include "MNRopeLeaf.h" 00051 #include "MNRopeFunction.h" 00052 #include "MNRopeSubstring.h" 00053 #include "MNRopeConcat.h" 00054 00055 #ifdef ITERATORS 00056 #include "MNRopeIterator.h" 00057 #include "MNRopeConstIterator.h" 00058 #endif /* ITERATORS */ 00059 00060 #include "MNPtrProxy.h" 00061 #include "MNRefProxy.h" 00062 00063 MNRope operator+ (const MNRope& __left, const MNRope& __right); 00064 00065 MNRope operator+ (const MNRope& __left, const uchar_t* __right); 00066 00067 MNRope operator+ (const MNRope& __left, uchar_t __right); 00068 00069 #ifdef USE_STL_POWER 00070 // Two helpers, so we can use power on ropes. 00071 // See below for why this isn't local to the implementation. 00072 00073 // This uses a nonstandard refcount convention. 00074 // The result has refcount 0. 00075 struct _Rope_Concat_fn 00076 : public binary_function<rope, rope, rope > 00077 { 00078 rope operator() (const rope& __x, const rope& __y) 00079 { 00080 return __x + __y; 00081 } 00082 }; 00083 00084 inline rope identity_element(_Rope_Concat_fn) 00085 { 00086 return rope(); 00087 } 00088 #endif /* USE_STL_POWER */ 00089 00090 00091 // 00092 // What follows should really be local to rope. Unfortunately, 00093 // that doesn't work, since it makes it impossible to define generic 00094 // equality on rope Iterators. According to the draft standard, the 00095 // template parameters for such an equality operator cannot be inferred 00096 // from the occurence of a member class as a parameter. 00097 // (SGI compilers in fact allow this, but the __result wouldn't be 00098 // portable.) 00099 // Similarly, some of the static member functions are member functions 00100 // only to avoid polluting the global namespace, and to circumvent 00101 // restrictions on type inference for template functions. 00102 // 00103 00104 00105 00112 class MNRope 00113 { 00114 MNRopeRep *_M_tree_ptr; 00115 00116 public: 00117 typedef uchar_t value_type; 00118 typedef ptrdiff_t difference_type; 00119 typedef uchar_t const_reference; 00120 typedef const uchar_t* const_pointer; 00121 typedef MNRefProxy reference; 00122 typedef MNPtrProxy pointer; 00123 00124 friend struct MNRopeRep; 00125 friend class MNPtrProxy; 00126 friend class MNRefProxy; 00127 friend struct MNRopeSubstring; 00128 friend class MNRopeIterator; 00129 friend class MNRopeConstIterator; 00130 friend class MNRopeIteratorBase; 00131 00132 00133 protected: 00134 typedef uchar_t* _Cstrptr; 00135 00136 static uchar_t _S_empty_c_str[1]; 00137 00138 static bool _S_is0(uchar_t __c) { return __c == _S_eos((uchar_t*)0); } 00139 00143 enum { _S_copy_max = 23 }; 00144 00146 static uchar_t _S_fetch(MNRopeRep* __r, size_t __pos); 00147 00155 static uchar_t* _S_fetch_ptr(MNRopeRep* __r, size_t __pos); 00156 00157 static bool _S_apply_to_pieces( 00158 // should be template parameter 00159 MNRopeCharConsumer& __c, 00160 const MNRopeRep* __r, 00161 size_t __begin, size_t __end); 00162 // begin and end are assumed to be in range. 00163 00164 static void _S_unref(MNRopeRep* __t) 00165 { 00166 MNRopeRep::_S_unref(__t); 00167 } 00168 static void _S_ref(MNRopeRep* __t) 00169 { 00170 MNRopeRep::_S_ref(__t); 00171 } 00172 00173 00175 static MNRopeRep* _S_substring( MNRopeRep* __base, 00176 size_t __start, 00177 size_t __endp1 ); 00178 00183 static MNRopeRep* _S_concat_char_iter( MNRopeRep* __r, 00184 const uchar_t* __iter, 00185 size_t __slen ); 00186 00191 static MNRopeRep* _S_destr_concat_char_iter( MNRopeRep* __r, 00192 const uchar_t* __iter, 00193 size_t __slen ); 00194 00198 static MNRopeRep* _S_concat( MNRopeRep* __left, 00199 MNRopeRep* __right ); 00200 00201 public: 00202 void apply_to_pieces( size_t __begin, size_t __end, 00203 MNRopeCharConsumer& __c) const { 00204 _S_apply_to_pieces(__c, _M_tree_ptr, __begin, __end); 00205 } 00206 00207 00208 protected: 00209 00210 static size_t _S_rounded_up_size(size_t __n) { 00211 return MNRopeLeaf::_S_rounded_up_size(__n); 00212 } 00213 00214 static size_t _S_allocated_capacity(size_t __n) { 00215 return _S_rounded_up_size(__n) - 1; 00216 } 00217 00218 // Allocate and construct a RopeLeaf using the supplied allocator 00219 // Takes ownership of s instead of copying. 00220 static MNRopeLeaf* _S_newMNRopeLeaf( uchar_t *__s, 00221 size_t __size) 00222 { 00223 return new MNRopeLeaf(__s, __size); 00224 } 00225 00226 static MNRopeConcat* _S_newMNRopeConcat( 00227 MNRopeRep* __left, MNRopeRep* __right) 00228 { 00229 return new MNRopeConcat(__left, __right); 00230 } 00231 00232 static MNRopeFunction* _S_newMNRopeFunction(MNRopeCharProducer* __f, 00233 size_t __size, bool __d) 00234 { 00235 return new MNRopeFunction(__f, __size, __d); 00236 } 00237 00238 static MNRopeSubstring* _S_newMNRopeSubstring( 00239 MNRopeRep* __b, size_t __s, 00240 size_t __l) 00241 { 00242 return new MNRopeSubstring(__b, __s, __l); 00243 } 00244 00245 # define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size) \ 00246 _SMNRopeLeaf_from_unowned_char_ptr(__s, __size) 00247 00248 static 00249 MNRopeLeaf* _SMNRopeLeaf_from_unowned_char_ptr(const uchar_t *__s, 00250 size_t __size) 00251 { 00252 if (0 == __size) return 0; 00253 uchar_t* __buf = (uchar_t*)malloc(_S_rounded_up_size(__size)); 00254 00255 uninitialized_copy_n(__s, __size, __buf); 00256 _S_cond_store_eos(__buf[__size]); 00257 return _S_newMNRopeLeaf(__buf, __size); 00258 } 00259 00260 00268 static MNRopeRep* 00269 _S_tree_concat(MNRopeRep* __left, MNRopeRep* __right); 00270 00272 static MNRopeLeaf* 00273 _S_leaf_concat_char_iter(MNRopeLeaf* __r, 00274 const uchar_t* __iter, size_t __slen); 00275 00280 static MNRopeLeaf* _S_destr_leaf_concat_char_iter 00281 (MNRopeLeaf* __r, const uchar_t* __iter, size_t __slen); 00282 // A version that potentially clobbers __r if __r->_M_ref_count == 1. 00283 00284 private: 00285 00287 static size_t _S_char_ptr_len(const uchar_t* __s); 00288 00289 00294 static uchar_t* _S_flatten(MNRopeRep* __r, uchar_t* __buffer); 00295 00299 static uchar_t* _S_flatten(MNRopeRep* __r, 00300 size_t __start, size_t __len, 00301 uchar_t* __buffer); 00302 00303 static const unsigned long _S_min_len[MNRopeRep::_S_max_rope_depth + 1]; 00304 00305 static bool _S_is_balanced(MNRopeRep* __r) 00306 { return (__r->_M_size >= _S_min_len[__r->_M_depth]); } 00307 00308 static bool _S_is_almost_balanced(MNRopeRep* __r) 00309 { return (__r->_M_depth == 0 || 00310 __r->_M_size >= _S_min_len[__r->_M_depth - 1]); } 00311 00312 static bool _S_is_roughly_balanced(MNRopeRep* __r) 00313 { return (__r->_M_depth <= 1 || 00314 __r->_M_size >= _S_min_len[__r->_M_depth - 2]); } 00315 00317 static MNRopeRep* _S_concat_and_set_balanced(MNRopeRep* __left, 00318 MNRopeRep* __right) 00319 { 00320 MNRopeRep* __result = _S_concat(__left, __right); 00321 if (_S_is_balanced(__result)) __result->_M_is_balanced = true; 00322 return __result; 00323 } 00324 00331 static MNRopeRep* _S_balance(MNRopeRep* __r); 00332 00336 static void _S_add_to_forest(MNRopeRep*__r, MNRopeRep** __forest); 00337 00340 static void _S_add_leaf_to_forest(MNRopeRep* __r, MNRopeRep** __forest); 00341 00344 static void _S_dump(MNRopeRep* __r, int __indent = 0); 00345 00348 static int _S_compare(const MNRopeRep* __x, const MNRopeRep* __y); 00349 00350 public: 00351 bool empty() const 00352 { 00353 return 0 == _M_tree_ptr; 00354 } 00355 00360 int compare(const MNRope& __y) const 00361 { 00362 return _S_compare(_M_tree_ptr, __y._M_tree_ptr); 00363 } 00364 00365 MNRope(const uchar_t* __s) 00366 { 00367 _M_tree_ptr = 00368 __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, _S_char_ptr_len(__s)); 00369 } 00370 00371 MNRope(const uchar_t* __s, size_t __len) 00372 { 00373 _M_tree_ptr = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __len); 00374 } 00375 00380 MNRope(const uchar_t *__s, const uchar_t *__e) 00381 { 00382 _M_tree_ptr = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __e - __s); 00383 } 00384 00385 MNRope(uchar_t __c) 00386 { 00387 assert( _S_rounded_up_size(1) >= 2 ); 00388 00389 uchar_t* __buf = (uchar_t*)malloc(_S_rounded_up_size(1)); 00390 __buf[0] = __c; 00391 __buf[1] = 0; 00392 00393 _M_tree_ptr = _S_newMNRopeLeaf(__buf, 1); 00394 } 00395 00396 MNRope(size_t __n, uchar_t __c); 00397 00398 MNRope() 00399 { 00400 _M_tree_ptr = NULL; 00401 } 00402 00404 MNRope(MNRopeCharProducer *__fn, size_t __len, bool __delete_fn) 00405 { 00406 _M_tree_ptr = (0 == __len) 00407 ? 0 : _S_newMNRopeFunction(__fn, __len, __delete_fn); 00408 } 00409 00410 MNRope(const MNRope& __x) 00411 { 00412 _M_tree_ptr = __x._M_tree_ptr; 00413 _S_ref(_M_tree_ptr); 00414 } 00415 00419 MNRope(MNRopeRep* __t) 00420 { 00421 _M_tree_ptr = __t; 00422 } 00423 00424 ~MNRope() 00425 { 00426 _S_unref(_M_tree_ptr); 00427 } 00428 00429 MNRope& operator=(const MNRope& __x) 00430 { 00431 MNRopeRep* __old = _M_tree_ptr; 00432 _M_tree_ptr = __x._M_tree_ptr; 00433 _S_ref(_M_tree_ptr); 00434 _S_unref(__old); 00435 return(*this); 00436 } 00437 00438 void clear() 00439 { 00440 _S_unref(_M_tree_ptr); 00441 _M_tree_ptr = 0; 00442 } 00443 00444 void push_back(uchar_t __x) 00445 { 00446 MNRopeRep* __old = _M_tree_ptr; 00447 _M_tree_ptr = _S_destr_concat_char_iter(_M_tree_ptr, &__x, 1); 00448 _S_unref(__old); 00449 } 00450 00451 void pop_back() 00452 { 00453 MNRopeRep* __old = _M_tree_ptr; 00454 _M_tree_ptr = 00455 _S_substring(_M_tree_ptr, 0, _M_tree_ptr->_M_size - 1); 00456 _S_unref(__old); 00457 } 00458 00459 uchar_t back() const 00460 { 00461 return _S_fetch(_M_tree_ptr, _M_tree_ptr->_M_size - 1); 00462 } 00463 00464 void push_front(uchar_t __x) 00465 { 00466 MNRopeRep* __old = _M_tree_ptr; 00467 MNRopeRep* __left = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(&__x, 1); 00468 _M_tree_ptr = _S_concat(__left, _M_tree_ptr); 00469 _S_unref(__old); 00470 _S_unref(__left); 00471 } 00472 00473 void pop_front() 00474 { 00475 MNRopeRep* __old = _M_tree_ptr; 00476 _M_tree_ptr = _S_substring(_M_tree_ptr, 1, _M_tree_ptr->_M_size); 00477 _S_unref(__old); 00478 } 00479 00480 uchar_t front() const 00481 { 00482 return _S_fetch(_M_tree_ptr, 0); 00483 } 00484 00485 void balance() 00486 { 00487 MNRopeRep* __old = _M_tree_ptr; 00488 _M_tree_ptr = _S_balance(_M_tree_ptr); 00489 _S_unref(__old); 00490 } 00491 00492 void copy(uchar_t* __buffer) const { 00493 destroy(__buffer, __buffer + size()); 00494 _S_flatten(_M_tree_ptr, __buffer); 00495 } 00496 00516 size_t copy(size_t __pos, size_t __n, uchar_t* __buffer) const 00517 { 00518 size_t __size = size(); 00519 size_t __len = (__pos + __n > __size? __size - __pos : __n); 00520 00521 destroy(__buffer, __buffer + __len); 00522 _S_flatten(_M_tree_ptr, __pos, __len, __buffer); 00523 return __len; 00524 } 00525 00529 void dump() { 00530 _S_dump(_M_tree_ptr); 00531 } 00532 00536 const uchar_t* c_str() const; 00537 00541 const uchar_t* replace_with_c_str(); 00542 00547 void delete_c_str () { 00548 if (0 == _M_tree_ptr) return; 00549 if (MNRopeRep::_S_leaf == _M_tree_ptr->_M_tag && 00550 ((MNRopeLeaf*)_M_tree_ptr)->_M_data == 00551 _M_tree_ptr->_M_c_string) { 00552 // Representation shared 00553 return; 00554 } 00555 _M_tree_ptr->_M_free_c_string(); 00556 _M_tree_ptr->_M_c_string = 0; 00557 } 00558 00559 uchar_t operator[] (size_t __pos) const { 00560 return _S_fetch(_M_tree_ptr, __pos); 00561 } 00562 00563 uchar_t at(size_t __pos) const { 00564 // if (__pos >= size()) throw out_of_range; // XXX 00565 return (*this)[__pos]; 00566 } 00567 00570 size_t size() const { 00571 return(0 == _M_tree_ptr? 0 : _M_tree_ptr->_M_size); 00572 } 00573 00576 size_t length() const { 00577 return size(); 00578 } 00579 00580 size_t max_size() const { 00581 return _S_min_len[MNRopeRep::_S_max_rope_depth-1] - 1; 00582 // Guarantees that the result can be sufficirntly 00583 // balanced. Longer ropes will probably still work, 00584 // but it's harder to make guarantees. 00585 } 00586 00596 friend MNRope 00597 operator+ (const MNRope& __left, 00598 const MNRope& __right); 00599 00600 friend MNRope 00601 operator+ (const MNRope& __left, 00602 const uchar_t* __right); 00603 00604 friend MNRope 00605 operator+ (const MNRope& __left, uchar_t __right); 00606 00607 MNRope& append(const uchar_t* __iter, size_t __n) { 00608 MNRopeRep* __result = 00609 _S_destr_concat_char_iter(_M_tree_ptr, __iter, __n); 00610 _S_unref(_M_tree_ptr); 00611 _M_tree_ptr = __result; 00612 return *this; 00613 } 00614 00615 MNRope& append(const uchar_t* __c_string) { 00616 size_t __len = _S_char_ptr_len(__c_string); 00617 append(__c_string, __len); 00618 return(*this); 00619 } 00620 00621 MNRope& append(const uchar_t* __s, const uchar_t* __e) { 00622 MNRopeRep* __result = 00623 _S_destr_concat_char_iter(_M_tree_ptr, __s, __e - __s); 00624 _S_unref(_M_tree_ptr); 00625 _M_tree_ptr = __result; 00626 return *this; 00627 } 00628 00629 MNRope& append(uchar_t __c) { 00630 MNRopeRep* __result = 00631 _S_destr_concat_char_iter(_M_tree_ptr, &__c, 1); 00632 _S_unref(_M_tree_ptr); 00633 _M_tree_ptr = __result; 00634 return *this; 00635 } 00636 00637 MNRope& append() { return append((uchar_t)0); } // XXX why? 00638 00639 MNRope& append(const MNRope& __y) { 00640 MNRopeRep* __result = _S_concat(_M_tree_ptr, __y._M_tree_ptr); 00641 _S_unref(_M_tree_ptr); 00642 _M_tree_ptr = __result; 00643 return *this; 00644 } 00645 00646 MNRope& append(size_t __n, uchar_t __c) { 00647 MNRope __last(__n, __c); 00648 return append(__last); 00649 } 00650 00651 void swap(MNRope& __b) { 00652 MNRopeRep* __tmp = _M_tree_ptr; 00653 _M_tree_ptr = __b._M_tree_ptr; 00654 __b._M_tree_ptr = __tmp; 00655 } 00656 00657 00658 protected: 00660 static MNRopeRep* replace(MNRopeRep* __old, size_t __pos1, 00661 size_t __pos2, MNRopeRep* __r) { 00662 if (0 == __old) { _S_ref(__r); return __r; } 00663 MNSelfDestrPtr __left( 00664 _S_substring(__old, 0, __pos1)); 00665 MNSelfDestrPtr __right( 00666 _S_substring(__old, __pos2, __old->_M_size)); 00667 MNRopeRep* __result; 00668 00669 if (0 == __r) { 00670 __result = _S_concat(__left, __right); 00671 } else { 00672 MNSelfDestrPtr __left_result(_S_concat(__left, __r)); 00673 __result = _S_concat(__left_result, __right); 00674 } 00675 return __result; 00676 } 00677 00678 public: 00679 void insert(size_t __p, const MNRope& __r) { 00680 MNRopeRep* __result = 00681 replace(_M_tree_ptr, __p, __p, __r._M_tree_ptr); 00682 _S_unref(_M_tree_ptr); 00683 _M_tree_ptr = __result; 00684 } 00685 00686 void insert(size_t __p, size_t __n, uchar_t __c) { 00687 MNRope __r(__n,__c); 00688 insert(__p, __r); 00689 } 00690 00691 void insert(size_t __p, const uchar_t* __i, size_t __n) { 00692 MNSelfDestrPtr __left(_S_substring(_M_tree_ptr, 0, __p)); 00693 MNSelfDestrPtr __right(_S_substring(_M_tree_ptr, __p, size())); 00694 MNSelfDestrPtr __left_result( 00695 _S_concat_char_iter(__left, __i, __n)); 00696 // _S_ destr_concat_char_iter should be safe here. 00697 // But as it stands it's probably not a win, since __left 00698 // is likely to have additional references. 00699 MNRopeRep* __result = _S_concat(__left_result, __right); 00700 _S_unref(_M_tree_ptr); 00701 _M_tree_ptr = __result; 00702 } 00703 00704 void insert(size_t __p, const uchar_t* __c_string) { 00705 insert(__p, __c_string, _S_char_ptr_len(__c_string)); 00706 } 00707 00708 void insert(size_t __p, uchar_t __c) { 00709 insert(__p, &__c, 1); 00710 } 00711 00712 void insert(size_t __p) { 00713 uchar_t __c = (uchar_t)0; 00714 insert(__p, &__c, 1); 00715 } 00716 00717 void insert(size_t __p, const uchar_t* __i, const uchar_t* __j) { 00718 MNRope __r(__i, __j); 00719 insert(__p, __r); 00720 } 00721 00723 00724 void replace(size_t __p, size_t __n, const MNRope& __r) { 00725 MNRopeRep* __result = 00726 replace(_M_tree_ptr, __p, __p + __n, __r._M_tree_ptr); 00727 _S_unref(_M_tree_ptr); 00728 _M_tree_ptr = __result; 00729 } 00730 00731 void replace(size_t __p, size_t __n, 00732 const uchar_t* __i, size_t __i_len) { 00733 MNRope __r(__i, __i_len); 00734 replace(__p, __n, __r); 00735 } 00736 00737 void replace(size_t __p, size_t __n, uchar_t __c) { 00738 MNRope __r(__c); 00739 replace(__p, __n, __r); 00740 } 00741 00742 void replace(size_t __p, size_t __n, const uchar_t* __c_string) { 00743 MNRope __r(__c_string); 00744 replace(__p, __n, __r); 00745 } 00746 00747 void replace(size_t __p, size_t __n, 00748 const uchar_t* __i, const uchar_t* __j) { 00749 MNRope __r(__i, __j); 00750 replace(__p, __n, __r); 00751 } 00753 00755 00756 void replace(size_t __p, const MNRope& __r) { 00757 replace(__p, 1, __r); 00758 } 00759 00760 void replace(size_t __p, const uchar_t* __i, size_t __i_len) { 00761 replace(__p, 1, __i, __i_len); 00762 } 00763 00764 void replace(size_t __p, const uchar_t* __c_string) { 00765 replace(__p, 1, __c_string); 00766 } 00767 00768 void replace(size_t __p, const uchar_t* __i, const uchar_t* __j) { 00769 replace(__p, 1, __i, __j); 00770 } 00772 00774 void erase(size_t __p, size_t __n) { 00775 MNRopeRep* __result = replace(_M_tree_ptr, __p, __p + __n, 0); 00776 _S_unref(_M_tree_ptr); 00777 _M_tree_ptr = __result; 00778 } 00779 00781 void erase(size_t __p) { 00782 erase(__p, __p + 1); 00783 } 00784 00785 MNRope substr(size_t __start, size_t __len = 1) const { 00786 return MNRope( 00787 _S_substring(_M_tree_ptr, __start, __start + __len)); 00788 } 00789 00790 static const size_t npos; 00791 00792 size_t find(uchar_t __c, size_t __pos = 0) const; 00793 00794 reference mutable_reference_at(size_t __pos) 00795 { 00796 return reference(this, __pos); 00797 } 00798 00799 #ifdef __STD_STUFF 00800 reference operator[] (size_t __pos) 00801 { 00802 return _char_ref_proxy(this, __pos); 00803 } 00804 00805 reference at(size_t __pos) 00806 { 00807 // if (__pos >= size()) throw out_of_range; // XXX 00808 return (*this)[__pos]; 00809 } 00810 00811 void resize(size_t __n, uchar_t __c) 00812 {} 00813 00814 void resize(size_t __n) 00815 {} 00816 00817 void reserve(size_t __res_arg = 0) 00818 {} 00819 00820 size_t capacity() const 00821 { 00822 return max_size(); 00823 } 00824 00825 // Stuff below this line is dangerous because it's error prone. 00826 // I would really like to get rid of it. 00827 // copy function with funny arg ordering. 00828 size_t copy(uchar_t* __buffer, size_t __n, 00829 size_t __pos = 0) const 00830 { 00831 return copy(__pos, __n, __buffer); 00832 } 00833 #endif 00834 00835 #ifdef ITERATORS 00836 public: 00837 MNRope(const MNRopeConstIterator& __s, const MNRopeConstIterator& __e) 00838 { 00839 _M_tree_ptr = _S_substring(__s._M_root, 00840 __s._M_current_pos, 00841 __e._M_current_pos); 00842 } 00843 00844 MNRope(const MNRopeIterator& __s, const MNRopeIterator& __e) 00845 { 00846 _M_tree_ptr = _S_substring(__s._M_root, 00847 __s._M_current_pos, 00848 __e._M_current_pos); 00849 } 00850 00851 MNRopeConstIterator begin() const 00852 { 00853 return(MNRopeConstIterator(_M_tree_ptr, 0)); 00854 } 00855 00857 MNRopeConstIterator const_begin() const 00858 { 00859 return(MNRopeConstIterator(_M_tree_ptr, 0)); 00860 } 00861 00862 MNRopeConstIterator end() const 00863 { 00864 return(MNRopeConstIterator(_M_tree_ptr, size())); 00865 } 00866 00867 MNRopeConstIterator const_end() const 00868 { 00869 return(MNRopeConstIterator(_M_tree_ptr, size())); 00870 } 00871 00872 #ifdef REVERSE_ITERATORS 00873 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 00874 typedef reverse_iterator<MNRopeConstIterator> const_reverse_iterator; 00875 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 00876 typedef reverse_iterator<MNRopeConstIterator, value_type, const_reference, 00877 difference_type> const_reverse_iterator; 00878 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 00879 00880 const_reverse_iterator rbegin() const 00881 { 00882 return const_reverse_iterator(end()); 00883 } 00884 00885 const_reverse_iterator const_rbegin() const 00886 { 00887 return const_reverse_iterator(end()); 00888 } 00889 00890 const_reverse_iterator rend() const 00891 { 00892 return const_reverse_iterator(begin()); 00893 } 00894 00895 const_reverse_iterator const_rend() const 00896 { 00897 return const_reverse_iterator(begin()); 00898 } 00899 #endif /* REVERSE_ITERATORS */ 00900 00901 MNRope& append(MNRopeConstIterator __s, MNRopeConstIterator __e) 00902 { 00903 assert(__s._M_root == __e._M_root); 00904 MNSelfDestrPtr __appendee(_S_substring( 00905 __s._M_root, __s._M_current_pos, __e._M_current_pos)); 00906 MNRopeRep* __result = 00907 _S_concat(_M_tree_ptr, (MNRopeRep*)__appendee); 00908 _S_unref(_M_tree_ptr); 00909 _M_tree_ptr = __result; 00910 return *this; 00911 } 00912 00913 void insert(size_t __p, const MNRopeConstIterator& __i, 00914 const MNRopeConstIterator& __j) 00915 { 00916 MNRope __r(__i, __j); 00917 insert(__p, __r); 00918 } 00919 00920 void insert(size_t __p, const MNRopeIterator& __i, 00921 const MNRopeIterator& __j) 00922 { 00923 MNRope __r(__i, __j); 00924 insert(__p, __r); 00925 } 00926 00927 void replace(size_t __p, size_t __n, 00928 const MNRopeConstIterator& __i, const MNRopeConstIterator& __j) 00929 { 00930 MNRope __r(__i, __j); 00931 replace(__p, __n, __r); 00932 } 00933 00934 void replace(size_t __p, size_t __n, 00935 const MNRopeIterator& __i, const MNRopeIterator& __j) 00936 { 00937 MNRope __r(__i, __j); 00938 replace(__p, __n, __r); 00939 } 00940 00942 00943 void replace(size_t __p, uchar_t __c) 00944 { 00945 MNRopeIterator __i(this, __p); 00946 *__i = __c; 00947 } 00948 00949 void replace(size_t __p, const MNRopeConstIterator& __i, 00950 const MNRopeConstIterator& __j) 00951 { 00952 replace(__p, 1, __i, __j); 00953 } 00954 00955 void replace(size_t __p, const MNRopeIterator& __i, 00956 const MNRopeIterator& __j) 00957 { 00958 replace(__p, 1, __i, __j); 00959 } 00961 00963 00964 MNRopeIterator insert(const MNRopeIterator& __p, const MNRope& __r) 00965 { insert(__p.index(), __r); return __p; } 00966 MNRopeIterator insert(const MNRopeIterator& __p, size_t __n, uchar_t __c) 00967 { insert(__p.index(), __n, __c); return __p; } 00968 MNRopeIterator insert(const MNRopeIterator& __p, uchar_t __c) 00969 { insert(__p.index(), __c); return __p; } 00970 MNRopeIterator insert(const MNRopeIterator& __p ) 00971 { insert(__p.index()); return __p; } 00972 MNRopeIterator insert(const MNRopeIterator& __p, const uchar_t* c_string) 00973 { insert(__p.index(), c_string); return __p; } 00974 MNRopeIterator insert(const MNRopeIterator& __p, const uchar_t* __i, size_t __n) 00975 { insert(__p.index(), __i, __n); return __p; } 00976 MNRopeIterator insert(const MNRopeIterator& __p, const uchar_t* __i, 00977 const uchar_t* __j) 00978 { insert(__p.index(), __i, __j); return __p; } 00979 MNRopeIterator insert(const MNRopeIterator& __p, 00980 const MNRopeConstIterator& __i, const MNRopeConstIterator& __j) 00981 { insert(__p.index(), __i, __j); return __p; } 00982 MNRopeIterator insert(const MNRopeIterator& __p, 00983 const MNRopeIterator& __i, const MNRopeIterator& __j) 00984 { insert(__p.index(), __i, __j); return __p; } 00986 00988 00989 void replace(const MNRopeIterator& __p, const MNRopeIterator& __q, 00990 const MNRope& __r) 00991 { replace(__p.index(), __q.index() - __p.index(), __r); } 00992 void replace(const MNRopeIterator& __p, const MNRopeIterator& __q, uchar_t __c) 00993 { replace(__p.index(), __q.index() - __p.index(), __c); } 00994 void replace(const MNRopeIterator& __p, const MNRopeIterator& __q, 00995 const uchar_t* __c_string) 00996 { replace(__p.index(), __q.index() - __p.index(), __c_string); } 00997 void replace(const MNRopeIterator& __p, const MNRopeIterator& __q, 00998 const uchar_t* __i, size_t __n) 00999 { replace(__p.index(), __q.index() - __p.index(), __i, __n); } 01000 void replace(const MNRopeIterator& __p, const MNRopeIterator& __q, 01001 const uchar_t* __i, const uchar_t* __j) 01002 { replace(__p.index(), __q.index() - __p.index(), __i, __j); } 01003 void replace(const MNRopeIterator& __p, const MNRopeIterator& __q, 01004 const MNRopeConstIterator& __i, const MNRopeConstIterator& __j) 01005 { replace(__p.index(), __q.index() - __p.index(), __i, __j); } 01006 void replace(const MNRopeIterator& __p, const MNRopeIterator& __q, 01007 const MNRopeIterator& __i, const MNRopeIterator& __j) 01008 { replace(__p.index(), __q.index() - __p.index(), __i, __j); } 01010 01012 01013 void replace(const MNRopeIterator& __p, const MNRope& __r) 01014 { replace(__p.index(), __r); } 01015 void replace(const MNRopeIterator& __p, uchar_t __c) 01016 { replace(__p.index(), __c); } 01017 void replace(const MNRopeIterator& __p, const uchar_t* __c_string) 01018 { replace(__p.index(), __c_string); } 01019 void replace(const MNRopeIterator& __p, const uchar_t* __i, size_t __n) 01020 { replace(__p.index(), __i, __n); } 01021 void replace(const MNRopeIterator& __p, const uchar_t* __i, const uchar_t* __j) 01022 { replace(__p.index(), __i, __j); } 01023 void replace(const MNRopeIterator& __p, MNRopeConstIterator __i, 01024 MNRopeConstIterator __j) 01025 { replace(__p.index(), __i, __j); } 01026 void replace(const MNRopeIterator& __p, MNRopeIterator __i, MNRopeIterator __j) 01027 { replace(__p.index(), __i, __j); } 01029 01031 01032 MNRopeIterator erase(const MNRopeIterator& __p, const MNRopeIterator& __q) 01033 { 01034 size_t __p_index = __p.index(); 01035 erase(__p_index, __q.index() - __p_index); 01036 return MNRopeIterator(this, __p_index); 01037 } 01038 01039 MNRopeIterator erase(const MNRopeIterator& __p) 01040 { 01041 size_t __p_index = __p.index(); 01042 erase(__p_index, 1); 01043 return MNRopeIterator(this, __p_index); 01044 } 01046 01048 01049 MNRope substr(MNRopeIterator __start, MNRopeIterator __end) const 01050 { 01051 return MNRope( 01052 _S_substring(_M_tree_ptr, __start.index(), __end.index())); 01053 } 01054 01055 MNRope substr(MNRopeIterator __start) const 01056 { 01057 size_t __pos = __start.index(); 01058 return MNRope( _S_substring(_M_tree_ptr, __pos, __pos + 1)); 01059 } 01060 01061 MNRope substr(MNRopeConstIterator __start, MNRopeConstIterator __end) const 01062 { 01063 // This might eventually take advantage of the cache in the 01064 // iterator. 01065 return MNRope( 01066 _S_substring(_M_tree_ptr, __start.index(), __end.index())); 01067 } 01068 01069 MNRope substr(MNRopeConstIterator __start) 01070 { 01071 size_t __pos = __start.index(); 01072 return MNRope( _S_substring(_M_tree_ptr, __pos, __pos + 1)); 01073 } 01075 01076 size_t find(const uchar_t* __s, size_t __pos = 0) const 01077 { 01078 size_t __result_pos; 01079 MNRopeConstIterator __result = search(const_begin() + __pos, 01080 const_end(), 01081 __s, 01082 __s + _S_char_ptr_len(__s)); 01083 __result_pos = __result.index(); 01084 #ifndef __STL_OLD_ROPE_SEMANTICS 01085 if (__result_pos == size()) __result_pos = npos; 01086 #endif 01087 return __result_pos; 01088 } 01089 01090 MNRopeIterator mutable_begin() 01091 { 01092 return(MNRopeIterator(this, 0)); 01093 } 01094 01095 MNRopeIterator mutable_end() 01096 { 01097 return(MNRopeIterator(this, size())); 01098 } 01099 01100 #ifdef REVERSE_ITERATORS 01101 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 01102 typedef reverse_iterator<iterator> reverse_iterator; 01103 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 01104 typedef reverse_iterator<iterator, value_type, reference, 01105 difference_type> reverse_iterator; 01106 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 01107 01108 reverse_iterator mutable_rbegin() 01109 { 01110 return reverse_iterator(mutable_end()); 01111 } 01112 01113 reverse_iterator mutable_rend() 01114 { 01115 return reverse_iterator(mutable_begin()); 01116 } 01117 #endif /* REVERSE_ITERATORS */ 01118 01119 #ifdef __STD_STUFF 01120 iterator end() { return mutable_end(); } 01121 iterator begin() { return mutable_begin(); } 01122 #ifdef REVERSE_ITERATORS 01123 reverse_iterator rend() { return mutable_rend(); } 01124 reverse_iterator rbegin() { return mutable_rbegin(); } 01125 #endif /* REVERSE_ITERATORS */ 01126 #else 01127 MNRopeConstIterator end() { return const_end(); } 01128 MNRopeConstIterator begin() { return const_begin(); } 01129 #ifdef REVERSE_ITERATORS 01130 const_reverse_iterator rend() { return const_rend(); } 01131 const_reverse_iterator rbegin() { return const_rbegin(); } 01132 #endif /* REVERSE_ITERATORS */ 01133 #endif 01134 01135 #endif /* ITERATORS */ 01136 }; 01137 01138 inline 01139 MNRope 01140 operator+ (const MNRope& __left, 01141 const MNRope& __right) 01142 { 01143 return MNRope( 01144 MNRope::_S_concat(__left._M_tree_ptr, __right._M_tree_ptr)); 01145 // Inlining this should make it possible to keep __left and 01146 // __right in registers. 01147 } 01148 01149 inline 01150 MNRope& 01151 operator+= (MNRope& __left, 01152 const MNRope& __right) 01153 { 01154 __left.append(__right); 01155 return __left; 01156 } 01157 01158 inline MNRope 01159 operator+ (const MNRope& __left, 01160 const uchar_t* __right) { 01161 size_t __rlen = MNRope::_S_char_ptr_len(__right); 01162 return MNRope( 01163 MNRope::_S_concat_char_iter( 01164 __left._M_tree_ptr, __right, __rlen)); 01165 } 01166 01167 inline MNRope& 01168 operator+= (MNRope& __left, 01169 const uchar_t* __right) { 01170 __left.append(__right); 01171 return __left; 01172 } 01173 01174 inline MNRope 01175 operator+ (const MNRope& __left, uchar_t __right) { 01176 return MNRope( 01177 MNRope::_S_concat_char_iter( 01178 __left._M_tree_ptr, &__right, 1)); 01179 } 01180 01181 inline MNRope& 01182 operator+= (MNRope& __left, uchar_t __right) { 01183 __left.append(__right); 01184 return __left; 01185 } 01186 01187 inline bool 01188 operator< (const MNRope& __left, 01189 const MNRope& __right) { 01190 return __left.compare(__right) < 0; 01191 } 01192 01193 inline bool 01194 operator== (const MNRope& __left, 01195 const MNRope& __right) { 01196 return __left.compare(__right) == 0; 01197 } 01198 01199 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER 01200 01201 inline bool 01202 operator!= (const MNRope& __x, const MNRope& __y) { 01203 return !(__x == __y); 01204 } 01205 01206 inline bool 01207 operator> (const MNRope& __x, const MNRope& __y) { 01208 return __y < __x; 01209 } 01210 01211 inline bool 01212 operator<= (const MNRope& __x, const MNRope& __y) { 01213 return !(__y < __x); 01214 } 01215 01216 inline bool 01217 operator>= (const MNRope& __x, const MNRope& __y) { 01218 return !(__x < __y); 01219 } 01220 01221 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ 01222 01223 ostream& operator<< (ostream& __o, const MNRope& __r); 01224 01225 inline void swap(MNRope& __x, MNRope& __y) { 01226 __x.swap(__y); 01227 } 01228 01230 01231 # endif /* ROPE_H */ 01232

Generated on Sun Mar 6 13:35:49 2005 for Komssys by doxygen 1.3.8