flex_string.hpp 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580
  1. /*=============================================================================
  2. Boost.Wave: A Standard compliant C++ preprocessor library
  3. http://www.boost.org/
  4. Copyright (c) 2001 by Andrei Alexandrescu. Distributed under the Boost
  5. Software License, Version 1.0. (See accompanying file
  6. LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. // This code is taken from:
  9. // Andrei Alexandrescu, Generic<Programming>: A Policy-Based basic_string
  10. // Implementation. http://www.cuj.com/documents/s=7994/cujcexp1906alexandr/
  11. //
  12. // #HK030306:
  13. // - Moved into the namespace boost::wave::util
  14. // - Added a bunch of missing typename(s)
  15. // - Integrated with boost config
  16. // - Added a missing header include
  17. // - Added special constructors and operator= to allow CowString to be
  18. // a real COW-string (removed unnecessary data copying)
  19. // - Fixed a string terminating bug in append
  20. //
  21. // #HK040109:
  22. // - Incorporated the changes from Andrei's latest version of this class
  23. //
  24. // #HK070307:
  25. // - Once again incorporated the changes from Andrei's latest version of
  26. // this class
  27. //
  28. // #HK090523:
  29. // - Incorporated the changes from latest version of flex_string as
  30. // maintained in Loki
  31. //
  32. // #HK130910:
  33. // - Removed the getline implementation which was borrowed from the SGI
  34. // STL as the license for this code is not compatible with Boost.
  35. #ifndef BOOST_FLEX_STRING_INC_
  36. #define BOOST_FLEX_STRING_INC_
  37. /*
  38. ////////////////////////////////////////////////////////////////////////////////
  39. template <typename E, class A = @>
  40. class StoragePolicy
  41. {
  42. typedef E value_type;
  43. typedef @ iterator;
  44. typedef @ const_iterator;
  45. typedef A allocator_type;
  46. typedef @ size_type;
  47. StoragePolicy(const StoragePolicy& s);
  48. StoragePolicy(const A&);
  49. StoragePolicy(const E* s, size_type len, const A&);
  50. StoragePolicy(size_type len, E c, const A&);
  51. ~StoragePolicy();
  52. iterator begin();
  53. const_iterator begin() const;
  54. iterator end();
  55. const_iterator end() const;
  56. size_type size() const;
  57. size_type max_size() const;
  58. size_type capacity() const;
  59. void reserve(size_type res_arg);
  60. void append(const E* s, size_type sz);
  61. template <class InputIterator>
  62. void append(InputIterator b, InputIterator e);
  63. void resize(size_type newSize, E fill);
  64. void swap(StoragePolicy& rhs);
  65. const E* c_str() const;
  66. const E* data() const;
  67. A get_allocator() const;
  68. };
  69. ////////////////////////////////////////////////////////////////////////////////
  70. */
  71. #include <boost/config.hpp>
  72. #include <boost/assert.hpp>
  73. #include <boost/throw_exception.hpp>
  74. #include <boost/core/allocator_access.hpp>
  75. #include <boost/iterator/reverse_iterator.hpp>
  76. #include <boost/wave/wave_config.hpp>
  77. #if BOOST_WAVE_SERIALIZATION != 0
  78. #include <boost/serialization/serialization.hpp>
  79. #include <boost/serialization/split_free.hpp>
  80. #include <boost/serialization/collections_save_imp.hpp>
  81. #include <boost/serialization/collections_load_imp.hpp>
  82. #define BOOST_WAVE_FLEX_STRING_SERIALIZATION_HACK 1
  83. #endif
  84. #include <memory>
  85. #include <new>
  86. #include <string>
  87. #include <vector>
  88. #include <algorithm>
  89. #include <functional>
  90. #include <limits>
  91. #include <stdexcept>
  92. #include <ios>
  93. #include <cstddef>
  94. #include <cstring>
  95. #include <cstdlib>
  96. // this must occur after all of the includes and before any code appears
  97. #ifdef BOOST_HAS_ABI_HEADERS
  98. #include BOOST_ABI_PREFIX
  99. #endif
  100. ///////////////////////////////////////////////////////////////////////////////
  101. namespace boost {
  102. namespace wave {
  103. namespace util {
  104. namespace flex_string_details
  105. {
  106. template <class InIt, class OutIt>
  107. OutIt copy_n(InIt b,
  108. typename std::iterator_traits<InIt>::difference_type n, OutIt d)
  109. {
  110. for (/**/; n != 0; --n, ++b, ++d)
  111. {
  112. *d = *b;
  113. }
  114. return d;
  115. }
  116. template <class Pod, class T>
  117. inline void pod_fill(Pod* b, Pod* e, T c)
  118. {
  119. switch ((e - b) & 7)
  120. {
  121. case 0:
  122. while (b != e)
  123. {
  124. *b = c; ++b; BOOST_FALLTHROUGH;
  125. case 7: *b = c; ++b; BOOST_FALLTHROUGH;
  126. case 6: *b = c; ++b; BOOST_FALLTHROUGH;
  127. case 5: *b = c; ++b; BOOST_FALLTHROUGH;
  128. case 4: *b = c; ++b; BOOST_FALLTHROUGH;
  129. case 3: *b = c; ++b; BOOST_FALLTHROUGH;
  130. case 2: *b = c; ++b; BOOST_FALLTHROUGH;
  131. case 1: *b = c; ++b;
  132. }
  133. }
  134. }
  135. template <class Pod>
  136. inline void pod_move(const Pod* b, const Pod* e, Pod* d)
  137. {
  138. using namespace std;
  139. memmove(d, b, (e - b) * sizeof(*b));
  140. }
  141. template <class Pod>
  142. inline Pod* pod_copy(const Pod* b, const Pod* e, Pod* d)
  143. {
  144. const std::size_t s = e - b;
  145. using namespace std;
  146. memcpy(d, b, s * sizeof(*b));
  147. return d + s;
  148. }
  149. template <typename T> struct get_unsigned
  150. {
  151. typedef T result;
  152. };
  153. template <> struct get_unsigned<char>
  154. {
  155. typedef unsigned char result;
  156. };
  157. template <> struct get_unsigned<signed char>
  158. {
  159. typedef unsigned char result;
  160. };
  161. template <> struct get_unsigned<short int>
  162. {
  163. typedef unsigned short int result;
  164. };
  165. template <> struct get_unsigned<int>
  166. {
  167. typedef unsigned int result;
  168. };
  169. template <> struct get_unsigned<long int>
  170. {
  171. typedef unsigned long int result;
  172. };
  173. enum Shallow {};
  174. }
  175. template <class T> class mallocator
  176. {
  177. public:
  178. typedef T value_type;
  179. typedef value_type* pointer;
  180. typedef const value_type* const_pointer;
  181. typedef value_type& reference;
  182. typedef const value_type& const_reference;
  183. typedef std::size_t size_type;
  184. //typedef unsigned int size_type;
  185. //typedef std::ptrdiff_t difference_type;
  186. typedef int difference_type;
  187. template <class U>
  188. struct rebind { typedef mallocator<U> other; };
  189. mallocator() {}
  190. mallocator(const mallocator&) {}
  191. //template <class U>
  192. //mallocator(const mallocator<U>&) {}
  193. ~mallocator() {}
  194. pointer address(reference x) const { return &x; }
  195. const_pointer address(const_reference x) const
  196. {
  197. return x;
  198. }
  199. pointer allocate(size_type n, const_pointer = 0)
  200. {
  201. using namespace std;
  202. void* p = malloc(n * sizeof(T));
  203. if (!p) boost::throw_exception(std::bad_alloc());
  204. return static_cast<pointer>(p);
  205. }
  206. void deallocate(pointer p, size_type)
  207. {
  208. using namespace std;
  209. free(p);
  210. }
  211. size_type max_size() const
  212. {
  213. return static_cast<size_type>(-1) / sizeof(T);
  214. }
  215. void construct(pointer p, const value_type& x)
  216. {
  217. new(p) value_type(x);
  218. }
  219. void destroy(pointer p)
  220. {
  221. p->~value_type();
  222. }
  223. private:
  224. void operator=(const mallocator&);
  225. };
  226. template<> class mallocator<void>
  227. {
  228. typedef void value_type;
  229. typedef void* pointer;
  230. typedef const void* const_pointer;
  231. template <class U>
  232. struct rebind { typedef mallocator<U> other; };
  233. };
  234. template <class T>
  235. inline bool operator==(const mallocator<T>&,
  236. const mallocator<T>&) {
  237. return true;
  238. }
  239. template <class T>
  240. inline bool operator!=(const mallocator<T>&,
  241. const mallocator<T>&) {
  242. return false;
  243. }
  244. ////////////////////////////////////////////////////////////////////////////////
  245. // class template SimpleStringStorage
  246. // Allocates memory with malloc
  247. ////////////////////////////////////////////////////////////////////////////////
  248. template <typename E, class A = std::allocator<E> >
  249. class SimpleStringStorage
  250. {
  251. // The "public" below exists because MSVC can't do template typedefs
  252. public:
  253. struct Data
  254. {
  255. Data() : pEnd_(buffer_), pEndOfMem_(buffer_) { buffer_[0] = E(0); }
  256. E* pEnd_;
  257. E* pEndOfMem_;
  258. E buffer_[1];
  259. };
  260. static const Data emptyString_;
  261. typedef typename boost::allocator_size_type<A>::type size_type;
  262. private:
  263. Data* pData_;
  264. void Init(size_type size, size_type capacity)
  265. {
  266. BOOST_ASSERT(size <= capacity);
  267. if (capacity == 0)
  268. {
  269. pData_ = const_cast<Data*>(&emptyString_);
  270. }
  271. else
  272. {
  273. // 11-17-2000: comment added:
  274. // No need to allocate (capacity + 1) to
  275. // accommodate the terminating 0, because Data already
  276. // has one character in there
  277. pData_ = static_cast<Data*>(
  278. malloc(sizeof(Data) + capacity * sizeof(E)));
  279. if (!pData_) boost::throw_exception(std::bad_alloc());
  280. pData_->pEnd_ = pData_->buffer_ + size;
  281. pData_->pEndOfMem_ = pData_->buffer_ + capacity;
  282. }
  283. }
  284. private:
  285. // Warning - this doesn't initialize pData_. Used in reserve()
  286. SimpleStringStorage()
  287. { }
  288. public:
  289. typedef E value_type;
  290. typedef E* iterator;
  291. typedef const E* const_iterator;
  292. typedef A allocator_type;
  293. SimpleStringStorage(const SimpleStringStorage& rhs)
  294. {
  295. const size_type sz = rhs.size();
  296. Init(sz, sz);
  297. if (sz) flex_string_details::pod_copy(rhs.begin(), rhs.end(), begin());
  298. }
  299. SimpleStringStorage(const SimpleStringStorage& s,
  300. flex_string_details::Shallow)
  301. : pData_(s.pData_)
  302. {
  303. }
  304. SimpleStringStorage(const A&)
  305. { pData_ = const_cast<Data*>(&emptyString_); }
  306. SimpleStringStorage(const E* s, size_type len, const A&)
  307. {
  308. Init(len, len);
  309. flex_string_details::pod_copy(s, s + len, begin());
  310. }
  311. SimpleStringStorage(size_type len, E c, const A&)
  312. {
  313. Init(len, len);
  314. flex_string_details::pod_fill(begin(), end(), c);
  315. }
  316. SimpleStringStorage& operator=(const SimpleStringStorage& rhs)
  317. {
  318. const size_type sz = rhs.size();
  319. reserve(sz);
  320. flex_string_details::pod_copy(&*rhs.begin(), &*rhs.end(), begin());
  321. pData_->pEnd_ = &*begin() + sz;
  322. return *this;
  323. }
  324. ~SimpleStringStorage()
  325. {
  326. BOOST_ASSERT(begin() <= end());
  327. if (pData_ != &emptyString_) free(pData_);
  328. }
  329. iterator begin()
  330. { return pData_->buffer_; }
  331. const_iterator begin() const
  332. { return pData_->buffer_; }
  333. iterator end()
  334. { return pData_->pEnd_; }
  335. const_iterator end() const
  336. { return pData_->pEnd_; }
  337. size_type size() const
  338. { return pData_->pEnd_ - pData_->buffer_; }
  339. size_type max_size() const
  340. { return std::size_t(-1) / sizeof(E) - sizeof(Data) - 1; }
  341. size_type capacity() const
  342. { return pData_->pEndOfMem_ - pData_->buffer_; }
  343. void reserve(size_type res_arg)
  344. {
  345. if (res_arg <= capacity())
  346. {
  347. // @@@ insert shrinkage here if you wish
  348. return;
  349. }
  350. if (pData_ == &emptyString_)
  351. {
  352. Init(0, res_arg);
  353. }
  354. else
  355. {
  356. const size_type sz = size();
  357. void* p = realloc(pData_,
  358. sizeof(Data) + res_arg * sizeof(E));
  359. if (!p) boost::throw_exception(std::bad_alloc());
  360. if (p != pData_)
  361. {
  362. pData_ = static_cast<Data*>(p);
  363. pData_->pEnd_ = pData_->buffer_ + sz;
  364. }
  365. pData_->pEndOfMem_ = pData_->buffer_ + res_arg;
  366. }
  367. }
  368. void append(const E* s, size_type sz)
  369. {
  370. const size_type neededCapacity = size() + sz;
  371. if (capacity() < neededCapacity)
  372. {
  373. const iterator b = begin();
  374. static std::less_equal<const E*> le;
  375. if (le(b, s) && le(s, end()))
  376. {
  377. // aliased
  378. const size_type offset = s - b;
  379. reserve(neededCapacity);
  380. s = begin() + offset;
  381. }
  382. else
  383. {
  384. reserve(neededCapacity);
  385. }
  386. }
  387. flex_string_details::pod_copy(s, s + sz, end());
  388. pData_->pEnd_ += sz;
  389. }
  390. template <class InputIterator>
  391. void append(InputIterator b, InputIterator e)
  392. {
  393. // @@@ todo: optimize this depending on iterator type
  394. for (; b != e; ++b)
  395. {
  396. *this += *b;
  397. }
  398. }
  399. void resize(size_type newSize, E fill)
  400. {
  401. const int delta = int(newSize - size());
  402. if (delta == 0) return;
  403. if (delta > 0)
  404. {
  405. if (newSize > capacity())
  406. {
  407. reserve(newSize);
  408. }
  409. E* e = &*end();
  410. flex_string_details::pod_fill(e, e + delta, fill);
  411. }
  412. pData_->pEnd_ = pData_->buffer_ + newSize;
  413. }
  414. void swap(SimpleStringStorage& rhs)
  415. {
  416. std::swap(pData_, rhs.pData_);
  417. }
  418. const E* c_str() const
  419. {
  420. if (pData_ != &emptyString_) *pData_->pEnd_ = E();
  421. return pData_->buffer_;
  422. }
  423. const E* data() const
  424. { return pData_->buffer_; }
  425. A get_allocator() const
  426. { return A(); }
  427. };
  428. template <typename E, class A>
  429. const typename SimpleStringStorage<E, A>::Data
  430. SimpleStringStorage<E, A>::emptyString_ =
  431. typename SimpleStringStorage<E, A>::Data();
  432. ////////////////////////////////////////////////////////////////////////////////
  433. // class template AllocatorStringStorage
  434. // Allocates with your allocator
  435. // Takes advantage of the Empty Base Optimization if available
  436. ////////////////////////////////////////////////////////////////////////////////
  437. template <typename E, class A = std::allocator<E> >
  438. class AllocatorStringStorage : public A
  439. {
  440. typedef typename boost::allocator_size_type<A>::type size_type;
  441. typedef typename SimpleStringStorage<E, A>::Data Data;
  442. void* Alloc(size_type sz, const void* p = 0)
  443. {
  444. return boost::allocator_allocate(static_cast<A&>(*this), 1 + (sz - 1) / sizeof(E),
  445. static_cast<const char*>(p));
  446. }
  447. void* Realloc(void* p, size_type oldSz, size_type newSz)
  448. {
  449. void* r = Alloc(newSz);
  450. flex_string_details::pod_copy(p, p + Min(oldSz, newSz), r);
  451. Free(p, oldSz);
  452. return r;
  453. }
  454. void Free(void* p, size_type sz)
  455. {
  456. boost::allocator_deallocate(static_cast<A&>(*this), static_cast<E*>(p), sz);
  457. }
  458. Data* pData_;
  459. void Init(size_type size, size_type cap)
  460. {
  461. BOOST_ASSERT(size <= cap);
  462. if (cap == 0)
  463. {
  464. pData_ = const_cast<Data*>(
  465. &SimpleStringStorage<E, A>::emptyString_);
  466. }
  467. else
  468. {
  469. pData_ = static_cast<Data*>(Alloc(
  470. cap * sizeof(E) + sizeof(Data)));
  471. pData_->pEnd_ = pData_->buffer_ + size;
  472. pData_->pEndOfMem_ = pData_->buffer_ + cap;
  473. }
  474. }
  475. public:
  476. typedef E value_type;
  477. typedef E* iterator;
  478. typedef const E* const_iterator;
  479. typedef A allocator_type;
  480. AllocatorStringStorage()
  481. : A(), pData_(0)
  482. {
  483. }
  484. AllocatorStringStorage(const AllocatorStringStorage& rhs)
  485. : A(rhs.get_allocator())
  486. {
  487. const size_type sz = rhs.size();
  488. Init(sz, sz);
  489. if (sz) flex_string_details::pod_copy(rhs.begin(), rhs.end(), begin());
  490. }
  491. AllocatorStringStorage(const AllocatorStringStorage& s,
  492. flex_string_details::Shallow)
  493. : A(s.get_allocator())
  494. {
  495. pData_ = s.pData_;
  496. }
  497. AllocatorStringStorage(const A& a) : A(a)
  498. {
  499. pData_ = const_cast<Data*>(
  500. &SimpleStringStorage<E, A>::emptyString_);
  501. }
  502. AllocatorStringStorage(const E* s, size_type len, const A& a)
  503. : A(a)
  504. {
  505. Init(len, len);
  506. flex_string_details::pod_copy(s, s + len, begin());
  507. }
  508. AllocatorStringStorage(size_type len, E c, const A& a)
  509. : A(a)
  510. {
  511. Init(len, len);
  512. flex_string_details::pod_fill(&*begin(), &*end(), c);
  513. }
  514. AllocatorStringStorage& operator=(const AllocatorStringStorage& rhs)
  515. {
  516. const size_type sz = rhs.size();
  517. reserve(sz);
  518. flex_string_details::pod_copy(&*rhs.begin(), &*rhs.end(), begin());
  519. pData_->pEnd_ = &*begin() + rhs.size();
  520. return *this;
  521. }
  522. ~AllocatorStringStorage()
  523. {
  524. if (capacity())
  525. {
  526. Free(pData_,
  527. sizeof(Data) + capacity() * sizeof(E));
  528. }
  529. }
  530. iterator begin()
  531. { return pData_->buffer_; }
  532. const_iterator begin() const
  533. { return pData_->buffer_; }
  534. iterator end()
  535. { return pData_->pEnd_; }
  536. const_iterator end() const
  537. { return pData_->pEnd_; }
  538. size_type size() const
  539. { return size_type(end() - begin()); }
  540. size_type max_size() const
  541. { return boost::allocator_max_size(static_cast<const A&>(*this)); }
  542. size_type capacity() const
  543. { return size_type(pData_->pEndOfMem_ - pData_->buffer_); }
  544. void resize(size_type n, E c)
  545. {
  546. reserve(n);
  547. iterator newEnd = begin() + n;
  548. iterator oldEnd = end();
  549. if (newEnd > oldEnd)
  550. {
  551. // Copy the characters
  552. flex_string_details::pod_fill(oldEnd, newEnd, c);
  553. }
  554. if (capacity()) pData_->pEnd_ = newEnd;
  555. }
  556. void reserve(size_type res_arg)
  557. {
  558. if (res_arg <= capacity())
  559. {
  560. // @@@ shrink to fit here
  561. return;
  562. }
  563. A& myAlloc = *this;
  564. AllocatorStringStorage newStr(myAlloc);
  565. newStr.Init(size(), res_arg);
  566. flex_string_details::pod_copy(begin(), end(), newStr.begin());
  567. swap(newStr);
  568. }
  569. template <class ForwardIterator>
  570. void append(ForwardIterator b, ForwardIterator e)
  571. {
  572. const size_type
  573. sz = std::distance(b, e),
  574. neededCapacity = size() + sz;
  575. if (capacity() < neededCapacity)
  576. {
  577. // typedef std::less_equal<const E*> le_type;
  578. // BOOST_ASSERT(!(le_type()(begin(), &*b) && le_type()(&*b, end())));
  579. reserve(neededCapacity);
  580. }
  581. std::copy(b, e, end());
  582. pData_->pEnd_ += sz;
  583. }
  584. void swap(AllocatorStringStorage& rhs)
  585. {
  586. // @@@ The following line is commented due to a bug in MSVC
  587. //std::swap(lhsAlloc, rhsAlloc);
  588. std::swap(pData_, rhs.pData_);
  589. }
  590. const E* c_str() const
  591. {
  592. if (pData_ != &SimpleStringStorage<E, A>::emptyString_)
  593. {
  594. *pData_->pEnd_ = E();
  595. }
  596. return &*begin();
  597. }
  598. const E* data() const
  599. { return &*begin(); }
  600. A get_allocator() const
  601. { return *this; }
  602. };
  603. ////////////////////////////////////////////////////////////////////////////////
  604. // class template VectorStringStorage
  605. // Uses std::vector
  606. // Takes advantage of the Empty Base Optimization if available
  607. ////////////////////////////////////////////////////////////////////////////////
  608. template <typename E, class A = std::allocator<E> >
  609. class VectorStringStorage : protected std::vector<E, A>
  610. {
  611. typedef std::vector<E, A> base;
  612. public: // protected:
  613. typedef E value_type;
  614. typedef typename base::iterator iterator;
  615. typedef typename base::const_iterator const_iterator;
  616. typedef A allocator_type;
  617. typedef typename boost::allocator_size_type<A>::type size_type;
  618. VectorStringStorage(const VectorStringStorage& s) : base(s)
  619. { }
  620. VectorStringStorage(const A& a) : base(1, E(), a)
  621. { }
  622. VectorStringStorage(const E* s, size_type len, const A& a)
  623. : base(a)
  624. {
  625. base::reserve(len + 1);
  626. base::insert(base::end(), s, s + len);
  627. // Terminating zero
  628. base::insert(base::end(), E());
  629. }
  630. VectorStringStorage(size_type len, E c, const A& a)
  631. : base(len + 1, c, a)
  632. {
  633. // Terminating zero
  634. base::back() = E();
  635. }
  636. VectorStringStorage& operator=(const VectorStringStorage& rhs)
  637. {
  638. base& v = *this;
  639. v = rhs;
  640. return *this;
  641. }
  642. iterator begin()
  643. { return base::begin(); }
  644. const_iterator begin() const
  645. { return base::begin(); }
  646. iterator end()
  647. { return base::end() - 1; }
  648. const_iterator end() const
  649. { return base::end() - 1; }
  650. size_type size() const
  651. { return base::size() - 1; }
  652. size_type max_size() const
  653. { return base::max_size() - 1; }
  654. size_type capacity() const
  655. { return base::capacity() - 1; }
  656. void reserve(size_type res_arg)
  657. {
  658. BOOST_ASSERT(res_arg < max_size());
  659. base::reserve(res_arg + 1);
  660. }
  661. void append(const E* s, size_type sz)
  662. {
  663. // Check for aliasing because std::vector doesn't do it.
  664. static std::less_equal<const E*> le;
  665. if (!base::empty())
  666. {
  667. const E* start = &base::front();
  668. if (le(start, s) && le(s, start + size()))
  669. {
  670. // aliased
  671. const size_type offset = s - start;
  672. reserve(size() + sz);
  673. s = &base::front() + offset;
  674. }
  675. }
  676. base::insert(end(), s, s + sz);
  677. }
  678. template <class InputIterator>
  679. void append(InputIterator b, InputIterator e)
  680. {
  681. base::insert(end(), b, e);
  682. }
  683. void resize(size_type n, E c)
  684. {
  685. base::reserve(n + 1);
  686. base::back() = c;
  687. base::resize(n + 1, c);
  688. base::back() = E();
  689. }
  690. void swap(VectorStringStorage& rhs)
  691. { base::swap(rhs); }
  692. const E* c_str() const
  693. { return &*begin(); }
  694. const E* data() const
  695. { return &*begin(); }
  696. A get_allocator() const
  697. { return base::get_allocator(); }
  698. };
  699. ////////////////////////////////////////////////////////////////////////////////
  700. // class template SmallStringOpt
  701. // Builds the small string optimization over any other storage
  702. ////////////////////////////////////////////////////////////////////////////////
  703. template <class Storage, unsigned int threshold,
  704. typename Align = typename Storage::value_type*>
  705. class SmallStringOpt
  706. {
  707. public:
  708. typedef typename Storage::value_type value_type;
  709. typedef value_type* iterator;
  710. typedef const value_type* const_iterator;
  711. typedef typename Storage::allocator_type allocator_type;
  712. typedef typename boost::allocator_size_type<allocator_type>::type size_type;
  713. private:
  714. enum { temp1 = threshold * sizeof(value_type) > sizeof(Storage)
  715. ? threshold * sizeof(value_type)
  716. : sizeof(Storage) };
  717. enum { temp2 = temp1 > sizeof(Align) ? temp1 : sizeof(Align) };
  718. public:
  719. enum { maxSmallString =
  720. (temp2 + sizeof(value_type) - 1) / sizeof(value_type) };
  721. private:
  722. enum { magic = maxSmallString + 1 };
  723. union
  724. {
  725. mutable value_type buf_[maxSmallString + 1];
  726. Align align_;
  727. };
  728. Storage& GetStorage()
  729. {
  730. BOOST_ASSERT(buf_[maxSmallString] == magic);
  731. Storage* p = reinterpret_cast<Storage*>(&buf_[0]);
  732. return *p;
  733. }
  734. const Storage& GetStorage() const
  735. {
  736. BOOST_ASSERT(buf_[maxSmallString] == magic);
  737. const Storage *p = reinterpret_cast<const Storage*>(&buf_[0]);
  738. return *p;
  739. }
  740. bool Small() const
  741. {
  742. return buf_[maxSmallString] != magic;
  743. }
  744. public:
  745. SmallStringOpt(const SmallStringOpt& s)
  746. {
  747. if (s.Small())
  748. {
  749. flex_string_details::pod_copy(
  750. s.buf_,
  751. s.buf_ + s.size(),
  752. buf_);
  753. }
  754. else
  755. {
  756. new(buf_) Storage(s.GetStorage());
  757. }
  758. buf_[maxSmallString] = s.buf_[maxSmallString];
  759. }
  760. SmallStringOpt(const allocator_type&)
  761. {
  762. buf_[maxSmallString] = maxSmallString;
  763. }
  764. SmallStringOpt(const value_type* s, size_type len, const allocator_type& a)
  765. {
  766. if (len <= maxSmallString)
  767. {
  768. flex_string_details::pod_copy(s, s + len, buf_);
  769. buf_[maxSmallString] = value_type(maxSmallString - len);
  770. }
  771. else
  772. {
  773. new(buf_) Storage(s, len, a);
  774. buf_[maxSmallString] = magic;
  775. }
  776. }
  777. SmallStringOpt(size_type len, value_type c, const allocator_type& a)
  778. {
  779. if (len <= maxSmallString)
  780. {
  781. flex_string_details::pod_fill(buf_, buf_ + len, c);
  782. buf_[maxSmallString] = value_type(maxSmallString - len);
  783. }
  784. else
  785. {
  786. new(buf_) Storage(len, c, a);
  787. buf_[maxSmallString] = magic;
  788. }
  789. }
  790. SmallStringOpt& operator=(const SmallStringOpt& rhs)
  791. {
  792. reserve(rhs.size());
  793. resize(0, 0);
  794. append(rhs.data(), rhs.size());
  795. return *this;
  796. }
  797. ~SmallStringOpt()
  798. {
  799. if (!Small()) GetStorage().~Storage();
  800. }
  801. iterator begin()
  802. {
  803. if (Small()) return buf_;
  804. return &*GetStorage().begin();
  805. }
  806. const_iterator begin() const
  807. {
  808. if (Small()) return buf_;
  809. return &*GetStorage().begin();
  810. }
  811. iterator end()
  812. {
  813. if (Small()) return buf_ + maxSmallString - buf_[maxSmallString];
  814. return &*GetStorage().end();
  815. }
  816. const_iterator end() const
  817. {
  818. if (Small()) return buf_ + maxSmallString - buf_[maxSmallString];
  819. return &*GetStorage().end();
  820. }
  821. size_type size() const
  822. {
  823. BOOST_ASSERT(!Small() || maxSmallString >= buf_[maxSmallString]);
  824. return Small()
  825. ? maxSmallString - buf_[maxSmallString]
  826. : GetStorage().size();
  827. }
  828. size_type max_size() const
  829. { return get_allocator().max_size(); }
  830. size_type capacity() const
  831. { return Small() ? maxSmallString : GetStorage().capacity(); }
  832. void reserve(size_type res_arg)
  833. {
  834. if (Small())
  835. {
  836. if (res_arg <= maxSmallString) return;
  837. SmallStringOpt temp(*this);
  838. this->~SmallStringOpt();
  839. new(buf_) Storage(temp.data(), temp.size(),
  840. temp.get_allocator());
  841. buf_[maxSmallString] = magic;
  842. GetStorage().reserve(res_arg);
  843. }
  844. else
  845. {
  846. GetStorage().reserve(res_arg);
  847. }
  848. BOOST_ASSERT(capacity() >= res_arg);
  849. }
  850. void append(const value_type* s, size_type sz)
  851. {
  852. if (!Small())
  853. {
  854. GetStorage().append(s, sz);
  855. }
  856. else
  857. {
  858. // append to a small string
  859. const size_type neededCapacity =
  860. maxSmallString - buf_[maxSmallString] + sz;
  861. if (maxSmallString < neededCapacity)
  862. {
  863. // need to change storage strategy
  864. allocator_type alloc;
  865. Storage temp(alloc);
  866. temp.reserve(neededCapacity);
  867. temp.append(buf_, maxSmallString - buf_[maxSmallString]);
  868. temp.append(s, sz);
  869. buf_[maxSmallString] = magic;
  870. new(buf_) Storage(temp.get_allocator());
  871. GetStorage().swap(temp);
  872. }
  873. else
  874. {
  875. flex_string_details::pod_move(s, s + sz,
  876. buf_ + maxSmallString - buf_[maxSmallString]);
  877. buf_[maxSmallString] -= value_type(sz);
  878. }
  879. }
  880. }
  881. template <class InputIterator>
  882. void append(InputIterator b, InputIterator e)
  883. {
  884. // @@@ todo: optimize this depending on iterator type
  885. for (; b != e; ++b)
  886. {
  887. *this += *b;
  888. }
  889. }
  890. void resize(size_type n, value_type c)
  891. {
  892. if (Small())
  893. {
  894. if (n > maxSmallString)
  895. {
  896. // Small string resized to big string
  897. SmallStringOpt temp(*this); // can't throw
  898. // 11-17-2001: correct exception safety bug
  899. Storage newString(temp.data(), temp.size(),
  900. temp.get_allocator());
  901. newString.resize(n, c);
  902. // We make the reasonable assumption that an empty Storage
  903. // constructor won't throw
  904. this->~SmallStringOpt();
  905. new(&buf_[0]) Storage(temp.get_allocator());
  906. buf_[maxSmallString] = value_type(magic);
  907. GetStorage().swap(newString);
  908. }
  909. else
  910. {
  911. // Small string resized to small string
  912. // 11-17-2001: bug fix: terminating zero not copied
  913. size_type toFill = n > size() ? n - size() : 0;
  914. flex_string_details::pod_fill(end(), end() + toFill, c);
  915. buf_[maxSmallString] = value_type(maxSmallString - n);
  916. }
  917. }
  918. else
  919. {
  920. if (n > maxSmallString)
  921. {
  922. // Big string resized to big string
  923. GetStorage().resize(n, c);
  924. }
  925. else
  926. {
  927. // Big string resized to small string
  928. // 11-17=2001: bug fix in the BOOST_ASSERTion below
  929. BOOST_ASSERT(capacity() > n);
  930. SmallStringOpt newObj(data(), n, get_allocator());
  931. newObj.swap(*this);
  932. }
  933. }
  934. }
  935. void swap(SmallStringOpt& rhs)
  936. {
  937. if (Small())
  938. {
  939. if (rhs.Small())
  940. {
  941. // Small swapped with small
  942. std::swap_ranges(buf_, buf_ + maxSmallString + 1,
  943. rhs.buf_);
  944. }
  945. else
  946. {
  947. // Small swapped with big
  948. // Make a copy of myself - can't throw
  949. SmallStringOpt temp(*this);
  950. // Nuke myself
  951. this->~SmallStringOpt();
  952. // Make an empty storage for myself (likely won't throw)
  953. new(buf_) Storage(0, value_type(), rhs.get_allocator());
  954. buf_[maxSmallString] = magic;
  955. // Recurse to this same function
  956. swap(rhs);
  957. // Nuke rhs
  958. rhs.~SmallStringOpt();
  959. // Build the new small string into rhs
  960. new(&rhs) SmallStringOpt(temp);
  961. }
  962. }
  963. else
  964. {
  965. if (rhs.Small())
  966. {
  967. // Big swapped with small
  968. // Already implemented, recurse with reversed args
  969. rhs.swap(*this);
  970. }
  971. else
  972. {
  973. // Big swapped with big
  974. GetStorage().swap(rhs.GetStorage());
  975. }
  976. }
  977. }
  978. const value_type* c_str() const
  979. {
  980. if (!Small()) return GetStorage().c_str();
  981. buf_[maxSmallString - buf_[maxSmallString]] = value_type();
  982. return buf_;
  983. }
  984. const value_type* data() const
  985. { return Small() ? buf_ : GetStorage().data(); }
  986. allocator_type get_allocator() const
  987. { return allocator_type(); }
  988. };
  989. ////////////////////////////////////////////////////////////////////////////////
  990. // class template CowString
  991. // Implements Copy on Write over any storage
  992. ////////////////////////////////////////////////////////////////////////////////
  993. template <
  994. typename Storage,
  995. typename Align = BOOST_DEDUCED_TYPENAME Storage::value_type*
  996. >
  997. class CowString
  998. {
  999. typedef typename Storage::value_type E;
  1000. typedef typename flex_string_details::get_unsigned<E>::result RefCountType;
  1001. public:
  1002. typedef E value_type;
  1003. typedef typename Storage::iterator iterator;
  1004. typedef typename Storage::const_iterator const_iterator;
  1005. typedef typename Storage::allocator_type allocator_type;
  1006. typedef typename boost::allocator_size_type<allocator_type>::type size_type;
  1007. typedef typename Storage::value_type& reference;
  1008. private:
  1009. union
  1010. {
  1011. mutable char buf_[sizeof(Storage)];
  1012. Align align_;
  1013. };
  1014. Storage& Data() const
  1015. {
  1016. Storage* p = reinterpret_cast<Storage*>(&buf_[0]);
  1017. return *p;
  1018. }
  1019. RefCountType GetRefs() const
  1020. {
  1021. const Storage& d = Data();
  1022. BOOST_ASSERT(d.size() > 0);
  1023. BOOST_ASSERT(static_cast<RefCountType>(*d.begin()) != 0);
  1024. return *d.begin();
  1025. }
  1026. RefCountType& Refs()
  1027. {
  1028. Storage& d = Data();
  1029. BOOST_ASSERT(d.size() > 0);
  1030. return reinterpret_cast<RefCountType&>(*d.begin());
  1031. }
  1032. void MakeUnique() const
  1033. {
  1034. BOOST_ASSERT(GetRefs() >= 1);
  1035. if (GetRefs() == 1) return;
  1036. union
  1037. {
  1038. char buf_[sizeof(Storage)];
  1039. Align align_;
  1040. } temp;
  1041. --(*Data().begin()); // decrement the use count of the remaining object
  1042. Storage* p = reinterpret_cast<Storage*>(&temp.buf_[0]);
  1043. new(buf_) Storage(
  1044. *new(p) Storage(Data()),
  1045. flex_string_details::Shallow());
  1046. *Data().begin() = 1;
  1047. }
  1048. public:
  1049. CowString(const CowString& s)
  1050. {
  1051. if (s.GetRefs() == (std::numeric_limits<RefCountType>::max)())
  1052. {
  1053. // must make a brand new copy
  1054. new(buf_) Storage(s.Data()); // non shallow
  1055. Refs() = 1;
  1056. }
  1057. else
  1058. {
  1059. new(buf_) Storage(s.Data(), flex_string_details::Shallow());
  1060. ++Refs();
  1061. }
  1062. BOOST_ASSERT(Data().size() > 0);
  1063. }
  1064. CowString(const allocator_type& a)
  1065. {
  1066. new(buf_) Storage(1, 1, a);
  1067. }
  1068. CowString(const E* s, size_type len, const allocator_type& a)
  1069. {
  1070. // Warning - MSVC's debugger has trouble tracing through the code below.
  1071. // It seems to be a const-correctness issue
  1072. //
  1073. new(buf_) Storage(a);
  1074. Data().reserve(len + 1);
  1075. Data().resize(1, 1);
  1076. Data().append(s, s + len);
  1077. }
  1078. CowString(size_type len, E c, const allocator_type& a)
  1079. {
  1080. new(buf_) Storage(len + 1, c, a);
  1081. Refs() = 1;
  1082. }
  1083. CowString& operator=(const CowString& rhs)
  1084. {
  1085. // CowString(rhs).swap(*this);
  1086. if (--Refs() == 0)
  1087. Data().~Storage();
  1088. if (rhs.GetRefs() == (std::numeric_limits<RefCountType>::max)())
  1089. {
  1090. // must make a brand new copy
  1091. new(buf_) Storage(rhs.Data()); // non shallow
  1092. Refs() = 1;
  1093. }
  1094. else
  1095. {
  1096. new(buf_) Storage(rhs.Data(), flex_string_details::Shallow());
  1097. ++Refs();
  1098. }
  1099. BOOST_ASSERT(Data().size() > 0);
  1100. return *this;
  1101. }
  1102. ~CowString()
  1103. {
  1104. BOOST_ASSERT(Data().size() > 0);
  1105. if (--Refs() == 0)
  1106. Data().~Storage();
  1107. }
  1108. iterator begin()
  1109. {
  1110. BOOST_ASSERT(Data().size() > 0);
  1111. MakeUnique();
  1112. return Data().begin() + 1;
  1113. }
  1114. const_iterator begin() const
  1115. {
  1116. BOOST_ASSERT(Data().size() > 0);
  1117. return Data().begin() + 1;
  1118. }
  1119. iterator end()
  1120. {
  1121. MakeUnique();
  1122. return Data().end();
  1123. }
  1124. const_iterator end() const
  1125. {
  1126. return Data().end();
  1127. }
  1128. size_type size() const
  1129. {
  1130. BOOST_ASSERT(Data().size() > 0);
  1131. return Data().size() - 1;
  1132. }
  1133. size_type max_size() const
  1134. {
  1135. BOOST_ASSERT(Data().max_size() > 0);
  1136. return Data().max_size() - 1;
  1137. }
  1138. size_type capacity() const
  1139. {
  1140. BOOST_ASSERT(Data().capacity() > 0);
  1141. return Data().capacity() - 1;
  1142. }
  1143. void resize(size_type n, E c)
  1144. {
  1145. BOOST_ASSERT(Data().size() > 0);
  1146. MakeUnique();
  1147. Data().resize(n + 1, c);
  1148. }
  1149. template <class FwdIterator>
  1150. void append(FwdIterator b, FwdIterator e)
  1151. {
  1152. MakeUnique();
  1153. Data().append(b, e);
  1154. }
  1155. void reserve(size_type res_arg)
  1156. {
  1157. if (capacity() > res_arg) return;
  1158. MakeUnique();
  1159. Data().reserve(res_arg + 1);
  1160. }
  1161. void swap(CowString& rhs)
  1162. {
  1163. Data().swap(rhs.Data());
  1164. }
  1165. const E* c_str() const
  1166. {
  1167. BOOST_ASSERT(Data().size() > 0);
  1168. return Data().c_str() + 1;
  1169. }
  1170. const E* data() const
  1171. {
  1172. BOOST_ASSERT(Data().size() > 0);
  1173. return Data().data() + 1;
  1174. }
  1175. allocator_type get_allocator() const
  1176. {
  1177. return Data().get_allocator();
  1178. }
  1179. };
  1180. ////////////////////////////////////////////////////////////////////////////////
  1181. // class template flex_string
  1182. // a std::basic_string compatible implementation
  1183. // Uses a Storage policy
  1184. ////////////////////////////////////////////////////////////////////////////////
  1185. template <typename E,
  1186. class T = std::char_traits<E>,
  1187. class A = std::allocator<E>,
  1188. class Storage = AllocatorStringStorage<E, A> >
  1189. class flex_string : private Storage
  1190. {
  1191. #if defined(BOOST_WAVE_FLEXSTRING_THROW_ON_ENFORCE)
  1192. template <typename Exception>
  1193. static void Enforce(bool condition, Exception*, const char* msg)
  1194. { if (!condition) boost::throw_exception(Exception(msg)); }
  1195. #else
  1196. template <typename Exception>
  1197. static inline void Enforce(bool condition, Exception*, const char* msg)
  1198. { BOOST_ASSERT(condition && msg); }
  1199. #endif // defined(BOOST_WAVE_FLEXSTRING_THROW_ON_ENFORCE)
  1200. #ifndef NDEBUG
  1201. bool Sane() const
  1202. {
  1203. return
  1204. begin() <= end() &&
  1205. empty() == (size() == 0) &&
  1206. empty() == (begin() == end()) &&
  1207. size() <= max_size() &&
  1208. capacity() <= max_size() &&
  1209. size() <= capacity();
  1210. }
  1211. struct Invariant;
  1212. friend struct Invariant;
  1213. struct Invariant
  1214. {
  1215. Invariant(const flex_string& s) : s_(s)
  1216. {
  1217. BOOST_ASSERT(s_.Sane());
  1218. }
  1219. ~Invariant()
  1220. {
  1221. BOOST_ASSERT(s_.Sane());
  1222. }
  1223. private:
  1224. const flex_string& s_;
  1225. Invariant& operator=(const Invariant&);
  1226. };
  1227. #endif
  1228. public:
  1229. // types
  1230. typedef T traits_type;
  1231. typedef typename traits_type::char_type value_type;
  1232. typedef A allocator_type;
  1233. typedef typename boost::allocator_value_type<A>::type& reference;
  1234. typedef typename boost::allocator_value_type<A>::type const& const_reference;
  1235. typedef typename boost::allocator_pointer<A>::type pointer;
  1236. typedef typename boost::allocator_const_pointer<A>::type const_pointer;
  1237. typedef typename boost::allocator_size_type<A>::type size_type;
  1238. typedef typename Storage::iterator iterator;
  1239. typedef typename Storage::const_iterator const_iterator;
  1240. typedef boost::reverse_iterator<iterator> reverse_iterator;
  1241. typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
  1242. static const size_type npos; // = size_type(-1)
  1243. private:
  1244. static size_type Min(size_type lhs, size_type rhs)
  1245. { return lhs < rhs ? lhs : rhs; }
  1246. static void Procust(size_type& n, size_type nmax)
  1247. { if (n > nmax) n = nmax; }
  1248. public:
  1249. // 21.3.1 construct/copy/destroy
  1250. explicit flex_string(const A& a = A())
  1251. : Storage(a)
  1252. {}
  1253. flex_string(const flex_string& str)
  1254. : Storage(str)
  1255. {
  1256. }
  1257. flex_string(const flex_string& str, size_type pos,
  1258. size_type n = npos, const A& a = A())
  1259. : Storage(a)
  1260. {
  1261. Enforce(pos <= str.size(), (std::out_of_range*)0, "");
  1262. assign(str, pos, n);
  1263. }
  1264. flex_string(const value_type* s, const A& a = A())
  1265. : Storage(s, traits_type::length(s), a)
  1266. {}
  1267. flex_string(const value_type* s, size_type n, const A& a = A())
  1268. : Storage(s, n, a)
  1269. {}
  1270. flex_string(size_type n, value_type c, const A& a = A())
  1271. : Storage(n, c, a)
  1272. {}
  1273. template <class InputIterator>
  1274. flex_string(InputIterator begin, InputIterator end, const A& a = A())
  1275. : Storage(a)
  1276. {
  1277. assign(begin, end);
  1278. }
  1279. ~flex_string()
  1280. {}
  1281. flex_string& operator=(const flex_string& str)
  1282. {
  1283. if (this != &str) {
  1284. Storage& s = *this;
  1285. s = str;
  1286. }
  1287. return *this;
  1288. }
  1289. flex_string& operator=(const value_type* s)
  1290. {
  1291. assign(s);
  1292. return *this;
  1293. }
  1294. flex_string& operator=(value_type c)
  1295. {
  1296. assign(1, c);
  1297. return *this;
  1298. }
  1299. // 21.3.2 iterators:
  1300. iterator begin()
  1301. { return Storage::begin(); }
  1302. const_iterator begin() const
  1303. { return Storage::begin(); }
  1304. iterator end()
  1305. { return Storage::end(); }
  1306. const_iterator end() const
  1307. { return Storage::end(); }
  1308. reverse_iterator rbegin()
  1309. { return reverse_iterator(end()); }
  1310. const_reverse_iterator rbegin() const
  1311. { return const_reverse_iterator(end()); }
  1312. reverse_iterator rend()
  1313. { return reverse_iterator(begin()); }
  1314. const_reverse_iterator rend() const
  1315. { return const_reverse_iterator(begin()); }
  1316. #if BOOST_WAVE_FLEX_STRING_SERIALIZATION_HACK != 0
  1317. // temporary hack to make it easier to serialize flex_string's using
  1318. // the Boost.Serialization library
  1319. value_type & back() { return *(begin()+size()-1); }
  1320. value_type const& back() const { return *(begin()+size()-1); }
  1321. #endif
  1322. // 21.3.3 capacity:
  1323. size_type size() const
  1324. { return Storage::size(); }
  1325. size_type length() const
  1326. { return size(); }
  1327. size_type max_size() const
  1328. { return Storage::max_size(); }
  1329. void resize(size_type n, value_type c)
  1330. { Storage::resize(n, c); }
  1331. void resize(size_type n)
  1332. { resize(n, value_type()); }
  1333. size_type capacity() const
  1334. { return Storage::capacity(); }
  1335. void reserve(size_type res_arg = 0)
  1336. {
  1337. Enforce(res_arg <= max_size(), (std::length_error*)0, "");
  1338. Storage::reserve(res_arg);
  1339. }
  1340. void clear()
  1341. { resize(0); }
  1342. bool empty() const
  1343. { return size() == 0; }
  1344. // 21.3.4 element access:
  1345. const_reference operator[](size_type pos) const
  1346. { return *(begin() + pos); }
  1347. reference operator[](size_type pos)
  1348. { return *(begin() + pos); }
  1349. const_reference at(size_type n) const
  1350. {
  1351. Enforce(n < size(), (std::out_of_range*)0, "");
  1352. return (*this)[n];
  1353. }
  1354. reference at(size_type n)
  1355. {
  1356. Enforce(n < size(), (std::out_of_range*)0, "");
  1357. return (*this)[n];
  1358. }
  1359. // 21.3.5 modifiers:
  1360. flex_string& operator+=(const flex_string& str)
  1361. { return append(str); }
  1362. flex_string& operator+=(const value_type* s)
  1363. { return append(s); }
  1364. flex_string& operator+=(value_type c)
  1365. {
  1366. push_back(c);
  1367. return *this;
  1368. }
  1369. flex_string& append(const flex_string& str)
  1370. { return append(str, 0, npos); }
  1371. flex_string& append(const flex_string& str, const size_type pos,
  1372. size_type n)
  1373. {
  1374. const size_type sz = str.size();
  1375. Enforce(pos <= sz, (std::out_of_range*)0, "");
  1376. Procust(n, sz - pos);
  1377. return append(str.c_str() + pos, n);
  1378. }
  1379. flex_string& append(const value_type* s, const size_type n)
  1380. {
  1381. #ifndef NDEBUG
  1382. Invariant checker(*this);
  1383. #endif
  1384. if (IsAliasedRange(s, s + n))
  1385. {
  1386. const size_type offset = s - &*begin();
  1387. Storage::reserve(size() + n);
  1388. s = &*begin() + offset;
  1389. }
  1390. Storage::append(s, s+ n);
  1391. return *this;
  1392. }
  1393. flex_string& append(const value_type* s)
  1394. { return append(s, traits_type::length(s)); }
  1395. flex_string& append(size_type n, value_type c)
  1396. {
  1397. resize(size() + n, c);
  1398. return *this;
  1399. }
  1400. template<class InputIterator>
  1401. flex_string& append(InputIterator first, InputIterator last)
  1402. {
  1403. insert(end(), first, last);
  1404. return *this;
  1405. }
  1406. void push_back(value_type c)
  1407. {
  1408. const size_type cap = capacity();
  1409. if (size() == cap)
  1410. {
  1411. reserve(cap << 1u);
  1412. }
  1413. Storage::append(&c, &c + 1);
  1414. }
  1415. flex_string& assign(const flex_string& str)
  1416. {
  1417. if (&str == this) return *this;
  1418. return assign(str.data(), str.size());
  1419. }
  1420. flex_string& assign(const flex_string& str, size_type pos,
  1421. size_type n)
  1422. {
  1423. const size_type sz = str.size();
  1424. Enforce(pos <= str.size(), (std::out_of_range*)0, "");
  1425. Procust(n, sz - pos);
  1426. return assign(str.data() + pos, n);
  1427. }
  1428. flex_string& assign(const value_type* s, size_type n)
  1429. {
  1430. #ifndef NDEBUG
  1431. Invariant checker(*this);
  1432. #endif
  1433. if (size() >= n)
  1434. {
  1435. std::copy(s, s + n, begin());
  1436. resize(n);
  1437. }
  1438. else
  1439. {
  1440. const value_type *const s2 = s + size();
  1441. std::copy(s, s2, begin());
  1442. append(s2, n - size());
  1443. }
  1444. return *this;
  1445. }
  1446. flex_string& assign(const value_type* s)
  1447. { return assign(s, traits_type::length(s)); }
  1448. template <class ItOrLength, class ItOrChar>
  1449. flex_string& assign(ItOrLength first_or_n, ItOrChar last_or_c)
  1450. { return replace(begin(), end(), first_or_n, last_or_c); }
  1451. flex_string& insert(size_type pos1, const flex_string& str)
  1452. { return insert(pos1, str.data(), str.size()); }
  1453. flex_string& insert(size_type pos1, const flex_string& str,
  1454. size_type pos2, size_type n)
  1455. {
  1456. Enforce(pos2 <= str.length(), (std::out_of_range*)0, "");
  1457. Procust(n, str.length() - pos2);
  1458. return insert(pos1, str.data() + pos2, n);
  1459. }
  1460. flex_string& insert(size_type pos, const value_type* s, size_type n)
  1461. {
  1462. Enforce(pos <= length(), (std::out_of_range*)0, "");
  1463. insert(begin() + pos, s, s + n);
  1464. return *this;
  1465. }
  1466. flex_string& insert(size_type pos, const value_type* s)
  1467. { return insert(pos, s, traits_type::length(s)); }
  1468. flex_string& insert(size_type pos, size_type n, value_type c)
  1469. {
  1470. Enforce(pos <= length(), (std::out_of_range*)0, "");
  1471. insert(begin() + pos, n, c);
  1472. return *this;
  1473. }
  1474. iterator insert(iterator p, value_type c = value_type())
  1475. {
  1476. const size_type pos = p - begin();
  1477. insert(pos, &c, 1);
  1478. return begin() + pos;
  1479. }
  1480. private:
  1481. // Care must be taken when dereferencing some iterator types.
  1482. //
  1483. // Users can implement this function in their namespace if their storage
  1484. // uses a special iterator type, the function will be found through ADL.
  1485. template<class Iterator>
  1486. const typename std::iterator_traits<Iterator>::value_type*
  1487. DereferenceValidIterator(Iterator it) const
  1488. {
  1489. return &*it;
  1490. }
  1491. // Care must be taken when dereferencing a reverse iterators, hence this
  1492. // special case. This isn't in the std namespace so as not to pollute it or
  1493. // create name clashes.
  1494. template<typename Iterator>
  1495. const typename std::iterator_traits<Iterator>::value_type*
  1496. DereferenceValidIterator(std::reverse_iterator<Iterator> it) const
  1497. {
  1498. return &*--it;
  1499. }
  1500. // Determine if the range aliases the current string.
  1501. //
  1502. // This method cannot be const because calling begin/end on copy-on-write
  1503. // implementations must have side effects.
  1504. // A const version wouldn't make the string unique through this call.
  1505. template<class Iterator>
  1506. bool IsAliasedRange(Iterator beginIterator, Iterator endIterator)
  1507. {
  1508. if(!empty() && beginIterator != endIterator)
  1509. {
  1510. typedef const typename std::iterator_traits<Iterator>::value_type *
  1511. value_pointer;
  1512. value_pointer myBegin(&*begin());
  1513. value_pointer myEnd(&*begin() + size());
  1514. value_pointer rangeBegin(DereferenceValidIterator(beginIterator));
  1515. const std::less_equal<value_pointer> less_equal = std::less_equal<value_pointer>();
  1516. if(less_equal(myBegin, rangeBegin) && less_equal(rangeBegin, myEnd))
  1517. return true;
  1518. }
  1519. return false;
  1520. }
  1521. template <int i> class Selector {};
  1522. flex_string& InsertImplDiscr(iterator p,
  1523. size_type n, value_type c, Selector<1>)
  1524. {
  1525. #ifndef NDEBUG
  1526. Invariant checker(*this);
  1527. #endif
  1528. BOOST_ASSERT(begin() <= p && p <= end());
  1529. const size_type insertOffset(p - begin());
  1530. const size_type originalSize(size());
  1531. if(n < originalSize - insertOffset)
  1532. {
  1533. // The new characters fit within the original string.
  1534. // The characters that are pushed back need to be moved because
  1535. // they're aliased.
  1536. // The appended characters will all be overwritten by the move.
  1537. append(n, value_type(0));
  1538. value_type* begin(&*begin());
  1539. flex_string_details::pod_move(begin + insertOffset,
  1540. begin + originalSize, begin + insertOffset + n);
  1541. std::fill(begin + insertOffset, begin + insertOffset + n, c);
  1542. }
  1543. else
  1544. {
  1545. // The new characters exceed the original string.
  1546. // The characters that are pushed back can simply be copied since
  1547. // they aren't aliased.
  1548. // The appended characters will partly be overwritten by the copy.
  1549. append(n, c);
  1550. value_type* begin(&*begin());
  1551. flex_string_details::pod_copy(begin + insertOffset,
  1552. begin + originalSize, begin + insertOffset + n);
  1553. std::fill(begin + insertOffset, begin + originalSize, c);
  1554. }
  1555. return *this;
  1556. }
  1557. template<class InputIterator>
  1558. flex_string& InsertImplDiscr(iterator i,
  1559. InputIterator b, InputIterator e, Selector<0>)
  1560. {
  1561. InsertImpl(i, b, e,
  1562. typename std::iterator_traits<InputIterator>::iterator_category());
  1563. return *this;
  1564. }
  1565. template <class FwdIterator>
  1566. void InsertImpl(iterator i,
  1567. FwdIterator s1, FwdIterator s2, std::forward_iterator_tag)
  1568. {
  1569. if(s1 == s2)
  1570. {
  1571. // Insert an empty range.
  1572. return;
  1573. }
  1574. if(IsAliasedRange(s1, s2))
  1575. {
  1576. // The source range is contained in the current string, copy it
  1577. // and recurse.
  1578. const flex_string temporary(s1, s2);
  1579. InsertImpl(i, temporary.begin(), temporary.end(),
  1580. typename std::iterator_traits<FwdIterator>::iterator_category());
  1581. return;
  1582. }
  1583. #ifndef NDEBUG
  1584. Invariant checker(*this);
  1585. #endif
  1586. const size_type pos = i - begin();
  1587. const typename std::iterator_traits<FwdIterator>::difference_type n2 =
  1588. std::distance(s1, s2);
  1589. BOOST_ASSERT(n2 >= 0);
  1590. using namespace flex_string_details;
  1591. BOOST_ASSERT(pos <= size());
  1592. const typename std::iterator_traits<FwdIterator>::difference_type maxn2 =
  1593. capacity() - size();
  1594. if (maxn2 < n2)
  1595. {
  1596. // Reallocate the string.
  1597. BOOST_ASSERT(!IsAliasedRange(s1, s2));
  1598. reserve(size() + n2);
  1599. i = begin() + pos;
  1600. }
  1601. if (pos + n2 <= size())
  1602. {
  1603. const iterator tailBegin = end() - n2;
  1604. Storage::append(tailBegin, tailBegin + n2);
  1605. std::copy(reverse_iterator(tailBegin), reverse_iterator(i),
  1606. reverse_iterator(tailBegin + n2));
  1607. std::copy(s1, s2, i);
  1608. }
  1609. else
  1610. {
  1611. FwdIterator t = s1;
  1612. const size_type old_size = size();
  1613. std::advance(t, old_size - pos);
  1614. BOOST_ASSERT(std::distance(t, s2) >= 0);
  1615. Storage::append(t, s2);
  1616. Storage::append(data() + pos, data() + old_size);
  1617. std::copy(s1, t, i);
  1618. }
  1619. }
  1620. template <class InputIterator>
  1621. void InsertImpl(iterator insertPosition,
  1622. InputIterator inputBegin, InputIterator inputEnd,
  1623. std::input_iterator_tag)
  1624. {
  1625. flex_string temporary(begin(), insertPosition);
  1626. for (; inputBegin != inputEnd; ++inputBegin)
  1627. {
  1628. temporary.push_back(*inputBegin);
  1629. }
  1630. temporary.append(insertPosition, end());
  1631. swap(temporary);
  1632. }
  1633. public:
  1634. template <class ItOrLength, class ItOrChar>
  1635. void insert(iterator p, ItOrLength first_or_n, ItOrChar last_or_c)
  1636. {
  1637. Selector<std::numeric_limits<ItOrLength>::is_specialized> sel;
  1638. InsertImplDiscr(p, first_or_n, last_or_c, sel);
  1639. }
  1640. flex_string& erase(size_type pos = 0, size_type n = npos)
  1641. {
  1642. #ifndef NDEBUG
  1643. Invariant checker(*this);
  1644. #endif
  1645. Enforce(pos <= length(), (std::out_of_range*)0, "");
  1646. Procust(n, length() - pos);
  1647. std::copy(begin() + pos + n, end(), begin() + pos);
  1648. resize(length() - n);
  1649. return *this;
  1650. }
  1651. iterator erase(iterator position)
  1652. {
  1653. const size_type pos(position - begin());
  1654. erase(pos, 1);
  1655. return begin() + pos;
  1656. }
  1657. iterator erase(iterator first, iterator last)
  1658. {
  1659. const size_type pos(first - begin());
  1660. erase(pos, last - first);
  1661. return begin() + pos;
  1662. }
  1663. // Replaces at most n1 chars of *this, starting with pos1 with the content of str
  1664. flex_string& replace(size_type pos1, size_type n1, const flex_string& str)
  1665. { return replace(pos1, n1, str, 0, npos); }
  1666. // Replaces at most n1 chars of *this, starting with pos1,
  1667. // with at most n2 chars of str starting with pos2
  1668. flex_string& replace(size_type pos1, size_type n1, const flex_string& str,
  1669. size_type pos2, size_type n2)
  1670. {
  1671. Enforce(pos2 <= str.length(), (std::out_of_range*)0, "");
  1672. return replace(pos1, n1, str.data() + pos2,
  1673. Min(n2, str.size() - pos2));
  1674. }
  1675. // Replaces at most n1 chars of *this, starting with pos, with chars from s
  1676. flex_string& replace(size_type pos, size_type n1, const value_type* s)
  1677. { return replace(pos, n1, s, traits_type::length(s)); }
  1678. // Replaces at most n1 chars of *this, starting with pos, with n2 occurrences of c
  1679. // consolidated with
  1680. // Replaces at most n1 chars of *this, starting with pos,
  1681. // with at most n2 chars of str.
  1682. // str must have at least n2 chars.
  1683. template <class StrOrLength, class NumOrChar>
  1684. flex_string& replace(size_type pos, size_type n1,
  1685. StrOrLength s_or_n2, NumOrChar n_or_c)
  1686. {
  1687. #ifndef NDEBUG
  1688. Invariant checker(*this);
  1689. #endif
  1690. Enforce(pos <= size(), (std::out_of_range*)0, "");
  1691. Procust(n1, length() - pos);
  1692. const iterator b = begin() + pos;
  1693. return replace(b, b + n1, s_or_n2, n_or_c);
  1694. }
  1695. flex_string& replace(iterator i1, iterator i2, const flex_string& str)
  1696. { return replace(i1, i2, str.c_str(), str.length()); }
  1697. flex_string& replace(iterator i1, iterator i2, const value_type* s)
  1698. { return replace(i1, i2, s, traits_type::length(s)); }
  1699. private:
  1700. flex_string& ReplaceImplDiscr(iterator i1, iterator i2,
  1701. const value_type* s, size_type n, Selector<2>)
  1702. {
  1703. BOOST_ASSERT(i1 <= i2);
  1704. BOOST_ASSERT(begin() <= i1 && i1 <= end());
  1705. BOOST_ASSERT(begin() <= i2 && i2 <= end());
  1706. return replace(i1, i2, s, s + n);
  1707. }
  1708. flex_string& ReplaceImplDiscr(iterator i1, iterator i2,
  1709. size_type n2, value_type c, Selector<1>)
  1710. {
  1711. const size_type n1 = i2 - i1;
  1712. if (n1 > n2)
  1713. {
  1714. std::fill(i1, i1 + n2, c);
  1715. erase(i1 + n2, i2);
  1716. }
  1717. else
  1718. {
  1719. std::fill(i1, i2, c);
  1720. insert(i2, n2 - n1, c);
  1721. }
  1722. return *this;
  1723. }
  1724. template <class InputIterator>
  1725. flex_string& ReplaceImplDiscr(iterator i1, iterator i2,
  1726. InputIterator b, InputIterator e, Selector<0>)
  1727. {
  1728. ReplaceImpl(i1, i2, b, e,
  1729. typename std::iterator_traits<InputIterator>::iterator_category());
  1730. return *this;
  1731. }
  1732. template <class FwdIterator>
  1733. void ReplaceImpl(iterator i1, iterator i2,
  1734. FwdIterator s1, FwdIterator s2, std::forward_iterator_tag)
  1735. {
  1736. #ifndef NDEBUG
  1737. Invariant checker(*this);
  1738. #endif
  1739. const typename std::iterator_traits<iterator>::difference_type n1 =
  1740. i2 - i1;
  1741. BOOST_ASSERT(n1 >= 0);
  1742. const typename std::iterator_traits<FwdIterator>::difference_type n2 =
  1743. std::distance(s1, s2);
  1744. BOOST_ASSERT(n2 >= 0);
  1745. if (IsAliasedRange(s1, s2))
  1746. {
  1747. // Aliased replace, copy to new string.
  1748. flex_string temporary;
  1749. temporary.reserve(size() - n1 + n2);
  1750. temporary.append(begin(), i1).append(s1, s2).append(i2, end());
  1751. swap(temporary);
  1752. return;
  1753. }
  1754. if (n1 > n2)
  1755. {
  1756. // Shrinks
  1757. std::copy(s1, s2, i1);
  1758. erase(i1 + n2, i2);
  1759. }
  1760. else
  1761. {
  1762. // Grows
  1763. flex_string_details::copy_n(s1, n1, i1);
  1764. std::advance(s1, n1);
  1765. insert(i2, s1, s2);
  1766. }
  1767. }
  1768. template <class InputIterator>
  1769. void ReplaceImpl(iterator i1, iterator i2,
  1770. InputIterator b, InputIterator e, std::input_iterator_tag)
  1771. {
  1772. flex_string temp(begin(), i1);
  1773. temp.append(b, e).append(i2, end());
  1774. swap(temp);
  1775. }
  1776. public:
  1777. template <class T1, class T2>
  1778. flex_string& replace(iterator i1, iterator i2,
  1779. T1 first_or_n_or_s, T2 last_or_c_or_n)
  1780. {
  1781. const bool
  1782. num1 = std::numeric_limits<T1>::is_specialized,
  1783. num2 = std::numeric_limits<T2>::is_specialized;
  1784. return ReplaceImplDiscr(i1, i2, first_or_n_or_s, last_or_c_or_n,
  1785. Selector<num1 ? (num2 ? 1 : -1) : (num2 ? 2 : 0)>());
  1786. }
  1787. size_type copy(value_type* s, size_type n, size_type pos = 0) const
  1788. {
  1789. Enforce(pos <= size(), (std::out_of_range*)0, "");
  1790. n = Min(n, size() - pos);
  1791. flex_string_details::pod_copy(
  1792. &*begin() + pos,
  1793. &*begin() + pos + n,
  1794. s);
  1795. return n;
  1796. }
  1797. void swap(flex_string& rhs)
  1798. {
  1799. Storage& srhs = rhs;
  1800. this->Storage::swap(srhs);
  1801. }
  1802. // 21.3.6 string operations:
  1803. const value_type* c_str() const
  1804. { return Storage::c_str(); }
  1805. const value_type* data() const
  1806. { return Storage::data(); }
  1807. allocator_type get_allocator() const
  1808. { return Storage::get_allocator(); }
  1809. size_type find(const flex_string& str, size_type pos = 0) const
  1810. { return find(str.data(), pos, str.length()); }
  1811. size_type find (const value_type* s, size_type pos, size_type n) const
  1812. {
  1813. const size_type size_(size());
  1814. if (n + pos > size_)
  1815. return npos;
  1816. for (; pos < size_; ++pos)
  1817. {
  1818. if (traits_type::compare(&*begin() + pos, s, n) == 0)
  1819. {
  1820. return pos;
  1821. }
  1822. }
  1823. return npos;
  1824. }
  1825. size_type find (const value_type* s, size_type pos = 0) const
  1826. { return find(s, pos, traits_type::length(s)); }
  1827. size_type find (value_type c, size_type pos = 0) const
  1828. { return find(&c, pos, 1); }
  1829. size_type rfind(const flex_string& str, size_type pos = npos) const
  1830. { return rfind(str.c_str(), pos, str.length()); }
  1831. size_type rfind(const value_type* s, size_type pos, size_type n) const
  1832. {
  1833. if (n > length()) return npos;
  1834. pos = Min(pos, length() - n);
  1835. if (n == 0) return pos;
  1836. const_iterator i(begin() + pos);
  1837. for (; ; --i)
  1838. {
  1839. if (traits_type::eq(*i, *s)
  1840. && traits_type::compare(&*i, s, n) == 0)
  1841. {
  1842. return i - begin();
  1843. }
  1844. if (i == begin()) break;
  1845. }
  1846. return npos;
  1847. }
  1848. size_type rfind(const value_type* s, size_type pos = npos) const
  1849. { return rfind(s, pos, traits_type::length(s)); }
  1850. size_type rfind(value_type c, size_type pos = npos) const
  1851. { return rfind(&c, pos, 1); }
  1852. size_type find_first_of(const flex_string& str, size_type pos = 0) const
  1853. { return find_first_of(str.c_str(), pos, str.length()); }
  1854. size_type find_first_of(const value_type* s,
  1855. size_type pos, size_type n) const
  1856. {
  1857. if (pos > length() || n == 0) return npos;
  1858. const_iterator i(begin() + pos),
  1859. finish(end());
  1860. for (; i != finish; ++i)
  1861. {
  1862. if (traits_type::find(s, n, *i) != 0)
  1863. {
  1864. return i - begin();
  1865. }
  1866. }
  1867. return npos;
  1868. }
  1869. size_type find_first_of(const value_type* s, size_type pos = 0) const
  1870. { return find_first_of(s, pos, traits_type::length(s)); }
  1871. size_type find_first_of(value_type c, size_type pos = 0) const
  1872. { return find_first_of(&c, pos, 1); }
  1873. size_type find_last_of (const flex_string& str,
  1874. size_type pos = npos) const
  1875. { return find_last_of(str.c_str(), pos, str.length()); }
  1876. size_type find_last_of (const value_type* s, size_type pos,
  1877. size_type n) const
  1878. {
  1879. if (!empty() && n > 0)
  1880. {
  1881. pos = Min(pos, length() - 1);
  1882. const_iterator i(begin() + pos);
  1883. for (;; --i)
  1884. {
  1885. if (traits_type::find(s, n, *i) != 0)
  1886. {
  1887. return i - begin();
  1888. }
  1889. if (i == begin()) break;
  1890. }
  1891. }
  1892. return npos;
  1893. }
  1894. size_type find_last_of (const value_type* s,
  1895. size_type pos = npos) const
  1896. { return find_last_of(s, pos, traits_type::length(s)); }
  1897. size_type find_last_of (value_type c, size_type pos = npos) const
  1898. { return find_last_of(&c, pos, 1); }
  1899. size_type find_first_not_of(const flex_string& str,
  1900. size_type pos = 0) const
  1901. { return find_first_not_of(str.data(), pos, str.size()); }
  1902. size_type find_first_not_of(const value_type* s, size_type pos,
  1903. size_type n) const
  1904. {
  1905. if (pos < length())
  1906. {
  1907. const_iterator
  1908. i(begin() + pos),
  1909. finish(end());
  1910. for (; i != finish; ++i)
  1911. {
  1912. if (traits_type::find(s, n, *i) == 0)
  1913. {
  1914. return i - begin();
  1915. }
  1916. }
  1917. }
  1918. return npos;
  1919. }
  1920. size_type find_first_not_of(const value_type* s,
  1921. size_type pos = 0) const
  1922. { return find_first_not_of(s, pos, traits_type::length(s)); }
  1923. size_type find_first_not_of(value_type c, size_type pos = 0) const
  1924. { return find_first_not_of(&c, pos, 1); }
  1925. size_type find_last_not_of(const flex_string& str,
  1926. size_type pos = npos) const
  1927. { return find_last_not_of(str.c_str(), pos, str.length()); }
  1928. size_type find_last_not_of(const value_type* s, size_type pos,
  1929. size_type n) const
  1930. {
  1931. if (!empty())
  1932. {
  1933. pos = Min(pos, size() - 1);
  1934. const_iterator i(begin() + pos);
  1935. for (;; --i)
  1936. {
  1937. if (traits_type::find(s, n, *i) == 0)
  1938. {
  1939. return i - begin();
  1940. }
  1941. if (i == begin()) break;
  1942. }
  1943. }
  1944. return npos;
  1945. }
  1946. size_type find_last_not_of(const value_type* s,
  1947. size_type pos = npos) const
  1948. { return find_last_not_of(s, pos, traits_type::length(s)); }
  1949. size_type find_last_not_of (value_type c, size_type pos = npos) const
  1950. { return find_last_not_of(&c, pos, 1); }
  1951. flex_string substr(size_type pos = 0, size_type n = npos) const
  1952. {
  1953. Enforce(pos <= size(), (std::out_of_range*)0, "");
  1954. return flex_string(data() + pos, Min(n, size() - pos));
  1955. }
  1956. std::ptrdiff_t compare(const flex_string& str) const
  1957. {
  1958. // FIX due to Goncalo N M de Carvalho July 18, 2005
  1959. return compare(0, size(), str);
  1960. }
  1961. std::ptrdiff_t compare(size_type pos1, size_type n1,
  1962. const flex_string& str) const
  1963. { return compare(pos1, n1, str.data(), str.size()); }
  1964. // FIX to compare: added the TC
  1965. // (http://www.comeaucomputing.com/iso/lwg-defects.html number 5)
  1966. // Thanks to Caleb Epstein for the fix
  1967. std::ptrdiff_t compare(size_type pos1, size_type n1,
  1968. const value_type* s) const
  1969. {
  1970. return compare(pos1, n1, s, traits_type::length(s));
  1971. }
  1972. std::ptrdiff_t compare(size_type pos1, size_type n1,
  1973. const value_type* s, size_type n2) const
  1974. {
  1975. Enforce(pos1 <= size(), (std::out_of_range*)0, "");
  1976. Procust(n1, size() - pos1);
  1977. const int r = traits_type::compare(pos1 + data(), s, Min(n1, n2));
  1978. return r != 0 ? r : n1 > n2 ? 1 : n1 < n2 ? -1 : 0;
  1979. }
  1980. std::ptrdiff_t compare(size_type pos1, size_type n1,
  1981. const flex_string& str,
  1982. size_type pos2, size_type n2) const
  1983. {
  1984. Enforce(pos2 <= str.size(), (std::out_of_range*)0, "");
  1985. return compare(pos1, n1, str.data() + pos2, Min(n2, str.size() - pos2));
  1986. }
  1987. std::ptrdiff_t compare(const value_type* s) const
  1988. {
  1989. // Could forward to compare(0, size(), s, traits_type::length(s))
  1990. // but that does two extra checks
  1991. const size_type n1(size()), n2(traits_type::length(s));
  1992. const int r = traits_type::compare(data(), s, Min(n1, n2));
  1993. return r != 0 ? r : n1 > n2 ? 1 : n1 < n2 ? -1 : 0;
  1994. }
  1995. };
  1996. // non-member functions
  1997. template <typename E, class T, class A, class S>
  1998. flex_string<E, T, A, S> operator+(const flex_string<E, T, A, S>& lhs,
  1999. const flex_string<E, T, A, S>& rhs)
  2000. {
  2001. flex_string<E, T, A, S> result;
  2002. result.reserve(lhs.size() + rhs.size());
  2003. result.append(lhs).append(rhs);
  2004. return result;
  2005. }
  2006. template <typename E, class T, class A, class S>
  2007. flex_string<E, T, A, S> operator+(const typename flex_string<E, T, A, S>::value_type* lhs,
  2008. const flex_string<E, T, A, S>& rhs)
  2009. {
  2010. flex_string<E, T, A, S> result;
  2011. const typename flex_string<E, T, A, S>::size_type len =
  2012. flex_string<E, T, A, S>::traits_type::length(lhs);
  2013. result.reserve(len + rhs.size());
  2014. result.append(lhs, len).append(rhs);
  2015. return result;
  2016. }
  2017. template <typename E, class T, class A, class S>
  2018. flex_string<E, T, A, S> operator+(
  2019. typename flex_string<E, T, A, S>::value_type lhs,
  2020. const flex_string<E, T, A, S>& rhs)
  2021. {
  2022. flex_string<E, T, A, S> result;
  2023. result.reserve(1 + rhs.size());
  2024. result.push_back(lhs);
  2025. result.append(rhs);
  2026. return result;
  2027. }
  2028. template <typename E, class T, class A, class S>
  2029. flex_string<E, T, A, S> operator+(const flex_string<E, T, A, S>& lhs,
  2030. const typename flex_string<E, T, A, S>::value_type* rhs)
  2031. {
  2032. typedef typename flex_string<E, T, A, S>::size_type size_type;
  2033. typedef typename flex_string<E, T, A, S>::traits_type traits_type;
  2034. flex_string<E, T, A, S> result;
  2035. const size_type len = traits_type::length(rhs);
  2036. result.reserve(lhs.size() + len);
  2037. result.append(lhs).append(rhs, len);
  2038. return result;
  2039. }
  2040. template <typename E, class T, class A, class S>
  2041. flex_string<E, T, A, S> operator+(const flex_string<E, T, A, S>& lhs,
  2042. typename flex_string<E, T, A, S>::value_type rhs)
  2043. {
  2044. flex_string<E, T, A, S> result;
  2045. result.reserve(lhs.size() + 1);
  2046. result.append(lhs);
  2047. result.push_back(rhs);
  2048. return result;
  2049. }
  2050. template <typename E, class T, class A, class S>
  2051. inline bool operator==(const flex_string<E, T, A, S>& lhs,
  2052. const flex_string<E, T, A, S>& rhs)
  2053. { return lhs.compare(rhs) == 0; }
  2054. template <typename E, class T, class A, class S>
  2055. inline bool operator==(const typename flex_string<E, T, A, S>::value_type* lhs,
  2056. const flex_string<E, T, A, S>& rhs)
  2057. { return rhs == lhs; }
  2058. template <typename E, class T, class A, class S>
  2059. inline bool operator==(const flex_string<E, T, A, S>& lhs,
  2060. const typename flex_string<E, T, A, S>::value_type* rhs)
  2061. { return lhs.compare(rhs) == 0; }
  2062. template <typename E, class T, class A, class S>
  2063. inline bool operator!=(const flex_string<E, T, A, S>& lhs,
  2064. const flex_string<E, T, A, S>& rhs)
  2065. { return !(lhs == rhs); }
  2066. template <typename E, class T, class A, class S>
  2067. inline bool operator!=(const typename flex_string<E, T, A, S>::value_type* lhs,
  2068. const flex_string<E, T, A, S>& rhs)
  2069. { return !(lhs == rhs); }
  2070. template <typename E, class T, class A, class S>
  2071. inline bool operator!=(const flex_string<E, T, A, S>& lhs,
  2072. const typename flex_string<E, T, A, S>::value_type* rhs)
  2073. { return !(lhs == rhs); }
  2074. template <typename E, class T, class A, class S>
  2075. inline bool operator<(const flex_string<E, T, A, S>& lhs,
  2076. const flex_string<E, T, A, S>& rhs)
  2077. { return lhs.compare(rhs) < 0; }
  2078. template <typename E, class T, class A, class S>
  2079. inline bool operator<(const flex_string<E, T, A, S>& lhs,
  2080. const typename flex_string<E, T, A, S>::value_type* rhs)
  2081. { return lhs.compare(rhs) < 0; }
  2082. template <typename E, class T, class A, class S>
  2083. inline bool operator<(const typename flex_string<E, T, A, S>::value_type* lhs,
  2084. const flex_string<E, T, A, S>& rhs)
  2085. { return rhs.compare(lhs) > 0; }
  2086. template <typename E, class T, class A, class S>
  2087. inline bool operator>(const flex_string<E, T, A, S>& lhs,
  2088. const flex_string<E, T, A, S>& rhs)
  2089. { return rhs < lhs; }
  2090. template <typename E, class T, class A, class S>
  2091. inline bool operator>(const flex_string<E, T, A, S>& lhs,
  2092. const typename flex_string<E, T, A, S>::value_type* rhs)
  2093. { return rhs < lhs; }
  2094. template <typename E, class T, class A, class S>
  2095. bool operator>(const typename flex_string<E, T, A, S>::value_type* lhs,
  2096. const flex_string<E, T, A, S>& rhs)
  2097. { return rhs < lhs; }
  2098. template <typename E, class T, class A, class S>
  2099. inline bool operator<=(const flex_string<E, T, A, S>& lhs,
  2100. const flex_string<E, T, A, S>& rhs)
  2101. { return !(rhs < lhs); }
  2102. template <typename E, class T, class A, class S>
  2103. inline bool operator<=(const flex_string<E, T, A, S>& lhs,
  2104. const typename flex_string<E, T, A, S>::value_type* rhs)
  2105. { return !(rhs < lhs); }
  2106. template <typename E, class T, class A, class S>
  2107. bool operator<=(const typename flex_string<E, T, A, S>::value_type* lhs,
  2108. const flex_string<E, T, A, S>& rhs)
  2109. { return !(rhs < lhs); }
  2110. template <typename E, class T, class A, class S>
  2111. bool operator>=(const flex_string<E, T, A, S>& lhs,
  2112. const flex_string<E, T, A, S>& rhs)
  2113. { return !(lhs < rhs); }
  2114. template <typename E, class T, class A, class S>
  2115. bool operator>=(const flex_string<E, T, A, S>& lhs,
  2116. const typename flex_string<E, T, A, S>::value_type* rhs)
  2117. { return !(lhs < rhs); }
  2118. template <typename E, class T, class A, class S>
  2119. inline bool operator>=(const typename flex_string<E, T, A, S>::value_type* lhs,
  2120. const flex_string<E, T, A, S>& rhs)
  2121. { return !(lhs < rhs); }
  2122. template <typename E, class T, class A, class S>
  2123. void swap(flex_string<E, T, A, S>& lhs, flex_string<E, T, A, S>& rhs)
  2124. {
  2125. // subclause 21.3.7.8:
  2126. lhs.swap(rhs);
  2127. }
  2128. template <typename E, class T, class A, class S>
  2129. inline std::basic_istream<typename flex_string<E, T, A, S>::value_type,
  2130. typename flex_string<E, T, A, S>::traits_type>&
  2131. operator>>(
  2132. std::basic_istream<typename flex_string<E, T, A, S>::value_type,
  2133. typename flex_string<E, T, A, S>::traits_type>& is,
  2134. flex_string<E, T, A, S>& str);
  2135. template <typename E, class T, class A, class S>
  2136. std::basic_ostream<typename flex_string<E, T, A, S>::value_type,
  2137. typename flex_string<E, T, A, S>::traits_type>&
  2138. operator<<(
  2139. std::basic_ostream<typename flex_string<E, T, A, S>::value_type,
  2140. typename flex_string<E, T, A, S>::traits_type>& os,
  2141. const flex_string<E, T, A, S>& str)
  2142. { return os << str.c_str(); }
  2143. template <typename E1, class T, class A, class S>
  2144. const typename flex_string<E1, T, A, S>::size_type
  2145. flex_string<E1, T, A, S>::npos = (typename flex_string<E1, T, A, S>::size_type)(-1);
  2146. ///////////////////////////////////////////////////////////////////////////////
  2147. } // namespace util
  2148. } // namespace wave
  2149. } // namespace boost
  2150. #if BOOST_WAVE_SERIALIZATION != 0
  2151. ///////////////////////////////////////////////////////////////////////////////
  2152. namespace boost { namespace serialization {
  2153. #if !defined(BOOST_WAVE_FLEX_STRING_SERIALIZATION_HACK)
  2154. // FIXME: This doesn't work because of the missing flex_string::operator>>()
  2155. template <typename E, class T, class A, class S>
  2156. struct implementation_level<boost::wave::util::flex_string<E, T, A, S> >
  2157. {
  2158. typedef mpl::integral_c_tag tag;
  2159. typedef mpl::int_<boost::serialization::primitive_type> type;
  2160. BOOST_STATIC_CONSTANT(
  2161. int,
  2162. value = implementation_level::type::value
  2163. );
  2164. };
  2165. #else
  2166. // We serialize flex_strings as vectors of char's for now
  2167. template<class Archive, typename E, class T, class A, class S>
  2168. inline void save(Archive & ar,
  2169. boost::wave::util::flex_string<E, T, A, S> const &t,
  2170. const unsigned int file_version)
  2171. {
  2172. boost::serialization::stl::save_collection<
  2173. Archive, wave::util::flex_string<E, T, A, S> >(ar, t);
  2174. }
  2175. template<class Archive, typename E, class T, class A, class S>
  2176. inline void load(Archive & ar, boost::wave::util::flex_string<E, T, A, S> &t,
  2177. const unsigned int file_version)
  2178. {
  2179. boost::serialization::stl::load_collection<
  2180. Archive, boost::wave::util::flex_string<E, T, A, S>,
  2181. boost::serialization::stl::archive_input_seq<
  2182. Archive, boost::wave::util::flex_string<E, T, A, S> >,
  2183. boost::serialization::stl::reserve_imp<
  2184. boost::wave::util::flex_string<E, T, A, S> >
  2185. >(ar, t);
  2186. }
  2187. // split non-intrusive serialization function member into separate
  2188. // non intrusive save/load member functions
  2189. template<class Archive, typename E, class T, class A, class S>
  2190. inline void serialize(Archive & ar, boost::wave::util::flex_string<E, T, A, S> &t,
  2191. const unsigned int file_version)
  2192. {
  2193. boost::serialization::split_free(ar, t, file_version);
  2194. }
  2195. #endif
  2196. ///////////////////////////////////////////////////////////////////////////////
  2197. }} // boost::serialization
  2198. #endif
  2199. // the suffix header occurs after all of the code
  2200. #ifdef BOOST_HAS_ABI_HEADERS
  2201. #include BOOST_ABI_SUFFIX
  2202. #endif
  2203. #endif // BOOST_FLEX_STRING_INC_