]> git.buserror.net Git - polintos/scott/priv.git/blob - include/c++/stl/stl/_string_sum.h
minor doc updates
[polintos/scott/priv.git] / include / c++ / stl / stl / _string_sum.h
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
16 #ifndef _STLP_STRING_SUM_H
17 #define _STLP_STRING_SUM_H
18
19 _STLP_BEGIN_NAMESPACE
20
21 _STLP_MOVE_TO_PRIV_NAMESPACE
22
23 /*char wrapper to simulate basic_string*/
24 template <class _CharT>
25 struct __char_wrapper {
26   typedef const _CharT& const_reference;
27
28   __char_wrapper(_CharT __val) : _Val(__val) {}
29
30   _CharT getValue() const { return _Val; }
31   size_t size() const { return 1; }
32
33   const_reference operator[] (size_t __n) const {
34     //To avoid a check on __n we use this strange implementation
35     return (&_Val)[__n];
36   }
37
38 private:
39   _CharT _Val;
40 };
41
42 /*C string wrapper to simulate basic_string*/
43 template <class _CharT>
44 struct __cstr_wrapper {
45   typedef const _CharT& const_reference;
46
47   __cstr_wrapper(const _CharT *__cstr, size_t __size) :
48     _CStr(__cstr), _Size(__size) {}
49
50   const _CharT* c_str() const { return _CStr; }
51
52   size_t size() const { return _Size; }
53
54   const_reference operator[] (size_t __n) const { return _CStr[__n]; }
55
56 private:
57   const _CharT *_CStr;
58   size_t _Size;
59 };
60
61 /*basic_string wrapper to ensure that we only store a reference to the original string and not copy it*/
62 template <class _CharT, class _Traits, class _Alloc>
63 struct __bstr_wrapper {
64   typedef const _CharT& const_reference;
65   typedef basic_string<_CharT, _Traits, _Alloc> _BString;
66
67   __bstr_wrapper (_BString const& __s) :
68     _BStr(__s) {}
69
70   size_t size() const { return _BStr.size(); }
71
72   const_reference operator[] (size_t __n) const { return _BStr[__n]; }
73
74   _BString const& b_str() const { return _BStr; }
75
76 private:
77   _BString const& _BStr;
78 };
79
80 struct __on_left {};
81 struct __on_right {};
82
83 template <class _CharT, class _Traits, class _Alloc,
84           class _Left, class _Right,
85           class _StorageDirection>
86 class __bstr_sum {
87 public:
88   typedef basic_string<_CharT, _Traits, _Alloc> _BString;
89   typedef typename _BString::const_reference const_reference;
90   typedef typename _BString::const_iterator const_iterator;
91   typedef typename _BString::const_reverse_iterator const_reverse_iterator;
92   typedef typename _BString::size_type size_type;
93   typedef typename _BString::allocator_type allocator_type;
94   typedef __bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDirection> _Self;
95
96   __bstr_sum (_Left const& lhs, _Right const& rhs) :
97     _lhs(lhs), _rhs(rhs) {}
98
99   _Left const& getLhs() const { return _lhs; }
100   _Right const& getRhs() const { return _rhs; }
101
102   allocator_type get_allocator() const { return _M_get_storage(false).get_allocator(); }
103
104   const_iterator begin() const { return _M_get_storage().begin(); }
105   const_iterator end()   const { return _M_get_storage().end(); }
106   const_reverse_iterator rbegin() const { return _M_get_storage().rbegin(); }
107   const_reverse_iterator rend()   const { return _M_get_storage().rend(); }
108
109   size_type size() const { return _lhs.size() + _rhs.size(); }
110   size_type length() const { return size(); }
111
112   size_t max_size() const { return _M_get_storage().max_size(); }
113   size_type capacity() const { return size(); }
114   bool empty() const { return size() == 0; }
115
116   const_reference operator[](size_t __n) const
117   { return (__n < _lhs.size())?_lhs[__n]:_rhs[__n - _lhs.size()]; }
118
119   const_reference at(size_type __n) const
120   { return _M_get_storage().at(__n); }
121
122   //operator +=
123   typedef __bstr_sum<_CharT, _Traits, _Alloc, _Self, __bstr_wrapper<_CharT, _Traits, _Alloc>, __on_left> _BStrOnLeft;
124   _BStrOnLeft operator += (const _BString& __s) { return append(__s); }
125
126   typedef __bstr_sum<_CharT, _Traits, _Alloc, _Self, __cstr_wrapper<_CharT>, __on_left> _CStrOnLeft;
127   _CStrOnLeft operator += (const _CharT* __s) { return append(__s); }
128
129   typedef __bstr_sum<_CharT, _Traits, _Alloc, _Self, __char_wrapper<_CharT>, __on_left> _CharOnLeft;
130   _CharOnLeft operator += (_CharT __c) { return _CharOnLeft(*this, __c); }
131
132   //append
133   _BStrOnLeft append (const _BString& __s)
134   { return _BStrOnLeft(*this, __s); }
135   _BString& append(const _BString& __s, size_type __pos, size_type __n)
136   { return _M_get_storage().append(__s, __pos, __n); }
137   _CStrOnLeft append(const _CharT* __s) {
138     const size_type __n = _Traits::length(__s);
139     return _CStrOnLeft(*this, __cstr_wrapper<_CharT>(__s, __n));
140   }
141   _CStrOnLeft append(const _CharT* __s, size_type __n)
142   { return _CStrOnLeft(*this, __cstr_wrapper<_CharT>(__s, __n)); }
143   _BString& append(size_type __n, _CharT __c)
144   {return _M_get_storage().append(__n, __c);}
145   template <class _InputIter>
146   _BString& append(_InputIter __first, _InputIter __last)
147   {return _M_get_storage().append(__first, __last);}
148
149   //assign
150   _BString& assign(const _BString& __s) {return _M_get_storage().assign(__s);}
151   _BString& assign(const _BString& __s, size_type __pos, size_type __n) {return _M_get_storage().assign(__s, __pos, __n);}
152   _BString& assign(const _CharT* __s, size_type __n) {return _M_get_storage().assign(__s, __n);}
153   _BString& assign(const _CharT* __s) {return _M_get_storage().assign(__s); }
154   _BString& assign(size_type __n, _CharT __c) {return _M_get_storage().assign(__n, __c);}
155
156   //insert
157   _BString& insert(size_type __pos, const _BString& __s) {return _M_get_storage().insert(__pos, __s);}
158   _BString& insert(size_type __pos, const _BString& __s, size_type __beg, size_type __n)
159   {return _M_get_storage().insert(__pos, __s, __beg, __n);}
160   _BString& insert(size_type __pos, const _CharT* __s, size_type __n) {return _M_get_storage().insert(__pos, __s, __n);}
161   _BString& insert(size_type __pos, const _CharT* __s) {return _M_get_storage().insert(__pos, __s);}
162   _BString& insert(size_type __pos, size_type __n, _CharT __c) {return _M_get_storage().insert(__pos, __n, __c);}
163
164   //erase
165   _BString& erase(size_type __pos = 0, size_type __n =_BString::npos) {return _M_get_storage().erase(__pos, __n);}
166
167   //replace
168   _BString& replace(size_type __pos, size_type __n, const _BString& __s)
169   {return _M_get_storage().replace(__pos, __n, __s);}
170   _BString& replace(size_type __pos1, size_type __n1, const _BString& __s, size_type __pos2, size_type __n2)
171   {return _M_get_storage().replace(__pos1, __n1, __s, __pos2, __n2);}
172   _BString& replace(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2)
173   {return _M_get_storage().replace(__pos, __n1, __s, __n2);}
174   _BString& replace(size_type __pos, size_type __n1, const _CharT* __s)
175   {return _M_get_storage().replace(__pos, __n1, __s);}
176   _BString& replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
177   {return _M_get_storage().replace(__pos, __n1, __n2, __c);}
178
179   size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const
180   {return _M_get_storage().copy(__s, __n, __pos);}
181
182   void swap(_BString& __s)
183   {_M_get_storage().swap(__s);}
184
185   const _CharT* c_str() const { return _M_get_storage().c_str(); }
186   const _CharT* data()  const { return _M_get_storage().data(); }
187
188   //find family
189   size_type find(const _BString& __s, size_type __pos = 0) const { return _M_get_storage().find(__s, __pos); }
190   size_type find(const _CharT* __s, size_type __pos = 0) const { return _M_get_storage().find(__s, __pos); }
191   size_type find(const _CharT* __s, size_type __pos, size_type __n) const { return _M_get_storage().find(__s, __pos, __n); }
192   size_type find(_CharT __c, size_type __pos = 0) const { return _M_get_storage().find(__c, __pos); }
193
194   size_type rfind(const _BString& __s, size_type __pos = _BString::npos) const { return _M_get_storage().rfind(__s, __pos); }
195   size_type rfind(const _CharT* __s, size_type __pos = _BString::npos) const { return _M_get_storage().rfind(__s, __pos); }
196   size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const { return _M_get_storage().rfind(__s, __pos, __n); }
197   size_type rfind(_CharT __c, size_type __pos = _BString::npos) const { return _M_get_storage().rfind(__c, __pos); }
198
199   size_type find_first_of(const _BString& __s, size_type __pos = 0) const
200   { return _M_get_storage().find_first_of(__s, __pos); }
201   size_type find_first_of(const _CharT* __s, size_type __pos = 0) const
202   { return _M_get_storage().find_first_of(__s, __pos); }
203   size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
204   { return _M_get_storage().find_first_of(__s, __pos, __n); }
205   size_type find_first_of(_CharT __c, size_type __pos = 0) const
206   { return _M_get_storage().find(__c, __pos); }
207
208   size_type find_last_of(const _BString& __s, size_type __pos = _BString::npos) const
209   { return _M_get_storage().find_last_of(__s, __pos); }
210   size_type find_last_of(const _CharT* __s, size_type __pos = _BString::npos) const
211   { return _M_get_storage().find_last_of(__s, __pos); }
212   size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
213   { return _M_get_storage().find_last_of(__s, __pos, __n); }
214   size_type find_last_of(_CharT __c, size_type __pos = _BString::npos) const
215   { return _M_get_storage().rfind(__c, __pos); }
216
217   size_type find_first_not_of(const _BString& __s, size_type __pos = 0) const
218   { return _M_get_storage().find_first_not_of(__s, __pos); }
219   size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const
220   { return _M_get_storage().find_first_not_of(__s, __pos); }
221   size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
222   { return _M_get_storage().find_first_not_of(__s, __pos, __n); }
223   size_type find_first_not_of(_CharT __c, size_type __pos = 0) const
224   { return _M_get_storage().find_first_not_of(__c, __pos); }
225
226   size_type find_last_not_of(const _BString& __s, size_type __pos = _BString::npos) const
227   { return _M_get_storage().find_last_not_of(__s, __pos); }
228   size_type find_last_not_of(const _CharT* __s, size_type __pos =_BString:: npos) const
229   { return _M_get_storage().find_last_not_of(__s, __pos); }
230   size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
231   { return _M_get_storage().find_last_not_of(__s, __pos, __n); }
232   size_type find_last_not_of(_CharT __c, size_type __pos = _BString::npos) const
233   { return _M_get_storage().find_last_not_of(__c, __pos); }
234
235   _BString substr(size_type __pos = 0, size_type __n = _BString::npos) const
236   { return _M_get_storage().substr(__pos, __n); }
237
238   //compare
239   int compare(const _BString& __s) const
240   { return _M_get_storage().compare(__s); }
241   int compare(size_type __pos1, size_type __n1, const _Self& __s) const
242   { return _M_get_storage().compare(__pos1, __n1, __s); }
243   int compare(size_type __pos1, size_type __n1, const _Self& __s, size_type __pos2, size_type __n2) const
244   { return _M_get_storage().compare(__pos1, __n1, __s, __pos2, __n2); }
245   int compare(const _CharT* __s) const
246   { return _M_get_storage().compare(__s); }
247   int compare(size_type __pos1, size_type __n1, const _CharT* __s) const
248   { return _M_get_storage().compare(__pos1, __n1, __s); }
249   int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const
250   { return _M_get_storage().compare(__pos1, __n1, __s, __n2); }
251
252   //Returns the underlying basic_string representation of the template expression
253   //The non const method will always initialise it.
254   _BString& _M_get_storage()
255   { return _rhs._M_get_storage(*this, _StorageDirection()); }
256
257   template <class _Lhs, class _Rhs, class _StorageDir>
258   _BString& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Lhs, _Rhs, _StorageDir>  const& __ref,
259                            __on_left const& /*StorageDir*/)
260   { return _lhs._M_get_storage(__ref); }
261
262   template <class _Lhs, class _Rhs, class _StorageDir>
263   _BString& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Lhs, _Rhs, _StorageDir>  const& __ref,
264                            __on_right const& /*StorageDir*/)
265   { return _rhs._M_get_storage(__ref); }
266
267   template <class _Lhs, class _Rhs, class _StorageDir>
268   _BString& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Lhs, _Rhs, _StorageDir>  const& __ref)
269   { return _M_get_storage(__ref, _StorageDirection()); }
270
271   //The const method can be invoked without initialising the basic_string so avoiding dynamic allocation.
272   _BString const& _M_get_storage(bool __do_init = true) const
273   { return _M_get_storage(*this, __do_init, _StorageDirection()); }
274
275   template <class _Lhs, class _Rhs, class _StorageDir>
276   _BString const& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Lhs, _Rhs, _StorageDir>  const& __ref,
277                                  bool __do_init, __on_left const& /*StorageDir*/) const
278   { return _lhs._M_get_storage(__ref, __do_init); }
279
280   template <class _Lhs, class _Rhs, class _StorageDir>
281   _BString const& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Lhs, _Rhs, _StorageDir>  const& __ref,
282                                  bool __do_init, __on_right const& /*StorageDir*/) const
283   { return _rhs._M_get_storage(__ref, __do_init); }
284
285   template <class _Lhs, class _Rhs, class _StorageDir>
286   _BString const& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Lhs, _Rhs, _StorageDir>  const& __ref,
287                                  bool __do_init) const
288   { return _M_get_storage(__ref, __do_init, _StorageDirection()); }
289
290 private:
291   _Left  _lhs;
292   _Right _rhs;
293 };
294
295 /*
296  * For this operator we choose to use the right part as the storage part
297  */
298 template <class _CharT, class _Traits, class _Alloc,
299           class _Lh1, class _Rh1, class _StoreDir1,
300           class _Lh2, class _Rh2, class _StoreDir2>
301 inline __bstr_sum<_CharT, _Traits, _Alloc,
302                   __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1>,
303                   __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2>,
304                   __on_right> _STLP_CALL
305 operator + (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
306             const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs) {
307   return __bstr_sum<_CharT, _Traits, _Alloc,
308                     __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1>,
309                     __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2>,
310                     __on_right>(__lhs, __rhs);
311 }
312
313 template <class _CharT, class _Traits, class _Alloc,
314           class _Lh1, class _Rh1, class _StoreDir1,
315           class _Lh2, class _Rh2, class _StoreDir2>
316 inline bool _STLP_CALL
317 operator == (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
318              const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs)
319 { return (__lhs.size() == __rhs.size()) && (__lhs._M_get_storage() == __rhs._M_get_storage()); }
320
321 template <class _CharT, class _Traits, class _Alloc,
322           class _Lh1, class _Rh1, class _StoreDir1,
323           class _Lh2, class _Rh2, class _StoreDir2>
324 inline bool _STLP_CALL
325 operator < (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
326             const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs)
327 { return __lhs._M_get_storage() < __rhs._M_get_storage(); }
328
329 #ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
330
331 template <class _CharT, class _Traits, class _Alloc,
332           class _Lh1, class _Rh1, class _StoreDir1,
333           class _Lh2, class _Rh2, class _StoreDir2>
334 inline bool _STLP_CALL
335 operator != (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
336              const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs)
337 { return !(__lhs == __rhs); }
338
339 template <class _CharT, class _Traits, class _Alloc,
340           class _Lh1, class _Rh1, class _StoreDir1,
341           class _Lh2, class _Rh2, class _StoreDir2>
342 inline bool _STLP_CALL
343 operator > (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
344             const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs)
345 { return __rhs < __lhs; }
346
347 template <class _CharT, class _Traits, class _Alloc,
348           class _Lh1, class _Rh1, class _StoreDir1,
349           class _Lh2, class _Rh2, class _StoreDir2>
350 inline bool _STLP_CALL
351 operator <= (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
352              const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs)
353 { return !(__rhs < __lhs); }
354
355 template <class _CharT, class _Traits, class _Alloc,
356           class _Lh1, class _Rh1, class _StoreDir1,
357           class _Lh2, class _Rh2, class _StoreDir2>
358 inline bool _STLP_CALL
359 operator >= (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
360              const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs)
361 { return !(__lhs < __rhs); }
362
363 #endif /* _STLP_USE_SEPARATE_RELOPS_NAMESPACE */
364
365
366 /*
367  * This class will be used to simulate a temporary string that is required for
368  * a call to the c_str method on the __bstr_sum class.
369  */
370
371 template <class _CharT, class _Traits, class _Alloc>
372 struct __sum_storage_elem {
373   typedef basic_string<_CharT, _Traits, _Alloc> _BString;
374
375   __sum_storage_elem(_Alloc __alloc) : _M_init(false), _M_storage(__alloc)
376   {}
377
378   template <class _Left, class _Right, class _StorageDir>
379   void _M_Init(__bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDir>  const& __ref) const {
380     if (!_M_init) {
381       _M_storage = __ref;
382       _M_init = true;
383     }
384   }
385
386   template <class _Left, class _Right, class _StorageDir>
387   _BString const& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDir>  const& __ref,
388                                  bool __do_init) const {
389     if (__do_init) {
390       _M_Init(__ref);
391     }
392     return _M_storage;
393   }
394   template <class _Left, class _Right, class _StorageDir>
395   _BString& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDir>  const& __ref) {
396     _M_Init(__ref);
397     return _M_storage;
398   }
399
400   size_t size() const { return 0; }
401   _CharT const& operator[](size_t __n) const
402   { return __STATIC_CAST(_CharT*, 0)[__n]; }
403
404 private:
405   mutable bool _M_init;
406   mutable basic_string<_CharT, _Traits, _Alloc> _M_storage;
407 };
408
409 _STLP_MOVE_TO_STD_NAMESPACE
410
411 _STLP_END_NAMESPACE
412
413 #endif /*_STLP_STRING_SUM_H*/