5 * This material is provided "as is", with absolutely no warranty expressed
6 * or implied. Any use is at your own risk.
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.
16 #ifndef _STLP_STRING_SUM_H
17 #define _STLP_STRING_SUM_H
21 _STLP_MOVE_TO_PRIV_NAMESPACE
23 /*char wrapper to simulate basic_string*/
24 template <class _CharT
>
25 struct __char_wrapper
{
26 typedef const _CharT
& const_reference
;
28 __char_wrapper(_CharT __val
) : _Val(__val
) {}
30 _CharT
getValue() const { return _Val
; }
31 size_t size() const { return 1; }
33 const_reference
operator[] (size_t __n
) const {
34 //To avoid a check on __n we use this strange implementation
42 /*C string wrapper to simulate basic_string*/
43 template <class _CharT
>
44 struct __cstr_wrapper
{
45 typedef const _CharT
& const_reference
;
47 __cstr_wrapper(const _CharT
*__cstr
, size_t __size
) :
48 _CStr(__cstr
), _Size(__size
) {}
50 const _CharT
* c_str() const { return _CStr
; }
52 size_t size() const { return _Size
; }
54 const_reference
operator[] (size_t __n
) const { return _CStr
[__n
]; }
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
;
67 __bstr_wrapper (_BString
const& __s
) :
70 size_t size() const { return _BStr
.size(); }
72 const_reference
operator[] (size_t __n
) const { return _BStr
[__n
]; }
74 _BString
const& b_str() const { return _BStr
; }
77 _BString
const& _BStr
;
83 template <class _CharT
, class _Traits
, class _Alloc
,
84 class _Left
, class _Right
,
85 class _StorageDirection
>
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
;
96 __bstr_sum (_Left
const& lhs
, _Right
const& rhs
) :
97 _lhs(lhs
), _rhs(rhs
) {}
99 _Left
const& getLhs() const { return _lhs
; }
100 _Right
const& getRhs() const { return _rhs
; }
102 allocator_type
get_allocator() const { return _M_get_storage(false).get_allocator(); }
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(); }
109 size_type
size() const { return _lhs
.size() + _rhs
.size(); }
110 size_type
length() const { return size(); }
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; }
116 const_reference
operator[](size_t __n
) const
117 { return (__n
< _lhs
.size())?_lhs
[__n
]:_rhs
[__n
- _lhs
.size()]; }
119 const_reference
at(size_type __n
) const
120 { return _M_get_storage().at(__n
); }
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
); }
126 typedef __bstr_sum
<_CharT
, _Traits
, _Alloc
, _Self
, __cstr_wrapper
<_CharT
>, __on_left
> _CStrOnLeft
;
127 _CStrOnLeft
operator += (const _CharT
* __s
) { return append(__s
); }
129 typedef __bstr_sum
<_CharT
, _Traits
, _Alloc
, _Self
, __char_wrapper
<_CharT
>, __on_left
> _CharOnLeft
;
130 _CharOnLeft
operator += (_CharT __c
) { return _CharOnLeft(*this, __c
); }
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
));
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
);}
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
);}
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
);}
165 _BString
& erase(size_type __pos
= 0, size_type __n
=_BString::npos
) {return _M_get_storage().erase(__pos
, __n
);}
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
);}
179 size_type
copy(_CharT
* __s
, size_type __n
, size_type __pos
= 0) const
180 {return _M_get_storage().copy(__s
, __n
, __pos
);}
182 void swap(_BString
& __s
)
183 {_M_get_storage().swap(__s
);}
185 const _CharT
* c_str() const { return _M_get_storage().c_str(); }
186 const _CharT
* data() const { return _M_get_storage().data(); }
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
); }
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
); }
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
); }
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
); }
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
); }
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
); }
235 _BString
substr(size_type __pos
= 0, size_type __n
= _BString::npos
) const
236 { return _M_get_storage().substr(__pos
, __n
); }
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
); }
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()); }
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
); }
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
); }
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()); }
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()); }
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
); }
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
); }
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()); }
296 * For this operator we choose to use the right part as the storage part
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
);
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()); }
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(); }
329 #ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
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
); }
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
; }
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
); }
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
); }
363 #endif /* _STLP_USE_SEPARATE_RELOPS_NAMESPACE */
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.
371 template <class _CharT
, class _Traits
, class _Alloc
>
372 struct __sum_storage_elem
{
373 typedef __sum_storage_elem
<_CharT
, _Traits
, _Alloc
> _Self
;
374 typedef basic_string
<_CharT
, _Traits
, _Alloc
> _BString
;
376 __sum_storage_elem(_Alloc __alloc
) : _M_init(false), _M_storage(__alloc
)
379 template <class _Left
, class _Right
, class _StorageDir
>
380 void _M_Init(__bstr_sum
<_CharT
, _Traits
, _Alloc
, _Left
, _Right
, _StorageDir
> const& __ref
) const {
382 _STLP_MUTABLE(_Self
, _M_storage
) = __ref
;
383 _STLP_MUTABLE(_Self
, _M_init
) = true;
387 template <class _Left
, class _Right
, class _StorageDir
>
388 _BString
const& _M_get_storage(__bstr_sum
<_CharT
, _Traits
, _Alloc
, _Left
, _Right
, _StorageDir
> const& __ref
,
389 bool __do_init
) const {
395 template <class _Left
, class _Right
, class _StorageDir
>
396 _BString
& _M_get_storage(__bstr_sum
<_CharT
, _Traits
, _Alloc
, _Left
, _Right
, _StorageDir
> const& __ref
) {
401 size_t size() const { return 0; }
402 _CharT
const& operator[](size_t __n
) const
403 { return __STATIC_CAST(_CharT
*, 0)[__n
]; }
406 mutable bool _M_init
;
407 mutable basic_string
<_CharT
, _Traits
, _Alloc
> _M_storage
;
410 _STLP_MOVE_TO_STD_NAMESPACE
414 #endif /*_STLP_STRING_SUM_H*/