flex_string_shell.h 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443
  1. ////////////////////////////////////////////////////////////////////////////////
  2. // flex_string
  3. // Copyright (c) 2001 by Andrei Alexandrescu
  4. // Permission to use, copy, modify, distribute and sell this software for any
  5. // purpose is hereby granted without fee, provided that the above copyright
  6. // notice appear in all copies and that both that copyright notice and this
  7. // permission notice appear in supporting documentation.
  8. // The author makes no representations about the
  9. // suitability of this software for any purpose. It is provided "as is"
  10. // without express or implied warranty.
  11. ////////////////////////////////////////////////////////////////////////////////
  12. #ifndef DAHUA_FLEX_STRING_SHELL_INC_
  13. #define DAHUA_FLEX_STRING_SHELL_INC_
  14. // revision 1111
  15. ///////////////////////////////////////////////////////////////////////////////
  16. // class template flex_string
  17. // This file does not include any storage policy headers
  18. ///////////////////////////////////////////////////////////////////////////////
  19. #include <memory>
  20. #include <algorithm>
  21. #include <functional>
  22. #include <cassert>
  23. #include <limits>
  24. #include <stdexcept>
  25. #include "flex_string_details.h"
  26. #include <string>
  27. #include <iostream>
  28. ////////////////////////////////////////////////////////////////////////////////
  29. namespace Dahua {
  30. namespace Infra {
  31. // Forward declaration for default storage policy
  32. template <typename E, class A> class AllocatorStringStorage;
  33. template <class T> class mallocator
  34. {
  35. public:
  36. typedef T value_type;
  37. typedef value_type* pointer;
  38. typedef const value_type* const_pointer;
  39. typedef value_type& reference;
  40. typedef const value_type& const_reference;
  41. typedef size_t size_type;
  42. //typedef unsigned int size_type;
  43. //typedef std::ptrdiff_t difference_type;
  44. typedef int difference_type;
  45. template <class U>
  46. struct rebind { typedef mallocator<U> other; };
  47. mallocator() {}
  48. mallocator(const mallocator&) {}
  49. //template <class U>
  50. //mallocator(const mallocator<U>&) {}
  51. ~mallocator() {}
  52. pointer address(reference x) const { return &x; }
  53. const_pointer address(const_reference x) const
  54. {
  55. return x;
  56. }
  57. pointer allocate(size_type n, const_pointer = 0)
  58. {
  59. using namespace std;
  60. void* p = malloc(n * sizeof(T));
  61. if (!p) throw bad_alloc();
  62. return static_cast<pointer>(p);
  63. }
  64. void deallocate(pointer p, size_type)
  65. {
  66. using namespace std;
  67. free(p);
  68. }
  69. size_type max_size() const
  70. {
  71. return static_cast<size_type>(-1) / sizeof(T);
  72. }
  73. void construct(pointer p, const value_type& x)
  74. {
  75. new(p) value_type(x);
  76. }
  77. void destroy(pointer p)
  78. {
  79. p->~value_type();
  80. }
  81. private:
  82. void operator=(const mallocator&);
  83. };
  84. template<> class mallocator<void>
  85. {
  86. typedef void value_type;
  87. typedef void* pointer;
  88. typedef const void* const_pointer;
  89. template <class U>
  90. struct rebind { typedef mallocator<U> other; };
  91. };
  92. template <class T>
  93. inline bool operator==(const mallocator<T>&,
  94. const mallocator<T>&) {
  95. return true;
  96. }
  97. template <class T>
  98. inline bool operator!=(const mallocator<T>&,
  99. const mallocator<T>&) {
  100. return false;
  101. }
  102. template <class Allocator>
  103. typename Allocator::pointer Reallocate(
  104. Allocator& alloc,
  105. typename Allocator::pointer p,
  106. typename Allocator::size_type oldObjCount,
  107. typename Allocator::size_type newObjCount,
  108. void*)
  109. {
  110. // @@@ not implemented
  111. }
  112. template <class Allocator>
  113. typename Allocator::pointer Reallocate(
  114. Allocator& alloc,
  115. typename Allocator::pointer p,
  116. typename Allocator::size_type oldObjCount,
  117. typename Allocator::size_type newObjCount,
  118. mallocator<void>*)
  119. {
  120. // @@@ not implemented
  121. }
  122. ////////////////////////////////////////////////////////////////////////////////
  123. // class template flex_string
  124. // a std::basic_string compatible implementation
  125. // Uses a Storage policy
  126. ////////////////////////////////////////////////////////////////////////////////
  127. template <typename E,
  128. class T = std::char_traits<E>,
  129. class A = std::allocator<E>,
  130. class Storage = AllocatorStringStorage<E, A> >
  131. class flex_string : private Storage
  132. {
  133. template <typename Exception>
  134. static void Enforce(bool condition, Exception*, const char* msg)
  135. { if (!condition) throw Exception(msg); }
  136. bool Sane() const
  137. {
  138. return
  139. begin() <= end() &&
  140. empty() == (size() == 0) &&
  141. empty() == (begin() == end()) &&
  142. size() <= max_size() &&
  143. capacity() <= max_size() &&
  144. size() <= capacity();
  145. }
  146. struct Invariant;
  147. friend struct Invariant;
  148. struct Invariant
  149. {
  150. #ifdef DAHUA_DEBUG_FLEX_STRING
  151. Invariant(const flex_string& s) : s_(s)
  152. {
  153. assert(s_.Sane());
  154. }
  155. ~Invariant()
  156. {
  157. assert(s_.Sane());
  158. }
  159. private:
  160. const flex_string& s_;
  161. #else
  162. Invariant(const flex_string&) {}
  163. #endif
  164. private:
  165. Invariant& operator=(const Invariant&);
  166. };
  167. public:
  168. // types
  169. typedef T traits_type;
  170. typedef typename traits_type::char_type value_type;
  171. typedef A allocator_type;
  172. typedef typename A::size_type size_type;
  173. typedef typename A::difference_type difference_type;
  174. typedef typename Storage::reference reference;
  175. typedef typename A::const_reference const_reference;
  176. typedef typename A::pointer pointer;
  177. typedef typename A::const_pointer const_pointer;
  178. typedef typename Storage::iterator iterator;
  179. typedef typename Storage::const_iterator const_iterator;
  180. typedef std::reverse_iterator<iterator
  181. #ifdef NO_ITERATOR_TRAITS
  182. , value_type
  183. #endif
  184. > reverse_iterator;
  185. typedef std::reverse_iterator<const_iterator
  186. #ifdef NO_ITERATOR_TRAITS
  187. , const value_type
  188. #endif
  189. > const_reverse_iterator;
  190. static const size_type npos; // = size_type(-1)
  191. private:
  192. static size_type Min(size_type lhs, size_type rhs)
  193. { return lhs < rhs ? lhs : rhs; }
  194. static size_type Max(size_type lhs, size_type rhs)
  195. { return lhs > rhs ? lhs : rhs; }
  196. static void Procust(size_type& n, size_type nmax)
  197. { if (n > nmax) n = nmax; }
  198. public:
  199. // 21.3.1 construct/copy/destroy
  200. explicit flex_string(const A& a = A())
  201. : Storage(a)
  202. {}
  203. flex_string(const flex_string& str)
  204. : Storage(str)
  205. {}
  206. flex_string(const flex_string& str, size_type pos,
  207. size_type n = npos, const A& a = A())
  208. : Storage(a)
  209. {
  210. assign(str, pos, n);
  211. }
  212. flex_string(const value_type* s, const A& a = A())
  213. : Storage(s, traits_type::length(s), a)
  214. {}
  215. flex_string(const value_type* s, size_type n, const A& a = A())
  216. : Storage(s, n, a)
  217. {}
  218. flex_string(size_type n, value_type c, const A& a = A())
  219. : Storage(n, c, a)
  220. {}
  221. template <class InputIterator>
  222. flex_string(InputIterator begin, InputIterator end, const A& a = A())
  223. : Storage(a)
  224. {
  225. assign(begin, end);
  226. }
  227. ~flex_string()
  228. {}
  229. flex_string& operator=(const flex_string& str)
  230. {
  231. Storage& s = *this;
  232. s = str;
  233. return *this;
  234. }
  235. flex_string& operator=(const value_type* s)
  236. {
  237. assign(s);
  238. return *this;
  239. }
  240. flex_string& operator=(value_type c)
  241. {
  242. assign(1, c);
  243. return *this;
  244. }
  245. // 21.3.2 iterators:
  246. iterator begin()
  247. { return Storage::begin(); }
  248. const_iterator begin() const
  249. { return Storage::begin(); }
  250. iterator end()
  251. { return Storage::end(); }
  252. const_iterator end() const
  253. { return Storage::end(); }
  254. reverse_iterator rbegin()
  255. { return reverse_iterator(end()); }
  256. const_reverse_iterator rbegin() const
  257. { return const_reverse_iterator(end()); }
  258. reverse_iterator rend()
  259. { return reverse_iterator(begin()); }
  260. const_reverse_iterator rend() const
  261. { return const_reverse_iterator(begin()); }
  262. // 21.3.3 capacity:
  263. size_type size() const
  264. { return Storage::size(); }
  265. size_type length() const
  266. { return size(); }
  267. size_type max_size() const
  268. { return Storage::max_size(); }
  269. void resize(size_type n, value_type c)
  270. { Storage::resize(n, c); }
  271. void resize(size_type n)
  272. { resize(n, value_type()); }
  273. size_type capacity() const
  274. { return Storage::capacity(); }
  275. void reserve(size_type res_arg = 0)
  276. {
  277. Enforce(res_arg <= max_size(), static_cast<std::length_error*>(0), "");
  278. Storage::reserve(res_arg);
  279. }
  280. void clear()
  281. { resize(0); }
  282. bool empty() const
  283. { return size() == 0; }
  284. // 21.3.4 element access:
  285. const_reference operator[](size_type pos) const
  286. { return *(c_str() + pos); }
  287. reference operator[](size_type pos)
  288. { return *(begin() + pos); }
  289. const_reference at(size_type n) const
  290. {
  291. Enforce(n <= size(), static_cast<std::out_of_range*>(0), "");
  292. return (*this)[n];
  293. }
  294. reference at(size_type n)
  295. {
  296. Enforce(n < size(), static_cast<std::out_of_range*>(0), "");
  297. return (*this)[n];
  298. }
  299. // 21.3.5 modifiers:
  300. flex_string& operator+=(const flex_string& str)
  301. { return append(str); }
  302. flex_string& operator+=(const value_type* s)
  303. { return append(s); }
  304. flex_string& operator+=(const value_type c)
  305. {
  306. push_back(c);
  307. return *this;
  308. }
  309. flex_string& append(const flex_string& str)
  310. { return append(str.data(), str.length()); }
  311. flex_string& append(const flex_string& str, const size_type pos,
  312. size_type n)
  313. {
  314. const size_type sz = str.size();
  315. Enforce(pos <= sz, static_cast<std::out_of_range*>(0), "");
  316. Procust(n, sz - pos);
  317. return append(str.data() + pos, n);
  318. }
  319. flex_string& append(const value_type* s, const size_type n)
  320. {
  321. Invariant checker(*this);
  322. (void) checker;
  323. if (IsAliasedRange(s, s + n))
  324. {
  325. const size_type offset = s - &*begin();
  326. Storage::reserve(size() + n);
  327. s = &*begin() + offset;
  328. }
  329. Storage::append(s, s + n);
  330. return *this;
  331. }
  332. flex_string& append(const value_type* s)
  333. { return append(s, traits_type::length(s)); }
  334. flex_string& append(size_type n, value_type c)
  335. {
  336. resize(size() + n, c);
  337. return *this;
  338. }
  339. template<class InputIterator>
  340. flex_string& append(InputIterator first, InputIterator last)
  341. {
  342. insert(end(), first, last);
  343. return *this;
  344. }
  345. void push_back(const value_type c) // primitive
  346. {
  347. const size_type cap = capacity();
  348. if (size() == cap)
  349. {
  350. reserve(cap << 1u);
  351. }
  352. Storage::append(&c, &c + 1);
  353. }
  354. flex_string& assign(const flex_string& str)
  355. {
  356. if (&str == this) return *this;
  357. return assign(str.data(), str.size());
  358. }
  359. flex_string& assign(const flex_string& str, const size_type pos,
  360. size_type n)
  361. {
  362. const size_type sz = str.size();
  363. Enforce(pos <= sz, static_cast<std::out_of_range*>(0), "");
  364. Procust(n, sz - pos);
  365. return assign(str.data() + pos, str.data() + pos + n);
  366. }
  367. flex_string& assign(const value_type* s, const size_type n)
  368. {
  369. Invariant checker(*this);
  370. (void) checker;
  371. if (size() >= n)
  372. {
  373. std::copy(s, s + n, begin());
  374. resize(n);
  375. }
  376. else
  377. {
  378. const value_type *const s2 = s + size();
  379. std::copy(s, s2, begin());
  380. append(s2, n - size());
  381. }
  382. return *this;
  383. }
  384. flex_string& assign(const value_type* s)
  385. {
  386. #ifdef WIN_VC6
  387. ///< VC6对模板支持不好,导致这里编译不过,
  388. ///< flex_string& assign(const value_type* s, const size_type n)将这里的代码拷贝进来
  389. const size_type n = traits_type::length(s);
  390. Invariant checker(*this);
  391. (void) checker;
  392. if (size() >= n)
  393. {
  394. std::copy(s, s + n, begin());
  395. resize(n);
  396. }
  397. else
  398. {
  399. const value_type *const s2 = s + size();
  400. std::copy(s, s2, begin());
  401. append(s2, n - size());
  402. }
  403. return *this;
  404. #else
  405. return assign(s, traits_type::length(s));
  406. #endif
  407. }
  408. template <class ItOrLength, class ItOrChar>
  409. flex_string& assign(ItOrLength first_or_n, ItOrChar last_or_c)
  410. { return replace(begin(), end(), first_or_n, last_or_c); }
  411. flex_string& insert(size_type pos1, const flex_string& str)
  412. { return insert(pos1, str.data(), str.size()); }
  413. flex_string& insert(size_type pos1, const flex_string& str,
  414. size_type pos2, size_type n)
  415. {
  416. Enforce(pos2 <= str.length(), static_cast<std::out_of_range*>(0), "");
  417. Procust(n, str.length() - pos2);
  418. return insert(pos1, str.data() + pos2, n);
  419. }
  420. flex_string& insert(size_type pos, const value_type* s, size_type n)
  421. {
  422. Enforce(pos <= length(), static_cast<std::out_of_range*>(0), "");
  423. insert(begin() + pos, s, s + n);
  424. return *this;
  425. }
  426. flex_string& insert(size_type pos, const value_type* s)
  427. { return insert(pos, s, traits_type::length(s)); }
  428. flex_string& insert(size_type pos, size_type n, value_type c)
  429. {
  430. Enforce(pos <= length(), static_cast<std::out_of_range*>(0), "");
  431. insert(begin() + pos, n, c);
  432. return *this;
  433. }
  434. iterator insert(const iterator p, const value_type c)
  435. {
  436. const size_type pos = p - begin();
  437. insert(p, 1, c);
  438. return begin() + pos;
  439. }
  440. private:
  441. // Care must be taken when dereferencing some iterator types.
  442. //
  443. // Users can implement this function in their namespace if their storage uses a special iterator type,
  444. // the function will be found through ADL.
  445. template<class Iterator>
  446. const typename std::iterator_traits<Iterator>::value_type * DereferenceValidIterator(Iterator it) const
  447. {
  448. return &*it;
  449. }
  450. // Care must be taken when dereferencing a reverse iterators, hence this special case.
  451. // This isn't in the std namespace so as not to pollute it or create name clashes.
  452. template<typename Iterator>
  453. const typename std::iterator_traits<Iterator>::value_type * DereferenceValidIterator(
  454. std::reverse_iterator<Iterator
  455. #ifdef NO_ITERATOR_TRAITS
  456. , typename std::iterator_traits<Iterator>::value_type
  457. #endif
  458. > it) const
  459. {
  460. return &*--it;
  461. }
  462. // Determine if the range aliases the current string.
  463. //
  464. // This method cannot be const because calling begin/end on copy-on-write implementations must have side effects.
  465. // A const version wouldn't make the string unique through this call.
  466. template<class Iterator>
  467. bool IsAliasedRange(Iterator beginIterator, Iterator endIterator)
  468. {
  469. if(!empty() && beginIterator != endIterator)
  470. {
  471. typedef const typename std::iterator_traits<Iterator>::value_type * pointer;
  472. pointer myBegin(&*begin());
  473. pointer myEnd(&*begin() + size());
  474. pointer rangeBegin(DereferenceValidIterator(beginIterator));
  475. const std::less_equal<pointer> less_equal = std::less_equal<pointer>();
  476. if(less_equal(myBegin, rangeBegin) && less_equal(rangeBegin, myEnd))
  477. return true;
  478. }
  479. return false;
  480. }
  481. template <int i> class Selector {};
  482. flex_string& InsertImplDiscr(iterator p,
  483. size_type n, value_type c, Selector<1>)
  484. {
  485. Invariant checker(*this);
  486. (void) checker;
  487. assert(begin() <= p && p <= end());
  488. const size_type insertOffset(p - begin());
  489. const size_type originalSize(size());
  490. if(n < originalSize - insertOffset)
  491. {
  492. // The new characters fit within the original string.
  493. // The characters that are pushed back need to be moved because they're aliased.
  494. // The appended characters will all be overwritten by the move.
  495. append(n, value_type(0));
  496. value_type * start = (&*begin());
  497. flex_string_details::pod_move(start + insertOffset, start + originalSize, start + insertOffset + n);
  498. std::fill(start + insertOffset, start + insertOffset + n, c);
  499. }
  500. else
  501. {
  502. // The new characters exceed the original string.
  503. // The characters that are pushed back can simply be copied since they aren't aliased.
  504. // The appended characters will partly be overwritten by the copy.
  505. append(n, c);
  506. value_type * start = (&*begin());
  507. flex_string_details::pod_copy(start + insertOffset, start + originalSize, start + insertOffset + n);
  508. std::fill(start + insertOffset, start + originalSize, c);
  509. }
  510. return *this;
  511. }
  512. template<class InputIterator>
  513. flex_string& InsertImplDiscr(iterator i,
  514. InputIterator b, InputIterator e, Selector<0>)
  515. {
  516. typedef typename std::iterator_traits<InputIterator>::iterator_category iterator_category; // 规避VC6编译错误
  517. InsertImpl(i, b, e, iterator_category());
  518. return *this;
  519. }
  520. template <class FwdIterator>
  521. void InsertImpl(iterator i,
  522. FwdIterator s1, FwdIterator s2, std::forward_iterator_tag)
  523. {
  524. if(s1 == s2)
  525. {
  526. // Insert an empty range.
  527. return;
  528. }
  529. if(IsAliasedRange(s1, s2))
  530. {
  531. // The source range is contained in the current string, copy it and recurse.
  532. const flex_string temporary(s1, s2);
  533. typedef typename std::iterator_traits<FwdIterator>::iterator_category iterator_category; // 规避VC6编译错误
  534. InsertImpl(i, temporary.begin(), temporary.end(), iterator_category());
  535. return;
  536. }
  537. Invariant checker(*this);
  538. (void) checker;
  539. const size_type pos = i - begin();
  540. #if defined(_MSC_VER) && (_MSC_VER < 1300)
  541. typedef typename std::iterator_traits<FwdIterator>::distance_type diff_t;
  542. #else
  543. typedef typename std::iterator_traits<FwdIterator>::difference_type diff_t;
  544. #endif
  545. const diff_t n2 = std::distance(s1, s2);
  546. assert(n2 >= 0);
  547. using namespace flex_string_details;
  548. assert(pos <= size());
  549. const diff_t maxn2 = capacity() - size();
  550. if (maxn2 < n2)
  551. {
  552. // Reallocate the string.
  553. assert(!IsAliasedRange(s1, s2));
  554. reserve(size() + n2);
  555. i = begin() + pos;
  556. }
  557. if (pos + n2 <= size())
  558. {
  559. //const iterator oldEnd = end();
  560. //Storage::append(oldEnd - n2, n2);
  561. //std::copy(i, oldEnd - n2, i + n2);
  562. const iterator tailBegin = end() - n2;
  563. Storage::append(tailBegin, tailBegin + n2);
  564. //std::copy(i, tailBegin, i + n2);
  565. std::copy(reverse_iterator(tailBegin), reverse_iterator(i),
  566. reverse_iterator(tailBegin + n2));
  567. std::copy(s1, s2, i);
  568. }
  569. else
  570. {
  571. FwdIterator t = s1;
  572. const size_type old_size = size();
  573. std::advance(t, old_size - pos);
  574. assert(std::distance(t, s2) >= 0);
  575. Storage::append(t, s2);
  576. Storage::append(data() + pos, data() + old_size);
  577. std::copy(s1, t, i);
  578. }
  579. }
  580. template <class InputIterator>
  581. void InsertImpl(iterator insertPosition,
  582. InputIterator inputBegin, InputIterator inputEnd, std::input_iterator_tag)
  583. {
  584. flex_string temporary(begin(), insertPosition);
  585. for (; inputBegin != inputEnd; ++inputBegin)
  586. {
  587. temporary.push_back(*inputBegin);
  588. }
  589. temporary.append(insertPosition, end());
  590. swap(temporary);
  591. }
  592. public:
  593. template <class ItOrLength, class ItOrChar>
  594. void insert(iterator p, ItOrLength first_or_n, ItOrChar last_or_c)
  595. {
  596. Selector<std::numeric_limits<ItOrLength>::is_specialized> sel;
  597. InsertImplDiscr(p, first_or_n, last_or_c, sel);
  598. }
  599. flex_string& erase(size_type pos = 0, size_type n = npos)
  600. {
  601. Invariant checker(*this);
  602. (void) checker;
  603. Enforce(pos <= length(), static_cast<std::out_of_range*>(0), "");
  604. Procust(n, length() - pos);
  605. std::copy(begin() + pos + n, end(), begin() + pos);
  606. resize(length() - n);
  607. return *this;
  608. }
  609. iterator erase(iterator position)
  610. {
  611. const size_type pos(position - begin());
  612. erase(pos, 1);
  613. return begin() + pos;
  614. }
  615. iterator erase(iterator first, iterator last)
  616. {
  617. const size_type pos(first - begin());
  618. erase(pos, last - first);
  619. return begin() + pos;
  620. }
  621. // Replaces at most n1 chars of *this, starting with pos1 with the content of str
  622. flex_string& replace(size_type pos1, size_type n1, const flex_string& str)
  623. { return replace(pos1, n1, str.data(), str.size()); }
  624. // Replaces at most n1 chars of *this, starting with pos1,
  625. // with at most n2 chars of str starting with pos2
  626. flex_string& replace(size_type pos1, size_type n1, const flex_string& str,
  627. size_type pos2, size_type n2)
  628. {
  629. Enforce(pos2 <= str.length(), static_cast<std::out_of_range*>(0), "");
  630. return replace(pos1, n1, str.data() + pos2,
  631. Min(n2, str.size() - pos2));
  632. }
  633. /*
  634. // Replaces at most n1 chars of *this, starting with pos,
  635. // with at most n2 chars of str.
  636. // str must have at least n2 chars.
  637. flex_string& replace(const size_type pos, size_type n1,
  638. const value_type* s1, const size_type n2)
  639. {
  640. Invariant checker(*this);
  641. (void) checker;
  642. Enforce(pos <= size(), (std::out_of_range*)0, "");
  643. Procust(n1, size() - pos);
  644. const iterator b = begin() + pos;
  645. return replace(b, b + n1, s1, s1 + n2);
  646. using namespace flex_string_details;
  647. const int delta = int(n2 - n1);
  648. const bool aliased = IsAliasedRange(s1, s1 + n2);
  649. // From here on we're dealing with an aliased replace
  650. if (delta <= 0)
  651. {
  652. // simple case, we're shrinking
  653. pod_move(s1, s1 + n2, &*begin() + pos);
  654. pod_move(&*begin() + pos + n1, &*end(), &*begin() + pos + n1 + delta);
  655. resize(size() + delta);
  656. return *this;
  657. }
  658. // From here on we deal with aliased growth
  659. if (capacity() < size() + delta)
  660. {
  661. // realloc the string
  662. const size_type offset = s1 - data();
  663. reserve(size() + delta);
  664. s1 = data() + offset;
  665. }
  666. const value_type* s2 = s1 + n2;
  667. value_type* d1 = &*begin() + pos;
  668. value_type* d2 = d1 + n1;
  669. const int tailLen = int(&*end() - d2);
  670. if (delta <= tailLen)
  671. {
  672. value_type* oldEnd = &*end();
  673. // simple case
  674. Storage::append(oldEnd - delta, delta);
  675. pod_move(d2, d2 + (tailLen - delta), d2 + delta);
  676. if (le(d2, s1))
  677. {
  678. pod_copy(s1 + delta, s2 + delta, d1);
  679. }
  680. else
  681. {
  682. // d2 > s1
  683. if (le(d2, s2))
  684. {
  685. pod_move(s1, d2, d1);
  686. pod_move(d2 + delta, s2 + delta, d1 + (d2 - s1));
  687. }
  688. else
  689. {
  690. pod_move(s1, s2, d1);
  691. }
  692. }
  693. }
  694. else
  695. {
  696. const size_type sz = delta - tailLen;
  697. Storage::append(s2 - sz, sz);
  698. Storage::append(d2, tailLen);
  699. pod_move(s1, s2 - (delta - tailLen), d1);
  700. }
  701. return *this;
  702. }
  703. */
  704. // Replaces at most n1 chars of *this, starting with pos, with chars from s
  705. flex_string& replace(size_type pos, size_type n1, const value_type* s)
  706. { return replace(pos, n1, s, traits_type::length(s)); }
  707. // Replaces at most n1 chars of *this, starting with pos, with n2 occurences of c
  708. // consolidated with
  709. // Replaces at most n1 chars of *this, starting with pos,
  710. // with at most n2 chars of str.
  711. // str must have at least n2 chars.
  712. template <class StrOrLength, class NumOrChar>
  713. flex_string& replace(size_type pos, size_type n1,
  714. StrOrLength s_or_n2, NumOrChar n_or_c)
  715. {
  716. Invariant checker(*this);
  717. (void) checker;
  718. Enforce(pos <= size(), static_cast<std::out_of_range*>(0), "");
  719. Procust(n1, length() - pos);
  720. const iterator b = begin() + pos;
  721. return replace(b, b + n1, s_or_n2, n_or_c);
  722. }
  723. flex_string& replace(iterator i1, iterator i2, const flex_string& str)
  724. { return replace(i1, i2, str.data(), str.length()); }
  725. flex_string& replace(iterator i1, iterator i2, const value_type* s)
  726. { return replace(i1, i2, s, traits_type::length(s)); }
  727. private:
  728. flex_string& ReplaceImplDiscr(iterator i1, iterator i2,
  729. const value_type* s, size_type n, Selector<2>)
  730. {
  731. assert(i1 <= i2);
  732. assert(begin() <= i1 && i1 <= end());
  733. assert(begin() <= i2 && i2 <= end());
  734. return replace(i1, i2, s, s + n);
  735. }
  736. flex_string& ReplaceImplDiscr(iterator i1, iterator i2,
  737. size_type n2, value_type c, Selector<1>)
  738. {
  739. const size_type n1 = i2 - i1;
  740. if (n1 > n2)
  741. {
  742. std::fill(i1, i1 + n2, c);
  743. erase(i1 + n2, i2);
  744. }
  745. else
  746. {
  747. std::fill(i1, i2, c);
  748. insert(i2, n2 - n1, c);
  749. }
  750. return *this;
  751. }
  752. template <class InputIterator>
  753. flex_string& ReplaceImplDiscr(iterator i1, iterator i2,
  754. InputIterator b, InputIterator e, Selector<0>)
  755. {
  756. typedef typename std::iterator_traits<InputIterator>::iterator_category iterator_category; // 规避VC6编译错误
  757. ReplaceImpl(i1, i2, b, e, iterator_category());
  758. return *this;
  759. }
  760. template <class FwdIterator>
  761. void ReplaceImpl(iterator i1, iterator i2,
  762. FwdIterator s1, FwdIterator s2, std::forward_iterator_tag)
  763. {
  764. Invariant checker(*this);
  765. (void) checker;
  766. #if defined(_MSC_VER) && (_MSC_VER < 1300)
  767. typedef typename std::iterator_traits<iterator>::distance_type diff_t;
  768. #else
  769. typedef typename std::iterator_traits<iterator>::difference_type diff_t;
  770. #endif
  771. const diff_t n1 = i2 - i1;
  772. assert(n1 >= 0);
  773. #if defined(_MSC_VER) && (_MSC_VER < 1300)
  774. typedef typename std::iterator_traits<FwdIterator>::distance_type fwd_diff_t;
  775. #else
  776. typedef typename std::iterator_traits<FwdIterator>::difference_type fwd_diff_t;
  777. #endif
  778. const fwd_diff_t n2 = std::distance(s1, s2);
  779. assert(n2 >= 0);
  780. if (IsAliasedRange(s1, s2))
  781. {
  782. // Aliased replace, copy to new string.
  783. flex_string temporary;
  784. temporary.reserve(size() - n1 + n2);
  785. temporary.append(begin(), i1).append(s1, s2).append(i2, end());
  786. swap(temporary);
  787. return;
  788. }
  789. if (n1 > n2)
  790. {
  791. // Shrinks.
  792. std::copy(s1, s2, i1);
  793. erase(i1 + n2, i2);
  794. }
  795. else
  796. {
  797. // Grows.
  798. flex_string_details::copy_n(s1, n1, i1);
  799. std::advance(s1, n1);
  800. insert(i2, s1, s2);
  801. }
  802. }
  803. template <class InputIterator>
  804. void ReplaceImpl(iterator i1, iterator i2,
  805. InputIterator b, InputIterator e, std::input_iterator_tag)
  806. {
  807. flex_string temp(begin(), i1);
  808. temp.append(b, e).append(i2, end());
  809. swap(temp);
  810. }
  811. public:
  812. template <class T1, class T2>
  813. flex_string& replace(iterator i1, iterator i2,
  814. T1 first_or_n_or_s, T2 last_or_c_or_n)
  815. {
  816. const bool
  817. num1 = std::numeric_limits<T1>::is_specialized,
  818. num2 = std::numeric_limits<T2>::is_specialized;
  819. return ReplaceImplDiscr(i1, i2, first_or_n_or_s, last_or_c_or_n,
  820. Selector<num1 ? (num2 ? 1 : -1) : (num2 ? 2 : 0)>());
  821. }
  822. size_type copy(value_type* s, size_type n, size_type pos = 0) const
  823. {
  824. Enforce(pos <= size(), static_cast<std::out_of_range*>(0), "");
  825. Procust(n, size() - pos);
  826. flex_string_details::pod_copy(
  827. data() + pos,
  828. data() + pos + n,
  829. s);
  830. return n;
  831. }
  832. void swap(flex_string& rhs)
  833. {
  834. Storage& srhs = rhs;
  835. this->Storage::swap(srhs);
  836. }
  837. // 21.3.6 string operations:
  838. const value_type* c_str() const
  839. { return Storage::c_str(); }
  840. const value_type* data() const
  841. { return Storage::data(); }
  842. allocator_type get_allocator() const
  843. { return Storage::get_allocator(); }
  844. size_type find(const flex_string& str, size_type pos = 0) const
  845. { return find(str.data(), pos, str.length()); }
  846. size_type find (const value_type* s, size_type pos, size_type n) const
  847. {
  848. const size_type count(size());
  849. if (n + pos > count)
  850. return npos;
  851. for (; pos + n <= count; ++pos)
  852. {
  853. if (traits_type::compare(data() + pos, s, n) == 0)
  854. {
  855. return pos;
  856. }
  857. }
  858. return npos;
  859. }
  860. size_type find (const value_type* s, size_type pos = 0) const
  861. { return find(s, pos, traits_type::length(s)); }
  862. size_type find (value_type c, size_type pos = 0) const
  863. { return find(&c, pos, 1); }
  864. size_type rfind(const flex_string& str, size_type pos = npos) const
  865. { return rfind(str.data(), pos, str.length()); }
  866. size_type rfind(const value_type* s, size_type pos, size_type n) const
  867. {
  868. if (n > length()) return npos;
  869. pos = Min(pos, length() - n);
  870. if (n == 0) return pos;
  871. const_iterator i(begin() + pos);
  872. for (; ; --i)
  873. {
  874. if (traits_type::eq(*i, *s)
  875. && traits_type::compare(&*i, s, n) == 0)
  876. {
  877. return i - begin();
  878. }
  879. if (i == begin()) break;
  880. }
  881. return npos;
  882. }
  883. size_type rfind(const value_type* s, size_type pos = npos) const
  884. { return rfind(s, pos, traits_type::length(s)); }
  885. size_type rfind(value_type c, size_type pos = npos) const
  886. { return rfind(&c, pos, 1); }
  887. size_type find_first_of(const flex_string& str, size_type pos = 0) const
  888. { return find_first_of(str.data(), pos, str.length()); }
  889. size_type find_first_of(const value_type* s,
  890. size_type pos, size_type n) const
  891. {
  892. if (pos > length() || n == 0) return npos;
  893. const_iterator i(begin() + pos),
  894. finish(end());
  895. for (; i != finish; ++i)
  896. {
  897. if (traits_type::find(s, n, *i) != 0)
  898. {
  899. return i - begin();
  900. }
  901. }
  902. return npos;
  903. }
  904. size_type find_first_of(const value_type* s, size_type pos = 0) const
  905. { return find_first_of(s, pos, traits_type::length(s)); }
  906. size_type find_first_of(value_type c, size_type pos = 0) const
  907. { return find_first_of(&c, pos, 1); }
  908. size_type find_last_of (const flex_string& str,
  909. size_type pos = npos) const
  910. { return find_last_of(str.data(), pos, str.length()); }
  911. size_type find_last_of (const value_type* s, size_type pos,
  912. size_type n) const
  913. {
  914. if (!empty() && n > 0)
  915. {
  916. pos = Min(pos, length() - 1);
  917. const_iterator i(begin() + pos);
  918. for (;; --i)
  919. {
  920. if (traits_type::find(s, n, *i) != 0)
  921. {
  922. return i - begin();
  923. }
  924. if (i == begin()) break;
  925. }
  926. }
  927. return npos;
  928. }
  929. size_type find_last_of (const value_type* s,
  930. size_type pos = npos) const
  931. { return find_last_of(s, pos, traits_type::length(s)); }
  932. size_type find_last_of (value_type c, size_type pos = npos) const
  933. { return find_last_of(&c, pos, 1); }
  934. size_type find_first_not_of(const flex_string& str,
  935. size_type pos = 0) const
  936. { return find_first_not_of(str.data(), pos, str.size()); }
  937. size_type find_first_not_of(const value_type* s, size_type pos,
  938. size_type n) const
  939. {
  940. if (pos < length())
  941. {
  942. const_iterator
  943. i(begin() + pos),
  944. finish(end());
  945. for (; i != finish; ++i)
  946. {
  947. if (traits_type::find(s, n, *i) == 0)
  948. {
  949. return i - begin();
  950. }
  951. }
  952. }
  953. return npos;
  954. }
  955. size_type find_first_not_of(const value_type* s,
  956. size_type pos = 0) const
  957. { return find_first_not_of(s, pos, traits_type::length(s)); }
  958. size_type find_first_not_of(value_type c, size_type pos = 0) const
  959. { return find_first_not_of(&c, pos, 1); }
  960. size_type find_last_not_of(const flex_string& str,
  961. size_type pos = npos) const
  962. { return find_last_not_of(str.data(), pos, str.length()); }
  963. size_type find_last_not_of(const value_type* s, size_type pos,
  964. size_type n) const
  965. {
  966. if (!this->empty())
  967. {
  968. pos = Min(pos, size() - 1);
  969. const_iterator i(begin() + pos);
  970. for (;; --i)
  971. {
  972. if (traits_type::find(s, n, *i) == 0)
  973. {
  974. return i - begin();
  975. }
  976. if (i == begin()) break;
  977. }
  978. }
  979. return npos;
  980. }
  981. size_type find_last_not_of(const value_type* s,
  982. size_type pos = npos) const
  983. { return find_last_not_of(s, pos, traits_type::length(s)); }
  984. size_type find_last_not_of (value_type c, size_type pos = npos) const
  985. { return find_last_not_of(&c, pos, 1); }
  986. flex_string substr(size_type pos = 0, size_type n = npos) const
  987. {
  988. Enforce(pos <= size(), static_cast<std::out_of_range*>(0), "");
  989. return flex_string(data() + pos, Min(n, size() - pos));
  990. }
  991. int compare(const flex_string& str) const
  992. {
  993. // FIX due to Goncalo N M de Carvalho July 18, 2005
  994. return compare(0, size(), str);
  995. }
  996. int compare(size_type pos1, size_type n1,
  997. const flex_string& str) const
  998. { return compare(pos1, n1, str.data(), str.size()); }
  999. // FIX to compare: added the TC
  1000. // (http://www.comeaucomputing.com/iso/lwg-defects.html number 5)
  1001. // Thanks to Caleb Epstein for the fix
  1002. int compare(size_type pos1, size_type n1,
  1003. const value_type* s) const
  1004. {
  1005. return compare(pos1, n1, s, traits_type::length(s));
  1006. }
  1007. int compare(size_type pos1, size_type n1,
  1008. const value_type* s, size_type n2) const
  1009. {
  1010. Enforce(pos1 <= size(), static_cast<std::out_of_range*>(0), "");
  1011. Procust(n1, size() - pos1);
  1012. // The line below fixed by Jean-Francois Bastien, 04-23-2007. Thanks!
  1013. const int r = traits_type::compare(pos1 + data(), s, Min(n1, n2));
  1014. return r != 0 ? r : n1 > n2 ? 1 : n1 < n2 ? -1 : 0;
  1015. }
  1016. int compare(size_type pos1, size_type n1,
  1017. const flex_string& str,
  1018. size_type pos2, size_type n2) const
  1019. {
  1020. Enforce(pos2 <= str.size(), static_cast<std::out_of_range*>(0), "");
  1021. return compare(pos1, n1, str.data() + pos2, Min(n2, str.size() - pos2));
  1022. }
  1023. // Code from Jean-Francois Bastien (03/26/2007)
  1024. int compare(const value_type* s) const
  1025. {
  1026. // Could forward to compare(0, size(), s, traits_type::length(s))
  1027. // but that does two extra checks
  1028. const size_type n1(size()), n2(traits_type::length(s));
  1029. const int r = traits_type::compare(data(), s, Min(n1, n2));
  1030. return r != 0 ? r : n1 > n2 ? 1 : n1 < n2 ? -1 : 0;
  1031. }
  1032. };
  1033. template <typename E1, class T, class A, class S>
  1034. const typename flex_string<E1, T, A, S>::size_type
  1035. flex_string<E1, T, A, S>::npos = static_cast<typename flex_string<E1, T, A, S>::size_type>(-1);
  1036. ////////////////////////////////////////////////////////////////////////////////
  1037. #define DAHUA_FLEX_STRING flex_string
  1038. // non-member functions
  1039. template <typename E, class T, class A, class S>
  1040. DAHUA_FLEX_STRING<E, T, A, S> operator+(const DAHUA_FLEX_STRING<E, T, A, S>& lhs,
  1041. const DAHUA_FLEX_STRING<E, T, A, S>& rhs)
  1042. {
  1043. DAHUA_FLEX_STRING<E, T, A, S> result;
  1044. result.reserve(lhs.size() + rhs.size());
  1045. result.append(lhs).append(rhs);
  1046. return result;
  1047. }
  1048. template <typename E, class T, class A, class S>
  1049. DAHUA_FLEX_STRING<E, T, A, S> operator+(const typename DAHUA_FLEX_STRING<E, T, A, S>::value_type* lhs,
  1050. const DAHUA_FLEX_STRING<E, T, A, S>& rhs)
  1051. {
  1052. DAHUA_FLEX_STRING<E, T, A, S> result;
  1053. const typename DAHUA_FLEX_STRING<E, T, A, S>::size_type len =
  1054. DAHUA_FLEX_STRING<E, T, A, S>::traits_type::length(lhs);
  1055. result.reserve(len + rhs.size());
  1056. result.append(lhs, len).append(rhs);
  1057. return result;
  1058. }
  1059. template <typename E, class T, class A, class S>
  1060. DAHUA_FLEX_STRING<E, T, A, S> operator+(
  1061. typename DAHUA_FLEX_STRING<E, T, A, S>::value_type lhs,
  1062. const DAHUA_FLEX_STRING<E, T, A, S>& rhs)
  1063. {
  1064. DAHUA_FLEX_STRING<E, T, A, S> result;
  1065. result.reserve(1 + rhs.size());
  1066. result.push_back(lhs);
  1067. result.append(rhs);
  1068. return result;
  1069. }
  1070. template <typename E, class T, class A, class S>
  1071. DAHUA_FLEX_STRING<E, T, A, S> operator+(const DAHUA_FLEX_STRING<E, T, A, S>& lhs,
  1072. const typename DAHUA_FLEX_STRING<E, T, A, S>::value_type* rhs)
  1073. {
  1074. typedef typename DAHUA_FLEX_STRING<E, T, A, S>::size_type size_type;
  1075. typedef typename DAHUA_FLEX_STRING<E, T, A, S>::traits_type traits_type;
  1076. DAHUA_FLEX_STRING<E, T, A, S> result;
  1077. const size_type len = traits_type::length(rhs);
  1078. result.reserve(lhs.size() + len);
  1079. result.append(lhs).append(rhs, len);
  1080. return result;
  1081. }
  1082. template <typename E, class T, class A, class S>
  1083. DAHUA_FLEX_STRING<E, T, A, S> operator+(const DAHUA_FLEX_STRING<E, T, A, S>& lhs,
  1084. typename DAHUA_FLEX_STRING<E, T, A, S>::value_type rhs)
  1085. {
  1086. DAHUA_FLEX_STRING<E, T, A, S> result;
  1087. result.reserve(lhs.size() + 1);
  1088. result.append(lhs);
  1089. result.push_back(rhs);
  1090. return result;
  1091. }
  1092. template <typename E, class T, class A, class S>
  1093. bool operator==(const DAHUA_FLEX_STRING<E, T, A, S>& lhs,
  1094. const DAHUA_FLEX_STRING<E, T, A, S>& rhs)
  1095. { return lhs.compare(rhs) == 0; }
  1096. template <typename E, class T, class A, class S>
  1097. bool operator==(const typename DAHUA_FLEX_STRING<E, T, A, S>::value_type* lhs,
  1098. const DAHUA_FLEX_STRING<E, T, A, S>& rhs)
  1099. { return rhs == lhs; }
  1100. template <typename E, class T, class A, class S>
  1101. bool operator==(const DAHUA_FLEX_STRING<E, T, A, S>& lhs,
  1102. const typename DAHUA_FLEX_STRING<E, T, A, S>::value_type* rhs)
  1103. { return lhs.compare(rhs) == 0; }
  1104. template <typename E, class T, class A, class S>
  1105. bool operator!=(const DAHUA_FLEX_STRING<E, T, A, S>& lhs,
  1106. const DAHUA_FLEX_STRING<E, T, A, S>& rhs)
  1107. { return !(lhs == rhs); }
  1108. template <typename E, class T, class A, class S>
  1109. bool operator!=(const typename DAHUA_FLEX_STRING<E, T, A, S>::value_type* lhs,
  1110. const DAHUA_FLEX_STRING<E, T, A, S>& rhs)
  1111. { return !(lhs == rhs); }
  1112. template <typename E, class T, class A, class S>
  1113. bool operator!=(const DAHUA_FLEX_STRING<E, T, A, S>& lhs,
  1114. const typename DAHUA_FLEX_STRING<E, T, A, S>::value_type* rhs)
  1115. { return !(lhs == rhs); }
  1116. template <typename E, class T, class A, class S>
  1117. bool operator<(const DAHUA_FLEX_STRING<E, T, A, S>& lhs,
  1118. const DAHUA_FLEX_STRING<E, T, A, S>& rhs)
  1119. { return lhs.compare(rhs) < 0; }
  1120. template <typename E, class T, class A, class S>
  1121. bool operator<(const DAHUA_FLEX_STRING<E, T, A, S>& lhs,
  1122. const typename DAHUA_FLEX_STRING<E, T, A, S>::value_type* rhs)
  1123. { return lhs.compare(rhs) < 0; }
  1124. template <typename E, class T, class A, class S>
  1125. bool operator<(const typename DAHUA_FLEX_STRING<E, T, A, S>::value_type* lhs,
  1126. const DAHUA_FLEX_STRING<E, T, A, S>& rhs)
  1127. { return rhs.compare(lhs) > 0; }
  1128. template <typename E, class T, class A, class S>
  1129. bool operator>(const DAHUA_FLEX_STRING<E, T, A, S>& lhs,
  1130. const DAHUA_FLEX_STRING<E, T, A, S>& rhs)
  1131. { return rhs < lhs; }
  1132. template <typename E, class T, class A, class S>
  1133. bool operator>(const DAHUA_FLEX_STRING<E, T, A, S>& lhs,
  1134. const typename DAHUA_FLEX_STRING<E, T, A, S>::value_type* rhs)
  1135. { return rhs < lhs; }
  1136. template <typename E, class T, class A, class S>
  1137. bool operator>(const typename DAHUA_FLEX_STRING<E, T, A, S>::value_type* lhs,
  1138. const DAHUA_FLEX_STRING<E, T, A, S>& rhs)
  1139. { return rhs < lhs; }
  1140. template <typename E, class T, class A, class S>
  1141. bool operator<=(const DAHUA_FLEX_STRING<E, T, A, S>& lhs,
  1142. const DAHUA_FLEX_STRING<E, T, A, S>& rhs)
  1143. { return !(rhs < lhs); }
  1144. template <typename E, class T, class A, class S>
  1145. bool operator<=(const DAHUA_FLEX_STRING<E, T, A, S>& lhs,
  1146. const typename DAHUA_FLEX_STRING<E, T, A, S>::value_type* rhs)
  1147. { return !(rhs < lhs); }
  1148. template <typename E, class T, class A, class S>
  1149. bool operator<=(const typename DAHUA_FLEX_STRING<E, T, A, S>::value_type* lhs,
  1150. const DAHUA_FLEX_STRING<E, T, A, S>& rhs)
  1151. { return !(rhs < lhs); }
  1152. template <typename E, class T, class A, class S>
  1153. bool operator>=(const DAHUA_FLEX_STRING<E, T, A, S>& lhs,
  1154. const DAHUA_FLEX_STRING<E, T, A, S>& rhs)
  1155. { return !(lhs < rhs); }
  1156. template <typename E, class T, class A, class S>
  1157. bool operator>=(const DAHUA_FLEX_STRING<E, T, A, S>& lhs,
  1158. const typename DAHUA_FLEX_STRING<E, T, A, S>::value_type* rhs)
  1159. { return !(lhs < rhs); }
  1160. template <typename E, class T, class A, class S>
  1161. bool operator>=(const typename DAHUA_FLEX_STRING<E, T, A, S>::value_type* lhs,
  1162. const DAHUA_FLEX_STRING<E, T, A, S>& rhs)
  1163. { return !(lhs < rhs); }
  1164. template <typename E, class T, class A, class S>
  1165. inline void swap(DAHUA_FLEX_STRING<E, T, A, S>& lhs, DAHUA_FLEX_STRING<E, T, A, S>& rhs)
  1166. {
  1167. // 21.3.7.8
  1168. lhs.swap(rhs);
  1169. }
  1170. template <typename E, class T, class A, class S>
  1171. std::basic_istream<typename DAHUA_FLEX_STRING<E, T, A, S>::value_type,
  1172. typename DAHUA_FLEX_STRING<E, T, A, S>::traits_type>&
  1173. operator>>(
  1174. std::basic_istream<typename DAHUA_FLEX_STRING<E, T, A, S>::value_type,
  1175. typename DAHUA_FLEX_STRING<E, T, A, S>::traits_type>& is,
  1176. DAHUA_FLEX_STRING<E, T, A, S>& str);
  1177. template <typename E, class T, class A, class S>
  1178. std::basic_ostream<typename DAHUA_FLEX_STRING<E, T, A, S>::value_type,
  1179. typename DAHUA_FLEX_STRING<E, T, A, S>::traits_type>&
  1180. operator<<(
  1181. std::basic_ostream<typename DAHUA_FLEX_STRING<E, T, A, S>::value_type,
  1182. typename DAHUA_FLEX_STRING<E, T, A, S>::traits_type>& os,
  1183. const DAHUA_FLEX_STRING<E, T, A, S>& str)
  1184. { return os << str.c_str(); }
  1185. template <typename E, class T, class A, class S>
  1186. std::basic_istream<typename DAHUA_FLEX_STRING<E, T, A, S>::value_type,
  1187. typename DAHUA_FLEX_STRING<E, T, A, S>::traits_type>&
  1188. getline(
  1189. std::basic_istream<typename DAHUA_FLEX_STRING<E, T, A, S>::value_type,
  1190. typename DAHUA_FLEX_STRING<E, T, A, S>::traits_type>& is,
  1191. DAHUA_FLEX_STRING<E, T, A, S>& str,
  1192. typename DAHUA_FLEX_STRING<E, T, A, S>::value_type delim)
  1193. {
  1194. size_t nread = 0;
  1195. typename std::basic_istream<typename DAHUA_FLEX_STRING<E, T, A, S>::value_type,
  1196. typename DAHUA_FLEX_STRING<E, T, A, S>::traits_type>::sentry sentry(is, true);
  1197. if (sentry) {
  1198. std::basic_streambuf<typename DAHUA_FLEX_STRING<E, T, A, S>::value_type,
  1199. typename DAHUA_FLEX_STRING<E, T, A, S>::traits_type>* buf = is.rdbuf();
  1200. str.clear();
  1201. while (nread < str.max_size()) {
  1202. int c1 = buf->sbumpc();
  1203. if (DAHUA_FLEX_STRING<E, T, A, S>::traits_type::eq_int_type(c1, DAHUA_FLEX_STRING<E, T, A, S>::traits_type::eof())) {
  1204. is.setstate(std::ios_base::eofbit);
  1205. break;
  1206. }
  1207. else {
  1208. ++nread;
  1209. typename DAHUA_FLEX_STRING<E, T, A, S>::value_type c = DAHUA_FLEX_STRING<E, T, A, S>::traits_type::to_char_type(c1);
  1210. if (!DAHUA_FLEX_STRING<E, T, A, S>::traits_type::eq(c, delim))
  1211. str.push_back(c);
  1212. else
  1213. break; // Character is extracted but not appended.
  1214. }
  1215. }
  1216. }
  1217. if (nread == 0 || nread >= str.max_size())
  1218. is.setstate(std::ios_base::failbit);
  1219. return is;
  1220. }
  1221. template <typename E, class T, class A, class S>
  1222. std::basic_istream<typename DAHUA_FLEX_STRING<E, T, A, S>::value_type,
  1223. typename DAHUA_FLEX_STRING<E, T, A, S>::traits_type>&
  1224. getline(
  1225. std::basic_istream<typename DAHUA_FLEX_STRING<E, T, A, S>::value_type,
  1226. typename DAHUA_FLEX_STRING<E, T, A, S>::traits_type>& is,
  1227. DAHUA_FLEX_STRING<E, T, A, S>& str)
  1228. {
  1229. return getline(is, str, is.widen('\n'));
  1230. }
  1231. } // namespace Infra
  1232. } // namespace Dahua
  1233. #undef DAHUA_FLEX_STRING
  1234. #endif // DAHUA_FLEX_STRING_SHELL_INC_