_string_sum.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. /*
  2. * Copyright (c) 2003
  3. * Francois Dumont
  4. *
  5. * This material is provided "as is", with absolutely no warranty expressed
  6. * or implied. Any use is at your own risk.
  7. *
  8. * Permission to use or copy this software for any purpose is hereby granted
  9. * without fee, provided the above notices are retained on all copies.
  10. * Permission to modify the code and to distribute modified code is granted,
  11. * provided the above notices are retained, and a notice that the code was
  12. * modified is included with the above copyright notice.
  13. *
  14. */
  15. #ifndef _STLP_STRING_SUM_H
  16. #define _STLP_STRING_SUM_H
  17. _STLP_BEGIN_NAMESPACE
  18. _STLP_MOVE_TO_PRIV_NAMESPACE
  19. /*char wrapper to simulate basic_string*/
  20. template <class _CharT>
  21. struct __char_wrapper {
  22. typedef const _CharT& const_reference;
  23. __char_wrapper(_CharT __val) : _Val(__val) {}
  24. _CharT getValue() const { return _Val; }
  25. size_t size() const { return 1; }
  26. const_reference operator[] (size_t __n) const {
  27. //To avoid a check on __n we use this strange implementation
  28. return (&_Val)[__n];
  29. }
  30. private:
  31. _CharT _Val;
  32. };
  33. /*C string wrapper to simulate basic_string*/
  34. template <class _CharT>
  35. struct __cstr_wrapper {
  36. typedef const _CharT& const_reference;
  37. __cstr_wrapper(const _CharT *__cstr, size_t __size) :
  38. _CStr(__cstr), _Size(__size) {}
  39. const _CharT* c_str() const { return _CStr; }
  40. size_t size() const { return _Size; }
  41. const_reference operator[] (size_t __n) const { return _CStr[__n]; }
  42. private:
  43. const _CharT *_CStr;
  44. size_t _Size;
  45. };
  46. /*basic_string wrapper to ensure that we only store a reference to the original string and not copy it*/
  47. template <class _CharT, class _Traits, class _Alloc>
  48. struct __bstr_wrapper {
  49. typedef const _CharT& const_reference;
  50. typedef basic_string<_CharT, _Traits, _Alloc> _BString;
  51. __bstr_wrapper (_BString const& __s) :
  52. _BStr(__s) {}
  53. size_t size() const { return _BStr.size(); }
  54. const_reference operator[] (size_t __n) const { return _BStr[__n]; }
  55. _BString const& b_str() const { return _BStr; }
  56. private:
  57. _BString const& _BStr;
  58. };
  59. struct __on_left {};
  60. struct __on_right {};
  61. template <class _CharT, class _Traits, class _Alloc,
  62. class _Left, class _Right,
  63. class _StorageDirection>
  64. class __bstr_sum {
  65. public:
  66. typedef basic_string<_CharT, _Traits, _Alloc> _BString;
  67. typedef typename _BString::const_reference const_reference;
  68. typedef typename _BString::const_iterator const_iterator;
  69. typedef typename _BString::const_reverse_iterator const_reverse_iterator;
  70. typedef typename _BString::size_type size_type;
  71. typedef typename _BString::allocator_type allocator_type;
  72. typedef __bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDirection> _Self;
  73. __bstr_sum (_Left const& lhs, _Right const& rhs) :
  74. _lhs(lhs), _rhs(rhs) {}
  75. _Left const& getLhs() const { return _lhs; }
  76. _Right const& getRhs() const { return _rhs; }
  77. allocator_type get_allocator() const { return _M_get_storage(false).get_allocator(); }
  78. const_iterator begin() const { return _M_get_storage().begin(); }
  79. const_iterator end() const { return _M_get_storage().end(); }
  80. const_reverse_iterator rbegin() const { return _M_get_storage().rbegin(); }
  81. const_reverse_iterator rend() const { return _M_get_storage().rend(); }
  82. size_type size() const { return _lhs.size() + _rhs.size(); }
  83. size_type length() const { return size(); }
  84. size_t max_size() const { return _M_get_storage().max_size(); }
  85. size_type capacity() const { return size(); }
  86. bool empty() const { return size() == 0; }
  87. const_reference operator[](size_t __n) const
  88. { return (__n < _lhs.size())?_lhs[__n]:_rhs[__n - _lhs.size()]; }
  89. const_reference at(size_type __n) const
  90. { return _M_get_storage().at(__n); }
  91. //operator +=
  92. typedef __bstr_sum<_CharT, _Traits, _Alloc, _Self, __bstr_wrapper<_CharT, _Traits, _Alloc>, __on_left> _BStrOnLeft;
  93. _BStrOnLeft operator += (const _BString& __s) { return append(__s); }
  94. typedef __bstr_sum<_CharT, _Traits, _Alloc, _Self, __cstr_wrapper<_CharT>, __on_left> _CStrOnLeft;
  95. _CStrOnLeft operator += (const _CharT* __s) { return append(__s); }
  96. typedef __bstr_sum<_CharT, _Traits, _Alloc, _Self, __char_wrapper<_CharT>, __on_left> _CharOnLeft;
  97. _CharOnLeft operator += (_CharT __c) { return _CharOnLeft(*this, __c); }
  98. //append
  99. _BStrOnLeft append (const _BString& __s)
  100. { return _BStrOnLeft(*this, __s); }
  101. _BString& append(const _BString& __s, size_type __pos, size_type __n)
  102. { return _M_get_storage().append(__s, __pos, __n); }
  103. _CStrOnLeft append(const _CharT* __s) {
  104. const size_type __n = _Traits::length(__s);
  105. return _CStrOnLeft(*this, __cstr_wrapper<_CharT>(__s, __n));
  106. }
  107. _CStrOnLeft append(const _CharT* __s, size_type __n)
  108. { return _CStrOnLeft(*this, __cstr_wrapper<_CharT>(__s, __n)); }
  109. _BString& append(size_type __n, _CharT __c)
  110. {return _M_get_storage().append(__n, __c);}
  111. template <class _InputIter>
  112. _BString& append(_InputIter __first, _InputIter __last)
  113. {return _M_get_storage().append(__first, __last);}
  114. //assign
  115. _BString& assign(const _BString& __s) {return _M_get_storage().assign(__s);}
  116. _BString& assign(const _BString& __s, size_type __pos, size_type __n) {return _M_get_storage().assign(__s, __pos, __n);}
  117. _BString& assign(const _CharT* __s, size_type __n) {return _M_get_storage().assign(__s, __n);}
  118. _BString& assign(const _CharT* __s) {return _M_get_storage().assign(__s); }
  119. _BString& assign(size_type __n, _CharT __c) {return _M_get_storage().assign(__n, __c);}
  120. //insert
  121. _BString& insert(size_type __pos, const _BString& __s) {return _M_get_storage().insert(__pos, __s);}
  122. _BString& insert(size_type __pos, const _BString& __s, size_type __beg, size_type __n)
  123. {return _M_get_storage().insert(__pos, __s, __beg, __n);}
  124. _BString& insert(size_type __pos, const _CharT* __s, size_type __n) {return _M_get_storage().insert(__pos, __s, __n);}
  125. _BString& insert(size_type __pos, const _CharT* __s) {return _M_get_storage().insert(__pos, __s);}
  126. _BString& insert(size_type __pos, size_type __n, _CharT __c) {return _M_get_storage().insert(__pos, __n, __c);}
  127. //erase
  128. _BString& erase(size_type __pos = 0, size_type __n =_BString::npos) {return _M_get_storage().erase(__pos, __n);}
  129. //replace
  130. _BString& replace(size_type __pos, size_type __n, const _BString& __s)
  131. {return _M_get_storage().replace(__pos, __n, __s);}
  132. _BString& replace(size_type __pos1, size_type __n1, const _BString& __s, size_type __pos2, size_type __n2)
  133. {return _M_get_storage().replace(__pos1, __n1, __s, __pos2, __n2);}
  134. _BString& replace(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2)
  135. {return _M_get_storage().replace(__pos, __n1, __s, __n2);}
  136. _BString& replace(size_type __pos, size_type __n1, const _CharT* __s)
  137. {return _M_get_storage().replace(__pos, __n1, __s);}
  138. _BString& replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
  139. {return _M_get_storage().replace(__pos, __n1, __n2, __c);}
  140. size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const
  141. {return _M_get_storage().copy(__s, __n, __pos);}
  142. void swap(_BString& __s)
  143. {_M_get_storage().swap(__s);}
  144. const _CharT* c_str() const { return _M_get_storage().c_str(); }
  145. const _CharT* data() const { return _M_get_storage().data(); }
  146. //find family
  147. size_type find(const _BString& __s, size_type __pos = 0) const { return _M_get_storage().find(__s, __pos); }
  148. size_type find(const _CharT* __s, size_type __pos = 0) const { return _M_get_storage().find(__s, __pos); }
  149. size_type find(const _CharT* __s, size_type __pos, size_type __n) const { return _M_get_storage().find(__s, __pos, __n); }
  150. size_type find(_CharT __c, size_type __pos = 0) const { return _M_get_storage().find(__c, __pos); }
  151. size_type rfind(const _BString& __s, size_type __pos = _BString::npos) const { return _M_get_storage().rfind(__s, __pos); }
  152. size_type rfind(const _CharT* __s, size_type __pos = _BString::npos) const { return _M_get_storage().rfind(__s, __pos); }
  153. size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const { return _M_get_storage().rfind(__s, __pos, __n); }
  154. size_type rfind(_CharT __c, size_type __pos = _BString::npos) const { return _M_get_storage().rfind(__c, __pos); }
  155. size_type find_first_of(const _BString& __s, size_type __pos = 0) const
  156. { return _M_get_storage().find_first_of(__s, __pos); }
  157. size_type find_first_of(const _CharT* __s, size_type __pos = 0) const
  158. { return _M_get_storage().find_first_of(__s, __pos); }
  159. size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
  160. { return _M_get_storage().find_first_of(__s, __pos, __n); }
  161. size_type find_first_of(_CharT __c, size_type __pos = 0) const
  162. { return _M_get_storage().find(__c, __pos); }
  163. size_type find_last_of(const _BString& __s, size_type __pos = _BString::npos) const
  164. { return _M_get_storage().find_last_of(__s, __pos); }
  165. size_type find_last_of(const _CharT* __s, size_type __pos = _BString::npos) const
  166. { return _M_get_storage().find_last_of(__s, __pos); }
  167. size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
  168. { return _M_get_storage().find_last_of(__s, __pos, __n); }
  169. size_type find_last_of(_CharT __c, size_type __pos = _BString::npos) const
  170. { return _M_get_storage().rfind(__c, __pos); }
  171. size_type find_first_not_of(const _BString& __s, size_type __pos = 0) const
  172. { return _M_get_storage().find_first_not_of(__s, __pos); }
  173. size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const
  174. { return _M_get_storage().find_first_not_of(__s, __pos); }
  175. size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
  176. { return _M_get_storage().find_first_not_of(__s, __pos, __n); }
  177. size_type find_first_not_of(_CharT __c, size_type __pos = 0) const
  178. { return _M_get_storage().find_first_not_of(__c, __pos); }
  179. size_type find_last_not_of(const _BString& __s, size_type __pos = _BString::npos) const
  180. { return _M_get_storage().find_last_not_of(__s, __pos); }
  181. size_type find_last_not_of(const _CharT* __s, size_type __pos =_BString:: npos) const
  182. { return _M_get_storage().find_last_not_of(__s, __pos); }
  183. size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
  184. { return _M_get_storage().find_last_not_of(__s, __pos, __n); }
  185. size_type find_last_not_of(_CharT __c, size_type __pos = _BString::npos) const
  186. { return _M_get_storage().find_last_not_of(__c, __pos); }
  187. _BString substr(size_type __pos = 0, size_type __n = _BString::npos) const
  188. { return _M_get_storage().substr(__pos, __n); }
  189. //compare
  190. int compare(const _BString& __s) const
  191. { return _M_get_storage().compare(__s); }
  192. int compare(size_type __pos1, size_type __n1, const _Self& __s) const
  193. { return _M_get_storage().compare(__pos1, __n1, __s); }
  194. int compare(size_type __pos1, size_type __n1, const _Self& __s, size_type __pos2, size_type __n2) const
  195. { return _M_get_storage().compare(__pos1, __n1, __s, __pos2, __n2); }
  196. int compare(const _CharT* __s) const
  197. { return _M_get_storage().compare(__s); }
  198. int compare(size_type __pos1, size_type __n1, const _CharT* __s) const
  199. { return _M_get_storage().compare(__pos1, __n1, __s); }
  200. int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const
  201. { return _M_get_storage().compare(__pos1, __n1, __s, __n2); }
  202. //Returns the underlying basic_string representation of the template expression
  203. //The non const method will always initialise it.
  204. _BString& _M_get_storage()
  205. { return _rhs._M_get_storage(*this, _StorageDirection()); }
  206. template <class _Lhs, class _Rhs, class _StorageDir>
  207. _BString& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Lhs, _Rhs, _StorageDir> const& __ref,
  208. __on_left const& /*StorageDir*/)
  209. { return _lhs._M_get_storage(__ref); }
  210. template <class _Lhs, class _Rhs, class _StorageDir>
  211. _BString& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Lhs, _Rhs, _StorageDir> const& __ref,
  212. __on_right const& /*StorageDir*/)
  213. { return _rhs._M_get_storage(__ref); }
  214. template <class _Lhs, class _Rhs, class _StorageDir>
  215. _BString& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Lhs, _Rhs, _StorageDir> const& __ref)
  216. { return _M_get_storage(__ref, _StorageDirection()); }
  217. //The const method can be invoked without initialising the basic_string so avoiding dynamic allocation.
  218. _BString const& _M_get_storage(bool __do_init = true) const
  219. { return _M_get_storage(*this, __do_init, _StorageDirection()); }
  220. template <class _Lhs, class _Rhs, class _StorageDir>
  221. _BString const& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Lhs, _Rhs, _StorageDir> const& __ref,
  222. bool __do_init, __on_left const& /*StorageDir*/) const
  223. { return _lhs._M_get_storage(__ref, __do_init); }
  224. template <class _Lhs, class _Rhs, class _StorageDir>
  225. _BString const& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Lhs, _Rhs, _StorageDir> const& __ref,
  226. bool __do_init, __on_right const& /*StorageDir*/) const
  227. { return _rhs._M_get_storage(__ref, __do_init); }
  228. template <class _Lhs, class _Rhs, class _StorageDir>
  229. _BString const& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Lhs, _Rhs, _StorageDir> const& __ref,
  230. bool __do_init) const
  231. { return _M_get_storage(__ref, __do_init, _StorageDirection()); }
  232. private:
  233. _Left _lhs;
  234. _Right _rhs;
  235. };
  236. /*
  237. * For this operator we choose to use the right part as the storage part
  238. */
  239. template <class _CharT, class _Traits, class _Alloc,
  240. class _Lh1, class _Rh1, class _StoreDir1,
  241. class _Lh2, class _Rh2, class _StoreDir2>
  242. inline __bstr_sum<_CharT, _Traits, _Alloc,
  243. __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1>,
  244. __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2>,
  245. __on_right> _STLP_CALL
  246. operator + (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
  247. const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs) {
  248. return __bstr_sum<_CharT, _Traits, _Alloc,
  249. __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1>,
  250. __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2>,
  251. __on_right>(__lhs, __rhs);
  252. }
  253. template <class _CharT, class _Traits, class _Alloc,
  254. class _Lh1, class _Rh1, class _StoreDir1,
  255. class _Lh2, class _Rh2, class _StoreDir2>
  256. inline bool _STLP_CALL
  257. operator == (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
  258. const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs)
  259. { return (__lhs.size() == __rhs.size()) && (__lhs._M_get_storage() == __rhs._M_get_storage()); }
  260. template <class _CharT, class _Traits, class _Alloc,
  261. class _Lh1, class _Rh1, class _StoreDir1,
  262. class _Lh2, class _Rh2, class _StoreDir2>
  263. inline bool _STLP_CALL
  264. operator < (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
  265. const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs)
  266. { return __lhs._M_get_storage() < __rhs._M_get_storage(); }
  267. #ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
  268. template <class _CharT, class _Traits, class _Alloc,
  269. class _Lh1, class _Rh1, class _StoreDir1,
  270. class _Lh2, class _Rh2, class _StoreDir2>
  271. inline bool _STLP_CALL
  272. operator != (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
  273. const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs)
  274. { return !(__lhs == __rhs); }
  275. template <class _CharT, class _Traits, class _Alloc,
  276. class _Lh1, class _Rh1, class _StoreDir1,
  277. class _Lh2, class _Rh2, class _StoreDir2>
  278. inline bool _STLP_CALL
  279. operator > (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
  280. const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs)
  281. { return __rhs < __lhs; }
  282. template <class _CharT, class _Traits, class _Alloc,
  283. class _Lh1, class _Rh1, class _StoreDir1,
  284. class _Lh2, class _Rh2, class _StoreDir2>
  285. inline bool _STLP_CALL
  286. operator <= (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
  287. const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs)
  288. { return !(__rhs < __lhs); }
  289. template <class _CharT, class _Traits, class _Alloc,
  290. class _Lh1, class _Rh1, class _StoreDir1,
  291. class _Lh2, class _Rh2, class _StoreDir2>
  292. inline bool _STLP_CALL
  293. operator >= (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
  294. const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs)
  295. { return !(__lhs < __rhs); }
  296. #endif /* _STLP_USE_SEPARATE_RELOPS_NAMESPACE */
  297. /*
  298. * This class will be used to simulate a temporary string that is required for
  299. * a call to the c_str method on the __bstr_sum class.
  300. */
  301. template <class _CharT, class _Traits, class _Alloc>
  302. struct __sum_storage_elem {
  303. typedef __sum_storage_elem<_CharT, _Traits, _Alloc> _Self;
  304. typedef basic_string<_CharT, _Traits, _Alloc> _BString;
  305. __sum_storage_elem(_Alloc __alloc) : _M_init(false), _M_storage(__alloc)
  306. {}
  307. template <class _Left, class _Right, class _StorageDir>
  308. void _M_Init(__bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDir> const& __ref) const {
  309. if (!_M_init) {
  310. _STLP_MUTABLE(_Self, _M_storage) = __ref;
  311. _STLP_MUTABLE(_Self, _M_init) = true;
  312. }
  313. }
  314. template <class _Left, class _Right, class _StorageDir>
  315. _BString const& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDir> const& __ref,
  316. bool __do_init) const {
  317. if (__do_init) {
  318. _M_Init(__ref);
  319. }
  320. return _M_storage;
  321. }
  322. template <class _Left, class _Right, class _StorageDir>
  323. _BString& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDir> const& __ref) {
  324. _M_Init(__ref);
  325. return _M_storage;
  326. }
  327. size_t size() const { return 0; }
  328. _CharT const& operator[](size_t __n) const
  329. { return __STATIC_CAST(_CharT*, 0)[__n]; }
  330. private:
  331. mutable bool _M_init;
  332. mutable basic_string<_CharT, _Traits, _Alloc> _M_storage;
  333. };
  334. _STLP_MOVE_TO_STD_NAMESPACE
  335. _STLP_END_NAMESPACE
  336. #endif /*_STLP_STRING_SUM_H*/