Irrlicht Engine: irrString.h Source File

Home | Namespaces | Hierarchy | Alphabetical List | Class list | Files | Namespace Members | Class members | File members | Tutorials

# irrString.h

Go to the documentation of this file.

    00001 // Copyright (C) 2002-2010 Nikolaus Gebhardt
    00002 // This file is part of the "Irrlicht Engine" and the "irrXML" project.
    00003 // For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
    00004
    00005 #ifndef __IRR_STRING_H_INCLUDED__
    00006 #define __IRR_STRING_H_INCLUDED__
    00007
    00008 #include "irrTypes.h"
    00009 #include "irrAllocator.h"
    00010 #include "irrMath.h"
    00011 #include <stdio.h>
    00012 #include <string.h>
    00013 #include <stdlib.h>
    00014
    00015 namespace irr
    00016 {
    00017 namespace core
    00018 {
    00019
    00021
    00032 enum eLocaleID
    00033 {
    00034         IRR_LOCALE_ANSI = 0,
    00035         IRR_LOCALE_GERMAN = 1
    00036 };
    00037
    00038 static eLocaleID locale_current = IRR_LOCALE_ANSI;
    00039 static inline void locale_set ( eLocaleID id )
    00040 {
    00041         locale_current = id;
    00042 }
    00043
    00045 static inline u32 locale_lower ( u32 x )
    00046 {
    00047         switch ( locale_current )
    00048         {
    00049                 case IRR_LOCALE_GERMAN:
    00050                 case IRR_LOCALE_ANSI:
    00051                         break;
    00052         }
    00053         // ansi
    00054         return x >= 'A' && x <= 'Z' ? x + 0x20 : x;
    00055 }
    00056
    00058 static inline u32 locale_upper ( u32 x )
    00059 {
    00060         switch ( locale_current )
    00061         {
    00062                 case IRR_LOCALE_GERMAN:
    00063                 case IRR_LOCALE_ANSI:
    00064                         break;
    00065         }
    00066
    00067         // ansi
    00068         return x >= 'a' && x <= 'z' ? x + ( 'A' - 'a' ) : x;
    00069 }
    00070
    00071
    00072 template <typename T, typename TAlloc = irrAllocator<T> >
    00073 class string
    00074 {
    00075 public:
    00076
    00078         string()
    00079         : array(0), allocated(1), used(1)
    00080         {
    00081                 array = allocator.allocate(1); // new T[1];
    00082                 array[0] = 0x0;
    00083         }
    00084
    00085
    00087         string(const string<T,TAlloc>& other)
    00088         : array(0), allocated(0), used(0)
    00089         {
    00090                 *this = other;
    00091         }
    00092
    00094         template <class B, class A>
    00095         string(const string<B, A>& other)
    00096         : array(0), allocated(0), used(0)
    00097         {
    00098                 *this = other;
    00099         }
    00100
    00101
    00103         explicit string(const double number)
    00104         : array(0), allocated(0), used(0)
    00105         {
    00106                 c8 tmpbuf[255];
    00107                 snprintf(tmpbuf, 255, "%0.6f", number);
    00108                 *this = tmpbuf;
    00109         }
    00110
    00111
    00113         explicit string(int number)
    00114         : array(0), allocated(0), used(0)
    00115         {
    00116                 // store if negative and make positive
    00117
    00118                 bool negative = false;
    00119                 if (number < 0)
    00120                 {
    00121                         number *= -1;
    00122                         negative = true;
    00123                 }
    00124
    00125                 // temporary buffer for 16 numbers
    00126
    00127                 c8 tmpbuf[16]={0};
    00128                 u32 idx = 15;
    00129
    00130                 // special case '0'
    00131
    00132                 if (!number)
    00133                 {
    00134                         tmpbuf[14] = '0';
    00135                         *this = &tmpbuf[14];
    00136                         return;
    00137                 }
    00138
    00139                 // add numbers
    00140
    00141                 while(number && idx)
    00142                 {
    00143                         --idx;
    00144                         tmpbuf[idx] = (c8)('0' + (number % 10));
    00145                         number /= 10;
    00146                 }
    00147
    00148                 // add sign
    00149
    00150                 if (negative)
    00151                 {
    00152                         --idx;
    00153                         tmpbuf[idx] = '-';
    00154                 }
    00155
    00156                 *this = &tmpbuf[idx];
    00157         }
    00158
    00159
    00161         explicit string(unsigned int number)
    00162         : array(0), allocated(0), used(0)
    00163         {
    00164                 // temporary buffer for 16 numbers
    00165
    00166                 c8 tmpbuf[16]={0};
    00167                 u32 idx = 15;
    00168
    00169                 // special case '0'
    00170
    00171                 if (!number)
    00172                 {
    00173                         tmpbuf[14] = '0';
    00174                         *this = &tmpbuf[14];
    00175                         return;
    00176                 }
    00177
    00178                 // add numbers
    00179
    00180                 while(number && idx)
    00181                 {
    00182                         --idx;
    00183                         tmpbuf[idx] = (c8)('0' + (number % 10));
    00184                         number /= 10;
    00185                 }
    00186
    00187                 *this = &tmpbuf[idx];
    00188         }
    00189
    00190
    00192         template <class B>
    00193         string(const B* const c, u32 length)
    00194         : array(0), allocated(0), used(0)
    00195         {
    00196                 if (!c)
    00197                 {
    00198                         // correctly init the string to an empty one
    00199                         *this="";
    00200                         return;
    00201                 }
    00202
    00203                 allocated = used = length+1;
    00204                 array = allocator.allocate(used); // new T[used];
    00205
    00206                 for (u32 l = 0; l<length; ++l)
    00207                         array[l] = (T)c[l];
    00208
    00209                 array[length] = 0;
    00210         }
    00211
    00212
    00214         template <class B>
    00215         string(const B* const c)
    00216         : array(0), allocated(0), used(0)
    00217         {
    00218                 *this = c;
    00219         }
    00220
    00221
    00223         ~string()
    00224         {
    00225                 allocator.deallocate(array); // delete [] array;
    00226         }
    00227
    00228
    00230         string<T,TAlloc>& operator=(const string<T,TAlloc>& other)
    00231         {
    00232                 if (this == &other)
    00233                         return *this;
    00234
    00235                 used = other.size()+1;
    00236                 if (used>allocated)
    00237                 {
    00238                         allocator.deallocate(array); // delete [] array;
    00239                         allocated = used;
    00240                         array = allocator.allocate(used); //new T[used];
    00241                 }
    00242
    00243                 const T* p = other.c_str();
    00244                 for (u32 i=0; i<used; ++i, ++p)
    00245                         array[i] = *p;
    00246
    00247                 return *this;
    00248         }
    00249
    00251         template <class B, class A>
    00252         string<T,TAlloc>& operator=(const string<B,A>& other)
    00253         {
    00254                 *this = other.c_str();
    00255                 return *this;
    00256         }
    00257
    00258
    00260         template <class B>
    00261         string<T,TAlloc>& operator=(const B* const c)
    00262         {
    00263                 if (!c)
    00264                 {
    00265                         if (!array)
    00266                         {
    00267                                 array = allocator.allocate(1); //new T[1];
    00268                                 allocated = 1;
    00269                         }
    00270                         used = 1;
    00271                         array[0] = 0x0;
    00272                         return *this;
    00273                 }
    00274
    00275                 if ((void*)c == (void*)array)
    00276                         return *this;
    00277
    00278                 u32 len = 0;
    00279                 const B* p = c;
    00280                 do
    00281                 {
    00282                         ++len;
    00283                 } while(*p++);
    00284
    00285                 // we'll keep the old string for a while, because the new
    00286                 // string could be a part of the current string.
    00287                 T* oldArray = array;
    00288
    00289                 used = len;
    00290                 if (used>allocated)
    00291                 {
    00292                         allocated = used;
    00293                         array = allocator.allocate(used); //new T[used];
    00294                 }
    00295
    00296                 for (u32 l = 0; l<len; ++l)
    00297                         array[l] = (T)c[l];
    00298
    00299                 if (oldArray != array)
    00300                         allocator.deallocate(oldArray); // delete [] oldArray;
    00301
    00302                 return *this;
    00303         }
    00304
    00305
    00307         string<T,TAlloc> operator+(const string<T,TAlloc>& other) const
    00308         {
    00309                 string<T,TAlloc> str(*this);
    00310                 str.append(other);
    00311
    00312                 return str;
    00313         }
    00314
    00315
    00317         template <class B>
    00318         string<T,TAlloc> operator+(const B* const c) const
    00319         {
    00320                 string<T,TAlloc> str(*this);
    00321                 str.append(c);
    00322
    00323                 return str;
    00324         }
    00325
    00326
    00328         T& operator [](const u32 index)
    00329         {
    00330                 _IRR_DEBUG_BREAK_IF(index>=used) // bad index
    00331                 return array[index];
    00332         }
    00333
    00334
    00336         const T& operator [](const u32 index) const
    00337         {
    00338                 _IRR_DEBUG_BREAK_IF(index>=used) // bad index
    00339                 return array[index];
    00340         }
    00341
    00342
    00344         bool operator ==(const T* const str) const
    00345         {
    00346                 if (!str)
    00347                         return false;
    00348
    00349                 u32 i;
    00350                 for(i=0; array[i] && str[i]; ++i)
    00351                         if (array[i] != str[i])
    00352                                 return false;
    00353
    00354                 return !array[i] && !str[i];
    00355         }
    00356
    00357
    00359         bool operator ==(const string<T,TAlloc>& other) const
    00360         {
    00361                 for(u32 i=0; array[i] && other.array[i]; ++i)
    00362                         if (array[i] != other.array[i])
    00363                                 return false;
    00364
    00365                 return used == other.used;
    00366         }
    00367
    00368
    00370         bool operator <(const string<T,TAlloc>& other) const
    00371         {
    00372                 for(u32 i=0; array[i] && other.array[i]; ++i)
    00373                 {
    00374                         s32 diff = array[i] - other.array[i];
    00375                         if ( diff )
    00376                                 return diff < 0;
    00377                 }
    00378
    00379                 return used < other.used;
    00380         }
    00381
    00382
    00384         bool operator !=(const T* const str) const
    00385         {
    00386                 return !(*this == str);
    00387         }
    00388
    00389
    00391         bool operator !=(const string<T,TAlloc>& other) const
    00392         {
    00393                 return !(*this == other);
    00394         }
    00395
    00396
    00398
    00400         u32 size() const
    00401         {
    00402                 return used-1;
    00403         }
    00404
    00405
    00407
    00408         const T* c_str() const
    00409         {
    00410                 return array;
    00411         }
    00412
    00413
    00415         void make_lower()
    00416         {
    00417                 for (u32 i=0; i<used; ++i)
    00418                         array[i] = locale_lower ( array[i] );
    00419         }
    00420
    00421
    00423         void make_upper()
    00424         {
    00425                 for (u32 i=0; i<used; ++i)
    00426                         array[i] = locale_upper ( array[i] );
    00427         }
    00428
    00429
    00431
    00433         bool equals_ignore_case(const string<T,TAlloc>& other) const
    00434         {
    00435                 for(u32 i=0; array[i] && other[i]; ++i)
    00436                         if (locale_lower( array[i]) != locale_lower(other[i]))
    00437                                 return false;
    00438
    00439                 return used == other.used;
    00440         }
    00441
    00443
    00446         bool equals_substring_ignore_case(const string<T,TAlloc>&other, const s32 sourcePos = 0 ) const
    00447         {
    00448                 if ( (u32) sourcePos > used )
    00449                         return false;
    00450
    00451                 u32 i;
    00452                 for( i=0; array[sourcePos + i] && other[i]; ++i)
    00453                         if (locale_lower( array[sourcePos + i]) != locale_lower(other[i]))
    00454                                 return false;
    00455
    00456                 return array[sourcePos + i] == 0 && other[i] == 0;
    00457         }
    00458
    00459
    00461
    00463         bool lower_ignore_case(const string<T,TAlloc>& other) const
    00464         {
    00465                 for(u32 i=0; array[i] && other.array[i]; ++i)
    00466                 {
    00467                         s32 diff = (s32) locale_lower ( array[i] ) - (s32) locale_lower ( other.array[i] );
    00468                         if ( diff )
    00469                                 return diff < 0;
    00470                 }
    00471
    00472                 return used < other.used;
    00473         }
    00474
    00475
    00477
    00480         bool equalsn(const string<T,TAlloc>& other, u32 n) const
    00481         {
    00482                 u32 i;
    00483                 for(i=0; array[i] && other[i] && i < n; ++i)
    00484                         if (array[i] != other[i])
    00485                                 return false;
    00486
    00487                 // if one (or both) of the strings was smaller then they
    00488                 // are only equal if they have the same length
    00489                 return (i == n) || (used == other.used);
    00490         }
    00491
    00492
    00494
    00497         bool equalsn(const T* const str, u32 n) const
    00498         {
    00499                 if (!str)
    00500                         return false;
    00501                 u32 i;
    00502                 for(i=0; array[i] && str[i] && i < n; ++i)
    00503                         if (array[i] != str[i])
    00504                                 return false;
    00505
    00506                 // if one (or both) of the strings was smaller then they
    00507                 // are only equal if they have the same length
    00508                 return (i == n) || (array[i] == 0 && str[i] == 0);
    00509         }
    00510
    00511
    00513
    00514         void append(T character)
    00515         {
    00516                 if (used + 1 > allocated)
    00517                         reallocate(used + 1);
    00518
    00519                 ++used;
    00520
    00521                 array[used-2] = character;
    00522                 array[used-1] = 0;
    00523         }
    00524
    00525
    00527
    00528         void append(const T* const other)
    00529         {
    00530                 if (!other)
    00531                         return;
    00532
    00533                 u32 len = 0;
    00534                 const T* p = other;
    00535                 while(*p)
    00536                 {
    00537                         ++len;
    00538                         ++p;
    00539                 }
    00540
    00541                 if (used + len > allocated)
    00542                         reallocate(used + len);
    00543
    00544                 --used;
    00545                 ++len;
    00546
    00547                 for (u32 l=0; l<len; ++l)
    00548                         array[l+used] = *(other+l);
    00549
    00550                 used += len;
    00551         }
    00552
    00553
    00555
    00556         void append(const string<T,TAlloc>& other)
    00557         {
    00558                 --used;
    00559                 u32 len = other.size()+1;
    00560
    00561                 if (used + len > allocated)
    00562                         reallocate(used + len);
    00563
    00564                 for (u32 l=0; l<len; ++l)
    00565                         array[used+l] = other[l];
    00566
    00567                 used += len;
    00568         }
    00569
    00570
    00572
    00574         void append(const string<T,TAlloc>& other, u32 length)
    00575         {
    00576                 if (other.size() < length)
    00577                 {
    00578                         append(other);
    00579                         return;
    00580                 }
    00581
    00582                 if (used + length > allocated)
    00583                         reallocate(used + length);
    00584
    00585                 --used;
    00586
    00587                 for (u32 l=0; l<length; ++l)
    00588                         array[l+used] = other[l];
    00589                 used += length;
    00590
    00591                 // ensure proper termination
    00592                 array[used]=0;
    00593                 ++used;
    00594         }
    00595
    00596
    00598
    00599         void reserve(u32 count)
    00600         {
    00601                 if (count < allocated)
    00602                         return;
    00603
    00604                 reallocate(count);
    00605         }
    00606
    00607
    00609
    00612         s32 findFirst(T c) const
    00613         {
    00614                 for (u32 i=0; i<used; ++i)
    00615                         if (array[i] == c)
    00616                                 return i;
    00617
    00618                 return -1;
    00619         }
    00620
    00622
    00628         s32 findFirstChar(const T* const c, u32 count) const
    00629         {
    00630                 if (!c)
    00631                         return -1;
    00632
    00633                 for (u32 i=0; i<used; ++i)
    00634                         for (u32 j=0; j<count; ++j)
    00635                                 if (array[i] == c[j])
    00636                                         return i;
    00637
    00638                 return -1;
    00639         }
    00640
    00641
    00643
    00649         template <class B>
    00650         s32 findFirstCharNotInList(const B* const c, u32 count) const
    00651         {
    00652                 for (u32 i=0; i<used-1; ++i)
    00653                 {
    00654                         u32 j;
    00655                         for (j=0; j<count; ++j)
    00656                                 if (array[i] == c[j])
    00657                                         break;
    00658
    00659                         if (j==count)
    00660                                 return i;
    00661                 }
    00662
    00663                 return -1;
    00664         }
    00665
    00667
    00673         template <class B>
    00674         s32 findLastCharNotInList(const B* const c, u32 count) const
    00675         {
    00676                 for (s32 i=(s32)(used-2); i>=0; --i)
    00677                 {
    00678                         u32 j;
    00679                         for (j=0; j<count; ++j)
    00680                                 if (array[i] == c[j])
    00681                                         break;
    00682
    00683                         if (j==count)
    00684                                 return i;
    00685                 }
    00686
    00687                 return -1;
    00688         }
    00689
    00691
    00695         s32 findNext(T c, u32 startPos) const
    00696         {
    00697                 for (u32 i=startPos; i<used; ++i)
    00698                         if (array[i] == c)
    00699                                 return i;
    00700
    00701                 return -1;
    00702         }
    00703
    00704
    00706
    00710         s32 findLast(T c, s32 start = -1) const
    00711         {
    00712                 start = core::clamp ( start < 0 ? (s32)(used) - 1 : start, 0, (s32)(used) - 1 );
    00713                 for (s32 i=start; i>=0; --i)
    00714                         if (array[i] == c)
    00715                                 return i;
    00716
    00717                 return -1;
    00718         }
    00719
    00721
    00727         s32 findLastChar(const T* const c, u32 count) const
    00728         {
    00729                 if (!c)
    00730                         return -1;
    00731
    00732                 for (s32 i=used-1; i>=0; --i)
    00733                         for (u32 j=0; j<count; ++j)
    00734                                 if (array[i] == c[j])
    00735                                         return i;
    00736
    00737                 return -1;
    00738         }
    00739
    00740
    00742
    00746         template <class B>
    00747         s32 find(const B* const str, const u32 start = 0) const
    00748         {
    00749                 if (str && *str)
    00750                 {
    00751                         u32 len = 0;
    00752
    00753                         while (str[len])
    00754                                 ++len;
    00755
    00756                         if (len > used-1)
    00757                                 return -1;
    00758
    00759                         for (u32 i=start; i<used-len; ++i)
    00760                         {
    00761                                 u32 j=0;
    00762
    00763                                 while(str[j] && array[i+j] == str[j])
    00764                                         ++j;
    00765
    00766                                 if (!str[j])
    00767                                         return i;
    00768                         }
    00769                 }
    00770
    00771                 return -1;
    00772         }
    00773
    00774
    00776
    00778         string<T,TAlloc> subString(u32 begin, s32 length) const
    00779         {
    00780                 // if start after string
    00781                 // or no proper substring length
    00782                 if ((length <= 0) || (begin>=size()))
    00783                         return string<T,TAlloc>("");
    00784                 // clamp length to maximal value
    00785                 if ((length+begin) > size())
    00786                         length = size()-begin;
    00787
    00788                 string<T,TAlloc> o;
    00789                 o.reserve(length+1);
    00790
    00791                 for (s32 i=0; i<length; ++i)
    00792                         o.array[i] = array[i+begin];
    00793
    00794                 o.array[length] = 0;
    00795                 o.used = o.allocated;
    00796
    00797                 return o;
    00798         }
    00799
    00800
    00802
    00803         string<T,TAlloc>& operator += (T c)
    00804         {
    00805                 append(c);
    00806                 return *this;
    00807         }
    00808
    00809
    00811
    00812         string<T,TAlloc>& operator += (const T* const c)
    00813         {
    00814                 append(c);
    00815                 return *this;
    00816         }
    00817
    00818
    00820
    00821         string<T,TAlloc>& operator += (const string<T,TAlloc>& other)
    00822         {
    00823                 append(other);
    00824                 return *this;
    00825         }
    00826
    00827
    00829
    00830         string<T,TAlloc>& operator += (const int i)
    00831         {
    00832                 append(string<T,TAlloc>(i));
    00833                 return *this;
    00834         }
    00835
    00836
    00838
    00839         string<T,TAlloc>& operator += (const unsigned int i)
    00840         {
    00841                 append(string<T,TAlloc>(i));
    00842                 return *this;
    00843         }
    00844
    00845
    00847
    00848         string<T,TAlloc>& operator += (const long i)
    00849         {
    00850                 append(string<T,TAlloc>(i));
    00851                 return *this;
    00852         }
    00853
    00854
    00856
    00857         string<T,TAlloc>& operator += (const unsigned long& i)
    00858         {
    00859                 append(string<T,TAlloc>(i));
    00860                 return *this;
    00861         }
    00862
    00863
    00865
    00866         string<T,TAlloc>& operator += (const double i)
    00867         {
    00868                 append(string<T,TAlloc>(i));
    00869                 return *this;
    00870         }
    00871
    00872
    00874
    00875         string<T,TAlloc>& operator += (const float i)
    00876         {
    00877                 append(string<T,TAlloc>(i));
    00878                 return *this;
    00879         }
    00880
    00881
    00883
    00885         void replace(T toReplace, T replaceWith)
    00886         {
    00887                 for (u32 i=0; i<used; ++i)
    00888                         if (array[i] == toReplace)
    00889                                 array[i] = replaceWith;
    00890         }
    00891
    00892
    00894
    00895         void remove(T c)
    00896         {
    00897                 u32 pos = 0;
    00898                 u32 found = 0;
    00899                 for (u32 i=0; i<used; ++i)
    00900                 {
    00901                         if (array[i] == c)
    00902                         {
    00903                                 ++found;
    00904                                 continue;
    00905                         }
    00906
    00907                         array[pos++] = array[i];
    00908                 }
    00909                 used -= found;
    00910                 array[used-1] = 0;
    00911         }
    00912
    00913
    00915
    00916         void remove(const string<T,TAlloc> toRemove)
    00917         {
    00918                 u32 size = toRemove.size();
    00919                 if ( size == 0 )
    00920                         return;
    00921                 u32 pos = 0;
    00922                 u32 found = 0;
    00923                 for (u32 i=0; i<used; ++i)
    00924                 {
    00925                         u32 j = 0;
    00926                         while (j < size)
    00927                         {
    00928                                 if (array[i + j] != toRemove[j])
    00929                                         break;
    00930                                 ++j;
    00931                         }
    00932                         if (j == size)
    00933                         {
    00934                                 found += size;
    00935                                 i += size - 1;
    00936                                 continue;
    00937                         }
    00938
    00939                         array[pos++] = array[i];
    00940                 }
    00941                 used -= found;
    00942                 array[used-1] = 0;
    00943         }
    00944
    00945
    00947
    00948         void removeChars(const string<T,TAlloc> & characters)
    00949         {
    00950                 u32 pos = 0;
    00951                 u32 found = 0;
    00952                 for (u32 i=0; i<used; ++i)
    00953                 {
    00954                         // Don't use characters.findFirst as it finds the \0,
    00955                         // causing used to become incorrect.
    00956                         bool docontinue = false;
    00957                         for (u32 j=0; j<characters.size(); ++j)
    00958                         {
    00959                                 if (characters[j] == array[i])
    00960                                 {
    00961                                         ++found;
    00962                                         docontinue = true;
    00963                                         break;
    00964                                 }
    00965                         }
    00966                         if (docontinue)
    00967                                 continue;
    00968
    00969                         array[pos++] = array[i];
    00970                 }
    00971                 used -= found;
    00972                 array[used-1] = 0;
    00973         }
    00974
    00975
    00977
    00979         string<T,TAlloc>& trim(const string<T,TAlloc> & whitespace = " \t\n\r")
    00980         {
    00981                 // find start and end of the substring without the specified characters
    00982                 const s32 begin = findFirstCharNotInList(whitespace.c_str(), whitespace.used);
    00983                 if (begin == -1)
    00984                         return (*this="");
    00985
    00986                 const s32 end = findLastCharNotInList(whitespace.c_str(), whitespace.used);
    00987
    00988                 return (*this = subString(begin, (end +1) - begin));
    00989         }
    00990
    00991
    00993
    00996         void erase(u32 index)
    00997         {
    00998                 _IRR_DEBUG_BREAK_IF(index>=used) // access violation
    00999
    01000                 for (u32 i=index+1; i<used; ++i)
    01001                         array[i-1] = array[i];
    01002
    01003                 --used;
    01004         }
    01005
    01007         void validate()
    01008         {
    01009                 // terminate on existing null
    01010                 for (u32 i=0; i<allocated; ++i)
    01011                 {
    01012                         if (array[i] == 0)
    01013                         {
    01014                                 used = i + 1;
    01015                                 return;
    01016                         }
    01017                 }
    01018
    01019                 // terminate
    01020                 if ( allocated > 0 )
    01021                 {
    01022                         used = allocated;
    01023                         array[used-1] = 0;
    01024                 }
    01025                 else
    01026                 {
    01027                         used = 0;
    01028                 }
    01029         }
    01030
    01032         T lastChar() const
    01033         {
    01034                 return used > 1 ? array[used-2] : 0;
    01035         }
    01036
    01038
    01055         template<class container>
    01056         u32 split(container& ret, const T* const c, u32 count=1, bool ignoreEmptyTokens=true, bool keepSeparators=false) const
    01057         {
    01058                 if (!c)
    01059                         return 0;
    01060
    01061                 const u32 oldSize=ret.size();
    01062                 u32 lastpos = 0;
    01063                 bool lastWasSeparator = false;
    01064                 for (u32 i=0; i<used; ++i)
    01065                 {
    01066                         bool foundSeparator = false;
    01067                         for (u32 j=0; j<count; ++j)
    01068                         {
    01069                                 if (array[i] == c[j])
    01070                                 {
    01071                                         if ((!ignoreEmptyTokens || i - lastpos != 0) &&
    01072                                                         !lastWasSeparator)
    01073                                                 ret.push_back(string<T,TAlloc>(&array[lastpos], i - lastpos));
    01074                                         foundSeparator = true;
    01075                                         lastpos = (keepSeparators ? i : i + 1);
    01076                                         break;
    01077                                 }
    01078                         }
    01079                         lastWasSeparator = foundSeparator;
    01080                 }
    01081                 if ((used - 1) > lastpos)
    01082                         ret.push_back(string<T,TAlloc>(&array[lastpos], (used - 1) - lastpos));
    01083                 return ret.size()-oldSize;
    01084         }
    01085
    01086 private:
    01087
    01089         void reallocate(u32 new_size)
    01090         {
    01091                 T* old_array = array;
    01092
    01093                 array = allocator.allocate(new_size); //new T[new_size];
    01094                 allocated = new_size;
    01095
    01096                 u32 amount = used < new_size ? used : new_size;
    01097                 for (u32 i=0; i<amount; ++i)
    01098                         array[i] = old_array[i];
    01099
    01100                 if (allocated < used)
    01101                         used = allocated;
    01102
    01103                 allocator.deallocate(old_array); // delete [] old_array;
    01104         }
    01105
    01106         //--- member variables
    01107
    01108         T* array;
    01109         u32 allocated;
    01110         u32 used;
    01111         TAlloc allocator;
    01112 };
    01113
    01114
    01116 typedef string<c8> stringc;
    01117
    01119 typedef string<wchar_t> stringw;
    01120
    01121
    01122 } // end namespace core
    01123 } // end namespace irr
    01124
    01125 #endif
    01126

| The Irrlicht Engine Documentation © 2003-2010 by Nikolaus Gebhardt. Generated on Sun Oct 24 12:41:57 2010 by Doxygen (1.6.2)