rope 88 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012
  1. // SGI's rope class -*- C++ -*-
  2. // Copyright (C) 2001-2022 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /*
  21. * Copyright (c) 1997
  22. * Silicon Graphics Computer Systems, Inc.
  23. *
  24. * Permission to use, copy, modify, distribute and sell this software
  25. * and its documentation for any purpose is hereby granted without fee,
  26. * provided that the above copyright notice appear in all copies and
  27. * that both that copyright notice and this permission notice appear
  28. * in supporting documentation. Silicon Graphics makes no
  29. * representations about the suitability of this software for any
  30. * purpose. It is provided "as is" without express or implied warranty.
  31. */
  32. /** @file ext/rope
  33. * This file is a GNU extension to the Standard C++ Library (possibly
  34. * containing extensions from the HP/SGI STL subset).
  35. */
  36. #ifndef _ROPE
  37. #define _ROPE 1
  38. #pragma GCC system_header
  39. #include <algorithm>
  40. #include <iosfwd>
  41. #include <bits/stl_construct.h>
  42. #include <bits/stl_uninitialized.h>
  43. #include <bits/stl_function.h>
  44. #include <bits/stl_numeric.h>
  45. #include <bits/allocator.h>
  46. #include <bits/gthr.h>
  47. #include <ext/alloc_traits.h>
  48. #include <tr1/functional>
  49. # ifdef __GC
  50. # define __GC_CONST const
  51. # else
  52. # define __GC_CONST // constant except for deallocation
  53. # endif
  54. #include <ext/memory> // For uninitialized_copy_n
  55. namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
  56. {
  57. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  58. namespace __detail
  59. {
  60. enum { _S_max_rope_depth = 45 };
  61. enum _Tag {_S_leaf, _S_concat, _S_substringfn, _S_function};
  62. } // namespace __detail
  63. // See libstdc++/36832.
  64. template<typename _ForwardIterator, typename _Allocator>
  65. void
  66. _Destroy_const(_ForwardIterator __first,
  67. _ForwardIterator __last, _Allocator __alloc)
  68. {
  69. for (; __first != __last; ++__first)
  70. __alloc.destroy(&*__first);
  71. }
  72. template<typename _ForwardIterator, typename _Tp>
  73. inline void
  74. _Destroy_const(_ForwardIterator __first,
  75. _ForwardIterator __last, std::allocator<_Tp>)
  76. { std::_Destroy(__first, __last); }
  77. // The _S_eos function is used for those functions that
  78. // convert to/from C-like strings to detect the end of the string.
  79. // The end-of-C-string character.
  80. // This is what the draft standard says it should be.
  81. template <class _CharT>
  82. inline _CharT
  83. _S_eos(_CharT*)
  84. { return _CharT(); }
  85. // Test for basic character types.
  86. // For basic character types leaves having a trailing eos.
  87. template <class _CharT>
  88. inline bool
  89. _S_is_basic_char_type(_CharT*)
  90. { return false; }
  91. template <class _CharT>
  92. inline bool
  93. _S_is_one_byte_char_type(_CharT*)
  94. { return false; }
  95. inline bool
  96. _S_is_basic_char_type(char*)
  97. { return true; }
  98. inline bool
  99. _S_is_one_byte_char_type(char*)
  100. { return true; }
  101. inline bool
  102. _S_is_basic_char_type(wchar_t*)
  103. { return true; }
  104. // Store an eos iff _CharT is a basic character type.
  105. // Do not reference _S_eos if it isn't.
  106. template <class _CharT>
  107. inline void
  108. _S_cond_store_eos(_CharT&) { }
  109. inline void
  110. _S_cond_store_eos(char& __c)
  111. { __c = 0; }
  112. inline void
  113. _S_cond_store_eos(wchar_t& __c)
  114. { __c = 0; }
  115. // char_producers are logically functions that generate a section of
  116. // a string. These can be converted to ropes. The resulting rope
  117. // invokes the char_producer on demand. This allows, for example,
  118. // files to be viewed as ropes without reading the entire file.
  119. template <class _CharT>
  120. class char_producer
  121. {
  122. public:
  123. virtual ~char_producer() { }
  124. virtual void
  125. operator()(std::size_t __start_pos, std::size_t __len,
  126. _CharT* __buffer) = 0;
  127. // Buffer should really be an arbitrary output iterator.
  128. // That way we could flatten directly into an ostream, etc.
  129. // This is thoroughly impossible, since iterator types don't
  130. // have runtime descriptions.
  131. };
  132. // Sequence buffers:
  133. //
  134. // Sequence must provide an append operation that appends an
  135. // array to the sequence. Sequence buffers are useful only if
  136. // appending an entire array is cheaper than appending element by element.
  137. // This is true for many string representations.
  138. // This should perhaps inherit from ostream<sequence::value_type>
  139. // and be implemented correspondingly, so that they can be used
  140. // for formatted. For the sake of portability, we don't do this yet.
  141. //
  142. // For now, sequence buffers behave as output iterators. But they also
  143. // behave a little like basic_ostringstream<sequence::value_type> and a
  144. // little like containers.
  145. // Ignore warnings about std::iterator.
  146. #pragma GCC diagnostic push
  147. #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  148. template<class _Sequence, std::size_t _Buf_sz = 100>
  149. class sequence_buffer
  150. : public std::iterator<std::output_iterator_tag, void, void, void, void>
  151. {
  152. public:
  153. typedef typename _Sequence::value_type value_type;
  154. protected:
  155. _Sequence* _M_prefix;
  156. value_type _M_buffer[_Buf_sz];
  157. std::size_t _M_buf_count;
  158. public:
  159. void
  160. flush()
  161. {
  162. _M_prefix->append(_M_buffer, _M_buffer + _M_buf_count);
  163. _M_buf_count = 0;
  164. }
  165. ~sequence_buffer()
  166. { flush(); }
  167. sequence_buffer()
  168. : _M_prefix(0), _M_buf_count(0) { }
  169. sequence_buffer(const sequence_buffer& __x)
  170. {
  171. _M_prefix = __x._M_prefix;
  172. _M_buf_count = __x._M_buf_count;
  173. std::copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer);
  174. }
  175. // Non-const "copy" modifies the parameter - yuck
  176. sequence_buffer(sequence_buffer& __x)
  177. {
  178. __x.flush();
  179. _M_prefix = __x._M_prefix;
  180. _M_buf_count = 0;
  181. }
  182. sequence_buffer(_Sequence& __s)
  183. : _M_prefix(&__s), _M_buf_count(0) { }
  184. // Non-const "copy" modifies the parameter - yuck
  185. sequence_buffer&
  186. operator=(sequence_buffer& __x)
  187. {
  188. __x.flush();
  189. _M_prefix = __x._M_prefix;
  190. _M_buf_count = 0;
  191. return *this;
  192. }
  193. sequence_buffer&
  194. operator=(const sequence_buffer& __x)
  195. {
  196. _M_prefix = __x._M_prefix;
  197. _M_buf_count = __x._M_buf_count;
  198. std::copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer);
  199. return *this;
  200. }
  201. #if __cplusplus >= 201103L
  202. sequence_buffer(sequence_buffer&& __x) : sequence_buffer(__x) { }
  203. sequence_buffer& operator=(sequence_buffer&& __x) { return *this = __x; }
  204. #endif
  205. void
  206. push_back(value_type __x)
  207. {
  208. if (_M_buf_count < _Buf_sz)
  209. {
  210. _M_buffer[_M_buf_count] = __x;
  211. ++_M_buf_count;
  212. }
  213. else
  214. {
  215. flush();
  216. _M_buffer[0] = __x;
  217. _M_buf_count = 1;
  218. }
  219. }
  220. void
  221. append(value_type* __s, std::size_t __len)
  222. {
  223. if (__len + _M_buf_count <= _Buf_sz)
  224. {
  225. std::size_t __i = _M_buf_count;
  226. for (std::size_t __j = 0; __j < __len; __i++, __j++)
  227. _M_buffer[__i] = __s[__j];
  228. _M_buf_count += __len;
  229. }
  230. else if (0 == _M_buf_count)
  231. _M_prefix->append(__s, __s + __len);
  232. else
  233. {
  234. flush();
  235. append(__s, __len);
  236. }
  237. }
  238. sequence_buffer&
  239. write(value_type* __s, std::size_t __len)
  240. {
  241. append(__s, __len);
  242. return *this;
  243. }
  244. sequence_buffer&
  245. put(value_type __x)
  246. {
  247. push_back(__x);
  248. return *this;
  249. }
  250. sequence_buffer&
  251. operator=(const value_type& __rhs)
  252. {
  253. push_back(__rhs);
  254. return *this;
  255. }
  256. sequence_buffer&
  257. operator*()
  258. { return *this; }
  259. sequence_buffer&
  260. operator++()
  261. { return *this; }
  262. sequence_buffer
  263. operator++(int)
  264. { return *this; }
  265. };
  266. #pragma GCC diagnostic pop
  267. // The following should be treated as private, at least for now.
  268. template<class _CharT>
  269. class _Rope_char_consumer
  270. {
  271. public:
  272. // If we had member templates, these should not be virtual.
  273. // For now we need to use run-time parametrization where
  274. // compile-time would do. Hence this should all be private
  275. // for now.
  276. // The symmetry with char_producer is accidental and temporary.
  277. virtual ~_Rope_char_consumer() { }
  278. virtual bool
  279. operator()(const _CharT* __buffer, std::size_t __len) = 0;
  280. };
  281. // First a lot of forward declarations. The standard seems to require
  282. // much stricter "declaration before use" than many of the implementations
  283. // that preceded it.
  284. template<class _CharT, class _Alloc = std::allocator<_CharT> >
  285. class rope;
  286. template<class _CharT, class _Alloc>
  287. struct _Rope_RopeConcatenation;
  288. template<class _CharT, class _Alloc>
  289. struct _Rope_RopeLeaf;
  290. template<class _CharT, class _Alloc>
  291. struct _Rope_RopeFunction;
  292. template<class _CharT, class _Alloc>
  293. struct _Rope_RopeSubstring;
  294. template<class _CharT, class _Alloc>
  295. class _Rope_iterator;
  296. template<class _CharT, class _Alloc>
  297. class _Rope_const_iterator;
  298. template<class _CharT, class _Alloc>
  299. class _Rope_char_ref_proxy;
  300. template<class _CharT, class _Alloc>
  301. class _Rope_char_ptr_proxy;
  302. template<class _CharT, class _Alloc>
  303. bool
  304. operator==(const _Rope_char_ptr_proxy<_CharT, _Alloc>& __x,
  305. const _Rope_char_ptr_proxy<_CharT, _Alloc>& __y);
  306. template<class _CharT, class _Alloc>
  307. _Rope_const_iterator<_CharT, _Alloc>
  308. operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x,
  309. std::ptrdiff_t __n);
  310. template<class _CharT, class _Alloc>
  311. _Rope_const_iterator<_CharT, _Alloc>
  312. operator+(const _Rope_const_iterator<_CharT, _Alloc>& __x,
  313. std::ptrdiff_t __n);
  314. template<class _CharT, class _Alloc>
  315. _Rope_const_iterator<_CharT, _Alloc>
  316. operator+(std::ptrdiff_t __n,
  317. const _Rope_const_iterator<_CharT, _Alloc>& __x);
  318. template<class _CharT, class _Alloc>
  319. bool
  320. operator==(const _Rope_const_iterator<_CharT, _Alloc>& __x,
  321. const _Rope_const_iterator<_CharT, _Alloc>& __y);
  322. template<class _CharT, class _Alloc>
  323. bool
  324. operator<(const _Rope_const_iterator<_CharT, _Alloc>& __x,
  325. const _Rope_const_iterator<_CharT, _Alloc>& __y);
  326. template<class _CharT, class _Alloc>
  327. std::ptrdiff_t
  328. operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x,
  329. const _Rope_const_iterator<_CharT, _Alloc>& __y);
  330. template<class _CharT, class _Alloc>
  331. _Rope_iterator<_CharT, _Alloc>
  332. operator-(const _Rope_iterator<_CharT, _Alloc>& __x, std::ptrdiff_t __n);
  333. template<class _CharT, class _Alloc>
  334. _Rope_iterator<_CharT, _Alloc>
  335. operator+(const _Rope_iterator<_CharT, _Alloc>& __x, std::ptrdiff_t __n);
  336. template<class _CharT, class _Alloc>
  337. _Rope_iterator<_CharT, _Alloc>
  338. operator+(std::ptrdiff_t __n, const _Rope_iterator<_CharT, _Alloc>& __x);
  339. template<class _CharT, class _Alloc>
  340. bool
  341. operator==(const _Rope_iterator<_CharT, _Alloc>& __x,
  342. const _Rope_iterator<_CharT, _Alloc>& __y);
  343. template<class _CharT, class _Alloc>
  344. bool
  345. operator<(const _Rope_iterator<_CharT, _Alloc>& __x,
  346. const _Rope_iterator<_CharT, _Alloc>& __y);
  347. template<class _CharT, class _Alloc>
  348. std::ptrdiff_t
  349. operator-(const _Rope_iterator<_CharT, _Alloc>& __x,
  350. const _Rope_iterator<_CharT, _Alloc>& __y);
  351. template<class _CharT, class _Alloc>
  352. rope<_CharT, _Alloc>
  353. operator+(const rope<_CharT, _Alloc>& __left,
  354. const rope<_CharT, _Alloc>& __right);
  355. template<class _CharT, class _Alloc>
  356. rope<_CharT, _Alloc>
  357. operator+(const rope<_CharT, _Alloc>& __left, const _CharT* __right);
  358. template<class _CharT, class _Alloc>
  359. rope<_CharT, _Alloc>
  360. operator+(const rope<_CharT, _Alloc>& __left, _CharT __right);
  361. // Some helpers, so we can use power on ropes.
  362. // See below for why this isn't local to the implementation.
  363. // Ignore warnings about std::binary_function.
  364. #pragma GCC diagnostic push
  365. #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  366. // This uses a nonstandard refcount convention.
  367. // The result has refcount 0.
  368. template<class _CharT, class _Alloc>
  369. struct _Rope_Concat_fn
  370. : public std::binary_function<rope<_CharT, _Alloc>, rope<_CharT, _Alloc>,
  371. rope<_CharT, _Alloc> >
  372. {
  373. rope<_CharT, _Alloc>
  374. operator()(const rope<_CharT, _Alloc>& __x,
  375. const rope<_CharT, _Alloc>& __y)
  376. { return __x + __y; }
  377. };
  378. #pragma GCC diagnostic pop
  379. template <class _CharT, class _Alloc>
  380. inline rope<_CharT, _Alloc>
  381. identity_element(_Rope_Concat_fn<_CharT, _Alloc>)
  382. { return rope<_CharT, _Alloc>(); }
  383. // Class _Refcount_Base provides a type, _RC_t, a data member,
  384. // _M_ref_count, and member functions _M_incr and _M_decr, which perform
  385. // atomic preincrement/predecrement. The constructor initializes
  386. // _M_ref_count.
  387. struct _Refcount_Base
  388. {
  389. // The type _RC_t
  390. typedef std::size_t _RC_t;
  391. // The data member _M_ref_count
  392. _RC_t _M_ref_count;
  393. // Constructor
  394. #ifdef __GTHREAD_MUTEX_INIT
  395. __gthread_mutex_t _M_ref_count_lock = __GTHREAD_MUTEX_INIT;
  396. #else
  397. __gthread_mutex_t _M_ref_count_lock;
  398. #endif
  399. _Refcount_Base(_RC_t __n) : _M_ref_count(__n)
  400. {
  401. #ifndef __GTHREAD_MUTEX_INIT
  402. #ifdef __GTHREAD_MUTEX_INIT_FUNCTION
  403. __GTHREAD_MUTEX_INIT_FUNCTION (&_M_ref_count_lock);
  404. #else
  405. #error __GTHREAD_MUTEX_INIT or __GTHREAD_MUTEX_INIT_FUNCTION should be defined by gthr.h abstraction layer, report problem to libstdc++@gcc.gnu.org.
  406. #endif
  407. #endif
  408. }
  409. #ifndef __GTHREAD_MUTEX_INIT
  410. ~_Refcount_Base()
  411. { __gthread_mutex_destroy(&_M_ref_count_lock); }
  412. #endif
  413. void
  414. _M_incr()
  415. {
  416. __gthread_mutex_lock(&_M_ref_count_lock);
  417. ++_M_ref_count;
  418. __gthread_mutex_unlock(&_M_ref_count_lock);
  419. }
  420. _RC_t
  421. _M_decr()
  422. {
  423. __gthread_mutex_lock(&_M_ref_count_lock);
  424. _RC_t __tmp = --_M_ref_count;
  425. __gthread_mutex_unlock(&_M_ref_count_lock);
  426. return __tmp;
  427. }
  428. };
  429. //
  430. // What follows should really be local to rope. Unfortunately,
  431. // that doesn't work, since it makes it impossible to define generic
  432. // equality on rope iterators. According to the draft standard, the
  433. // template parameters for such an equality operator cannot be inferred
  434. // from the occurrence of a member class as a parameter.
  435. // (SGI compilers in fact allow this, but the __result wouldn't be
  436. // portable.)
  437. // Similarly, some of the static member functions are member functions
  438. // only to avoid polluting the global namespace, and to circumvent
  439. // restrictions on type inference for template functions.
  440. //
  441. //
  442. // The internal data structure for representing a rope. This is
  443. // private to the implementation. A rope is really just a pointer
  444. // to one of these.
  445. //
  446. // A few basic functions for manipulating this data structure
  447. // are members of _RopeRep. Most of the more complex algorithms
  448. // are implemented as rope members.
  449. //
  450. // Some of the static member functions of _RopeRep have identically
  451. // named functions in rope that simply invoke the _RopeRep versions.
  452. #define __ROPE_DEFINE_ALLOCS(__a) \
  453. __ROPE_DEFINE_ALLOC(_CharT,_Data) /* character data */ \
  454. typedef _Rope_RopeConcatenation<_CharT,__a> __C; \
  455. __ROPE_DEFINE_ALLOC(__C,_C) \
  456. typedef _Rope_RopeLeaf<_CharT,__a> __L; \
  457. __ROPE_DEFINE_ALLOC(__L,_L) \
  458. typedef _Rope_RopeFunction<_CharT,__a> __F; \
  459. __ROPE_DEFINE_ALLOC(__F,_F) \
  460. typedef _Rope_RopeSubstring<_CharT,__a> __S; \
  461. __ROPE_DEFINE_ALLOC(__S,_S)
  462. // Internal rope nodes potentially store a copy of the allocator
  463. // instance used to allocate them. This is mostly redundant.
  464. // But the alternative would be to pass allocator instances around
  465. // in some form to nearly all internal functions, since any pointer
  466. // assignment may result in a zero reference count and thus require
  467. // deallocation.
  468. #define __STATIC_IF_SGI_ALLOC /* not static */
  469. template <class _CharT, class _Alloc>
  470. struct _Rope_rep_base
  471. : public _Alloc
  472. {
  473. typedef std::size_t size_type;
  474. typedef _Alloc allocator_type;
  475. allocator_type
  476. get_allocator() const
  477. { return *static_cast<const _Alloc*>(this); }
  478. allocator_type&
  479. _M_get_allocator()
  480. { return *static_cast<_Alloc*>(this); }
  481. const allocator_type&
  482. _M_get_allocator() const
  483. { return *static_cast<const _Alloc*>(this); }
  484. _Rope_rep_base(size_type __size, const allocator_type&)
  485. : _M_size(__size) { }
  486. size_type _M_size;
  487. # define __ROPE_DEFINE_ALLOC(_Tp, __name) \
  488. typedef typename \
  489. __alloc_traits<_Alloc>::template rebind<_Tp>::other __name##Alloc; \
  490. static _Tp* __name##_allocate(size_type __n) \
  491. { return __name##Alloc().allocate(__n); } \
  492. static void __name##_deallocate(_Tp *__p, size_type __n) \
  493. { __name##Alloc().deallocate(__p, __n); }
  494. __ROPE_DEFINE_ALLOCS(_Alloc)
  495. # undef __ROPE_DEFINE_ALLOC
  496. };
  497. template<class _CharT, class _Alloc>
  498. struct _Rope_RopeRep
  499. : public _Rope_rep_base<_CharT, _Alloc>
  500. # ifndef __GC
  501. , _Refcount_Base
  502. # endif
  503. {
  504. public:
  505. __detail::_Tag _M_tag:8;
  506. bool _M_is_balanced:8;
  507. unsigned char _M_depth;
  508. __GC_CONST _CharT* _M_c_string;
  509. #ifdef __GTHREAD_MUTEX_INIT
  510. __gthread_mutex_t _M_c_string_lock = __GTHREAD_MUTEX_INIT;
  511. #else
  512. __gthread_mutex_t _M_c_string_lock;
  513. #endif
  514. /* Flattened version of string, if needed. */
  515. /* typically 0. */
  516. /* If it's not 0, then the memory is owned */
  517. /* by this node. */
  518. /* In the case of a leaf, this may point to */
  519. /* the same memory as the data field. */
  520. typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type
  521. allocator_type;
  522. typedef std::size_t size_type;
  523. using _Rope_rep_base<_CharT, _Alloc>::get_allocator;
  524. using _Rope_rep_base<_CharT, _Alloc>::_M_get_allocator;
  525. _Rope_RopeRep(__detail::_Tag __t, int __d, bool __b, size_type __size,
  526. const allocator_type& __a)
  527. : _Rope_rep_base<_CharT, _Alloc>(__size, __a),
  528. #ifndef __GC
  529. _Refcount_Base(1),
  530. #endif
  531. _M_tag(__t), _M_is_balanced(__b), _M_depth(__d), _M_c_string(0)
  532. #ifdef __GTHREAD_MUTEX_INIT
  533. { }
  534. #else
  535. { __GTHREAD_MUTEX_INIT_FUNCTION (&_M_c_string_lock); }
  536. ~_Rope_RopeRep()
  537. { __gthread_mutex_destroy (&_M_c_string_lock); }
  538. #endif
  539. #ifdef __GC
  540. void
  541. _M_incr () { }
  542. #endif
  543. static void
  544. _S_free_string(__GC_CONST _CharT*, size_type __len,
  545. allocator_type& __a);
  546. #define __STL_FREE_STRING(__s, __l, __a) _S_free_string(__s, __l, __a);
  547. // Deallocate data section of a leaf.
  548. // This shouldn't be a member function.
  549. // But its hard to do anything else at the
  550. // moment, because it's templatized w.r.t.
  551. // an allocator.
  552. // Does nothing if __GC is defined.
  553. #ifndef __GC
  554. void _M_free_c_string();
  555. void _M_free_tree();
  556. // Deallocate t. Assumes t is not 0.
  557. void
  558. _M_unref_nonnil()
  559. {
  560. if (0 == _M_decr())
  561. _M_free_tree();
  562. }
  563. void
  564. _M_ref_nonnil()
  565. { _M_incr(); }
  566. static void
  567. _S_unref(_Rope_RopeRep* __t)
  568. {
  569. if (0 != __t)
  570. __t->_M_unref_nonnil();
  571. }
  572. static void
  573. _S_ref(_Rope_RopeRep* __t)
  574. {
  575. if (0 != __t)
  576. __t->_M_incr();
  577. }
  578. static void
  579. _S_free_if_unref(_Rope_RopeRep* __t)
  580. {
  581. if (0 != __t && 0 == __t->_M_ref_count)
  582. __t->_M_free_tree();
  583. }
  584. # else /* __GC */
  585. void _M_unref_nonnil() { }
  586. void _M_ref_nonnil() { }
  587. static void _S_unref(_Rope_RopeRep*) { }
  588. static void _S_ref(_Rope_RopeRep*) { }
  589. static void _S_free_if_unref(_Rope_RopeRep*) { }
  590. # endif
  591. protected:
  592. _Rope_RopeRep&
  593. operator=(const _Rope_RopeRep&);
  594. _Rope_RopeRep(const _Rope_RopeRep&);
  595. };
  596. template<class _CharT, class _Alloc>
  597. struct _Rope_RopeLeaf
  598. : public _Rope_RopeRep<_CharT, _Alloc>
  599. {
  600. typedef std::size_t size_type;
  601. public:
  602. // Apparently needed by VC++
  603. // The data fields of leaves are allocated with some
  604. // extra space, to accommodate future growth and for basic
  605. // character types, to hold a trailing eos character.
  606. enum { _S_alloc_granularity = 8 };
  607. static size_type
  608. _S_rounded_up_size(size_type __n)
  609. {
  610. size_type __size_with_eos;
  611. if (_S_is_basic_char_type((_CharT*)0))
  612. __size_with_eos = __n + 1;
  613. else
  614. __size_with_eos = __n;
  615. #ifdef __GC
  616. return __size_with_eos;
  617. #else
  618. // Allow slop for in-place expansion.
  619. return ((__size_with_eos + size_type(_S_alloc_granularity) - 1)
  620. &~ (size_type(_S_alloc_granularity) - 1));
  621. #endif
  622. }
  623. __GC_CONST _CharT* _M_data; /* Not necessarily 0 terminated. */
  624. /* The allocated size is */
  625. /* _S_rounded_up_size(size), except */
  626. /* in the GC case, in which it */
  627. /* doesn't matter. */
  628. typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type
  629. allocator_type;
  630. _Rope_RopeLeaf(__GC_CONST _CharT* __d, size_type __size,
  631. const allocator_type& __a)
  632. : _Rope_RopeRep<_CharT, _Alloc>(__detail::_S_leaf, 0, true,
  633. __size, __a), _M_data(__d)
  634. {
  635. if (_S_is_basic_char_type((_CharT *)0))
  636. {
  637. // already eos terminated.
  638. this->_M_c_string = __d;
  639. }
  640. }
  641. // The constructor assumes that d has been allocated with
  642. // the proper allocator and the properly padded size.
  643. // In contrast, the destructor deallocates the data:
  644. #ifndef __GC
  645. ~_Rope_RopeLeaf() throw()
  646. {
  647. if (_M_data != this->_M_c_string)
  648. this->_M_free_c_string();
  649. this->__STL_FREE_STRING(_M_data, this->_M_size, this->_M_get_allocator());
  650. }
  651. #endif
  652. protected:
  653. _Rope_RopeLeaf&
  654. operator=(const _Rope_RopeLeaf&);
  655. _Rope_RopeLeaf(const _Rope_RopeLeaf&);
  656. };
  657. template<class _CharT, class _Alloc>
  658. struct _Rope_RopeConcatenation
  659. : public _Rope_RopeRep<_CharT, _Alloc>
  660. {
  661. public:
  662. _Rope_RopeRep<_CharT, _Alloc>* _M_left;
  663. _Rope_RopeRep<_CharT, _Alloc>* _M_right;
  664. typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type
  665. allocator_type;
  666. _Rope_RopeConcatenation(_Rope_RopeRep<_CharT, _Alloc>* __l,
  667. _Rope_RopeRep<_CharT, _Alloc>* __r,
  668. const allocator_type& __a)
  669. : _Rope_RopeRep<_CharT, _Alloc>(__detail::_S_concat,
  670. std::max(__l->_M_depth,
  671. __r->_M_depth) + 1,
  672. false,
  673. __l->_M_size + __r->_M_size, __a),
  674. _M_left(__l), _M_right(__r)
  675. { }
  676. #ifndef __GC
  677. ~_Rope_RopeConcatenation() throw()
  678. {
  679. this->_M_free_c_string();
  680. _M_left->_M_unref_nonnil();
  681. _M_right->_M_unref_nonnil();
  682. }
  683. #endif
  684. protected:
  685. _Rope_RopeConcatenation&
  686. operator=(const _Rope_RopeConcatenation&);
  687. _Rope_RopeConcatenation(const _Rope_RopeConcatenation&);
  688. };
  689. template<class _CharT, class _Alloc>
  690. struct _Rope_RopeFunction
  691. : public _Rope_RopeRep<_CharT, _Alloc>
  692. {
  693. public:
  694. char_producer<_CharT>* _M_fn;
  695. #ifndef __GC
  696. bool _M_delete_when_done; // Char_producer is owned by the
  697. // rope and should be explicitly
  698. // deleted when the rope becomes
  699. // inaccessible.
  700. #else
  701. // In the GC case, we either register the rope for
  702. // finalization, or not. Thus the field is unnecessary;
  703. // the information is stored in the collector data structures.
  704. // We do need a finalization procedure to be invoked by the
  705. // collector.
  706. static void
  707. _S_fn_finalization_proc(void * __tree, void *)
  708. { delete ((_Rope_RopeFunction *)__tree) -> _M_fn; }
  709. #endif
  710. typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type
  711. allocator_type;
  712. _Rope_RopeFunction(char_producer<_CharT>* __f, std::size_t __size,
  713. bool __d, const allocator_type& __a)
  714. : _Rope_RopeRep<_CharT, _Alloc>(__detail::_S_function, 0, true, __size, __a)
  715. , _M_fn(__f)
  716. #ifndef __GC
  717. , _M_delete_when_done(__d)
  718. #endif
  719. {
  720. #ifdef __GC
  721. if (__d)
  722. {
  723. GC_REGISTER_FINALIZER(this, _Rope_RopeFunction::
  724. _S_fn_finalization_proc, 0, 0, 0);
  725. }
  726. #endif
  727. }
  728. #ifndef __GC
  729. ~_Rope_RopeFunction() throw()
  730. {
  731. this->_M_free_c_string();
  732. if (_M_delete_when_done)
  733. delete _M_fn;
  734. }
  735. # endif
  736. protected:
  737. _Rope_RopeFunction&
  738. operator=(const _Rope_RopeFunction&);
  739. _Rope_RopeFunction(const _Rope_RopeFunction&);
  740. };
  741. // Substring results are usually represented using just
  742. // concatenation nodes. But in the case of very long flat ropes
  743. // or ropes with a functional representation that isn't practical.
  744. // In that case, we represent the __result as a special case of
  745. // RopeFunction, whose char_producer points back to the rope itself.
  746. // In all cases except repeated substring operations and
  747. // deallocation, we treat the __result as a RopeFunction.
  748. template<class _CharT, class _Alloc>
  749. struct _Rope_RopeSubstring
  750. : public _Rope_RopeFunction<_CharT, _Alloc>,
  751. public char_producer<_CharT>
  752. {
  753. typedef std::size_t size_type;
  754. public:
  755. // XXX this whole class should be rewritten.
  756. _Rope_RopeRep<_CharT,_Alloc>* _M_base; // not 0
  757. size_type _M_start;
  758. virtual void
  759. operator()(size_type __start_pos, size_type __req_len,
  760. _CharT* __buffer)
  761. {
  762. switch(_M_base->_M_tag)
  763. {
  764. case __detail::_S_function:
  765. case __detail::_S_substringfn:
  766. {
  767. char_producer<_CharT>* __fn =
  768. ((_Rope_RopeFunction<_CharT,_Alloc>*)_M_base)->_M_fn;
  769. (*__fn)(__start_pos + _M_start, __req_len, __buffer);
  770. }
  771. break;
  772. case __detail::_S_leaf:
  773. {
  774. __GC_CONST _CharT* __s =
  775. ((_Rope_RopeLeaf<_CharT,_Alloc>*)_M_base)->_M_data;
  776. uninitialized_copy_n(__s + __start_pos + _M_start, __req_len,
  777. __buffer);
  778. }
  779. break;
  780. default:
  781. break;
  782. }
  783. }
  784. typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type
  785. allocator_type;
  786. _Rope_RopeSubstring(_Rope_RopeRep<_CharT, _Alloc>* __b, size_type __s,
  787. size_type __l, const allocator_type& __a)
  788. : _Rope_RopeFunction<_CharT, _Alloc>(this, __l, false, __a),
  789. char_producer<_CharT>(), _M_base(__b), _M_start(__s)
  790. {
  791. #ifndef __GC
  792. _M_base->_M_ref_nonnil();
  793. #endif
  794. this->_M_tag = __detail::_S_substringfn;
  795. }
  796. virtual ~_Rope_RopeSubstring() throw()
  797. {
  798. #ifndef __GC
  799. _M_base->_M_unref_nonnil();
  800. // _M_free_c_string(); -- done by parent class
  801. #endif
  802. }
  803. };
  804. // Self-destructing pointers to Rope_rep.
  805. // These are not conventional smart pointers. Their
  806. // only purpose in life is to ensure that unref is called
  807. // on the pointer either at normal exit or if an exception
  808. // is raised. It is the caller's responsibility to
  809. // adjust reference counts when these pointers are initialized
  810. // or assigned to. (This convention significantly reduces
  811. // the number of potentially expensive reference count
  812. // updates.)
  813. #ifndef __GC
  814. template<class _CharT, class _Alloc>
  815. struct _Rope_self_destruct_ptr
  816. {
  817. _Rope_RopeRep<_CharT, _Alloc>* _M_ptr;
  818. ~_Rope_self_destruct_ptr()
  819. { _Rope_RopeRep<_CharT, _Alloc>::_S_unref(_M_ptr); }
  820. #if __cpp_exceptions
  821. _Rope_self_destruct_ptr() : _M_ptr(0) { }
  822. #else
  823. _Rope_self_destruct_ptr() { }
  824. #endif
  825. _Rope_self_destruct_ptr(_Rope_RopeRep<_CharT, _Alloc>* __p)
  826. : _M_ptr(__p) { }
  827. _Rope_RopeRep<_CharT, _Alloc>&
  828. operator*()
  829. { return *_M_ptr; }
  830. _Rope_RopeRep<_CharT, _Alloc>*
  831. operator->()
  832. { return _M_ptr; }
  833. operator _Rope_RopeRep<_CharT, _Alloc>*()
  834. { return _M_ptr; }
  835. _Rope_self_destruct_ptr&
  836. operator=(_Rope_RopeRep<_CharT, _Alloc>* __x)
  837. { _M_ptr = __x; return *this; }
  838. };
  839. #endif
  840. // Dereferencing a nonconst iterator has to return something
  841. // that behaves almost like a reference. It's not possible to
  842. // return an actual reference since assignment requires extra
  843. // work. And we would get into the same problems as with the
  844. // CD2 version of basic_string.
  845. template<class _CharT, class _Alloc>
  846. class _Rope_char_ref_proxy
  847. {
  848. friend class rope<_CharT, _Alloc>;
  849. friend class _Rope_iterator<_CharT, _Alloc>;
  850. friend class _Rope_char_ptr_proxy<_CharT, _Alloc>;
  851. #ifdef __GC
  852. typedef _Rope_RopeRep<_CharT, _Alloc>* _Self_destruct_ptr;
  853. #else
  854. typedef _Rope_self_destruct_ptr<_CharT, _Alloc> _Self_destruct_ptr;
  855. #endif
  856. typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep;
  857. typedef rope<_CharT, _Alloc> _My_rope;
  858. std::size_t _M_pos;
  859. _CharT _M_current;
  860. bool _M_current_valid;
  861. _My_rope* _M_root; // The whole rope.
  862. public:
  863. _Rope_char_ref_proxy(_My_rope* __r, std::size_t __p)
  864. : _M_pos(__p), _M_current(), _M_current_valid(false), _M_root(__r) { }
  865. _Rope_char_ref_proxy(const _Rope_char_ref_proxy& __x)
  866. : _M_pos(__x._M_pos), _M_current(__x._M_current),
  867. _M_current_valid(false), _M_root(__x._M_root) { }
  868. // Don't preserve cache if the reference can outlive the
  869. // expression. We claim that's not possible without calling
  870. // a copy constructor or generating reference to a proxy
  871. // reference. We declare the latter to have undefined semantics.
  872. _Rope_char_ref_proxy(_My_rope* __r, std::size_t __p, _CharT __c)
  873. : _M_pos(__p), _M_current(__c), _M_current_valid(true), _M_root(__r) { }
  874. inline operator _CharT () const;
  875. _Rope_char_ref_proxy&
  876. operator=(_CharT __c);
  877. _Rope_char_ptr_proxy<_CharT, _Alloc> operator&() const;
  878. _Rope_char_ref_proxy&
  879. operator=(const _Rope_char_ref_proxy& __c)
  880. { return operator=((_CharT)__c); }
  881. };
  882. template<class _CharT, class __Alloc>
  883. inline void
  884. swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a,
  885. _Rope_char_ref_proxy <_CharT, __Alloc > __b)
  886. {
  887. _CharT __tmp = __a;
  888. __a = __b;
  889. __b = __tmp;
  890. }
  891. template<class _CharT, class _Alloc>
  892. class _Rope_char_ptr_proxy
  893. {
  894. // XXX this class should be rewritten.
  895. friend class _Rope_char_ref_proxy<_CharT, _Alloc>;
  896. std::size_t _M_pos;
  897. rope<_CharT,_Alloc>* _M_root; // The whole rope.
  898. public:
  899. _Rope_char_ptr_proxy(const _Rope_char_ref_proxy<_CharT,_Alloc>& __x)
  900. : _M_pos(__x._M_pos), _M_root(__x._M_root) { }
  901. _Rope_char_ptr_proxy(const _Rope_char_ptr_proxy& __x)
  902. : _M_pos(__x._M_pos), _M_root(__x._M_root) { }
  903. _Rope_char_ptr_proxy() { }
  904. _Rope_char_ptr_proxy(_CharT* __x)
  905. : _M_root(0), _M_pos(0) { }
  906. _Rope_char_ptr_proxy&
  907. operator=(const _Rope_char_ptr_proxy& __x)
  908. {
  909. _M_pos = __x._M_pos;
  910. _M_root = __x._M_root;
  911. return *this;
  912. }
  913. template<class _CharT2, class _Alloc2>
  914. friend bool
  915. operator==(const _Rope_char_ptr_proxy<_CharT2, _Alloc2>& __x,
  916. const _Rope_char_ptr_proxy<_CharT2, _Alloc2>& __y);
  917. _Rope_char_ref_proxy<_CharT, _Alloc> operator*() const
  918. { return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root, _M_pos); }
  919. };
  920. // Rope iterators:
  921. // Unlike in the C version, we cache only part of the stack
  922. // for rope iterators, since they must be efficiently copyable.
  923. // When we run out of cache, we have to reconstruct the iterator
  924. // value.
  925. // Pointers from iterators are not included in reference counts.
  926. // Iterators are assumed to be thread private. Ropes can
  927. // be shared.
  928. // Ignore warnings about std::iterator
  929. #pragma GCC diagnostic push
  930. #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  931. template<class _CharT, class _Alloc>
  932. class _Rope_iterator_base
  933. : public std::iterator<std::random_access_iterator_tag, _CharT>
  934. {
  935. friend class rope<_CharT, _Alloc>;
  936. public:
  937. typedef _Alloc _allocator_type; // used in _Rope_rotate, VC++ workaround
  938. typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep;
  939. // Borland doesn't want this to be protected.
  940. protected:
  941. enum { _S_path_cache_len = 4 }; // Must be <= 9.
  942. enum { _S_iterator_buf_len = 15 };
  943. std::size_t _M_current_pos;
  944. _RopeRep* _M_root; // The whole rope.
  945. std::size_t _M_leaf_pos; // Starting position for current leaf
  946. __GC_CONST _CharT* _M_buf_start;
  947. // Buffer possibly
  948. // containing current char.
  949. __GC_CONST _CharT* _M_buf_ptr;
  950. // Pointer to current char in buffer.
  951. // != 0 ==> buffer valid.
  952. __GC_CONST _CharT* _M_buf_end;
  953. // One past __last valid char in buffer.
  954. // What follows is the path cache. We go out of our
  955. // way to make this compact.
  956. // Path_end contains the bottom section of the path from
  957. // the root to the current leaf.
  958. const _RopeRep* _M_path_end[_S_path_cache_len];
  959. int _M_leaf_index; // Last valid __pos in path_end;
  960. // _M_path_end[0] ... _M_path_end[leaf_index-1]
  961. // point to concatenation nodes.
  962. unsigned char _M_path_directions;
  963. // (path_directions >> __i) & 1 is 1
  964. // iff we got from _M_path_end[leaf_index - __i - 1]
  965. // to _M_path_end[leaf_index - __i] by going to the
  966. // __right. Assumes path_cache_len <= 9.
  967. _CharT _M_tmp_buf[_S_iterator_buf_len];
  968. // Short buffer for surrounding chars.
  969. // This is useful primarily for
  970. // RopeFunctions. We put the buffer
  971. // here to avoid locking in the
  972. // multithreaded case.
  973. // The cached path is generally assumed to be valid
  974. // only if the buffer is valid.
  975. static void _S_setbuf(_Rope_iterator_base& __x);
  976. // Set buffer contents given
  977. // path cache.
  978. static void _S_setcache(_Rope_iterator_base& __x);
  979. // Set buffer contents and
  980. // path cache.
  981. static void _S_setcache_for_incr(_Rope_iterator_base& __x);
  982. // As above, but assumes path
  983. // cache is valid for previous posn.
  984. _Rope_iterator_base() { }
  985. _Rope_iterator_base(_RopeRep* __root, std::size_t __pos)
  986. : _M_current_pos(__pos), _M_root(__root), _M_buf_ptr(0) { }
  987. void _M_incr(std::size_t __n);
  988. void _M_decr(std::size_t __n);
  989. public:
  990. std::size_t
  991. index() const
  992. { return _M_current_pos; }
  993. _Rope_iterator_base(const _Rope_iterator_base& __x)
  994. {
  995. if (0 != __x._M_buf_ptr && __x._M_buf_start != __x._M_tmp_buf)
  996. *this = __x;
  997. else
  998. {
  999. _M_current_pos = __x._M_current_pos;
  1000. _M_root = __x._M_root;
  1001. _M_buf_ptr = 0;
  1002. }
  1003. }
  1004. };
  1005. #pragma GCC diagnostic pop
  1006. template<class _CharT, class _Alloc>
  1007. class _Rope_iterator;
  1008. template<class _CharT, class _Alloc>
  1009. class _Rope_const_iterator
  1010. : public _Rope_iterator_base<_CharT, _Alloc>
  1011. {
  1012. friend class rope<_CharT, _Alloc>;
  1013. protected:
  1014. typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep;
  1015. // The one from the base class may not be directly visible.
  1016. _Rope_const_iterator(const _RopeRep* __root, std::size_t __pos)
  1017. : _Rope_iterator_base<_CharT, _Alloc>(const_cast<_RopeRep*>(__root),
  1018. __pos)
  1019. // Only nonconst iterators modify root ref count
  1020. { }
  1021. public:
  1022. typedef _CharT reference; // Really a value. Returning a reference
  1023. // Would be a mess, since it would have
  1024. // to be included in refcount.
  1025. typedef const _CharT* pointer;
  1026. public:
  1027. _Rope_const_iterator() { }
  1028. _Rope_const_iterator(const _Rope_const_iterator& __x)
  1029. : _Rope_iterator_base<_CharT,_Alloc>(__x) { }
  1030. _Rope_const_iterator(const _Rope_iterator<_CharT,_Alloc>& __x);
  1031. _Rope_const_iterator(const rope<_CharT, _Alloc>& __r, std::size_t __pos)
  1032. : _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos) { }
  1033. _Rope_const_iterator&
  1034. operator=(const _Rope_const_iterator& __x)
  1035. {
  1036. if (0 != __x._M_buf_ptr && __x._M_buf_start != __x._M_tmp_buf)
  1037. *(static_cast<_Rope_iterator_base<_CharT, _Alloc>*>(this)) = __x;
  1038. else
  1039. {
  1040. this->_M_current_pos = __x._M_current_pos;
  1041. this->_M_root = __x._M_root;
  1042. this->_M_buf_ptr = 0;
  1043. }
  1044. return(*this);
  1045. }
  1046. reference
  1047. operator*()
  1048. {
  1049. if (0 == this->_M_buf_ptr)
  1050. this->_S_setcache(*this);
  1051. return *this->_M_buf_ptr;
  1052. }
  1053. // Without this const version, Rope iterators do not meet the
  1054. // requirements of an Input Iterator.
  1055. reference
  1056. operator*() const
  1057. {
  1058. return *const_cast<_Rope_const_iterator&>(*this);
  1059. }
  1060. _Rope_const_iterator&
  1061. operator++()
  1062. {
  1063. __GC_CONST _CharT* __next;
  1064. if (0 != this->_M_buf_ptr
  1065. && (__next = this->_M_buf_ptr + 1) < this->_M_buf_end)
  1066. {
  1067. this->_M_buf_ptr = __next;
  1068. ++this->_M_current_pos;
  1069. }
  1070. else
  1071. this->_M_incr(1);
  1072. return *this;
  1073. }
  1074. _Rope_const_iterator&
  1075. operator+=(std::ptrdiff_t __n)
  1076. {
  1077. if (__n >= 0)
  1078. this->_M_incr(__n);
  1079. else
  1080. this->_M_decr(-__n);
  1081. return *this;
  1082. }
  1083. _Rope_const_iterator&
  1084. operator--()
  1085. {
  1086. this->_M_decr(1);
  1087. return *this;
  1088. }
  1089. _Rope_const_iterator&
  1090. operator-=(std::ptrdiff_t __n)
  1091. {
  1092. if (__n >= 0)
  1093. this->_M_decr(__n);
  1094. else
  1095. this->_M_incr(-__n);
  1096. return *this;
  1097. }
  1098. _Rope_const_iterator
  1099. operator++(int)
  1100. {
  1101. std::size_t __old_pos = this->_M_current_pos;
  1102. this->_M_incr(1);
  1103. return _Rope_const_iterator<_CharT,_Alloc>(this->_M_root, __old_pos);
  1104. // This makes a subsequent dereference expensive.
  1105. // Perhaps we should instead copy the iterator
  1106. // if it has a valid cache?
  1107. }
  1108. _Rope_const_iterator
  1109. operator--(int)
  1110. {
  1111. std::size_t __old_pos = this->_M_current_pos;
  1112. this->_M_decr(1);
  1113. return _Rope_const_iterator<_CharT,_Alloc>(this->_M_root, __old_pos);
  1114. }
  1115. template<class _CharT2, class _Alloc2>
  1116. friend _Rope_const_iterator<_CharT2, _Alloc2>
  1117. operator-(const _Rope_const_iterator<_CharT2, _Alloc2>& __x,
  1118. std::ptrdiff_t __n);
  1119. template<class _CharT2, class _Alloc2>
  1120. friend _Rope_const_iterator<_CharT2, _Alloc2>
  1121. operator+(const _Rope_const_iterator<_CharT2, _Alloc2>& __x,
  1122. std::ptrdiff_t __n);
  1123. template<class _CharT2, class _Alloc2>
  1124. friend _Rope_const_iterator<_CharT2, _Alloc2>
  1125. operator+(std::ptrdiff_t __n,
  1126. const _Rope_const_iterator<_CharT2, _Alloc2>& __x);
  1127. reference
  1128. operator[](std::size_t __n)
  1129. { return rope<_CharT, _Alloc>::_S_fetch(this->_M_root,
  1130. this->_M_current_pos + __n); }
  1131. template<class _CharT2, class _Alloc2>
  1132. friend bool
  1133. operator==(const _Rope_const_iterator<_CharT2, _Alloc2>& __x,
  1134. const _Rope_const_iterator<_CharT2, _Alloc2>& __y);
  1135. template<class _CharT2, class _Alloc2>
  1136. friend bool
  1137. operator<(const _Rope_const_iterator<_CharT2, _Alloc2>& __x,
  1138. const _Rope_const_iterator<_CharT2, _Alloc2>& __y);
  1139. template<class _CharT2, class _Alloc2>
  1140. friend std::ptrdiff_t
  1141. operator-(const _Rope_const_iterator<_CharT2, _Alloc2>& __x,
  1142. const _Rope_const_iterator<_CharT2, _Alloc2>& __y);
  1143. };
  1144. template<class _CharT, class _Alloc>
  1145. class _Rope_iterator
  1146. : public _Rope_iterator_base<_CharT, _Alloc>
  1147. {
  1148. friend class rope<_CharT, _Alloc>;
  1149. protected:
  1150. typedef typename _Rope_iterator_base<_CharT, _Alloc>::_RopeRep _RopeRep;
  1151. rope<_CharT, _Alloc>* _M_root_rope;
  1152. // root is treated as a cached version of this, and is used to
  1153. // detect changes to the underlying rope.
  1154. // Root is included in the reference count. This is necessary
  1155. // so that we can detect changes reliably. Unfortunately, it
  1156. // requires careful bookkeeping for the nonGC case.
  1157. _Rope_iterator(rope<_CharT, _Alloc>* __r, std::size_t __pos)
  1158. : _Rope_iterator_base<_CharT, _Alloc>(__r->_M_tree_ptr, __pos),
  1159. _M_root_rope(__r)
  1160. { _RopeRep::_S_ref(this->_M_root);
  1161. if (!(__r -> empty()))
  1162. this->_S_setcache(*this);
  1163. }
  1164. void _M_check();
  1165. public:
  1166. typedef _Rope_char_ref_proxy<_CharT, _Alloc> reference;
  1167. typedef _Rope_char_ref_proxy<_CharT, _Alloc>* pointer;
  1168. rope<_CharT, _Alloc>&
  1169. container()
  1170. { return *_M_root_rope; }
  1171. _Rope_iterator()
  1172. {
  1173. this->_M_root = 0; // Needed for reference counting.
  1174. }
  1175. _Rope_iterator(const _Rope_iterator& __x)
  1176. : _Rope_iterator_base<_CharT, _Alloc>(__x)
  1177. {
  1178. _M_root_rope = __x._M_root_rope;
  1179. _RopeRep::_S_ref(this->_M_root);
  1180. }
  1181. _Rope_iterator(rope<_CharT, _Alloc>& __r, std::size_t __pos);
  1182. ~_Rope_iterator()
  1183. { _RopeRep::_S_unref(this->_M_root); }
  1184. _Rope_iterator&
  1185. operator=(const _Rope_iterator& __x)
  1186. {
  1187. _RopeRep* __old = this->_M_root;
  1188. _RopeRep::_S_ref(__x._M_root);
  1189. if (0 != __x._M_buf_ptr && __x._M_buf_start != __x._M_tmp_buf)
  1190. {
  1191. _M_root_rope = __x._M_root_rope;
  1192. *(static_cast<_Rope_iterator_base<_CharT, _Alloc>*>(this)) = __x;
  1193. }
  1194. else
  1195. {
  1196. this->_M_current_pos = __x._M_current_pos;
  1197. this->_M_root = __x._M_root;
  1198. _M_root_rope = __x._M_root_rope;
  1199. this->_M_buf_ptr = 0;
  1200. }
  1201. _RopeRep::_S_unref(__old);
  1202. return(*this);
  1203. }
  1204. reference
  1205. operator*()
  1206. {
  1207. _M_check();
  1208. if (0 == this->_M_buf_ptr)
  1209. return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root_rope,
  1210. this->_M_current_pos);
  1211. else
  1212. return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root_rope,
  1213. this->_M_current_pos,
  1214. *this->_M_buf_ptr);
  1215. }
  1216. // See above comment.
  1217. reference
  1218. operator*() const
  1219. {
  1220. return *const_cast<_Rope_iterator&>(*this);
  1221. }
  1222. _Rope_iterator&
  1223. operator++()
  1224. {
  1225. this->_M_incr(1);
  1226. return *this;
  1227. }
  1228. _Rope_iterator&
  1229. operator+=(std::ptrdiff_t __n)
  1230. {
  1231. if (__n >= 0)
  1232. this->_M_incr(__n);
  1233. else
  1234. this->_M_decr(-__n);
  1235. return *this;
  1236. }
  1237. _Rope_iterator&
  1238. operator--()
  1239. {
  1240. this->_M_decr(1);
  1241. return *this;
  1242. }
  1243. _Rope_iterator&
  1244. operator-=(std::ptrdiff_t __n)
  1245. {
  1246. if (__n >= 0)
  1247. this->_M_decr(__n);
  1248. else
  1249. this->_M_incr(-__n);
  1250. return *this;
  1251. }
  1252. _Rope_iterator
  1253. operator++(int)
  1254. {
  1255. std::size_t __old_pos = this->_M_current_pos;
  1256. this->_M_incr(1);
  1257. return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos);
  1258. }
  1259. _Rope_iterator
  1260. operator--(int)
  1261. {
  1262. std::size_t __old_pos = this->_M_current_pos;
  1263. this->_M_decr(1);
  1264. return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos);
  1265. }
  1266. reference
  1267. operator[](std::ptrdiff_t __n)
  1268. { return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root_rope,
  1269. this->_M_current_pos
  1270. + __n); }
  1271. template<class _CharT2, class _Alloc2>
  1272. friend bool
  1273. operator==(const _Rope_iterator<_CharT2, _Alloc2>& __x,
  1274. const _Rope_iterator<_CharT2, _Alloc2>& __y);
  1275. template<class _CharT2, class _Alloc2>
  1276. friend bool
  1277. operator<(const _Rope_iterator<_CharT2, _Alloc2>& __x,
  1278. const _Rope_iterator<_CharT2, _Alloc2>& __y);
  1279. template<class _CharT2, class _Alloc2>
  1280. friend std::ptrdiff_t
  1281. operator-(const _Rope_iterator<_CharT2, _Alloc2>& __x,
  1282. const _Rope_iterator<_CharT2, _Alloc2>& __y);
  1283. template<class _CharT2, class _Alloc2>
  1284. friend _Rope_iterator<_CharT2, _Alloc2>
  1285. operator-(const _Rope_iterator<_CharT2, _Alloc2>& __x,
  1286. std::ptrdiff_t __n);
  1287. template<class _CharT2, class _Alloc2>
  1288. friend _Rope_iterator<_CharT2, _Alloc2>
  1289. operator+(const _Rope_iterator<_CharT2, _Alloc2>& __x,
  1290. std::ptrdiff_t __n);
  1291. template<class _CharT2, class _Alloc2>
  1292. friend _Rope_iterator<_CharT2, _Alloc2>
  1293. operator+(std::ptrdiff_t __n,
  1294. const _Rope_iterator<_CharT2, _Alloc2>& __x);
  1295. };
  1296. template <class _CharT, class _Alloc>
  1297. struct _Rope_base
  1298. : public _Alloc
  1299. {
  1300. typedef _Alloc allocator_type;
  1301. allocator_type
  1302. get_allocator() const
  1303. { return *static_cast<const _Alloc*>(this); }
  1304. allocator_type&
  1305. _M_get_allocator()
  1306. { return *static_cast<_Alloc*>(this); }
  1307. const allocator_type&
  1308. _M_get_allocator() const
  1309. { return *static_cast<const _Alloc*>(this); }
  1310. typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep;
  1311. // The one in _Base may not be visible due to template rules.
  1312. _Rope_base(_RopeRep* __t, const allocator_type&)
  1313. : _M_tree_ptr(__t) { }
  1314. _Rope_base(const allocator_type&) { }
  1315. // The only data member of a rope:
  1316. _RopeRep *_M_tree_ptr;
  1317. #define __ROPE_DEFINE_ALLOC(_Tp, __name) \
  1318. typedef typename \
  1319. __alloc_traits<_Alloc>::template rebind<_Tp>::other __name##Alloc; \
  1320. static _Tp* __name##_allocate(std::size_t __n) \
  1321. { return __name##Alloc().allocate(__n); } \
  1322. static void __name##_deallocate(_Tp *__p, std::size_t __n) \
  1323. { __name##Alloc().deallocate(__p, __n); }
  1324. __ROPE_DEFINE_ALLOCS(_Alloc)
  1325. #undef __ROPE_DEFINE_ALLOC
  1326. protected:
  1327. _Rope_base&
  1328. operator=(const _Rope_base&);
  1329. _Rope_base(const _Rope_base&);
  1330. };
  1331. /**
  1332. * This is an SGI extension.
  1333. * @ingroup SGIextensions
  1334. * @doctodo
  1335. */
  1336. template <class _CharT, class _Alloc>
  1337. class rope : public _Rope_base<_CharT, _Alloc>
  1338. {
  1339. public:
  1340. typedef _CharT value_type;
  1341. typedef std::ptrdiff_t difference_type;
  1342. typedef std::size_t size_type;
  1343. typedef _CharT const_reference;
  1344. typedef const _CharT* const_pointer;
  1345. typedef _Rope_iterator<_CharT, _Alloc> iterator;
  1346. typedef _Rope_const_iterator<_CharT, _Alloc> const_iterator;
  1347. typedef _Rope_char_ref_proxy<_CharT, _Alloc> reference;
  1348. typedef _Rope_char_ptr_proxy<_CharT, _Alloc> pointer;
  1349. friend class _Rope_iterator<_CharT, _Alloc>;
  1350. friend class _Rope_const_iterator<_CharT, _Alloc>;
  1351. friend struct _Rope_RopeRep<_CharT, _Alloc>;
  1352. friend class _Rope_iterator_base<_CharT, _Alloc>;
  1353. friend class _Rope_char_ptr_proxy<_CharT, _Alloc>;
  1354. friend class _Rope_char_ref_proxy<_CharT, _Alloc>;
  1355. friend struct _Rope_RopeSubstring<_CharT, _Alloc>;
  1356. protected:
  1357. typedef _Rope_base<_CharT, _Alloc> _Base;
  1358. typedef typename _Base::allocator_type allocator_type;
  1359. using _Base::_M_tree_ptr;
  1360. using _Base::get_allocator;
  1361. using _Base::_M_get_allocator;
  1362. typedef __GC_CONST _CharT* _Cstrptr;
  1363. static _CharT _S_empty_c_str[1];
  1364. static bool
  1365. _S_is0(_CharT __c)
  1366. { return __c == _S_eos((_CharT*)0); }
  1367. enum { _S_copy_max = 23 };
  1368. // For strings shorter than _S_copy_max, we copy to
  1369. // concatenate.
  1370. typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep;
  1371. typedef _Rope_RopeConcatenation<_CharT, _Alloc> _RopeConcatenation;
  1372. typedef _Rope_RopeLeaf<_CharT, _Alloc> _RopeLeaf;
  1373. typedef _Rope_RopeFunction<_CharT, _Alloc> _RopeFunction;
  1374. typedef _Rope_RopeSubstring<_CharT, _Alloc> _RopeSubstring;
  1375. // Retrieve a character at the indicated position.
  1376. static _CharT _S_fetch(_RopeRep* __r, size_type __pos);
  1377. #ifndef __GC
  1378. // Obtain a pointer to the character at the indicated position.
  1379. // The pointer can be used to change the character.
  1380. // If such a pointer cannot be produced, as is frequently the
  1381. // case, 0 is returned instead.
  1382. // (Returns nonzero only if all nodes in the path have a refcount
  1383. // of 1.)
  1384. static _CharT* _S_fetch_ptr(_RopeRep* __r, size_type __pos);
  1385. #endif
  1386. static bool
  1387. _S_apply_to_pieces(// should be template parameter
  1388. _Rope_char_consumer<_CharT>& __c,
  1389. const _RopeRep* __r,
  1390. size_type __begin, size_type __end);
  1391. // begin and end are assumed to be in range.
  1392. #ifndef __GC
  1393. static void
  1394. _S_unref(_RopeRep* __t)
  1395. { _RopeRep::_S_unref(__t); }
  1396. static void
  1397. _S_ref(_RopeRep* __t)
  1398. { _RopeRep::_S_ref(__t); }
  1399. #else /* __GC */
  1400. static void _S_unref(_RopeRep*) { }
  1401. static void _S_ref(_RopeRep*) { }
  1402. #endif
  1403. #ifdef __GC
  1404. typedef _Rope_RopeRep<_CharT, _Alloc>* _Self_destruct_ptr;
  1405. #else
  1406. typedef _Rope_self_destruct_ptr<_CharT, _Alloc> _Self_destruct_ptr;
  1407. #endif
  1408. // _Result is counted in refcount.
  1409. static _RopeRep* _S_substring(_RopeRep* __base,
  1410. size_type __start, size_type __endp1);
  1411. static _RopeRep* _S_concat_char_iter(_RopeRep* __r,
  1412. const _CharT* __iter,
  1413. size_type __slen,
  1414. allocator_type& __a);
  1415. // Concatenate rope and char ptr, copying __iter.
  1416. // Should really take an arbitrary iterator.
  1417. // Result is counted in refcount.
  1418. static _RopeRep* _S_destr_concat_char_iter(_RopeRep* __r,
  1419. const _CharT* __iter,
  1420. size_type __slen,
  1421. allocator_type& __a)
  1422. // As above, but one reference to __r is about to be
  1423. // destroyed. Thus the pieces may be recycled if all
  1424. // relevant reference counts are 1.
  1425. #ifdef __GC
  1426. // We can't really do anything since refcounts are unavailable.
  1427. { return _S_concat_char_iter(__r, __iter, __slen, __a); }
  1428. #else
  1429. ;
  1430. #endif
  1431. static _RopeRep* _S_concat(_RopeRep* __left, _RopeRep* __right);
  1432. // General concatenation on _RopeRep. _Result
  1433. // has refcount of 1. Adjusts argument refcounts.
  1434. public:
  1435. void
  1436. apply_to_pieces(size_type __begin, size_type __end,
  1437. _Rope_char_consumer<_CharT>& __c) const
  1438. { _S_apply_to_pieces(__c, this->_M_tree_ptr, __begin, __end); }
  1439. protected:
  1440. static size_type
  1441. _S_rounded_up_size(size_type __n)
  1442. { return _RopeLeaf::_S_rounded_up_size(__n); }
  1443. static size_type
  1444. _S_allocated_capacity(size_type __n)
  1445. {
  1446. if (_S_is_basic_char_type((_CharT*)0))
  1447. return _S_rounded_up_size(__n) - 1;
  1448. else
  1449. return _S_rounded_up_size(__n);
  1450. }
  1451. // Allocate and construct a RopeLeaf using the supplied allocator
  1452. // Takes ownership of s instead of copying.
  1453. static _RopeLeaf*
  1454. _S_new_RopeLeaf(__GC_CONST _CharT *__s,
  1455. size_type __size, allocator_type& __a)
  1456. {
  1457. _RopeLeaf* __space = typename _Base::_LAlloc(__a).allocate(1);
  1458. return new(__space) _RopeLeaf(__s, __size, __a);
  1459. }
  1460. static _RopeConcatenation*
  1461. _S_new_RopeConcatenation(_RopeRep* __left, _RopeRep* __right,
  1462. allocator_type& __a)
  1463. {
  1464. _RopeConcatenation* __space = typename _Base::_CAlloc(__a).allocate(1);
  1465. return new(__space) _RopeConcatenation(__left, __right, __a);
  1466. }
  1467. static _RopeFunction*
  1468. _S_new_RopeFunction(char_producer<_CharT>* __f,
  1469. size_type __size, bool __d, allocator_type& __a)
  1470. {
  1471. _RopeFunction* __space = typename _Base::_FAlloc(__a).allocate(1);
  1472. return new(__space) _RopeFunction(__f, __size, __d, __a);
  1473. }
  1474. static _RopeSubstring*
  1475. _S_new_RopeSubstring(_Rope_RopeRep<_CharT,_Alloc>* __b, size_type __s,
  1476. size_type __l, allocator_type& __a)
  1477. {
  1478. _RopeSubstring* __space = typename _Base::_SAlloc(__a).allocate(1);
  1479. return new(__space) _RopeSubstring(__b, __s, __l, __a);
  1480. }
  1481. static _RopeLeaf*
  1482. _S_RopeLeaf_from_unowned_char_ptr(const _CharT *__s,
  1483. size_type __size, allocator_type& __a)
  1484. #define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) \
  1485. _S_RopeLeaf_from_unowned_char_ptr(__s, __size, __a)
  1486. {
  1487. if (0 == __size)
  1488. return 0;
  1489. _CharT* __buf = __a.allocate(_S_rounded_up_size(__size));
  1490. __uninitialized_copy_n_a(__s, __size, __buf, __a);
  1491. _S_cond_store_eos(__buf[__size]);
  1492. __try
  1493. { return _S_new_RopeLeaf(__buf, __size, __a); }
  1494. __catch(...)
  1495. {
  1496. _RopeRep::__STL_FREE_STRING(__buf, __size, __a);
  1497. __throw_exception_again;
  1498. }
  1499. }
  1500. // Concatenation of nonempty strings.
  1501. // Always builds a concatenation node.
  1502. // Rebalances if the result is too deep.
  1503. // Result has refcount 1.
  1504. // Does not increment left and right ref counts even though
  1505. // they are referenced.
  1506. static _RopeRep*
  1507. _S_tree_concat(_RopeRep* __left, _RopeRep* __right);
  1508. // Concatenation helper functions
  1509. static _RopeLeaf*
  1510. _S_leaf_concat_char_iter(_RopeLeaf* __r,
  1511. const _CharT* __iter, size_type __slen);
  1512. // Concatenate by copying leaf.
  1513. // should take an arbitrary iterator
  1514. // result has refcount 1.
  1515. #ifndef __GC
  1516. static _RopeLeaf*
  1517. _S_destr_leaf_concat_char_iter(_RopeLeaf* __r,
  1518. const _CharT* __iter, size_type __slen);
  1519. // A version that potentially clobbers __r if __r->_M_ref_count == 1.
  1520. #endif
  1521. private:
  1522. static size_type _S_char_ptr_len(const _CharT* __s);
  1523. // slightly generalized strlen
  1524. rope(_RopeRep* __t, const allocator_type& __a = allocator_type())
  1525. : _Base(__t, __a) { }
  1526. // Copy __r to the _CharT buffer.
  1527. // Returns __buffer + __r->_M_size.
  1528. // Assumes that buffer is uninitialized.
  1529. static _CharT* _S_flatten(_RopeRep* __r, _CharT* __buffer);
  1530. // Again, with explicit starting position and length.
  1531. // Assumes that buffer is uninitialized.
  1532. static _CharT* _S_flatten(_RopeRep* __r,
  1533. size_type __start, size_type __len,
  1534. _CharT* __buffer);
  1535. static const unsigned long
  1536. _S_min_len[__detail::_S_max_rope_depth + 1];
  1537. static bool
  1538. _S_is_balanced(_RopeRep* __r)
  1539. { return (__r->_M_size >= _S_min_len[__r->_M_depth]); }
  1540. static bool
  1541. _S_is_almost_balanced(_RopeRep* __r)
  1542. { return (__r->_M_depth == 0
  1543. || __r->_M_size >= _S_min_len[__r->_M_depth - 1]); }
  1544. static bool
  1545. _S_is_roughly_balanced(_RopeRep* __r)
  1546. { return (__r->_M_depth <= 1
  1547. || __r->_M_size >= _S_min_len[__r->_M_depth - 2]); }
  1548. // Assumes the result is not empty.
  1549. static _RopeRep*
  1550. _S_concat_and_set_balanced(_RopeRep* __left, _RopeRep* __right)
  1551. {
  1552. _RopeRep* __result = _S_concat(__left, __right);
  1553. if (_S_is_balanced(__result))
  1554. __result->_M_is_balanced = true;
  1555. return __result;
  1556. }
  1557. // The basic rebalancing operation. Logically copies the
  1558. // rope. The result has refcount of 1. The client will
  1559. // usually decrement the reference count of __r.
  1560. // The result is within height 2 of balanced by the above
  1561. // definition.
  1562. static _RopeRep* _S_balance(_RopeRep* __r);
  1563. // Add all unbalanced subtrees to the forest of balanced trees.
  1564. // Used only by balance.
  1565. static void _S_add_to_forest(_RopeRep*__r, _RopeRep** __forest);
  1566. // Add __r to forest, assuming __r is already balanced.
  1567. static void _S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest);
  1568. // Print to stdout, exposing structure
  1569. static void _S_dump(_RopeRep* __r, int __indent = 0);
  1570. // Return -1, 0, or 1 if __x < __y, __x == __y, or __x > __y resp.
  1571. static int _S_compare(const _RopeRep* __x, const _RopeRep* __y);
  1572. public:
  1573. _GLIBCXX_NODISCARD bool
  1574. empty() const
  1575. { return 0 == this->_M_tree_ptr; }
  1576. // Comparison member function. This is public only for those
  1577. // clients that need a ternary comparison. Others
  1578. // should use the comparison operators below.
  1579. int
  1580. compare(const rope& __y) const
  1581. { return _S_compare(this->_M_tree_ptr, __y._M_tree_ptr); }
  1582. rope(const _CharT* __s, const allocator_type& __a = allocator_type())
  1583. : _Base(__a)
  1584. {
  1585. this->_M_tree_ptr =
  1586. __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, _S_char_ptr_len(__s),
  1587. _M_get_allocator());
  1588. }
  1589. rope(const _CharT* __s, size_type __len,
  1590. const allocator_type& __a = allocator_type())
  1591. : _Base(__a)
  1592. {
  1593. this->_M_tree_ptr =
  1594. __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __len, _M_get_allocator());
  1595. }
  1596. // Should perhaps be templatized with respect to the iterator type
  1597. // and use Sequence_buffer. (It should perhaps use sequence_buffer
  1598. // even now.)
  1599. rope(const _CharT* __s, const _CharT* __e,
  1600. const allocator_type& __a = allocator_type())
  1601. : _Base(__a)
  1602. {
  1603. this->_M_tree_ptr =
  1604. __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __e - __s, _M_get_allocator());
  1605. }
  1606. rope(const const_iterator& __s, const const_iterator& __e,
  1607. const allocator_type& __a = allocator_type())
  1608. : _Base(_S_substring(__s._M_root, __s._M_current_pos,
  1609. __e._M_current_pos), __a)
  1610. { }
  1611. rope(const iterator& __s, const iterator& __e,
  1612. const allocator_type& __a = allocator_type())
  1613. : _Base(_S_substring(__s._M_root, __s._M_current_pos,
  1614. __e._M_current_pos), __a)
  1615. { }
  1616. rope(_CharT __c, const allocator_type& __a = allocator_type())
  1617. : _Base(__a)
  1618. {
  1619. _CharT* __buf = this->_Data_allocate(_S_rounded_up_size(1));
  1620. __alloc_traits<allocator_type>::construct(_M_get_allocator(),
  1621. __buf, __c);
  1622. __try
  1623. {
  1624. this->_M_tree_ptr = _S_new_RopeLeaf(__buf, 1,
  1625. _M_get_allocator());
  1626. }
  1627. __catch(...)
  1628. {
  1629. _RopeRep::__STL_FREE_STRING(__buf, 1, _M_get_allocator());
  1630. __throw_exception_again;
  1631. }
  1632. }
  1633. rope(size_type __n, _CharT __c,
  1634. const allocator_type& __a = allocator_type());
  1635. rope(const allocator_type& __a = allocator_type())
  1636. : _Base(0, __a) { }
  1637. // Construct a rope from a function that can compute its members
  1638. rope(char_producer<_CharT> *__fn, size_type __len, bool __delete_fn,
  1639. const allocator_type& __a = allocator_type())
  1640. : _Base(__a)
  1641. {
  1642. this->_M_tree_ptr = (0 == __len)
  1643. ? 0
  1644. : _S_new_RopeFunction(__fn, __len, __delete_fn, _M_get_allocator());
  1645. }
  1646. rope(const rope& __x, const allocator_type& __a = allocator_type())
  1647. : _Base(__x._M_tree_ptr, __a)
  1648. { _S_ref(this->_M_tree_ptr); }
  1649. ~rope() throw()
  1650. { _S_unref(this->_M_tree_ptr); }
  1651. rope&
  1652. operator=(const rope& __x)
  1653. {
  1654. _RopeRep* __old = this->_M_tree_ptr;
  1655. this->_M_tree_ptr = __x._M_tree_ptr;
  1656. _S_ref(this->_M_tree_ptr);
  1657. _S_unref(__old);
  1658. return *this;
  1659. }
  1660. void
  1661. clear()
  1662. {
  1663. _S_unref(this->_M_tree_ptr);
  1664. this->_M_tree_ptr = 0;
  1665. }
  1666. void
  1667. push_back(_CharT __x)
  1668. {
  1669. allocator_type __a = _M_get_allocator();
  1670. _RopeRep* __old = this->_M_tree_ptr;
  1671. this->_M_tree_ptr
  1672. = _S_destr_concat_char_iter(this->_M_tree_ptr, &__x, 1, __a);
  1673. _S_unref(__old);
  1674. }
  1675. void
  1676. pop_back()
  1677. {
  1678. _RopeRep* __old = this->_M_tree_ptr;
  1679. this->_M_tree_ptr = _S_substring(this->_M_tree_ptr,
  1680. 0, this->_M_tree_ptr->_M_size - 1);
  1681. _S_unref(__old);
  1682. }
  1683. _CharT
  1684. back() const
  1685. { return _S_fetch(this->_M_tree_ptr, this->_M_tree_ptr->_M_size - 1); }
  1686. void
  1687. push_front(_CharT __x)
  1688. {
  1689. _RopeRep* __old = this->_M_tree_ptr;
  1690. _RopeRep* __left =
  1691. __STL_ROPE_FROM_UNOWNED_CHAR_PTR(&__x, 1, _M_get_allocator());
  1692. __try
  1693. {
  1694. this->_M_tree_ptr = _S_concat(__left, this->_M_tree_ptr);
  1695. _S_unref(__old);
  1696. _S_unref(__left);
  1697. }
  1698. __catch(...)
  1699. {
  1700. _S_unref(__left);
  1701. __throw_exception_again;
  1702. }
  1703. }
  1704. void
  1705. pop_front()
  1706. {
  1707. _RopeRep* __old = this->_M_tree_ptr;
  1708. this->_M_tree_ptr
  1709. = _S_substring(this->_M_tree_ptr, 1, this->_M_tree_ptr->_M_size);
  1710. _S_unref(__old);
  1711. }
  1712. _CharT
  1713. front() const
  1714. { return _S_fetch(this->_M_tree_ptr, 0); }
  1715. void
  1716. balance()
  1717. {
  1718. _RopeRep* __old = this->_M_tree_ptr;
  1719. this->_M_tree_ptr = _S_balance(this->_M_tree_ptr);
  1720. _S_unref(__old);
  1721. }
  1722. void
  1723. copy(_CharT* __buffer) const
  1724. {
  1725. _Destroy_const(__buffer, __buffer + size(), _M_get_allocator());
  1726. _S_flatten(this->_M_tree_ptr, __buffer);
  1727. }
  1728. // This is the copy function from the standard, but
  1729. // with the arguments reordered to make it consistent with the
  1730. // rest of the interface.
  1731. // Note that this guaranteed not to compile if the draft standard
  1732. // order is assumed.
  1733. size_type
  1734. copy(size_type __pos, size_type __n, _CharT* __buffer) const
  1735. {
  1736. size_type __size = size();
  1737. size_type __len = (__pos + __n > __size? __size - __pos : __n);
  1738. _Destroy_const(__buffer, __buffer + __len, _M_get_allocator());
  1739. _S_flatten(this->_M_tree_ptr, __pos, __len, __buffer);
  1740. return __len;
  1741. }
  1742. // Print to stdout, exposing structure. May be useful for
  1743. // performance debugging.
  1744. void
  1745. dump()
  1746. { _S_dump(this->_M_tree_ptr); }
  1747. // Convert to 0 terminated string in new allocated memory.
  1748. // Embedded 0s in the input do not terminate the copy.
  1749. const _CharT* c_str() const;
  1750. // As above, but also use the flattened representation as
  1751. // the new rope representation.
  1752. const _CharT* replace_with_c_str();
  1753. // Reclaim memory for the c_str generated flattened string.
  1754. // Intentionally undocumented, since it's hard to say when this
  1755. // is safe for multiple threads.
  1756. void
  1757. delete_c_str ()
  1758. {
  1759. if (0 == this->_M_tree_ptr)
  1760. return;
  1761. if (__detail::_S_leaf == this->_M_tree_ptr->_M_tag &&
  1762. ((_RopeLeaf*)this->_M_tree_ptr)->_M_data ==
  1763. this->_M_tree_ptr->_M_c_string)
  1764. {
  1765. // Representation shared
  1766. return;
  1767. }
  1768. #ifndef __GC
  1769. this->_M_tree_ptr->_M_free_c_string();
  1770. #endif
  1771. this->_M_tree_ptr->_M_c_string = 0;
  1772. }
  1773. _CharT
  1774. operator[] (size_type __pos) const
  1775. { return _S_fetch(this->_M_tree_ptr, __pos); }
  1776. _CharT
  1777. at(size_type __pos) const
  1778. {
  1779. // if (__pos >= size()) throw out_of_range; // XXX
  1780. return (*this)[__pos];
  1781. }
  1782. const_iterator
  1783. begin() const
  1784. { return(const_iterator(this->_M_tree_ptr, 0)); }
  1785. // An easy way to get a const iterator from a non-const container.
  1786. const_iterator
  1787. const_begin() const
  1788. { return(const_iterator(this->_M_tree_ptr, 0)); }
  1789. const_iterator
  1790. end() const
  1791. { return(const_iterator(this->_M_tree_ptr, size())); }
  1792. const_iterator
  1793. const_end() const
  1794. { return(const_iterator(this->_M_tree_ptr, size())); }
  1795. size_type
  1796. size() const
  1797. { return(0 == this->_M_tree_ptr? 0 : this->_M_tree_ptr->_M_size); }
  1798. size_type
  1799. length() const
  1800. { return size(); }
  1801. size_type
  1802. max_size() const
  1803. {
  1804. return _S_min_len[int(__detail::_S_max_rope_depth) - 1] - 1;
  1805. // Guarantees that the result can be sufficiently
  1806. // balanced. Longer ropes will probably still work,
  1807. // but it's harder to make guarantees.
  1808. }
  1809. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  1810. const_reverse_iterator
  1811. rbegin() const
  1812. { return const_reverse_iterator(end()); }
  1813. const_reverse_iterator
  1814. const_rbegin() const
  1815. { return const_reverse_iterator(end()); }
  1816. const_reverse_iterator
  1817. rend() const
  1818. { return const_reverse_iterator(begin()); }
  1819. const_reverse_iterator
  1820. const_rend() const
  1821. { return const_reverse_iterator(begin()); }
  1822. template<class _CharT2, class _Alloc2>
  1823. friend rope<_CharT2, _Alloc2>
  1824. operator+(const rope<_CharT2, _Alloc2>& __left,
  1825. const rope<_CharT2, _Alloc2>& __right);
  1826. template<class _CharT2, class _Alloc2>
  1827. friend rope<_CharT2, _Alloc2>
  1828. operator+(const rope<_CharT2, _Alloc2>& __left, const _CharT2* __right);
  1829. template<class _CharT2, class _Alloc2>
  1830. friend rope<_CharT2, _Alloc2>
  1831. operator+(const rope<_CharT2, _Alloc2>& __left, _CharT2 __right);
  1832. // The symmetric cases are intentionally omitted, since they're
  1833. // presumed to be less common, and we don't handle them as well.
  1834. // The following should really be templatized. The first
  1835. // argument should be an input iterator or forward iterator with
  1836. // value_type _CharT.
  1837. rope&
  1838. append(const _CharT* __iter, size_type __n)
  1839. {
  1840. allocator_type __a = _M_get_allocator();
  1841. _RopeRep* __result =
  1842. _S_destr_concat_char_iter(this->_M_tree_ptr, __iter, __n, __a);
  1843. _S_unref(this->_M_tree_ptr);
  1844. this->_M_tree_ptr = __result;
  1845. return *this;
  1846. }
  1847. rope&
  1848. append(const _CharT* __c_string)
  1849. {
  1850. size_type __len = _S_char_ptr_len(__c_string);
  1851. append(__c_string, __len);
  1852. return(*this);
  1853. }
  1854. rope&
  1855. append(const _CharT* __s, const _CharT* __e)
  1856. {
  1857. allocator_type __a = _M_get_allocator();
  1858. _RopeRep* __result =
  1859. _S_destr_concat_char_iter(this->_M_tree_ptr, __s, __e - __s, __a);
  1860. _S_unref(this->_M_tree_ptr);
  1861. this->_M_tree_ptr = __result;
  1862. return *this;
  1863. }
  1864. rope&
  1865. append(const_iterator __s, const_iterator __e)
  1866. {
  1867. _Self_destruct_ptr __appendee(_S_substring(__s._M_root,
  1868. __s._M_current_pos,
  1869. __e._M_current_pos));
  1870. _RopeRep* __result = _S_concat(this->_M_tree_ptr,
  1871. (_RopeRep*)__appendee);
  1872. _S_unref(this->_M_tree_ptr);
  1873. this->_M_tree_ptr = __result;
  1874. return *this;
  1875. }
  1876. rope&
  1877. append(_CharT __c)
  1878. {
  1879. allocator_type __a = _M_get_allocator();
  1880. _RopeRep* __result =
  1881. _S_destr_concat_char_iter(this->_M_tree_ptr, &__c, 1, __a);
  1882. _S_unref(this->_M_tree_ptr);
  1883. this->_M_tree_ptr = __result;
  1884. return *this;
  1885. }
  1886. rope&
  1887. append()
  1888. { return append(_CharT()); } // XXX why?
  1889. rope&
  1890. append(const rope& __y)
  1891. {
  1892. _RopeRep* __result = _S_concat(this->_M_tree_ptr, __y._M_tree_ptr);
  1893. _S_unref(this->_M_tree_ptr);
  1894. this->_M_tree_ptr = __result;
  1895. return *this;
  1896. }
  1897. rope&
  1898. append(size_type __n, _CharT __c)
  1899. {
  1900. rope<_CharT,_Alloc> __last(__n, __c);
  1901. return append(__last);
  1902. }
  1903. void
  1904. swap(rope& __b)
  1905. {
  1906. _RopeRep* __tmp = this->_M_tree_ptr;
  1907. this->_M_tree_ptr = __b._M_tree_ptr;
  1908. __b._M_tree_ptr = __tmp;
  1909. }
  1910. protected:
  1911. // Result is included in refcount.
  1912. static _RopeRep*
  1913. replace(_RopeRep* __old, size_type __pos1,
  1914. size_type __pos2, _RopeRep* __r)
  1915. {
  1916. if (0 == __old)
  1917. {
  1918. _S_ref(__r);
  1919. return __r;
  1920. }
  1921. _Self_destruct_ptr __left(_S_substring(__old, 0, __pos1));
  1922. _Self_destruct_ptr __right(_S_substring(__old, __pos2, __old->_M_size));
  1923. _RopeRep* __result;
  1924. if (0 == __r)
  1925. __result = _S_concat(__left, __right);
  1926. else
  1927. {
  1928. _Self_destruct_ptr __left_result(_S_concat(__left, __r));
  1929. __result = _S_concat(__left_result, __right);
  1930. }
  1931. return __result;
  1932. }
  1933. public:
  1934. void
  1935. insert(size_type __p, const rope& __r)
  1936. {
  1937. _RopeRep* __result =
  1938. replace(this->_M_tree_ptr, __p, __p, __r._M_tree_ptr);
  1939. _S_unref(this->_M_tree_ptr);
  1940. this->_M_tree_ptr = __result;
  1941. }
  1942. void
  1943. insert(size_type __p, size_type __n, _CharT __c)
  1944. {
  1945. rope<_CharT,_Alloc> __r(__n,__c);
  1946. insert(__p, __r);
  1947. }
  1948. void
  1949. insert(size_type __p, const _CharT* __i, size_type __n)
  1950. {
  1951. _Self_destruct_ptr __left(_S_substring(this->_M_tree_ptr, 0, __p));
  1952. _Self_destruct_ptr __right(_S_substring(this->_M_tree_ptr,
  1953. __p, size()));
  1954. _Self_destruct_ptr __left_result(_S_concat_char_iter(__left, __i, __n,
  1955. _M_get_allocator()));
  1956. // _S_ destr_concat_char_iter should be safe here.
  1957. // But as it stands it's probably not a win, since __left
  1958. // is likely to have additional references.
  1959. _RopeRep* __result = _S_concat(__left_result, __right);
  1960. _S_unref(this->_M_tree_ptr);
  1961. this->_M_tree_ptr = __result;
  1962. }
  1963. void
  1964. insert(size_type __p, const _CharT* __c_string)
  1965. { insert(__p, __c_string, _S_char_ptr_len(__c_string)); }
  1966. void
  1967. insert(size_type __p, _CharT __c)
  1968. { insert(__p, &__c, 1); }
  1969. void
  1970. insert(size_type __p)
  1971. {
  1972. _CharT __c = _CharT();
  1973. insert(__p, &__c, 1);
  1974. }
  1975. void
  1976. insert(size_type __p, const _CharT* __i, const _CharT* __j)
  1977. {
  1978. rope __r(__i, __j);
  1979. insert(__p, __r);
  1980. }
  1981. void
  1982. insert(size_type __p, const const_iterator& __i,
  1983. const const_iterator& __j)
  1984. {
  1985. rope __r(__i, __j);
  1986. insert(__p, __r);
  1987. }
  1988. void
  1989. insert(size_type __p, const iterator& __i,
  1990. const iterator& __j)
  1991. {
  1992. rope __r(__i, __j);
  1993. insert(__p, __r);
  1994. }
  1995. // (position, length) versions of replace operations:
  1996. void
  1997. replace(size_type __p, size_type __n, const rope& __r)
  1998. {
  1999. _RopeRep* __result =
  2000. replace(this->_M_tree_ptr, __p, __p + __n, __r._M_tree_ptr);
  2001. _S_unref(this->_M_tree_ptr);
  2002. this->_M_tree_ptr = __result;
  2003. }
  2004. void
  2005. replace(size_type __p, size_type __n,
  2006. const _CharT* __i, size_type __i_len)
  2007. {
  2008. rope __r(__i, __i_len);
  2009. replace(__p, __n, __r);
  2010. }
  2011. void
  2012. replace(size_type __p, size_type __n, _CharT __c)
  2013. {
  2014. rope __r(__c);
  2015. replace(__p, __n, __r);
  2016. }
  2017. void
  2018. replace(size_type __p, size_type __n, const _CharT* __c_string)
  2019. {
  2020. rope __r(__c_string);
  2021. replace(__p, __n, __r);
  2022. }
  2023. void
  2024. replace(size_type __p, size_type __n,
  2025. const _CharT* __i, const _CharT* __j)
  2026. {
  2027. rope __r(__i, __j);
  2028. replace(__p, __n, __r);
  2029. }
  2030. void
  2031. replace(size_type __p, size_type __n,
  2032. const const_iterator& __i, const const_iterator& __j)
  2033. {
  2034. rope __r(__i, __j);
  2035. replace(__p, __n, __r);
  2036. }
  2037. void
  2038. replace(size_type __p, size_type __n,
  2039. const iterator& __i, const iterator& __j)
  2040. {
  2041. rope __r(__i, __j);
  2042. replace(__p, __n, __r);
  2043. }
  2044. // Single character variants:
  2045. void
  2046. replace(size_type __p, _CharT __c)
  2047. {
  2048. iterator __i(this, __p);
  2049. *__i = __c;
  2050. }
  2051. void
  2052. replace(size_type __p, const rope& __r)
  2053. { replace(__p, 1, __r); }
  2054. void
  2055. replace(size_type __p, const _CharT* __i, size_type __i_len)
  2056. { replace(__p, 1, __i, __i_len); }
  2057. void
  2058. replace(size_type __p, const _CharT* __c_string)
  2059. { replace(__p, 1, __c_string); }
  2060. void
  2061. replace(size_type __p, const _CharT* __i, const _CharT* __j)
  2062. { replace(__p, 1, __i, __j); }
  2063. void
  2064. replace(size_type __p, const const_iterator& __i,
  2065. const const_iterator& __j)
  2066. { replace(__p, 1, __i, __j); }
  2067. void
  2068. replace(size_type __p, const iterator& __i,
  2069. const iterator& __j)
  2070. { replace(__p, 1, __i, __j); }
  2071. // Erase, (position, size) variant.
  2072. void
  2073. erase(size_type __p, size_type __n)
  2074. {
  2075. _RopeRep* __result = replace(this->_M_tree_ptr, __p,
  2076. __p + __n, 0);
  2077. _S_unref(this->_M_tree_ptr);
  2078. this->_M_tree_ptr = __result;
  2079. }
  2080. // Insert, iterator variants.
  2081. iterator
  2082. insert(const iterator& __p, const rope& __r)
  2083. {
  2084. insert(__p.index(), __r);
  2085. return __p;
  2086. }
  2087. iterator
  2088. insert(const iterator& __p, size_type __n, _CharT __c)
  2089. {
  2090. insert(__p.index(), __n, __c);
  2091. return __p;
  2092. }
  2093. iterator insert(const iterator& __p, _CharT __c)
  2094. {
  2095. insert(__p.index(), __c);
  2096. return __p;
  2097. }
  2098. iterator
  2099. insert(const iterator& __p )
  2100. {
  2101. insert(__p.index());
  2102. return __p;
  2103. }
  2104. iterator
  2105. insert(const iterator& __p, const _CharT* c_string)
  2106. {
  2107. insert(__p.index(), c_string);
  2108. return __p;
  2109. }
  2110. iterator
  2111. insert(const iterator& __p, const _CharT* __i, size_type __n)
  2112. {
  2113. insert(__p.index(), __i, __n);
  2114. return __p;
  2115. }
  2116. iterator
  2117. insert(const iterator& __p, const _CharT* __i,
  2118. const _CharT* __j)
  2119. {
  2120. insert(__p.index(), __i, __j);
  2121. return __p;
  2122. }
  2123. iterator
  2124. insert(const iterator& __p,
  2125. const const_iterator& __i, const const_iterator& __j)
  2126. {
  2127. insert(__p.index(), __i, __j);
  2128. return __p;
  2129. }
  2130. iterator
  2131. insert(const iterator& __p,
  2132. const iterator& __i, const iterator& __j)
  2133. {
  2134. insert(__p.index(), __i, __j);
  2135. return __p;
  2136. }
  2137. // Replace, range variants.
  2138. void
  2139. replace(const iterator& __p, const iterator& __q, const rope& __r)
  2140. { replace(__p.index(), __q.index() - __p.index(), __r); }
  2141. void
  2142. replace(const iterator& __p, const iterator& __q, _CharT __c)
  2143. { replace(__p.index(), __q.index() - __p.index(), __c); }
  2144. void
  2145. replace(const iterator& __p, const iterator& __q,
  2146. const _CharT* __c_string)
  2147. { replace(__p.index(), __q.index() - __p.index(), __c_string); }
  2148. void
  2149. replace(const iterator& __p, const iterator& __q,
  2150. const _CharT* __i, size_type __n)
  2151. { replace(__p.index(), __q.index() - __p.index(), __i, __n); }
  2152. void
  2153. replace(const iterator& __p, const iterator& __q,
  2154. const _CharT* __i, const _CharT* __j)
  2155. { replace(__p.index(), __q.index() - __p.index(), __i, __j); }
  2156. void
  2157. replace(const iterator& __p, const iterator& __q,
  2158. const const_iterator& __i, const const_iterator& __j)
  2159. { replace(__p.index(), __q.index() - __p.index(), __i, __j); }
  2160. void
  2161. replace(const iterator& __p, const iterator& __q,
  2162. const iterator& __i, const iterator& __j)
  2163. { replace(__p.index(), __q.index() - __p.index(), __i, __j); }
  2164. // Replace, iterator variants.
  2165. void
  2166. replace(const iterator& __p, const rope& __r)
  2167. { replace(__p.index(), __r); }
  2168. void
  2169. replace(const iterator& __p, _CharT __c)
  2170. { replace(__p.index(), __c); }
  2171. void
  2172. replace(const iterator& __p, const _CharT* __c_string)
  2173. { replace(__p.index(), __c_string); }
  2174. void
  2175. replace(const iterator& __p, const _CharT* __i, size_type __n)
  2176. { replace(__p.index(), __i, __n); }
  2177. void
  2178. replace(const iterator& __p, const _CharT* __i, const _CharT* __j)
  2179. { replace(__p.index(), __i, __j); }
  2180. void
  2181. replace(const iterator& __p, const_iterator __i, const_iterator __j)
  2182. { replace(__p.index(), __i, __j); }
  2183. void
  2184. replace(const iterator& __p, iterator __i, iterator __j)
  2185. { replace(__p.index(), __i, __j); }
  2186. // Iterator and range variants of erase
  2187. iterator
  2188. erase(const iterator& __p, const iterator& __q)
  2189. {
  2190. size_type __p_index = __p.index();
  2191. erase(__p_index, __q.index() - __p_index);
  2192. return iterator(this, __p_index);
  2193. }
  2194. iterator
  2195. erase(const iterator& __p)
  2196. {
  2197. size_type __p_index = __p.index();
  2198. erase(__p_index, 1);
  2199. return iterator(this, __p_index);
  2200. }
  2201. rope
  2202. substr(size_type __start, size_type __len = 1) const
  2203. {
  2204. return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr,
  2205. __start,
  2206. __start + __len));
  2207. }
  2208. rope
  2209. substr(iterator __start, iterator __end) const
  2210. {
  2211. return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr,
  2212. __start.index(),
  2213. __end.index()));
  2214. }
  2215. rope
  2216. substr(iterator __start) const
  2217. {
  2218. size_type __pos = __start.index();
  2219. return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr,
  2220. __pos, __pos + 1));
  2221. }
  2222. rope
  2223. substr(const_iterator __start, const_iterator __end) const
  2224. {
  2225. // This might eventually take advantage of the cache in the
  2226. // iterator.
  2227. return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr,
  2228. __start.index(),
  2229. __end.index()));
  2230. }
  2231. rope<_CharT, _Alloc>
  2232. substr(const_iterator __start)
  2233. {
  2234. size_type __pos = __start.index();
  2235. return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr,
  2236. __pos, __pos + 1));
  2237. }
  2238. static const size_type npos;
  2239. size_type find(_CharT __c, size_type __pos = 0) const;
  2240. size_type
  2241. find(const _CharT* __s, size_type __pos = 0) const
  2242. {
  2243. size_type __result_pos;
  2244. const_iterator __result =
  2245. std::search(const_begin() + __pos, const_end(),
  2246. __s, __s + _S_char_ptr_len(__s));
  2247. __result_pos = __result.index();
  2248. #ifndef __STL_OLD_ROPE_SEMANTICS
  2249. if (__result_pos == size())
  2250. __result_pos = npos;
  2251. #endif
  2252. return __result_pos;
  2253. }
  2254. iterator
  2255. mutable_begin()
  2256. { return(iterator(this, 0)); }
  2257. iterator
  2258. mutable_end()
  2259. { return(iterator(this, size())); }
  2260. typedef std::reverse_iterator<iterator> reverse_iterator;
  2261. reverse_iterator
  2262. mutable_rbegin()
  2263. { return reverse_iterator(mutable_end()); }
  2264. reverse_iterator
  2265. mutable_rend()
  2266. { return reverse_iterator(mutable_begin()); }
  2267. reference
  2268. mutable_reference_at(size_type __pos)
  2269. { return reference(this, __pos); }
  2270. #ifdef __STD_STUFF
  2271. reference
  2272. operator[] (size_type __pos)
  2273. { return _char_ref_proxy(this, __pos); }
  2274. reference
  2275. at(size_type __pos)
  2276. {
  2277. // if (__pos >= size()) throw out_of_range; // XXX
  2278. return (*this)[__pos];
  2279. }
  2280. void resize(size_type __n, _CharT __c) { }
  2281. void resize(size_type __n) { }
  2282. void reserve(size_type __res_arg = 0) { }
  2283. size_type
  2284. capacity() const
  2285. { return max_size(); }
  2286. // Stuff below this line is dangerous because it's error prone.
  2287. // I would really like to get rid of it.
  2288. // copy function with funny arg ordering.
  2289. size_type
  2290. copy(_CharT* __buffer, size_type __n,
  2291. size_type __pos = 0) const
  2292. { return copy(__pos, __n, __buffer); }
  2293. iterator
  2294. end()
  2295. { return mutable_end(); }
  2296. iterator
  2297. begin()
  2298. { return mutable_begin(); }
  2299. reverse_iterator
  2300. rend()
  2301. { return mutable_rend(); }
  2302. reverse_iterator
  2303. rbegin()
  2304. { return mutable_rbegin(); }
  2305. #else
  2306. const_iterator
  2307. end()
  2308. { return const_end(); }
  2309. const_iterator
  2310. begin()
  2311. { return const_begin(); }
  2312. const_reverse_iterator
  2313. rend()
  2314. { return const_rend(); }
  2315. const_reverse_iterator
  2316. rbegin()
  2317. { return const_rbegin(); }
  2318. #endif
  2319. };
  2320. template <class _CharT, class _Alloc>
  2321. const typename rope<_CharT, _Alloc>::size_type
  2322. rope<_CharT, _Alloc>::npos = (size_type)(-1);
  2323. template <class _CharT, class _Alloc>
  2324. inline bool operator==(const _Rope_const_iterator<_CharT, _Alloc>& __x,
  2325. const _Rope_const_iterator<_CharT, _Alloc>& __y)
  2326. { return (__x._M_current_pos == __y._M_current_pos
  2327. && __x._M_root == __y._M_root); }
  2328. template <class _CharT, class _Alloc>
  2329. inline bool operator<(const _Rope_const_iterator<_CharT, _Alloc>& __x,
  2330. const _Rope_const_iterator<_CharT, _Alloc>& __y)
  2331. { return (__x._M_current_pos < __y._M_current_pos); }
  2332. template <class _CharT, class _Alloc>
  2333. inline bool operator!=(const _Rope_const_iterator<_CharT, _Alloc>& __x,
  2334. const _Rope_const_iterator<_CharT, _Alloc>& __y)
  2335. { return !(__x == __y); }
  2336. template <class _CharT, class _Alloc>
  2337. inline bool operator>(const _Rope_const_iterator<_CharT, _Alloc>& __x,
  2338. const _Rope_const_iterator<_CharT, _Alloc>& __y)
  2339. { return __y < __x; }
  2340. template <class _CharT, class _Alloc>
  2341. inline bool
  2342. operator<=(const _Rope_const_iterator<_CharT, _Alloc>& __x,
  2343. const _Rope_const_iterator<_CharT, _Alloc>& __y)
  2344. { return !(__y < __x); }
  2345. template <class _CharT, class _Alloc>
  2346. inline bool
  2347. operator>=(const _Rope_const_iterator<_CharT, _Alloc>& __x,
  2348. const _Rope_const_iterator<_CharT, _Alloc>& __y)
  2349. { return !(__x < __y); }
  2350. template <class _CharT, class _Alloc>
  2351. inline std::ptrdiff_t
  2352. operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x,
  2353. const _Rope_const_iterator<_CharT, _Alloc>& __y)
  2354. {
  2355. return (std::ptrdiff_t)__x._M_current_pos
  2356. - (std::ptrdiff_t)__y._M_current_pos;
  2357. }
  2358. template <class _CharT, class _Alloc>
  2359. inline _Rope_const_iterator<_CharT, _Alloc>
  2360. operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x,
  2361. std::ptrdiff_t __n)
  2362. { return _Rope_const_iterator<_CharT, _Alloc>(__x._M_root,
  2363. __x._M_current_pos - __n); }
  2364. template <class _CharT, class _Alloc>
  2365. inline _Rope_const_iterator<_CharT, _Alloc>
  2366. operator+(const _Rope_const_iterator<_CharT, _Alloc>& __x,
  2367. std::ptrdiff_t __n)
  2368. { return _Rope_const_iterator<_CharT, _Alloc>(__x._M_root,
  2369. __x._M_current_pos + __n); }
  2370. template <class _CharT, class _Alloc>
  2371. inline _Rope_const_iterator<_CharT, _Alloc>
  2372. operator+(std::ptrdiff_t __n,
  2373. const _Rope_const_iterator<_CharT, _Alloc>& __x)
  2374. { return _Rope_const_iterator<_CharT, _Alloc>(__x._M_root,
  2375. __x._M_current_pos + __n); }
  2376. template <class _CharT, class _Alloc>
  2377. inline bool
  2378. operator==(const _Rope_iterator<_CharT, _Alloc>& __x,
  2379. const _Rope_iterator<_CharT, _Alloc>& __y)
  2380. {return (__x._M_current_pos == __y._M_current_pos
  2381. && __x._M_root_rope == __y._M_root_rope); }
  2382. template <class _CharT, class _Alloc>
  2383. inline bool
  2384. operator<(const _Rope_iterator<_CharT, _Alloc>& __x,
  2385. const _Rope_iterator<_CharT, _Alloc>& __y)
  2386. { return (__x._M_current_pos < __y._M_current_pos); }
  2387. template <class _CharT, class _Alloc>
  2388. inline bool
  2389. operator!=(const _Rope_iterator<_CharT, _Alloc>& __x,
  2390. const _Rope_iterator<_CharT, _Alloc>& __y)
  2391. { return !(__x == __y); }
  2392. template <class _CharT, class _Alloc>
  2393. inline bool
  2394. operator>(const _Rope_iterator<_CharT, _Alloc>& __x,
  2395. const _Rope_iterator<_CharT, _Alloc>& __y)
  2396. { return __y < __x; }
  2397. template <class _CharT, class _Alloc>
  2398. inline bool
  2399. operator<=(const _Rope_iterator<_CharT, _Alloc>& __x,
  2400. const _Rope_iterator<_CharT, _Alloc>& __y)
  2401. { return !(__y < __x); }
  2402. template <class _CharT, class _Alloc>
  2403. inline bool
  2404. operator>=(const _Rope_iterator<_CharT, _Alloc>& __x,
  2405. const _Rope_iterator<_CharT, _Alloc>& __y)
  2406. { return !(__x < __y); }
  2407. template <class _CharT, class _Alloc>
  2408. inline std::ptrdiff_t
  2409. operator-(const _Rope_iterator<_CharT, _Alloc>& __x,
  2410. const _Rope_iterator<_CharT, _Alloc>& __y)
  2411. { return ((std::ptrdiff_t)__x._M_current_pos
  2412. - (std::ptrdiff_t)__y._M_current_pos); }
  2413. template <class _CharT, class _Alloc>
  2414. inline _Rope_iterator<_CharT, _Alloc>
  2415. operator-(const _Rope_iterator<_CharT, _Alloc>& __x,
  2416. std::ptrdiff_t __n)
  2417. { return _Rope_iterator<_CharT, _Alloc>(__x._M_root_rope,
  2418. __x._M_current_pos - __n); }
  2419. template <class _CharT, class _Alloc>
  2420. inline _Rope_iterator<_CharT, _Alloc>
  2421. operator+(const _Rope_iterator<_CharT, _Alloc>& __x, std::ptrdiff_t __n)
  2422. { return _Rope_iterator<_CharT, _Alloc>(__x._M_root_rope,
  2423. __x._M_current_pos + __n); }
  2424. template <class _CharT, class _Alloc>
  2425. inline _Rope_iterator<_CharT, _Alloc>
  2426. operator+(std::ptrdiff_t __n, const _Rope_iterator<_CharT, _Alloc>& __x)
  2427. { return _Rope_iterator<_CharT, _Alloc>(__x._M_root_rope,
  2428. __x._M_current_pos + __n); }
  2429. template <class _CharT, class _Alloc>
  2430. inline rope<_CharT, _Alloc>
  2431. operator+(const rope<_CharT, _Alloc>& __left,
  2432. const rope<_CharT, _Alloc>& __right)
  2433. {
  2434. // Inlining this should make it possible to keep __left and
  2435. // __right in registers.
  2436. typedef rope<_CharT, _Alloc> rope_type;
  2437. return rope_type(rope_type::_S_concat(__left._M_tree_ptr,
  2438. __right._M_tree_ptr));
  2439. }
  2440. template <class _CharT, class _Alloc>
  2441. inline rope<_CharT, _Alloc>&
  2442. operator+=(rope<_CharT, _Alloc>& __left,
  2443. const rope<_CharT, _Alloc>& __right)
  2444. {
  2445. __left.append(__right);
  2446. return __left;
  2447. }
  2448. template <class _CharT, class _Alloc>
  2449. inline rope<_CharT, _Alloc>
  2450. operator+(const rope<_CharT, _Alloc>& __left,
  2451. const _CharT* __right)
  2452. {
  2453. typedef rope<_CharT, _Alloc> rope_type;
  2454. std::size_t __rlen = rope_type::_S_char_ptr_len(__right);
  2455. _Alloc __a = __left.get_allocator();
  2456. return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr,
  2457. __right, __rlen, __a));
  2458. }
  2459. template <class _CharT, class _Alloc>
  2460. inline rope<_CharT, _Alloc>&
  2461. operator+=(rope<_CharT, _Alloc>& __left,
  2462. const _CharT* __right)
  2463. {
  2464. __left.append(__right);
  2465. return __left;
  2466. }
  2467. template <class _CharT, class _Alloc>
  2468. inline rope<_CharT, _Alloc>
  2469. operator+(const rope<_CharT, _Alloc>& __left, _CharT __right)
  2470. {
  2471. typedef rope<_CharT, _Alloc> rope_type;
  2472. _Alloc __a = __left.get_allocator();
  2473. return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr,
  2474. &__right, 1, __a));
  2475. }
  2476. template <class _CharT, class _Alloc>
  2477. inline rope<_CharT, _Alloc>&
  2478. operator+=(rope<_CharT, _Alloc>& __left, _CharT __right)
  2479. {
  2480. __left.append(__right);
  2481. return __left;
  2482. }
  2483. template <class _CharT, class _Alloc>
  2484. bool
  2485. operator<(const rope<_CharT, _Alloc>& __left,
  2486. const rope<_CharT, _Alloc>& __right)
  2487. { return __left.compare(__right) < 0; }
  2488. template <class _CharT, class _Alloc>
  2489. bool
  2490. operator==(const rope<_CharT, _Alloc>& __left,
  2491. const rope<_CharT, _Alloc>& __right)
  2492. { return __left.compare(__right) == 0; }
  2493. template <class _CharT, class _Alloc>
  2494. inline bool
  2495. operator==(const _Rope_char_ptr_proxy<_CharT, _Alloc>& __x,
  2496. const _Rope_char_ptr_proxy<_CharT, _Alloc>& __y)
  2497. { return (__x._M_pos == __y._M_pos && __x._M_root == __y._M_root); }
  2498. template <class _CharT, class _Alloc>
  2499. inline bool
  2500. operator!=(const rope<_CharT, _Alloc>& __x,
  2501. const rope<_CharT, _Alloc>& __y)
  2502. { return !(__x == __y); }
  2503. template <class _CharT, class _Alloc>
  2504. inline bool
  2505. operator>(const rope<_CharT, _Alloc>& __x,
  2506. const rope<_CharT, _Alloc>& __y)
  2507. { return __y < __x; }
  2508. template <class _CharT, class _Alloc>
  2509. inline bool
  2510. operator<=(const rope<_CharT, _Alloc>& __x,
  2511. const rope<_CharT, _Alloc>& __y)
  2512. { return !(__y < __x); }
  2513. template <class _CharT, class _Alloc>
  2514. inline bool
  2515. operator>=(const rope<_CharT, _Alloc>& __x,
  2516. const rope<_CharT, _Alloc>& __y)
  2517. { return !(__x < __y); }
  2518. template <class _CharT, class _Alloc>
  2519. inline bool
  2520. operator!=(const _Rope_char_ptr_proxy<_CharT, _Alloc>& __x,
  2521. const _Rope_char_ptr_proxy<_CharT, _Alloc>& __y)
  2522. { return !(__x == __y); }
  2523. template<class _CharT, class _Traits, class _Alloc>
  2524. std::basic_ostream<_CharT, _Traits>&
  2525. operator<<(std::basic_ostream<_CharT, _Traits>& __o,
  2526. const rope<_CharT, _Alloc>& __r);
  2527. typedef rope<char> crope;
  2528. typedef rope<wchar_t> wrope;
  2529. inline crope::reference
  2530. __mutable_reference_at(crope& __c, std::size_t __i)
  2531. { return __c.mutable_reference_at(__i); }
  2532. inline wrope::reference
  2533. __mutable_reference_at(wrope& __c, std::size_t __i)
  2534. { return __c.mutable_reference_at(__i); }
  2535. template <class _CharT, class _Alloc>
  2536. inline void
  2537. swap(rope<_CharT, _Alloc>& __x, rope<_CharT, _Alloc>& __y)
  2538. { __x.swap(__y); }
  2539. _GLIBCXX_END_NAMESPACE_VERSION
  2540. } // namespace
  2541. namespace std _GLIBCXX_VISIBILITY(default)
  2542. {
  2543. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  2544. namespace tr1
  2545. {
  2546. template<>
  2547. struct hash<__gnu_cxx::crope>
  2548. {
  2549. size_t
  2550. operator()(const __gnu_cxx::crope& __str) const
  2551. {
  2552. size_t __size = __str.size();
  2553. if (0 == __size)
  2554. return 0;
  2555. return 13 * __str[0] + 5 * __str[__size - 1] + __size;
  2556. }
  2557. };
  2558. template<>
  2559. struct hash<__gnu_cxx::wrope>
  2560. {
  2561. size_t
  2562. operator()(const __gnu_cxx::wrope& __str) const
  2563. {
  2564. size_t __size = __str.size();
  2565. if (0 == __size)
  2566. return 0;
  2567. return 13 * __str[0] + 5 * __str[__size - 1] + __size;
  2568. }
  2569. };
  2570. } // namespace tr1
  2571. _GLIBCXX_END_NAMESPACE_VERSION
  2572. } // namespace std
  2573. # include <ext/ropeimpl.h>
  2574. #endif