/home/ntakagi/work/STLport-5.1.5/stlport/stl/_string_sum.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2003
00003  * Francois Dumont
00004  *
00005  * This material is provided "as is", with absolutely no warranty expressed
00006  * or implied. Any use is at your own risk.
00007  *
00008  * Permission to use or copy this software for any purpose is hereby granted
00009  * without fee, provided the above notices are retained on all copies.
00010  * Permission to modify the code and to distribute modified code is granted,
00011  * provided the above notices are retained, and a notice that the code was
00012  * modified is included with the above copyright notice.
00013  *
00014  */
00015 
00016 #ifndef _STLP_STRING_SUM_H
00017 #define _STLP_STRING_SUM_H
00018 
00019 _STLP_BEGIN_NAMESPACE
00020 
00021 _STLP_MOVE_TO_PRIV_NAMESPACE
00022 
00023 /*char wrapper to simulate basic_string*/
00024 template <class _CharT>
00025 struct __char_wrapper {
00026   typedef const _CharT& const_reference;
00027 
00028   __char_wrapper(_CharT __val) : _Val(__val) {}
00029 
00030   _CharT getValue() const { return _Val; }
00031   size_t size() const { return 1; }
00032 
00033   const_reference operator[] (size_t __n) const {
00034     //To avoid a check on __n we use this strange implementation
00035     return (&_Val)[__n];
00036   }
00037 
00038 private:
00039   _CharT _Val;
00040 };
00041 
00042 /*C string wrapper to simulate basic_string*/
00043 template <class _CharT>
00044 struct __cstr_wrapper {
00045   typedef const _CharT& const_reference;
00046 
00047   __cstr_wrapper(const _CharT *__cstr, size_t __size) :
00048     _CStr(__cstr), _Size(__size) {}
00049 
00050   const _CharT* c_str() const { return _CStr; }
00051 
00052   size_t size() const { return _Size; }
00053 
00054   const_reference operator[] (size_t __n) const { return _CStr[__n]; }
00055 
00056 private:
00057   const _CharT *_CStr;
00058   size_t _Size;
00059 };
00060 
00061 /*basic_string wrapper to ensure that we only store a reference to the original string and not copy it*/
00062 template <class _CharT, class _Traits, class _Alloc>
00063 struct __bstr_wrapper {
00064   typedef const _CharT& const_reference;
00065   typedef basic_string<_CharT, _Traits, _Alloc> _BString;
00066 
00067   __bstr_wrapper (_BString const& __s) :
00068     _BStr(__s) {}
00069 
00070   size_t size() const { return _BStr.size(); }
00071 
00072   const_reference operator[] (size_t __n) const { return _BStr[__n]; }
00073 
00074   _BString const& b_str() const { return _BStr; }
00075 
00076 private:
00077   _BString const& _BStr;
00078 };
00079 
00080 struct __on_left {};
00081 struct __on_right {};
00082 
00083 template <class _CharT, class _Traits, class _Alloc,
00084           class _Left, class _Right,
00085           class _StorageDirection>
00086 class __bstr_sum {
00087 public:
00088   typedef basic_string<_CharT, _Traits, _Alloc> _BString;
00089   typedef typename _BString::const_reference const_reference;
00090   typedef typename _BString::const_iterator const_iterator;
00091   typedef typename _BString::const_reverse_iterator const_reverse_iterator;
00092   typedef typename _BString::size_type size_type;
00093   typedef typename _BString::allocator_type allocator_type;
00094   typedef __bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDirection> _Self;
00095 
00096   __bstr_sum (_Left const& lhs, _Right const& rhs) :
00097     _lhs(lhs), _rhs(rhs) {}
00098 
00099   _Left const& getLhs() const { return _lhs; }
00100   _Right const& getRhs() const { return _rhs; }
00101 
00102   allocator_type get_allocator() const { return _M_get_storage(false).get_allocator(); }
00103 
00104   const_iterator begin() const { return _M_get_storage().begin(); }
00105   const_iterator end()   const { return _M_get_storage().end(); }
00106   const_reverse_iterator rbegin() const { return _M_get_storage().rbegin(); }
00107   const_reverse_iterator rend()   const { return _M_get_storage().rend(); }
00108 
00109   size_type size() const { return _lhs.size() + _rhs.size(); }
00110   size_type length() const { return size(); }
00111 
00112   size_t max_size() const { return _M_get_storage().max_size(); }
00113   size_type capacity() const { return size(); }
00114   bool empty() const { return size() == 0; }
00115 
00116   const_reference operator[](size_t __n) const
00117   { return (__n < _lhs.size())?_lhs[__n]:_rhs[__n - _lhs.size()]; }
00118 
00119   const_reference at(size_type __n) const
00120   { return _M_get_storage().at(__n); }
00121 
00122   //operator +=
00123   typedef __bstr_sum<_CharT, _Traits, _Alloc, _Self, __bstr_wrapper<_CharT, _Traits, _Alloc>, __on_left> _BStrOnLeft;
00124   _BStrOnLeft operator += (const _BString& __s) { return append(__s); }
00125 
00126   typedef __bstr_sum<_CharT, _Traits, _Alloc, _Self, __cstr_wrapper<_CharT>, __on_left> _CStrOnLeft;
00127   _CStrOnLeft operator += (const _CharT* __s) { return append(__s); }
00128 
00129   typedef __bstr_sum<_CharT, _Traits, _Alloc, _Self, __char_wrapper<_CharT>, __on_left> _CharOnLeft;
00130   _CharOnLeft operator += (_CharT __c) { return _CharOnLeft(*this, __c); }
00131 
00132   //append
00133   _BStrOnLeft append (const _BString& __s)
00134   { return _BStrOnLeft(*this, __s); }
00135   _BString& append(const _BString& __s, size_type __pos, size_type __n)
00136   { return _M_get_storage().append(__s, __pos, __n); }
00137   _CStrOnLeft append(const _CharT* __s) {
00138     const size_type __n = _Traits::length(__s);
00139     return _CStrOnLeft(*this, __cstr_wrapper<_CharT>(__s, __n));
00140   }
00141   _CStrOnLeft append(const _CharT* __s, size_type __n)
00142   { return _CStrOnLeft(*this, __cstr_wrapper<_CharT>(__s, __n)); }
00143   _BString& append(size_type __n, _CharT __c)
00144   {return _M_get_storage().append(__n, __c);}
00145   template <class _InputIter>
00146   _BString& append(_InputIter __first, _InputIter __last)
00147   {return _M_get_storage().append(__first, __last);}
00148 
00149   //assign
00150   _BString& assign(const _BString& __s) {return _M_get_storage().assign(__s);}
00151   _BString& assign(const _BString& __s, size_type __pos, size_type __n) {return _M_get_storage().assign(__s, __pos, __n);}
00152   _BString& assign(const _CharT* __s, size_type __n) {return _M_get_storage().assign(__s, __n);}
00153   _BString& assign(const _CharT* __s) {return _M_get_storage().assign(__s); }
00154   _BString& assign(size_type __n, _CharT __c) {return _M_get_storage().assign(__n, __c);}
00155 
00156   //insert
00157   _BString& insert(size_type __pos, const _BString& __s) {return _M_get_storage().insert(__pos, __s);}
00158   _BString& insert(size_type __pos, const _BString& __s, size_type __beg, size_type __n)
00159   {return _M_get_storage().insert(__pos, __s, __beg, __n);}
00160   _BString& insert(size_type __pos, const _CharT* __s, size_type __n) {return _M_get_storage().insert(__pos, __s, __n);}
00161   _BString& insert(size_type __pos, const _CharT* __s) {return _M_get_storage().insert(__pos, __s);}
00162   _BString& insert(size_type __pos, size_type __n, _CharT __c) {return _M_get_storage().insert(__pos, __n, __c);}
00163 
00164   //erase
00165   _BString& erase(size_type __pos = 0, size_type __n =_BString::npos) {return _M_get_storage().erase(__pos, __n);}
00166 
00167   //replace
00168   _BString& replace(size_type __pos, size_type __n, const _BString& __s)
00169   {return _M_get_storage().replace(__pos, __n, __s);}
00170   _BString& replace(size_type __pos1, size_type __n1, const _BString& __s, size_type __pos2, size_type __n2)
00171   {return _M_get_storage().replace(__pos1, __n1, __s, __pos2, __n2);}
00172   _BString& replace(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2)
00173   {return _M_get_storage().replace(__pos, __n1, __s, __n2);}
00174   _BString& replace(size_type __pos, size_type __n1, const _CharT* __s)
00175   {return _M_get_storage().replace(__pos, __n1, __s);}
00176   _BString& replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
00177   {return _M_get_storage().replace(__pos, __n1, __n2, __c);}
00178 
00179   size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const
00180   {return _M_get_storage().copy(__s, __n, __pos);}
00181 
00182   void swap(_BString& __s)
00183   {_M_get_storage().swap(__s);}
00184 
00185   const _CharT* c_str() const { return _M_get_storage().c_str(); }
00186   const _CharT* data()  const { return _M_get_storage().data(); }
00187 
00188   //find family
00189   size_type find(const _BString& __s, size_type __pos = 0) const { return _M_get_storage().find(__s, __pos); }
00190   size_type find(const _CharT* __s, size_type __pos = 0) const { return _M_get_storage().find(__s, __pos); }
00191   size_type find(const _CharT* __s, size_type __pos, size_type __n) const { return _M_get_storage().find(__s, __pos, __n); }
00192   size_type find(_CharT __c, size_type __pos = 0) const { return _M_get_storage().find(__c, __pos); }
00193 
00194   size_type rfind(const _BString& __s, size_type __pos = _BString::npos) const { return _M_get_storage().rfind(__s, __pos); }
00195   size_type rfind(const _CharT* __s, size_type __pos = _BString::npos) const { return _M_get_storage().rfind(__s, __pos); }
00196   size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const { return _M_get_storage().rfind(__s, __pos, __n); }
00197   size_type rfind(_CharT __c, size_type __pos = _BString::npos) const { return _M_get_storage().rfind(__c, __pos); }
00198 
00199   size_type find_first_of(const _BString& __s, size_type __pos = 0) const
00200   { return _M_get_storage().find_first_of(__s, __pos); }
00201   size_type find_first_of(const _CharT* __s, size_type __pos = 0) const
00202   { return _M_get_storage().find_first_of(__s, __pos); }
00203   size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
00204   { return _M_get_storage().find_first_of(__s, __pos, __n); }
00205   size_type find_first_of(_CharT __c, size_type __pos = 0) const
00206   { return _M_get_storage().find(__c, __pos); }
00207 
00208   size_type find_last_of(const _BString& __s, size_type __pos = _BString::npos) const
00209   { return _M_get_storage().find_last_of(__s, __pos); }
00210   size_type find_last_of(const _CharT* __s, size_type __pos = _BString::npos) const
00211   { return _M_get_storage().find_last_of(__s, __pos); }
00212   size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
00213   { return _M_get_storage().find_last_of(__s, __pos, __n); }
00214   size_type find_last_of(_CharT __c, size_type __pos = _BString::npos) const
00215   { return _M_get_storage().rfind(__c, __pos); }
00216 
00217   size_type find_first_not_of(const _BString& __s, size_type __pos = 0) const
00218   { return _M_get_storage().find_first_not_of(__s, __pos); }
00219   size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const
00220   { return _M_get_storage().find_first_not_of(__s, __pos); }
00221   size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
00222   { return _M_get_storage().find_first_not_of(__s, __pos, __n); }
00223   size_type find_first_not_of(_CharT __c, size_type __pos = 0) const
00224   { return _M_get_storage().find_first_not_of(__c, __pos); }
00225 
00226   size_type find_last_not_of(const _BString& __s, size_type __pos = _BString::npos) const
00227   { return _M_get_storage().find_last_not_of(__s, __pos); }
00228   size_type find_last_not_of(const _CharT* __s, size_type __pos =_BString:: npos) const
00229   { return _M_get_storage().find_last_not_of(__s, __pos); }
00230   size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
00231   { return _M_get_storage().find_last_not_of(__s, __pos, __n); }
00232   size_type find_last_not_of(_CharT __c, size_type __pos = _BString::npos) const
00233   { return _M_get_storage().find_last_not_of(__c, __pos); }
00234 
00235   _BString substr(size_type __pos = 0, size_type __n = _BString::npos) const
00236   { return _M_get_storage().substr(__pos, __n); }
00237 
00238   //compare
00239   int compare(const _BString& __s) const
00240   { return _M_get_storage().compare(__s); }
00241   int compare(size_type __pos1, size_type __n1, const _Self& __s) const
00242   { return _M_get_storage().compare(__pos1, __n1, __s); }
00243   int compare(size_type __pos1, size_type __n1, const _Self& __s, size_type __pos2, size_type __n2) const
00244   { return _M_get_storage().compare(__pos1, __n1, __s, __pos2, __n2); }
00245   int compare(const _CharT* __s) const
00246   { return _M_get_storage().compare(__s); }
00247   int compare(size_type __pos1, size_type __n1, const _CharT* __s) const
00248   { return _M_get_storage().compare(__pos1, __n1, __s); }
00249   int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const
00250   { return _M_get_storage().compare(__pos1, __n1, __s, __n2); }
00251 
00252   //Returns the underlying basic_string representation of the template expression
00253   //The non const method will always initialise it.
00254   _BString& _M_get_storage()
00255   { return _rhs._M_get_storage(*this, _StorageDirection()); }
00256 
00257   template <class _Lhs, class _Rhs, class _StorageDir>
00258   _BString& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Lhs, _Rhs, _StorageDir>  const& __ref,
00259                            __on_left const& /*StorageDir*/)
00260   { return _lhs._M_get_storage(__ref); }
00261 
00262   template <class _Lhs, class _Rhs, class _StorageDir>
00263   _BString& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Lhs, _Rhs, _StorageDir>  const& __ref,
00264                            __on_right const& /*StorageDir*/)
00265   { return _rhs._M_get_storage(__ref); }
00266 
00267   template <class _Lhs, class _Rhs, class _StorageDir>
00268   _BString& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Lhs, _Rhs, _StorageDir>  const& __ref)
00269   { return _M_get_storage(__ref, _StorageDirection()); }
00270 
00271   //The const method can be invoked without initialising the basic_string so avoiding dynamic allocation.
00272   _BString const& _M_get_storage(bool __do_init = true) const
00273   { return _M_get_storage(*this, __do_init, _StorageDirection()); }
00274 
00275   template <class _Lhs, class _Rhs, class _StorageDir>
00276   _BString const& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Lhs, _Rhs, _StorageDir>  const& __ref,
00277                                  bool __do_init, __on_left const& /*StorageDir*/) const
00278   { return _lhs._M_get_storage(__ref, __do_init); }
00279 
00280   template <class _Lhs, class _Rhs, class _StorageDir>
00281   _BString const& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Lhs, _Rhs, _StorageDir>  const& __ref,
00282                                  bool __do_init, __on_right const& /*StorageDir*/) const
00283   { return _rhs._M_get_storage(__ref, __do_init); }
00284 
00285   template <class _Lhs, class _Rhs, class _StorageDir>
00286   _BString const& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Lhs, _Rhs, _StorageDir>  const& __ref,
00287                                  bool __do_init) const
00288   { return _M_get_storage(__ref, __do_init, _StorageDirection()); }
00289 
00290 private:
00291   _Left  _lhs;
00292   _Right _rhs;
00293 };
00294 
00295 /*
00296  * For this operator we choose to use the right part as the storage part
00297  */
00298 template <class _CharT, class _Traits, class _Alloc,
00299           class _Lh1, class _Rh1, class _StoreDir1,
00300           class _Lh2, class _Rh2, class _StoreDir2>
00301 inline __bstr_sum<_CharT, _Traits, _Alloc,
00302                   __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1>,
00303                   __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2>,
00304                   __on_right> _STLP_CALL
00305 operator + (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
00306             const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs) {
00307   return __bstr_sum<_CharT, _Traits, _Alloc,
00308                     __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1>,
00309                     __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2>,
00310                     __on_right>(__lhs, __rhs);
00311 }
00312 
00313 template <class _CharT, class _Traits, class _Alloc,
00314           class _Lh1, class _Rh1, class _StoreDir1,
00315           class _Lh2, class _Rh2, class _StoreDir2>
00316 inline bool _STLP_CALL
00317 operator == (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
00318              const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs)
00319 { return (__lhs.size() == __rhs.size()) && (__lhs._M_get_storage() == __rhs._M_get_storage()); }
00320 
00321 template <class _CharT, class _Traits, class _Alloc,
00322           class _Lh1, class _Rh1, class _StoreDir1,
00323           class _Lh2, class _Rh2, class _StoreDir2>
00324 inline bool _STLP_CALL
00325 operator < (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
00326             const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs)
00327 { return __lhs._M_get_storage() < __rhs._M_get_storage(); }
00328 
00329 #ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
00330 
00331 template <class _CharT, class _Traits, class _Alloc,
00332           class _Lh1, class _Rh1, class _StoreDir1,
00333           class _Lh2, class _Rh2, class _StoreDir2>
00334 inline bool _STLP_CALL
00335 operator != (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
00336              const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs)
00337 { return !(__lhs == __rhs); }
00338 
00339 template <class _CharT, class _Traits, class _Alloc,
00340           class _Lh1, class _Rh1, class _StoreDir1,
00341           class _Lh2, class _Rh2, class _StoreDir2>
00342 inline bool _STLP_CALL
00343 operator > (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
00344             const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs)
00345 { return __rhs < __lhs; }
00346 
00347 template <class _CharT, class _Traits, class _Alloc,
00348           class _Lh1, class _Rh1, class _StoreDir1,
00349           class _Lh2, class _Rh2, class _StoreDir2>
00350 inline bool _STLP_CALL
00351 operator <= (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
00352              const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs)
00353 { return !(__rhs < __lhs); }
00354 
00355 template <class _CharT, class _Traits, class _Alloc,
00356           class _Lh1, class _Rh1, class _StoreDir1,
00357           class _Lh2, class _Rh2, class _StoreDir2>
00358 inline bool _STLP_CALL
00359 operator >= (const __bstr_sum<_CharT, _Traits, _Alloc, _Lh1, _Rh1, _StoreDir1> &__lhs,
00360              const __bstr_sum<_CharT, _Traits, _Alloc, _Lh2, _Rh2, _StoreDir2> &__rhs)
00361 { return !(__lhs < __rhs); }
00362 
00363 #endif /* _STLP_USE_SEPARATE_RELOPS_NAMESPACE */
00364 
00365 
00366 /*
00367  * This class will be used to simulate a temporary string that is required for
00368  * a call to the c_str method on the __bstr_sum class.
00369  */
00370 
00371 template <class _CharT, class _Traits, class _Alloc>
00372 struct __sum_storage_elem {
00373   typedef basic_string<_CharT, _Traits, _Alloc> _BString;
00374 
00375   __sum_storage_elem(_Alloc __alloc) : _M_init(false), _M_storage(__alloc)
00376   {}
00377 
00378   template <class _Left, class _Right, class _StorageDir>
00379   void _M_Init(__bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDir>  const& __ref) const {
00380     if (!_M_init) {
00381       _M_storage = __ref;
00382       _M_init = true;
00383     }
00384   }
00385 
00386   template <class _Left, class _Right, class _StorageDir>
00387   _BString const& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDir>  const& __ref,
00388                                  bool __do_init) const {
00389     if (__do_init) {
00390       _M_Init(__ref);
00391     }
00392     return _M_storage;
00393   }
00394   template <class _Left, class _Right, class _StorageDir>
00395   _BString& _M_get_storage(__bstr_sum<_CharT, _Traits, _Alloc, _Left, _Right, _StorageDir>  const& __ref) {
00396     _M_Init(__ref);
00397     return _M_storage;
00398   }
00399 
00400   size_t size() const { return 0; }
00401   _CharT const& operator[](size_t __n) const
00402   { return __STATIC_CAST(_CharT*, 0)[__n]; }
00403 
00404 private:
00405   mutable bool _M_init;
00406   mutable basic_string<_CharT, _Traits, _Alloc> _M_storage;
00407 };
00408 
00409 _STLP_MOVE_TO_STD_NAMESPACE
00410 
00411 _STLP_END_NAMESPACE
00412 
00413 #endif /*_STLP_STRING_SUM_H*/



Generated on Mon Mar 10 15:32:41 2008 by  doxygen 1.5.1