PCL
String.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.1.16
6 // ----------------------------------------------------------------------------
7 // pcl/String.h - Released 2019-09-29T12:27:26Z
8 // ----------------------------------------------------------------------------
9 // This file is part of the PixInsight Class Library (PCL).
10 // PCL is a multiplatform C++ framework for development of PixInsight modules.
11 //
12 // Copyright (c) 2003-2019 Pleiades Astrophoto S.L. All Rights Reserved.
13 //
14 // Redistribution and use in both source and binary forms, with or without
15 // modification, is permitted provided that the following conditions are met:
16 //
17 // 1. All redistributions of source code must retain the above copyright
18 // notice, this list of conditions and the following disclaimer.
19 //
20 // 2. All redistributions in binary form must reproduce the above copyright
21 // notice, this list of conditions and the following disclaimer in the
22 // documentation and/or other materials provided with the distribution.
23 //
24 // 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names
25 // of their contributors, may be used to endorse or promote products derived
26 // from this software without specific prior written permission. For written
27 // permission, please contact info@pixinsight.com.
28 //
29 // 4. All products derived from this software, in any form whatsoever, must
30 // reproduce the following acknowledgment in the end-user documentation
31 // and/or other materials provided with the product:
32 //
33 // "This product is based on software from the PixInsight project, developed
34 // by Pleiades Astrophoto and its contributors (http://pixinsight.com/)."
35 //
36 // Alternatively, if that is where third-party acknowledgments normally
37 // appear, this acknowledgment must be reproduced in the product itself.
38 //
39 // THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS
40 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
41 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS
43 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
44 // EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS
45 // INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE,
46 // DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
49 // POSSIBILITY OF SUCH DAMAGE.
50 // ----------------------------------------------------------------------------
51 
52 #ifndef __PCL_String_h
53 #define __PCL_String_h
54 
56 
57 #include <pcl/Defs.h>
58 #include <pcl/Diagnostics.h>
59 
60 #include <pcl/Allocator.h>
61 #include <pcl/Atomic.h>
62 #include <pcl/ByteArray.h>
63 #include <pcl/CharTraits.h>
64 #include <pcl/Container.h>
65 #include <pcl/Flags.h>
66 #include <pcl/Iterator.h>
67 #include <pcl/Math.h>
68 #include <pcl/ReferenceCounter.h>
69 #include <pcl/Sort.h>
70 #include <pcl/StdAlloc.h>
71 #include <pcl/Utility.h>
72 
73 #include <stdarg.h>
74 
75 #ifndef __PCL_NO_STRING_COMPLEX
76 # include <pcl/Complex.h>
77 #endif
78 
79 #ifndef __PCL_NO_STRING_OSTREAM
80 # ifndef _MSC_VER
81 # define _GLIBCXX_USE_WCHAR_T 1
82 # endif
83 # include <ostream>
84 #endif
85 
86 #ifdef __PCL_QT_INTERFACE
87 # include <QtCore/QByteArray>
88 # include <QtCore/QDateTime>
89 # include <QtCore/QString>
90 # define PCL_GET_CHARPTR_FROM_QSTRING( qs ) (qs.toLatin1().data())
91 # define PCL_GET_CHAR16PTR_FROM_QSTRING( qs ) ((char16_type*)( qs.utf16() ))
92 # define PCL_GET_QSTRING_FROM_CHAR16PTR( s ) (QString::fromUtf16( (const ushort*)(s) ))
93 # define PCL_GET_CHARPTR_FROM_QBYTEARRAY( qb ) (qb.data())
94 # define PCL_QDATE_FMT_STR "yyyy/MM/dd"
95 # define PCL_QDATETIME_FMT_STR "yyyy/MM/dd hh:mm:ss"
96 #endif
97 
98 namespace pcl
99 {
100 
101 // ----------------------------------------------------------------------------
102 
119 namespace RandomizationOption
120 {
121  enum mask_type
122  {
123  Lowercase = 0x00000001, // Generate random lowercase alphabetic characters: a..z
124  Uppercase = 0x00000002, // Generate random uppercase alphabetic characters: A..Z
125  Alpha = Lowercase|Uppercase, // Generate random alphabetic characters: a..zA..Z
126  Digits = 0x00000004, // Generate random decimal digits: 0..9
127  Symbols = 0x00000008, // Generate random symbol characters: .#/[]() etc
128  HexDigits = 0x00000010, // Generate hexadecimal digits: 0..9a..f or 0..9A..F
129  BinDigits = 0x00000020, // Generate binary digits: 0 and 1
130  FullRange = 0x80000000, // Generate random characters in the whole range of code points except zero
131  Default = Alpha|Digits
132  };
133 };
134 
140 
141 // ----------------------------------------------------------------------------
142 
157 {
164  unsigned items : 2;
165 
170  unsigned precision : 4;
171 
176  bool sign : 1;
177 
185  unsigned width : 4;
186 
191  char separator;
192 
198  char padding;
199 
203  constexpr SexagesimalConversionOptions( unsigned items_ = 3,
204  unsigned precision_ = 2,
205  bool sign_ = false,
206  unsigned width_ = 0,
207  char separator_ = ':',
208  char padding_ = ' ' ) :
209  items( items_ ),
210  precision( precision_ ),
211  sign( sign_ ),
212  width( width_ ),
213  separator( separator_ ),
214  padding( padding_ )
215  {
216  }
217 
222 
226  SexagesimalConversionOptions& operator =( const SexagesimalConversionOptions& ) = default;
227 };
228 
229 // ----------------------------------------------------------------------------
230 
244 {
252  constexpr AngleConversionOptions( unsigned precision = 2, unsigned width = 3, char padding = ' ' ) :
253  SexagesimalConversionOptions( 3/*items*/, precision, false/*sign*/, width, ' '/*separator*/, padding )
254  {}
255 };
256 
257 // ----------------------------------------------------------------------------
258 
273 {
282  constexpr LongitudeConversionOptions( unsigned precision = 2, unsigned width = 4, char padding = ' ' ) :
283  SexagesimalConversionOptions( 3/*items*/, precision, true/*sign*/, width, ' '/*separator*/, padding )
284  {}
285 };
286 
287 // ----------------------------------------------------------------------------
288 
304 {
312  constexpr RAConversionOptions( unsigned precision = 3, unsigned width = 2, char padding = ' ' ) :
313  SexagesimalConversionOptions( 3/*items*/, precision, false/*sign*/, width, ' '/*separator*/, padding )
314  {}
315 };
316 
317 // ----------------------------------------------------------------------------
318 
333 {
342  constexpr LatitudeConversionOptions( unsigned precision = 2, unsigned width = 3, char padding = ' ' ) :
343  SexagesimalConversionOptions( 3/*items*/, precision, true/*sign*/, width, ' '/*separator*/, padding )
344  {}
345 };
346 
347 // ----------------------------------------------------------------------------
348 
362 {
371  constexpr DecConversionOptions( unsigned precision = 2, unsigned width = 3, char padding = ' ' ) :
372  LatitudeConversionOptions( precision, width, padding )
373  {}
374 };
375 
376 // ----------------------------------------------------------------------------
377 
385 struct PCL_CLASS ISO8601ConversionOptions
386 {
393  unsigned timeItems : 2;
394 
399  unsigned precision : 4;
400 
405  bool timeZone : 1;
406 
411  bool zuluTime : 1;
412 
416  constexpr ISO8601ConversionOptions( unsigned timeItems_ = 3,
417  unsigned precision_ = 3,
418  bool timeZone_ = true,
419  bool zuluTime_ = true ) :
420  timeItems( timeItems_ ),
421  precision( precision_ ),
422  timeZone( timeZone_ ),
423  zuluTime( zuluTime_ )
424  {
425  }
426 
431 
435  ISO8601ConversionOptions& operator =( const ISO8601ConversionOptions& ) = default;
436 };
437 
438 // ----------------------------------------------------------------------------
439 
459 template <class T, class R, class A = StandardAllocator>
460 class PCL_CLASS GenericString : public DirectContainer<T>
461 {
462 public:
463 
467  typedef T char_type;
468 
472  typedef R char_traits;
473 
477  typedef A block_allocator;
478 
483 
487  typedef T* c_string;
488 
492  typedef const T* const_c_string;
493 
497  typedef T* iterator;
498 
502  typedef const T* const_iterator;
503 
509 
515 
516  // -------------------------------------------------------------------------
517 
521  static const size_type notFound = ~size_type( 0 );
522 
526  static const size_type maxPos = ~size_type( 0 );
527 
528  // -------------------------------------------------------------------------
529 
534  {
535  m_data = Data::New();
536  }
537 
541  GenericString( const GenericString& s ) : m_data( s.m_data )
542  {
543  m_data->Attach();
544  }
545 
549  GenericString( GenericString&& s ) : m_data( s.m_data )
550  {
551  s.m_data = nullptr;
552  }
553 
558  GenericString( const_c_string t )
559  {
560  size_type len = R::Length( t );
561  if ( len > 0 )
562  {
563  m_data = Data::New( len );
564  R::Copy( m_data->string, t, len );
565  }
566  else
567  m_data = Data::New();
568  }
569 
587  GenericString( const_iterator i, const_iterator j )
588  {
589  if ( i < j )
590  {
591  size_type len = j - i;
592  m_data = Data::New( len );
593  R::Copy( m_data->string, i, len );
594  }
595  else
596  m_data = Data::New();
597  }
598 
607  GenericString( std::initializer_list<char_type> l ) : GenericString( l.begin(), l.end() )
608  {
609  }
610 
615  GenericString( const_c_string t, size_type i, size_type n )
616  {
617  size_type len = R::Length( t );
618  if ( i < len && (n = pcl::Min( n, len-i )) > 0 )
619  {
620  m_data = Data::New( n );
621  R::Copy( m_data->string, t+i, n );
622  }
623  else
624  m_data = Data::New();
625  }
626 
630  GenericString( char_type c, size_type n = 1 )
631  {
632  if ( n > 0 )
633  {
634  m_data = Data::New( n );
635  R::Fill( m_data->string, c, n );
636  }
637  else
638  m_data = Data::New();
639  }
640 
646  {
647  if ( m_data != nullptr )
648  {
649  DetachFromData();
650  m_data = nullptr;
651  }
652  }
653 
659  bool IsUnique() const
660  {
661  return m_data->IsUnique();
662  }
663 
671  bool IsAliasOf( const GenericString& s ) const
672  {
673  return m_data == s.m_data;
674  }
675 
686  {
687  if ( !IsUnique() )
688  {
689  size_type len = Length();
690  Data* newData = Data::New( len );
691  if ( len > 0 )
692  R::Copy( newData->string, m_data->string, len );
693  DetachFromData();
694  m_data = newData;
695  }
696  }
697 
706  {
707  return R::BytesPerChar();
708  }
709 
716  size_type Size() const
717  {
718  return Length()*BytesPerChar();
719  }
720 
728  {
729  return m_data->end - m_data->string;
730  }
731 
741  {
742  return m_data->capacity - m_data->string;
743  }
744 
753  {
754  return m_data->capacity - m_data->end;
755  }
756 
773  bool IsValid() const
774  {
775  return m_data != nullptr;
776  }
777 
785  bool IsEmpty() const
786  {
787  return m_data->string == m_data->end;
788  }
789 
799  {
800  return 0;
801  }
802 
812  {
813  PCL_PRECONDITION( !IsEmpty() )
814  return Length()-1;
815  }
816 
822  const allocator& GetAllocator() const
823  {
824  return m_data->alloc;
825  }
826 
836  void SetAllocator( const allocator& a )
837  {
838  EnsureUnique();
839  m_data->alloc = a;
840  }
841 
854  iterator At( size_type i )
855  {
856  PCL_PRECONDITION( i < Length() )
857  EnsureUnique();
858  return m_data->string + i;
859  }
860 
870  const_iterator At( size_type i ) const
871  {
872  PCL_PRECONDITION( i < Length() )
873  return m_data->string + i;
874  }
875 
888  char_type& operator []( size_type i )
889  {
890  return *At( i );
891  }
892 
902  char_type operator []( size_type i ) const
903  {
904  return *At( i );
905  }
906 
914  char_type& operator *()
915  {
916  EnsureUnique();
917  return *m_data->string;
918  }
919 
927  char_type operator *() const
928  {
929  return *m_data->string;
930  }
931 
943  iterator Begin()
944  {
945  EnsureUnique();
946  return m_data->string;
947  }
948 
957  const_iterator Begin() const
958  {
959  return m_data->string;
960  }
961 
973  iterator End()
974  {
975  EnsureUnique();
976  return m_data->end;
977  }
978 
987  const_iterator End() const
988  {
989  return m_data->end;
990  }
991 
1006  {
1007  EnsureUnique();
1008  return (m_data->string < m_data->end) ? m_data->end-1 : nullptr;
1009  }
1010 
1022  {
1023  return (m_data->string < m_data->end) ? m_data->end-1 : nullptr;
1024  }
1025 
1040  {
1041  EnsureUnique();
1042  return (m_data->string < m_data->end) ? m_data->string-1 : nullptr;
1043  }
1044 
1056  {
1057  return (m_data->string < m_data->end) ? m_data->string-1 : nullptr;
1058  }
1059 
1070  size_type IndexAt( const_iterator i ) const
1071  {
1072  PCL_PRECONDITION( i >= m_data->string )
1073  return i - m_data->string;
1074  }
1075 
1076 #ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
1077 
1080  iterator begin()
1081  {
1082  return Begin();
1083  }
1084 
1088  const_iterator begin() const
1089  {
1090  return Begin();
1091  }
1092 
1096  iterator end()
1097  {
1098  return End();
1099  }
1100 
1104  const_iterator end() const
1105  {
1106  return End();
1107  }
1108 #endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
1109 
1117  const_c_string c_str() const
1118  {
1119  static const char_type theNullChar = char_traits::Null();
1120  return IsEmpty() ? &theNullChar : Begin();
1121  }
1122 
1128  GenericString& operator =( const GenericString& s )
1129  {
1130  Assign( s );
1131  return *this;
1132  }
1133 
1148  void Assign( const GenericString& s )
1149  {
1150  s.m_data->Attach();
1151  DetachFromData();
1152  m_data = s.m_data;
1153  }
1154 
1160  GenericString& operator =( GenericString&& s )
1161  {
1162  Transfer( s );
1163  return *this;
1164  }
1165 
1180  {
1181  DetachFromData();
1182  m_data = s.m_data;
1183  s.m_data = nullptr;
1184  }
1185 
1192  {
1193  DetachFromData();
1194  m_data = s.m_data;
1195  s.m_data = nullptr;
1196  }
1197 
1202  GenericString& operator =( const_c_string t )
1203  {
1204  Assign( t );
1205  return *this;
1206  }
1207 
1212  GenericString& operator =( char_type c )
1213  {
1214  Assign( c, 1 );
1215  return *this;
1216  }
1217 
1222  void Assign( const GenericString& s, size_type i, size_type n )
1223  {
1224  Transfer( s.Substring( i, n ) );
1225  }
1226 
1234  void Assign( const_c_string t )
1235  {
1236  size_type len = R::Length( t );
1237  if ( len > 0 )
1238  {
1239  MaybeReallocate( len );
1240  R::Copy( m_data->string, t, len );
1241  }
1242  else
1243  Clear();
1244  }
1245 
1266  void Assign( const_iterator i, const_iterator j )
1267  {
1268  if ( i < j )
1269  {
1270  size_type len = j - i;
1271  MaybeReallocate( len );
1272  R::Copy( m_data->string, i, len );
1273  }
1274  else
1275  Clear();
1276  }
1277 
1284  void Assign( std::initializer_list<char_type> l )
1285  {
1286  Assign( l.begin(), l.end() );
1287  }
1288 
1302  void Assign( const_c_string t, size_type i, size_type n )
1303  {
1304  size_type len = R::Length( t );
1305  if ( i < len && (n = pcl::Min( n, len-i )) > 0 )
1306  {
1307  MaybeReallocate( n );
1308  R::Copy( m_data->string, t+i, n );
1309  }
1310  else
1311  Clear();
1312  }
1313 
1319  void Assign( char_type c, size_type n = 1 )
1320  {
1321  if ( !R::IsNull( c ) && n > 0 )
1322  {
1323  MaybeReallocate( n );
1324  R::Fill( m_data->string, c, n );
1325  }
1326  else
1327  Clear();
1328  }
1329 
1333  void Swap( GenericString& s )
1334  {
1335  pcl::Swap( m_data, s.m_data );
1336  }
1337 
1347  void Fill( char_type c )
1348  {
1349  size_type len = Length();
1350  if ( len > 0 )
1351  {
1352  if ( !IsUnique() )
1353  {
1354  Data* newData = Data::New( len );
1355  DetachFromData();
1356  m_data = newData;
1357  }
1358  R::Fill( m_data->string, c, len );
1359  }
1360  }
1361 
1376  void Fill( char_type c, size_type i, size_type n = maxPos )
1377  {
1378  size_type len = Length();
1379  if ( i < len )
1380  {
1381  n = pcl::Min( n, len-i );
1382  if ( n < len )
1383  EnsureUnique();
1384  else if ( !IsUnique() )
1385  {
1386  Data* newData = Data::New( len );
1387  DetachFromData();
1388  m_data = newData;
1389  }
1390  R::Fill( m_data->string+i, c, n );
1391  }
1392  }
1393 
1415  void SecureFill( char c = '\0' )
1416  {
1417  volatile char* s = reinterpret_cast<volatile char*>( m_data->string );
1418  for ( size_type n = Capacity()*sizeof( char_type ); n > 0; --n )
1419  *s++ = c;
1420  }
1421 
1429  void Reserve( size_type n )
1430  {
1431  if ( n > 0 )
1432  if ( IsUnique() )
1433  {
1434  if ( Capacity() < n+1 )
1435  {
1436  iterator old = m_data->string;
1437  size_type len = Length();
1438  m_data->Reserve( len, n );
1439  if ( old != nullptr )
1440  {
1441  if ( len > 0 )
1442  R::Copy( m_data->string, old, len );
1443  m_data->alloc.Deallocate( old );
1444  }
1445  }
1446  }
1447  else
1448  {
1449  size_type len = Length();
1450  Data* newData = Data::New(); // ### FIXME: unlikely, but this is a potential leak
1451  newData->Reserve( len, pcl::Max( len, n ) );
1452  if ( len > 0 )
1453  R::Copy( newData->string, m_data->string, len );
1454  DetachFromData();
1455  m_data = newData;
1456  }
1457  }
1458 
1473  {
1474  if ( n != Length() )
1475  {
1476  if ( n > 0 )
1477  {
1478  if ( !IsUnique() || m_data->ShouldReallocate( n ) )
1479  {
1480  Data* newData = Data::New( n );
1481  size_type m = Capacity();
1482  if ( m > 0 )
1483  R::Copy( newData->string, m_data->string, pcl::Min( n, m ) );
1484  DetachFromData();
1485  m_data = newData;
1486  }
1487  else
1488  m_data->SetLength( n );
1489  }
1490  else
1491  Clear();
1492  }
1493  else
1494  EnsureUnique();
1495  }
1496 
1503  {
1504  // NB: This can be done more efficiently if this string is unique.
1505  GenericString s( *this );
1506  s.SetLength( n );
1507  return s;
1508  }
1509 
1519  {
1520  SetLength( R::Length( m_data->string ) );
1521  }
1522 
1528  {
1529  GenericString s( *this );
1531  return s;
1532  }
1533 
1546  void Squeeze()
1547  {
1548  if ( Available() > 0 )
1549  {
1550  size_type len = Length();
1551  if ( len > 0 )
1552  {
1553  if ( IsUnique() )
1554  {
1555  iterator old = m_data->string;
1556  m_data->Allocate( len, 0 );
1557  R::Copy( m_data->string, old, len );
1558  m_data->alloc.Deallocate( old );
1559  }
1560  else
1561  {
1562  Data* newData = Data::New( len, 0 );
1563  R::Copy( newData->string, m_data->string, len );
1564  DetachFromData();
1565  m_data = newData;
1566  }
1567  }
1568  else
1569  Clear();
1570  }
1571  }
1572 
1578  {
1579  // NB: This can be done more efficiently if this string is unique.
1580  GenericString s( *this );
1581  s.Squeeze();
1582  return s;
1583  }
1584 
1597  c_string Release()
1598  {
1599  EnsureUnique();
1600  iterator string = m_data->string;
1601  m_data->Reset();
1602  return string;
1603  }
1604 
1621  void c_copy( iterator dst, size_type maxCharsToCopy, size_type i = 0 ) const
1622  {
1623  if ( dst != nullptr )
1624  if ( maxCharsToCopy > 0 )
1625  {
1626  if ( --maxCharsToCopy > 0 )
1627  {
1628  size_type len = Length();
1629  if ( i < len )
1630  {
1631  size_type n = pcl::Min( maxCharsToCopy, len-i );
1632  R::Copy( dst, m_data->string+i, n );
1633  dst += n;
1634  }
1635  }
1636 
1637  *dst = R::Null();
1638  }
1639  }
1640 
1644  template <class R1, class A1>
1646  {
1647  size_type n = s.Length();
1648  if ( n > 0 )
1649  {
1650  UninitializedGrow( i, n ); // -> 0 <= i <= len
1651  R::Copy( m_data->string+i, s.m_data->string, n );
1652  }
1653  }
1654 
1662  void Insert( size_type i, const_iterator p, const_iterator q )
1663  {
1664  if ( p < q )
1665  {
1666  size_type n = q - p;
1667  UninitializedGrow( i, n ); // -> 0 <= i <= len
1668  R::Copy( m_data->string+i, p, n );
1669  }
1670  }
1671 
1676  void Insert( size_type i, const_c_string t )
1677  {
1678  size_type n = R::Length( t );
1679  if ( n > 0 )
1680  {
1681  UninitializedGrow( i, n ); // -> 0 <= i <= len
1682  R::Copy( m_data->string+i, t, n );
1683  }
1684  }
1685 
1690  void Insert( size_type i, const_c_string t, size_type n )
1691  {
1692  if ( (n = pcl::Min( n, R::Length( t ) )) > 0 )
1693  {
1694  UninitializedGrow( i, n ); // -> 0 <= i <= len
1695  R::Copy( m_data->string+i, t, n );
1696  }
1697  }
1698 
1702  void Insert( size_type i, char_type c, size_type n = 1 )
1703  {
1704  if ( n > 0 )
1705  {
1706  UninitializedGrow( i, n ); // -> 0 <= i <= len
1707  R::Fill( m_data->string+i, c, n );
1708  }
1709  }
1710 
1714  template <class R1, class A1>
1716  {
1717  Insert( maxPos, s );
1718  }
1719 
1724  template <class R1, class A1>
1725  GenericString& operator +=( const GenericString<T,R1,A1>& s )
1726  {
1727  Append( s );
1728  return *this;
1729  }
1730 
1738  void Append( const_iterator i, const_iterator j )
1739  {
1740  Insert( maxPos, i, j );
1741  }
1742 
1747  void Append( const_c_string t, size_type n )
1748  {
1749  Insert( maxPos, t, n );
1750  }
1751 
1755  void Append( const_c_string t )
1756  {
1757  Insert( maxPos, t );
1758  }
1759 
1764  GenericString& operator +=( const_c_string t )
1765  {
1766  Append( t );
1767  return *this;
1768  }
1769 
1773  void Append( char_type c, size_type n = 1 )
1774  {
1775  Insert( maxPos, c, n );
1776  }
1777 
1782  template <class R1, class A1>
1783  void Add( const GenericString<T,R1,A1>& s )
1784  {
1785  Append( s );
1786  }
1787 
1792  void Add( const_iterator i, const_iterator j )
1793  {
1794  Append( i, j );
1795  }
1796 
1801  void Add( const_c_string t, size_type n )
1802  {
1803  Append( t, n );
1804  }
1805 
1810  void Add( const_c_string t )
1811  {
1812  Append( t );
1813  }
1814 
1819  void Add( char_type c, size_type n = 1 )
1820  {
1821  Append( c, n );
1822  }
1823 
1828  GenericString& operator +=( char_type c )
1829  {
1830  Append( c );
1831  return *this;
1832  }
1833 
1838  template <class R1, class A1>
1840  {
1841  Insert( 0, s );
1842  }
1843 
1848  template <class R1, class A1>
1849  GenericString& operator -=( const GenericString<T,R1,A1>& s )
1850  {
1851  Prepend( s );
1852  return *this;
1853  }
1854 
1862  void Prepend( const_iterator i, const_iterator j )
1863  {
1864  Insert( 0, i, j );
1865  }
1866 
1871  void Prepend( const_c_string t, size_type n )
1872  {
1873  Insert( 0, t, n );
1874  }
1875 
1880  void Prepend( const_c_string t )
1881  {
1882  Insert( 0, t );
1883  }
1884 
1889  GenericString& operator -=( const_c_string t )
1890  {
1891  Prepend( t );
1892  return *this;
1893  }
1894 
1898  void Prepend( char_type c, size_type n = 1 )
1899  {
1900  Insert( 0, c, n );
1901  }
1902 
1907  GenericString& operator -=( char_type c )
1908  {
1909  Prepend( c );
1910  return *this;
1911  }
1912 
1917  template <class R1, class A1>
1919  {
1920  if ( n > 0 )
1921  {
1922  size_type len = Length();
1923  if ( i < len )
1924  {
1925  n = pcl::Min( n, len-i );
1926  if ( n != len )
1927  {
1928  size_type ns = s.Length();
1929  if ( ns > 0 )
1930  {
1931  if ( n < ns )
1932  UninitializedGrow( i, ns-n );
1933  else if ( ns < n )
1934  Delete( i, n-ns );
1935  else
1936  EnsureUnique();
1937 
1938  R::Copy( m_data->string+i, s.m_data->string, ns );
1939  }
1940  else
1941  Delete( i, n );
1942  }
1943  else
1944  Assign( s );
1945  }
1946  }
1947  }
1948 
1957  void Replace( size_type i, size_type n, const_c_string t )
1958  {
1959  if ( n > 0 )
1960  {
1961  size_type len = Length();
1962  if ( i < len )
1963  {
1964  n = pcl::Min( n, len-i );
1965  if ( n != len )
1966  {
1967  size_type nt = R::Length( t );
1968  if ( nt > 0 )
1969  {
1970  if ( n < nt )
1971  UninitializedGrow( i, nt-n );
1972  else if ( nt < n )
1973  Delete( i, n-nt );
1974  else
1975  EnsureUnique();
1976 
1977  R::Copy( m_data->string+i, t, nt );
1978  }
1979  else
1980  Delete( i, n );
1981  }
1982  else
1983  Assign( t );
1984  }
1985  }
1986  }
1987 
1992  void Replace( size_type i, size_type n, char_type c, size_type nc = 1 )
1993  {
1994  if ( n > 0 )
1995  {
1996  size_type len = Length();
1997  if ( i < len )
1998  {
1999  n = pcl::Min( n, len-i );
2000  if ( n != len )
2001  {
2002  if ( nc > 0 )
2003  {
2004  if ( n < nc )
2005  UninitializedGrow( i, nc-n );
2006  else if ( nc < n )
2007  Delete( i, n-nc );
2008  else
2009  EnsureUnique();
2010 
2011  R::Fill( m_data->string+i, c, nc );
2012  }
2013  else
2014  Delete( i, n );
2015  }
2016  else
2017  Assign( c, nc );
2018  }
2019  }
2020  }
2021 
2027  void ReplaceChar( char_type c1, char_type c2, size_type i = 0, size_type n = maxPos )
2028  {
2029  ReplaceChar( c1, c2, i, n, true/*case*/ );
2030  }
2031 
2039  void ReplaceCharIC( char_type c1, char_type c2, size_type i = 0, size_type n = maxPos )
2040  {
2041  ReplaceChar( c1, c2, i, n, false/*case*/ );
2042  }
2043 
2049  template <class R1, class A1, class R2, class A2>
2051  const GenericString<T,R2,A2>& s2, size_type i = 0 )
2052  {
2053  ReplaceString( s1.m_data->string, s1.Length(), s2.m_data->string, s2.Length(), i, true/*case*/ );
2054  }
2055 
2061  void ReplaceString( const_c_string t1, const_c_string t2, size_type i = 0 )
2062  {
2063  ReplaceString( t1, R::Length( t1 ), t2, R::Length( t2 ), i, true/*case*/ );
2064  }
2065 
2073  template <class R1, class A1, class R2, class A2>
2075  const GenericString<T,R2,A2>& s2, size_type i = 0 )
2076  {
2077  ReplaceString( s1.m_data->string, s1.Length(), s2.m_data->string, s2.Length(), i, false/*case*/ );
2078  }
2079 
2087  void ReplaceStringIC( const_c_string t1, const_c_string t2, size_type i = 0 )
2088  {
2089  ReplaceString( t1, R::Length( t1 ), t2, R::Length( t2 ), i, false/*case*/ );
2090  }
2091 
2096  void Delete( size_type i, size_type n = 1 )
2097  {
2098  if ( n > 0 )
2099  {
2100  size_type len = Length();
2101  if ( i < len )
2102  {
2103  n = pcl::Min( n, len-i );
2104  if ( n < len )
2105  {
2106  size_type newLen = len-n;
2107  if ( !IsUnique() || m_data->ShouldReallocate( newLen ) )
2108  {
2109  Data* newData = Data::New( newLen );
2110  if ( i > 0 )
2111  R::Copy( newData->string, m_data->string, i );
2112  if ( i < newLen )
2113  R::Copy( newData->string+i, m_data->string+i+n, newLen-i );
2114  DetachFromData();
2115  m_data = newData;
2116  }
2117  else
2118  {
2119  if ( i < newLen )
2120  R::CopyOverlapped( m_data->string+i, m_data->string+i+n, newLen-i );
2121  m_data->SetLength( newLen );
2122  }
2123  }
2124  else
2125  Clear();
2126  }
2127  }
2128  }
2129 
2135  {
2136  Delete( i, maxPos );
2137  }
2138 
2144  {
2145  Delete( 0, i );
2146  }
2147 
2153  void DeleteChar( char_type c, size_type i = 0 )
2154  {
2155  ReplaceString( &c, 1, nullptr, 0, i, true/*case*/ );
2156  }
2157 
2165  void DeleteCharIC( char_type c, size_type i = 0 )
2166  {
2167  ReplaceString( &c, 1, nullptr, 0, i, false/*case*/ );
2168  }
2169 
2175  template <class R1, class A1>
2177  {
2178  ReplaceString( s.m_data->string, s.Length(), nullptr, 0, i, true/*case*/ );
2179  }
2180 
2186  void DeleteString( const_c_string t, size_type i = 0 )
2187  {
2188  ReplaceString( t, R::Length( t ), nullptr, 0, i, true/*case*/ );
2189  }
2190 
2198  template <class R1, class A1>
2200  {
2201  ReplaceString( s.m_data->string, s.Length(), nullptr, 0, i, false/*case*/ );
2202  }
2203 
2211  void DeleteStringIC( const_c_string t, size_type i = 0 )
2212  {
2213  ReplaceString( t, R::Length( t ), nullptr, 0, i, false/*case*/ );
2214  }
2215 
2225  void Clear()
2226  {
2227  if ( !IsEmpty() )
2228  if ( IsUnique() )
2229  m_data->Deallocate();
2230  else
2231  {
2232  Data* newData = Data::New();
2233  DetachFromData();
2234  m_data = newData;
2235  }
2236  }
2237 
2243  {
2244  size_type len = Length();
2245  if ( i < len )
2246  {
2247  n = pcl::Min( n, len-i );
2248  if ( n > 0 )
2249  {
2250  if ( n < len )
2251  {
2252  GenericString t;
2253  t.m_data->Allocate( n );
2254  R::Copy( t.m_data->string, m_data->string+i, n );
2255  return t;
2256  }
2257  return *this;
2258  }
2259  }
2260  return GenericString();
2261  }
2262 
2268  {
2269  size_type len = Length();
2270  n = pcl::Min( n, len );
2271  if ( n > 0 )
2272  {
2273  if ( n < len )
2274  {
2275  GenericString t;
2276  t.m_data->Allocate( n );
2277  R::Copy( t.m_data->string, m_data->string, n );
2278  return t;
2279  }
2280  return *this;
2281  }
2282  return GenericString();
2283  }
2284 
2290  {
2291  size_type len = Length();
2292  n = pcl::Min( n, len );
2293  if ( n > 0 )
2294  {
2295  if ( n < len )
2296  {
2297  GenericString t;
2298  t.m_data->Allocate( n );
2299  R::Copy( t.m_data->string, m_data->string+len-n, n );
2300  return t;
2301  }
2302  return *this;
2303  }
2304  return GenericString();
2305  }
2306 
2314  {
2315  return Substring( i );
2316  }
2317 
2325  {
2326  return Left( (i > 0) ? i-1 : 0 );
2327  }
2328 
2346  template <class C, class R1, class A1>
2347  size_type Break( C& list, const GenericString<T,R1,A1>& s, bool trim = false, size_type i = 0 ) const
2348  {
2349  size_type count = 0;
2350  size_type len = Length();
2351  if ( i < len )
2352  {
2353  size_type n = s.Length();
2354  if ( n > 0 )
2355  for ( SearchEngine S( s.m_data->string, n, true/*case*/ ); ; )
2356  {
2357  size_type j = S( m_data->string, i, len );
2358 
2359  GenericString t;
2360  if ( i < j )
2361  {
2362  const_iterator l = m_data->string + i;
2363  size_type m = j - i;
2364  if ( trim )
2365  {
2366  const_iterator r = l + m;
2367  l = R::SearchTrimLeft( l, r );
2368  m = R::SearchTrimRight( l, r ) - l;
2369  }
2370  if ( m > 0 )
2371  {
2372  t.m_data->Allocate( m );
2373  R::Copy( t.m_data->string, l, m );
2374  }
2375  }
2376  list.Add( t );
2377  ++count;
2378 
2379  if ( j == len )
2380  break;
2381 
2382  i = j + n;
2383  }
2384  }
2385  return count;
2386  }
2387 
2406  template <class C>
2407  size_type Break( C& list, const_c_string s, bool trim = false, size_type i = 0 ) const
2408  {
2409  size_type count = 0;
2410  size_type len = Length();
2411  if ( i < len )
2412  {
2413  size_type n = R::Length( s );
2414  if ( n > 0 )
2415  for ( SearchEngine S( s, n, true/*case*/ ); ; )
2416  {
2417  size_type j = S( m_data->string, i, len );
2418 
2419  GenericString t;
2420  if ( i < j )
2421  {
2422  const_iterator l = m_data->string + i;
2423  size_type m = j - i;
2424  if ( trim )
2425  {
2426  const_iterator r = l + m;
2427  l = R::SearchTrimLeft( l, r );
2428  m = R::SearchTrimRight( l, r ) - l;
2429  }
2430  if ( m > 0 )
2431  {
2432  t.m_data->Allocate( m );
2433  R::Copy( t.m_data->string, l, m );
2434  }
2435  }
2436  list.Add( t );
2437  ++count;
2438 
2439  if ( j == len )
2440  break;
2441 
2442  i = j + n;
2443  }
2444  }
2445  return count;
2446  }
2447 
2466  template <class C>
2467  size_type Break( C& list, char_type c, bool trim = false, size_type i = 0 ) const
2468  {
2469  size_type count = 0;
2470  size_type len = Length();
2471  if ( i < len )
2472  {
2473  for ( ;; )
2474  {
2475  size_type j = i;
2476  for ( const_iterator p = m_data->string + i; j < len; ++j, ++p )
2477  if ( *p == c )
2478  break;
2479 
2480  GenericString t;
2481  if ( i < j )
2482  {
2483  const_iterator l = m_data->string + i;
2484  size_type m = j - i;
2485  if ( trim )
2486  {
2487  const_iterator r = l + m;
2488  l = R::SearchTrimLeft( l, r );
2489  m = R::SearchTrimRight( l, r ) - l;
2490  }
2491  if ( m > 0 )
2492  {
2493  t.m_data->Allocate( m );
2494  R::Copy( t.m_data->string, l, m );
2495  }
2496  }
2497  list.Add( t );
2498  ++count;
2499 
2500  if ( j == len )
2501  break;
2502 
2503  i = j + 1;
2504  }
2505  }
2506  return count;
2507  }
2508 
2531  template <class C, typename S>
2532  size_type Break( C& list, const Array<S>& ca, bool trim = false, size_type i = 0 ) const
2533  {
2534  size_type count = 0;
2535  if ( !ca.IsEmpty() )
2536  {
2537  size_type len = Length();
2538  if ( i < len )
2539  {
2540  for ( ;; )
2541  {
2542  size_type j = i;
2543  for ( const_iterator p = m_data->string + i; j < len; ++j, ++p )
2544  for ( auto c : ca )
2545  if ( *p == char_type( c ) )
2546  goto __Break_1;
2547 __Break_1:
2548  GenericString t;
2549  if ( i < j )
2550  {
2551  const_iterator l = m_data->string + i;
2552  size_type m = j - i;
2553  if ( trim )
2554  {
2555  const_iterator r = l + m;
2556  l = R::SearchTrimLeft( l, r );
2557  m = R::SearchTrimRight( l, r ) - l;
2558  }
2559  if ( m > 0 )
2560  {
2561  t.m_data->Allocate( m );
2562  R::Copy( t.m_data->string, l, m );
2563  }
2564  }
2565  list.Add( t );
2566  ++count;
2567 
2568  if ( j == len )
2569  break;
2570 
2571  i = j + 1;
2572  }
2573  }
2574  }
2575  return count;
2576  }
2577 
2598  template <class C, class R1, class A1>
2599  size_type BreakIC( C& list, const GenericString<T,R1,A1>& s, bool trim = false, size_type i = 0 ) const
2600  {
2601  size_type count = 0;
2602  size_type len = Length();
2603  if ( i < len )
2604  {
2605  size_type n = s.Length();
2606  if ( n > 0 )
2607  {
2608  for ( SearchEngine S( s.m_data->string, n, false/*case*/ ); ; )
2609  {
2610  size_type j = S( m_data->string, i, len );
2611 
2612  GenericString t;
2613  if ( i < j )
2614  {
2615  const_iterator l = m_data->string + i;
2616  size_type m = j - i;
2617  if ( trim )
2618  {
2619  const_iterator r = l + m;
2620  l = R::SearchTrimLeft( l, r );
2621  m = R::SearchTrimRight( l, r ) - l;
2622  }
2623  if ( m > 0 )
2624  {
2625  t.m_data->Allocate( m );
2626  R::Copy( t.m_data->string, l, m );
2627  }
2628  }
2629  list.Add( t );
2630  ++count;
2631 
2632  if ( j == len )
2633  break;
2634 
2635  i = j + n;
2636  }
2637  }
2638  }
2639  return count;
2640  }
2641 
2664  template <class C>
2665  size_type BreakIC( C& list, const_c_string s, bool trim = false, size_type i = 0 ) const
2666  {
2667  size_type count = 0;
2668  size_type len = Length();
2669  if ( i < len )
2670  {
2671  size_type n = R::Length( s );
2672  if ( n > 0 )
2673  {
2674  for ( SearchEngine S( s, n, false/*case*/ ); ; )
2675  {
2676  size_type j = S( m_data->string, i, len );
2677 
2678  GenericString t;
2679  if ( i < j )
2680  {
2681  const_iterator l = m_data->string + i;
2682  size_type m = j - i;
2683  if ( trim )
2684  {
2685  const_iterator r = l + m;
2686  l = R::SearchTrimLeft( l, r );
2687  m = R::SearchTrimRight( l, r ) - l;
2688  }
2689  if ( m > 0 )
2690  {
2691  t.m_data->Allocate( m );
2692  R::Copy( t.m_data->string, l, m );
2693  }
2694  }
2695  list.Add( t );
2696  ++count;
2697 
2698  if ( j == len )
2699  break;
2700 
2701  i = j + n;
2702  }
2703  }
2704  }
2705  return count;
2706  }
2707 
2729  template <class C>
2730  size_type BreakIC( C& list, char_type c, bool trim = false, size_type i = 0 ) const
2731  {
2732  size_type count = 0;
2733  size_type len = Length();
2734  if ( i < len )
2735  {
2736  c = R::ToCaseFolded( c );
2737  for ( ;; )
2738  {
2739  size_type j = i;
2740  for ( const_iterator p = m_data->string + i; j < len; ++j, ++p )
2741  if ( R::ToCaseFolded( *p ) == c )
2742  break;
2743 
2744  GenericString t;
2745  if ( i < j )
2746  {
2747  const_iterator l = m_data->string + i;
2748  size_type m = j - i;
2749  if ( trim )
2750  {
2751  const_iterator r = l + m;
2752  l = R::SearchTrimLeft( l, r );
2753  m = R::SearchTrimRight( l, r ) - l;
2754  }
2755  if ( m > 0 )
2756  {
2757  t.m_data->Allocate( m );
2758  R::Copy( t.m_data->string, l, m );
2759  }
2760  }
2761  list.Add( t );
2762  ++count;
2763 
2764  if ( j == len )
2765  break;
2766 
2767  i = j + 1;
2768  }
2769  }
2770  return count;
2771  }
2772 
2777  char_type FirstChar() const
2778  {
2779  return (m_data->string != nullptr) ? *m_data->string : R::Null();
2780  }
2781 
2786  char_type LastChar() const
2787  {
2788  return (m_data->string < m_data->end) ? *(m_data->end-1) : R::Null();
2789  }
2790 
2794  template <class R1, class A1>
2795  bool StartsWith( const GenericString<T,R1,A1>& s ) const
2796  {
2797  if ( s.IsEmpty() || Length() < s.Length() )
2798  return false;
2799  for ( const_iterator p = m_data->string, q = s.m_data->string; q < s.m_data->end; ++p, ++q )
2800  if ( *p != *q )
2801  return false;
2802  return true;
2803  }
2804 
2809  bool StartsWith( const_c_string t ) const
2810  {
2811  size_type n = R::Length( t );
2812  if ( n == 0 || Length() < n )
2813  return false;
2814  for ( const_iterator p = m_data->string, e = p+n; p < e; ++p, ++t )
2815  if ( *p != *t )
2816  return false;
2817  return true;
2818  }
2819 
2823  bool StartsWith( char_type c ) const
2824  {
2825  return m_data->string < m_data->end && *m_data->string == c;
2826  }
2827 
2832  template <class R1, class A1>
2833  bool StartsWithIC( const GenericString<T,R1,A1>& s ) const
2834  {
2835  if ( s.IsEmpty() || Length() < s.Length() )
2836  return false;
2837  for ( const_iterator p = m_data->string, q = s.m_data->string; q < s.m_data->end; ++p, ++q )
2838  if ( R::ToCaseFolded( *p ) != R::ToCaseFolded( *q ) )
2839  return false;
2840  return true;
2841  }
2842 
2847  bool StartsWithIC( const_c_string t ) const
2848  {
2849  size_type n = R::Length( t );
2850  if ( n == 0 || Length() < n )
2851  return false;
2852  for ( const_iterator p = m_data->string, e = p+n; p < e; ++p, ++t )
2853  if ( R::ToCaseFolded( *p ) != R::ToCaseFolded( *t ) )
2854  return false;
2855  return true;
2856  }
2857 
2862  bool StartsWithIC( char_type c ) const
2863  {
2864  return m_data->string < m_data->end && R::ToCaseFolded( *m_data->string ) == R::ToCaseFolded( c );
2865  }
2866 
2870  template <class R1, class A1>
2871  bool EndsWith( const GenericString<T,R1,A1>& s ) const
2872  {
2873  size_type n = s.Length();
2874  if ( n == 0 || Length() < n )
2875  return false;
2876  for ( const_iterator p = m_data->end-n, q = s.m_data->string; p < m_data->end; ++p, ++q )
2877  if ( *p != *q )
2878  return false;
2879  return true;
2880  }
2881 
2886  bool EndsWith( const_c_string t ) const
2887  {
2888  size_type n = R::Length( t );
2889  if ( n == 0 || Length() < n )
2890  return false;
2891  for ( const_iterator p = m_data->end-n; p < m_data->end; ++p, ++t )
2892  if ( *p != *t )
2893  return false;
2894  return true;
2895  }
2896 
2900  bool EndsWith( char_type c ) const
2901  {
2902  return m_data->string < m_data->end && *(m_data->end-1) == c;
2903  }
2904 
2909  template <class R1, class A1>
2910  bool EndsWithIC( const GenericString<T,R1,A1>& s ) const
2911  {
2912  size_type n = s.Length();
2913  if ( n == 0 || Length() < n )
2914  return false;
2915  for ( const_iterator p = m_data->end-n, q = s.m_data->string; p < m_data->end; ++p, ++q )
2916  if ( R::ToCaseFolded( *p ) != R::ToCaseFolded( *q ) )
2917  return false;
2918  return true;
2919  }
2920 
2925  bool EndsWithIC( const_c_string t ) const
2926  {
2927  size_type n = R::Length( t );
2928  if ( n == 0 || Length() < n )
2929  return false;
2930  for ( const_iterator p = m_data->end-n; p < m_data->end; ++p, ++t )
2931  if ( R::ToCaseFolded( *p ) != R::ToCaseFolded( *t ) )
2932  return false;
2933  return true;
2934  }
2935 
2940  bool EndsWithIC( char_type c ) const
2941  {
2942  return m_data->string < m_data->end && R::ToCaseFolded( *(m_data->end-1) ) == R::ToCaseFolded( c );
2943  }
2944 
2950  template <class R1, class A1>
2952  {
2953  size_type len = Length();
2954  i = SearchEngine( s.m_data->string, s.Length(), true/*case*/ )( m_data->string, i, len );
2955  return (i < len) ? i : notFound;
2956  }
2957 
2963  size_type FindFirst( const_c_string t, size_type i = 0 ) const
2964  {
2965  size_type len = Length();
2966  i = SearchEngine( t, R::Length( t ), true/*case*/ )( m_data->string, i, len );
2967  return (i < len) ? i : notFound;
2968  }
2969 
2975  size_type FindFirst( char_type c, size_type i = 0 ) const
2976  {
2977  for ( const_iterator p = m_data->string+i; p < m_data->end; ++p )
2978  if ( *p == c )
2979  return p - m_data->string;
2980  return notFound;
2981  }
2982 
2991  template <class R1, class A1>
2993  {
2994  size_type len = Length();
2995  i = SearchEngine( s.m_data->string, s.Length(), false/*case*/ )( m_data->string, i, len );
2996  return (i < len) ? i : notFound;
2997  }
2998 
3007  size_type FindFirstIC( const_c_string t, size_type i = 0 ) const
3008  {
3009  size_type len = Length();
3010  i = SearchEngine( t, R::Length( t ), false/*case*/ )( m_data->string, i, len );
3011  return (i < len) ? i : notFound;
3012  }
3013 
3022  size_type FindFirstIC( char_type c, size_type i = 0 ) const
3023  {
3024  c = R::ToCaseFolded( c );
3025  for ( const_iterator p = m_data->string+i; p < m_data->end; ++p )
3026  if ( R::ToCaseFolded( *p ) == c )
3027  return p - m_data->string;
3028  return notFound;
3029  }
3030 
3034  template <class R1, class A1>
3036  {
3037  return FindFirst( s, i );
3038  }
3039 
3043  size_type Find( const_c_string t, size_type i = 0 ) const
3044  {
3045  return FindFirst( t, i );
3046  }
3047 
3051  size_type Find( char_type c, size_type i = 0 ) const
3052  {
3053  return FindFirst( c, i );
3054  }
3055 
3059  template <class R1, class A1>
3061  {
3062  return FindFirstIC( s, i );
3063  }
3064 
3068  size_type FindIC( const_c_string t, size_type i = 0 ) const
3069  {
3070  return FindFirstIC( t, i );
3071  }
3072 
3076  size_type FindIC( char_type c, size_type i = 0 ) const
3077  {
3078  return FindFirstIC( c, i );
3079  }
3080 
3090  template <class R1, class A1>
3091  size_type FindLast( const GenericString<T,R1,A1>& s, size_type r = maxPos ) const
3092  {
3093  r = pcl::Min( r, Length() );
3094  size_type i = SearchEngine( s.m_data->string, s.Length(), true/*case*/, true/*last*/ )( m_data->string, 0, r );
3095  return (i < r) ? i : notFound;
3096  }
3097 
3107  size_type FindLast( const_c_string t, size_type r = maxPos ) const
3108  {
3109  r = pcl::Min( r, Length() );
3110  size_type i = SearchEngine( t, R::Length( t ), true/*case*/, true/*last*/ )( m_data->string, 0, r );
3111  return (i < r) ? i : notFound;
3112  }
3113 
3119  size_type FindLast( char_type c, size_type r = maxPos ) const
3120  {
3121  r = pcl::Min( r, Length() );
3122  for ( const_iterator p = m_data->string+r; r > 0; --r )
3123  if ( *--p == c )
3124  return r - 1;
3125  return notFound;
3126  }
3127 
3140  template <class R1, class A1>
3142  {
3143  r = pcl::Min( r, Length() );
3144  size_type i = SearchEngine( s.m_data->string, s.Length(), false/*case*/, true/*last*/ )( m_data->string, 0, r );
3145  return (i < r) ? i : notFound;
3146  }
3147 
3160  size_type FindLastIC( const_c_string t, size_type r = maxPos ) const
3161  {
3162  r = pcl::Min( r, Length() );
3163  size_type i = SearchEngine( t, R::Length( t ), false/*case*/, true/*last*/ )( m_data->string, 0, r );
3164  return (i < r) ? i : notFound;
3165  }
3166 
3175  size_type FindLastIC( char_type c, size_type r = maxPos ) const
3176  {
3177  c = R::ToCaseFolded( c );
3178  r = pcl::Min( r, Length() );
3179  for ( const_iterator p = m_data->string+r; r > 0; --r )
3180  if ( R::ToCaseFolded( *--p ) == c )
3181  return r - 1;
3182  return notFound;
3183  }
3184 
3188  template <class R1, class A1>
3189  bool Contains( const GenericString<T,R1,A1>& s ) const
3190  {
3191  return Find( s ) != notFound;
3192  }
3193 
3197  bool Contains( const_c_string t ) const
3198  {
3199  return Find( t ) != notFound;
3200  }
3201 
3205  bool Contains( char_type c ) const
3206  {
3207  return Find( c ) != notFound;
3208  }
3209 
3216  template <class R1, class A1>
3217  bool ContainsIC( const GenericString<T,R1,A1>& s ) const
3218  {
3219  return FindIC( s ) != notFound;
3220  }
3221 
3228  bool ContainsIC( const_c_string t ) const
3229  {
3230  return FindIC( t ) != notFound;
3231  }
3232 
3239  bool ContainsIC( char_type c ) const
3240  {
3241  return FindIC( c ) != notFound;
3242  }
3243 
3253  void Trim()
3254  {
3255  const_iterator l = R::SearchTrimLeft( m_data->string, m_data->end );
3256  const_iterator r = R::SearchTrimRight( l, m_data->end );
3257  if ( m_data->string < l || r < m_data->end )
3258  Trim( l, r - l );
3259  }
3260 
3270  void TrimLeft()
3271  {
3272  const_iterator l = R::SearchTrimLeft( m_data->string, m_data->end );
3273  if ( m_data->string < l )
3274  Trim( l, m_data->end - l );
3275  }
3276 
3286  void TrimRight()
3287  {
3288  const_iterator r = R::SearchTrimRight( m_data->string, m_data->end );
3289  if ( r < m_data->end )
3290  Trim( m_data->string, r - m_data->string );
3291  }
3292 
3299  {
3300  GenericString s( *this );
3301  s.Trim();
3302  return s;
3303  }
3304 
3311  {
3312  GenericString s( *this );
3313  s.TrimLeft();
3314  return s;
3315  }
3316 
3323  {
3324  GenericString s( *this );
3325  s.TrimRight();
3326  return s;
3327  }
3328 
3335  void EnsureEnclosed( char_type c )
3336  {
3337  int encloseLeft = 1;
3338  int encloseRight = 1;
3339  size_type len = Length();
3340  if ( len > 0 )
3341  {
3342  if ( *m_data->string == c )
3343  encloseLeft = 0;
3344  if ( *(m_data->end-1) == c )
3345  if ( len > 1 )
3346  encloseRight = 0;
3347  else
3348  encloseLeft = 0;
3349  }
3350  size_type n = len + encloseLeft + encloseRight;
3351  if ( n > len )
3352  {
3353  if ( !IsUnique() || m_data->ShouldReallocate( n ) )
3354  {
3355  Data* newData = Data::New( n );
3356  R::Copy( newData->string + encloseLeft, m_data->string, len );
3357  DetachFromData();
3358  m_data = newData;
3359  }
3360  else
3361  {
3362  m_data->SetLength( n );
3363  R::CopyOverlapped( m_data->string + encloseLeft, m_data->string, len );
3364  }
3365 
3366  if ( encloseLeft )
3367  *m_data->string = c;
3368  if ( encloseRight )
3369  *(m_data->end-1) = c;
3370  }
3371  }
3372 
3379  GenericString Enclosed( char_type c ) const
3380  {
3381  GenericString s( *this );
3382  s.EnsureEnclosed( c );
3383  return s;
3384  }
3385 
3393  {
3394  EnsureEnclosed( R::SingleQuote() );
3395  }
3396 
3404  {
3405  GenericString s( *this );
3406  s.EnsureSingleQuoted();
3407  return s;
3408  }
3409 
3417  {
3418  EnsureEnclosed( R::DoubleQuote() );
3419  }
3420 
3428  {
3429  GenericString s( *this );
3430  s.EnsureDoubleQuoted();
3431  return s;
3432  }
3433 
3447  void Unquote()
3448  {
3449  size_type len = Length();
3450  if ( len > 1 )
3451  if ( *m_data->string == R::SingleQuote() && *(m_data->end-1) == R::SingleQuote() ||
3452  *m_data->string == R::DoubleQuote() && *(m_data->end-1) == R::DoubleQuote() )
3453  if ( IsUnique() )
3454  {
3455  R::CopyOverlapped( m_data->string, m_data->string+1, len-2 );
3456  m_data->SetLength( len-2 );
3457  }
3458  else
3459  {
3460  Data* newData = Data::New( len-2 );
3461  R::Copy( newData->string, m_data->string+1, len-2 );
3462  DetachFromData();
3463  m_data = newData;
3464  }
3465  }
3466 
3472  {
3473  GenericString s( *this );
3474  s.Unquote();
3475  return s;
3476  }
3477 
3489  void JustifyLeft( size_type width, char_type fill = R::Blank() )
3490  {
3491  size_type len = Length();
3492  if ( len < width )
3493  Append( fill, width-len );
3494  }
3495 
3507  void JustifyRight( size_type width, char_type fill = R::Blank() )
3508  {
3509  size_type len = Length();
3510  if ( len < width )
3511  Prepend( fill, width-len );
3512  }
3513 
3526  void JustifyCenter( size_type width, char_type fill = R::Blank() )
3527  {
3528  size_type len = Length();
3529  if ( len < width )
3530  {
3531  size_type n = width-len;
3532  size_type n2 = n >> 1;
3533  Prepend( fill, n2 );
3534  Append( fill, n-n2 );
3535  }
3536  }
3537 
3544  GenericString LeftJustified( size_type width, char_type fill = R::Blank() ) const
3545  {
3546  GenericString s( *this );
3547  s.JustifyLeft( width, fill );
3548  return s;
3549  }
3550 
3557  GenericString RightJustified( size_type width, char_type fill = R::Blank() ) const
3558  {
3559  GenericString s( *this );
3560  s.JustifyRight( width, fill );
3561  return s;
3562  }
3563 
3570  GenericString CenterJustified( size_type width, char_type fill = R::Blank() ) const
3571  {
3572  GenericString s( *this );
3573  s.JustifyCenter( width, fill );
3574  return s;
3575  }
3576 
3600  template <class R1, class A1>
3601  int CompareCodePoints( const GenericString<T,R1,A1>& s, bool caseSensitive = true ) const
3602  {
3603  return R::CompareCodePoints( m_data->string, Length(), s.m_data->string, s.Length(), caseSensitive );
3604  }
3605 
3630  int CompareCodePoints( const_c_string t, bool caseSensitive = true ) const
3631  {
3632  return R::CompareCodePoints( m_data->string, Length(), t, R::Length( t ), caseSensitive );
3633  }
3634 
3662  int CompareCodePoints( char_type c, bool caseSensitive = true ) const
3663  {
3664  return R::CompareCodePoints( m_data->string, Length(), &c, 1, caseSensitive );
3665  }
3666 
3693  template <class R1, class A1>
3695  bool caseSensitive = true, bool localeAware = true ) const
3696  {
3697  return R::Compare( m_data->string, Length(), s.m_data->string, s.Length(), caseSensitive, localeAware );
3698  }
3699 
3727  int Compare( const_c_string t, bool caseSensitive = true, bool localeAware = true ) const
3728  {
3729  return R::Compare( m_data->string, Length(), t, R::Length( t ), caseSensitive, localeAware );
3730  }
3731 
3761  int Compare( char_type c, bool caseSensitive = true, bool localeAware = true ) const
3762  {
3763  return R::Compare( m_data->string, Length(), &c, 1, caseSensitive, localeAware );
3764  }
3765 
3786  template <class R1, class A1>
3787  int CompareIC( const GenericString<T,R1,A1>& s, bool localeAware = true ) const
3788  {
3789  return R::Compare( m_data->string, Length(), s.m_data->string, s.Length(), false/*caseSensitive*/, localeAware );
3790  }
3791 
3813  int CompareIC( const_c_string t, bool localeAware = true ) const
3814  {
3815  return R::Compare( m_data->string, Length(), t, R::Length( t ), false/*caseSensitive*/, localeAware );
3816  }
3817 
3842  int CompareIC( char_type c, bool localeAware = true ) const
3843  {
3844  return R::Compare( m_data->string, Length(), &c, 1, false/*caseSensitive*/, localeAware );
3845  }
3846 
3862  template <class R1, class A1>
3863  bool WildMatch( const GenericString<T,R1,A1>& pattern, bool caseSensitive = true ) const
3864  {
3865  return R::WildMatch( m_data->string, Length(), pattern.m_data->string, pattern.Length(), caseSensitive );
3866  }
3867 
3881  template <class R1, class A1>
3882  bool WildMatchIC( const GenericString<T,R1,A1>& pattern ) const
3883  {
3884  return R::WildMatch( m_data->string, Length(), pattern.m_data->string, pattern.Length(), false/*caseSensitive*/ );
3885  }
3886 
3902  bool WildMatch( const_c_string pattern, bool caseSensitive = true ) const
3903  {
3904  return R::WildMatch( m_data->string, Length(), pattern, R::Length( pattern ), caseSensitive );
3905  }
3906 
3921  bool WildMatchIC( const_c_string pattern ) const
3922  {
3923  return R::WildMatch( m_data->string, Length(), pattern, R::Length( pattern ), false/*caseSensitive*/ );
3924  }
3925 
3930  bool HasWildcards() const
3931  {
3932  for ( iterator i = m_data->string; i < m_data->end; ++i )
3933  if ( R::IsWildcard( *i ) )
3934  return true;
3935  return false;
3936  }
3937 
3943  {
3944  size_type len = Length();
3945  if ( len > 0 )
3946  {
3947  EnsureUnique();
3948  R::ToCaseFolded( m_data->string, len );
3949  }
3950  }
3951 
3957  {
3958  size_type len = Length();
3959  if ( len > 0 )
3960  {
3961  EnsureUnique();
3962  R::ToLowercase( m_data->string, len );
3963  }
3964  }
3965 
3971  {
3972  size_type len = Length();
3973  if ( len > 0 )
3974  {
3975  EnsureUnique();
3976  R::ToUppercase( m_data->string, len );
3977  }
3978  }
3979 
3985  {
3986  GenericString s( *this );
3987  s.ToCaseFolded();
3988  return s;
3989  }
3990 
3996  {
3997  GenericString s( *this );
3998  s.ToLowercase();
3999  return s;
4000  }
4001 
4007  {
4008  GenericString s( *this );
4009  s.ToUppercase();
4010  return s;
4011  }
4012 
4018  void Reverse()
4019  {
4020  if ( !IsEmpty() )
4021  {
4022  EnsureUnique();
4023  for ( iterator i = m_data->string, j = m_data->end; i < --j; ++i )
4024  pcl::Swap( *i, *j );
4025  }
4026  }
4027 
4032  {
4033  GenericString s( *this );
4034  s.Reverse();
4035  return s;
4036  }
4037 
4041  void Sort()
4042  {
4043  if ( !IsEmpty() )
4044  {
4045  EnsureUnique();
4046  pcl::Sort( m_data->string, m_data->end );
4047  }
4048  }
4049 
4055  {
4056  GenericString s( *this );
4057  s.Sort();
4058  return s;
4059  }
4060 
4066  template <class BP>
4067  void Sort( BP p )
4068  {
4069  if ( !IsEmpty() )
4070  {
4071  EnsureUnique();
4072  pcl::Sort( m_data->string, m_data->end, p );
4073  }
4074  }
4075 
4080  template <class BP>
4081  GenericString Sorted( BP p ) const
4082  {
4083  GenericString s( *this );
4084  s.Sort( p );
4085  return s;
4086  }
4087 
4102  bool IsNumeral() const
4103  {
4104  if ( IsEmpty() )
4105  return false;
4106  char_type c = *R::SearchTrimLeft( m_data->string, m_data->end );
4107  return R::IsDigit( c ) || R::IsSign( c ) || R::IsDecimalSeparator( c );
4108  }
4109 
4124  bool IsSymbol() const
4125  {
4126  if ( IsEmpty() )
4127  return false;
4128  char_type c = *R::SearchTrimLeft( m_data->string, m_data->end );
4129  return R::IsSymbolDigit( c );
4130  }
4131 
4148  {
4149  if ( IsEmpty() )
4150  {
4151  pos = 0;
4152  return false;
4153  }
4154  const_iterator i = m_data->string;
4155  if ( R::IsStartingSymbolDigit( *i ) )
4156  for ( ;; )
4157  {
4158  if ( ++i == m_data->end )
4159  return true;
4160  if ( !R::IsSymbolDigit( *i ) )
4161  break;
4162  }
4163  pos = i - m_data->string;
4164  return false;
4165  }
4166 
4178  bool IsValidIdentifier() const
4179  {
4180  if ( !IsEmpty() )
4181  if ( R::IsStartingSymbolDigit( *m_data->string ) )
4182  {
4183  for ( const_iterator i = m_data->string; ++i < m_data->end; )
4184  if ( !R::IsSymbolDigit( *i ) )
4185  return false;
4186  return true;
4187  }
4188  return false;
4189  }
4190 
4199  uint64 Hash64( uint64 seed = 0 ) const
4200  {
4201  return pcl::Hash64( m_data->string, Size(), seed );
4202  }
4203 
4212  uint32 Hash32( uint32 seed = 0 ) const
4213  {
4214  return pcl::Hash32( m_data->string, Size(), seed );
4215  }
4216 
4221  uint64 Hash( uint64 seed = 0 ) const
4222  {
4223  return Hash64( seed );
4224  }
4225 
4234  {
4235  return Data::DeleteFreeList();
4236  }
4237 
4238  // -------------------------------------------------------------------------
4239 
4240 protected:
4241 
4246  void DetachFromData()
4247  {
4248  if ( !m_data->Detach() )
4249  Data::Dispose( m_data );
4250  }
4251 
4263  void MaybeReallocate( size_type len )
4264  {
4265  if ( IsUnique() )
4266  {
4267  if ( m_data->ShouldReallocate( len ) )
4268  {
4269  m_data->Deallocate();
4270  m_data->Allocate( len );
4271  }
4272  else
4273  m_data->SetLength( len );
4274  }
4275  else
4276  {
4277  Data* newData = Data::New( len );
4278  DetachFromData();
4279  m_data = newData;
4280  }
4281  }
4282 
4291  void UninitializedGrow( size_type& i, size_type n )
4292  {
4293  size_type len = Length();
4294  size_type newLen = len+n;
4295  if ( newLen > len )
4296  {
4297  if ( i > len )
4298  i = len;
4299  if ( IsUnique() )
4300  {
4301  if ( size_type( m_data->capacity - m_data->string ) < newLen+1 )
4302  {
4303  iterator old = m_data->string;
4304  m_data->Allocate( newLen );
4305  if ( old != nullptr )
4306  {
4307  if ( i > 0 )
4308  R::Copy( m_data->string, old, i );
4309  if ( i < len )
4310  R::Copy( m_data->string+i+n, old+i, len-i );
4311  m_data->alloc.Deallocate( old );
4312  }
4313  }
4314  else
4315  {
4316  if ( i < len )
4317  R::CopyOverlapped( m_data->string+i+n, m_data->string+i, len-i );
4318  m_data->SetLength( newLen );
4319  }
4320  }
4321  else
4322  {
4323  Data* newData = Data::New( newLen );
4324  if ( i > 0 )
4325  R::Copy( newData->string, m_data->string, i );
4326  if ( i < len )
4327  R::Copy( newData->string+i+n, m_data->string+i, len-i );
4328  DetachFromData();
4329  m_data = newData;
4330  }
4331  }
4332  }
4333 
4338  void Trim( const_iterator left, size_type len )
4339  {
4340  if ( len > 0 )
4341  {
4342  if ( IsUnique() )
4343  {
4344  if ( m_data->ShouldReallocate( len ) )
4345  {
4346  iterator old = m_data->string;
4347  m_data->Allocate( len );
4348  R::Copy( m_data->string, left, len );
4349  if ( old != nullptr )
4350  m_data->alloc.Deallocate( old );
4351  }
4352  else
4353  {
4354  if ( left != m_data->string ) // trim left
4355  R::CopyOverlapped( m_data->string, left, len );
4356  m_data->SetLength( len ); // trim right
4357  }
4358  }
4359  else
4360  {
4361  Data* newData = Data::New( len );
4362  R::Copy( newData->string, left, len );
4363  DetachFromData();
4364  m_data = newData;
4365  }
4366  }
4367  else
4368  Clear();
4369  }
4370 
4375  void ReplaceChar( char_type c1, char_type c2, size_type i, size_type n, bool caseSensitive )
4376  {
4377  if ( n > 0 )
4378  {
4379  size_type len = Length();
4380  if ( i < len )
4381  {
4382  n = pcl::Min( n, len-i );
4383  if ( caseSensitive )
4384  {
4385  for ( iterator p = m_data->string + i, p1 = p + n; p < p1; ++p )
4386  if ( *p == c1 )
4387  {
4388  EnsureUnique();
4389  *p = c2;
4390  for ( ; ++p < p1; )
4391  if ( *p == c1 )
4392  *p = c2;
4393  break;
4394  }
4395  }
4396  else
4397  {
4398  c1 = R::ToCaseFolded( c1 );
4399  for ( iterator p = m_data->string + i, p1 = p + n; p < p1; ++p )
4400  if ( R::ToCaseFolded( *p ) == c1 )
4401  {
4402  EnsureUnique();
4403  *p = c2;
4404  for ( ; ++p < p1; )
4405  if ( R::ToCaseFolded( *p ) == c1 )
4406  *p = c2;
4407  break;
4408  }
4409  }
4410  }
4411  }
4412  }
4413 
4418  void ReplaceString( const_iterator t1, size_type n1, const_iterator t2, size_type n2, size_type i, bool caseSensitive )
4419  {
4420  if ( n1 > 0 )
4421  {
4422  size_type len = Length();
4423  if ( i < len )
4424  {
4425  SearchEngine S( t1, n1, caseSensitive );
4426  if ( n1 == n2 )
4427  {
4428  EnsureUnique();
4429  for ( size_type p = i; (p = S( m_data->string, p, len )) < len; p += n1 )
4430  R::Copy( m_data->string + p, t2, n2 );
4431  }
4432  else
4433  {
4434  Array<size_type> P;
4435  for ( size_type p = i; (p = S( m_data->string, p, len )) < len; p += n1 )
4436  P.Add( p );
4437  if ( !P.IsEmpty() )
4438  {
4439  size_type newLen = len;
4440  if ( n1 < n2 )
4441  newLen += P.Length()*(n2 - n1);
4442  else
4443  newLen -= P.Length()*(n1 - n2);
4444 
4445  if ( newLen > 0 )
4446  {
4447  Data* newData = Data::New( newLen );
4448  size_type targetIndex = 0;
4449  size_type sourceIndex = 0;
4450  for ( size_type p : P )
4451  {
4452  size_type n = p - sourceIndex;
4453  if ( n > 0 )
4454  R::Copy( newData->string+targetIndex, m_data->string+sourceIndex, n );
4455  R::Copy( newData->string+targetIndex+n, t2, n2 );
4456  targetIndex += n + n2;
4457  sourceIndex = p + n1;
4458  }
4459  if ( sourceIndex < len )
4460  R::Copy( newData->string+targetIndex, m_data->string+sourceIndex, len-sourceIndex );
4461  DetachFromData();
4462  m_data = newData;
4463  }
4464  else
4465  Clear();
4466  }
4467  }
4468  }
4469  }
4470  }
4471 
4489  class PCL_CLASS SearchEngine
4490  {
4491  public:
4492 
4503  SearchEngine( const_iterator pattern, size_type patternLength,
4504  bool caseSensitive = true, bool searchLast = false, bool useBoyerMoore = true ) :
4505  m_pattern( pattern ),
4506  m_patternLength( int( patternLength ) ),
4507  m_caseSensitive( caseSensitive ),
4508  m_searchLast( searchLast ),
4509  m_useBoyerMoore( useBoyerMoore && m_patternLength > 3 )
4510  {
4511  if ( m_useBoyerMoore )
4512  InitSkipList();
4513  }
4514 
4527  size_type operator()( const_iterator text, size_type startIndex, size_type endIndex ) const
4528  {
4529  if ( endIndex <= startIndex
4530  || m_patternLength <= 0
4531  || endIndex-startIndex < size_type( m_patternLength )
4532  || text == nullptr
4533  || m_pattern == nullptr )
4534  return endIndex;
4535 
4536  if ( m_caseSensitive )
4537  {
4538  if ( m_useBoyerMoore )
4539  {
4540  if ( m_searchLast )
4541  {
4542  for ( size_type i = startIndex, r = endIndex-m_patternLength; i <= r; )
4543  {
4544  int skip = 0;
4545  const_iterator t = text + r - i;
4546  const_iterator p = m_pattern;
4547  for ( int j = m_patternLength; --j >= 0; )
4548  {
4549  char_type c = *t++;
4550  if ( c != *p++ )
4551  {
4552  skip = j - m_skipList[uint8( c )];
4553  if ( skip < 1 )
4554  skip = 1;
4555  break;
4556  }
4557  }
4558  if ( skip == 0 )
4559  return r - i;
4560  i += skip;
4561  }
4562  }
4563  else
4564  {
4565  for ( size_type i = startIndex, r = endIndex-m_patternLength; i <= r; )
4566  {
4567  int skip = 0;
4568  const_iterator t = text + i + m_patternLength;
4569  const_iterator p = m_pattern + m_patternLength;
4570  for ( int j = m_patternLength; --j >= 0; )
4571  {
4572  char_type c = *--t;
4573  if ( c != *--p )
4574  {
4575  // ### N.B.: Could do better with a precomputed pattern mismatch table.
4576  skip = j - m_skipList[uint8( c )];
4577  if ( skip < 1 )
4578  skip = 1;
4579  break;
4580  }
4581  }
4582  if ( skip == 0 )
4583  return i;
4584  i += skip;
4585  }
4586  }
4587  }
4588  else
4589  {
4590  // Use a brute force search for very small patterns.
4591  if ( m_searchLast )
4592  {
4593  for ( size_type i = endIndex-m_patternLength; ; --i )
4594  {
4595  const_iterator t = text + i;
4596  const_iterator p = m_pattern;
4597  for ( int j = m_patternLength; ; ++t, ++p )
4598  {
4599  if ( *t != *p )
4600  break;
4601  if ( --j == 0 )
4602  return i;
4603  }
4604  if ( i == startIndex )
4605  break;
4606  }
4607  }
4608  else
4609  {
4610  for ( size_type i = startIndex, r = endIndex-m_patternLength; ; ++i )
4611  {
4612  const_iterator t = text + i;
4613  const_iterator p = m_pattern;
4614  for ( int j = m_patternLength; ; ++t, ++p )
4615  {
4616  if ( *t != *p )
4617  break;
4618  if ( --j == 0 )
4619  return i;
4620  }
4621  if ( i == r )
4622  break;
4623  }
4624  }
4625  }
4626  }
4627  else
4628  {
4629  if ( m_useBoyerMoore )
4630  {
4631  if ( m_searchLast )
4632  {
4633  for ( size_type i = startIndex, r = endIndex-m_patternLength; i <= r; )
4634  {
4635  int skip = 0;
4636  const_iterator t = text + r - i;
4637  const_iterator p = m_pattern;
4638  for ( int j = m_patternLength; --j >= 0; )
4639  {
4640  char_type c = R::ToCaseFolded( *t++ );
4641  if ( c != R::ToCaseFolded( *p++ ) )
4642  {
4643  skip = j - m_skipList[uint8( c )];
4644  if ( skip < 1 )
4645  skip = 1;
4646  break;
4647  }
4648  }
4649  if ( skip == 0 )
4650  return r - i;
4651  i += skip;
4652  }
4653  }
4654  else
4655  {
4656  for ( size_type i = startIndex, r = endIndex-m_patternLength; i <= r; )
4657  {
4658  int skip = 0;
4659  const_iterator t = text + i + m_patternLength;
4660  const_iterator p = m_pattern + m_patternLength;
4661  for ( int j = m_patternLength; --j >= 0; )
4662  {
4663  char_type c = R::ToCaseFolded( *--t );
4664  if ( c != R::ToCaseFolded( *--p ) )
4665  {
4666  // ### N.B.: Could do better with a precomputed pattern mismatch table.
4667  skip = j - m_skipList[uint8( c )];
4668  if ( skip < 1 )
4669  skip = 1;
4670  break;
4671  }
4672  }
4673  if ( skip == 0 )
4674  return i;
4675  i += skip;
4676  }
4677  }
4678  }
4679  else
4680  {
4681  // Use a brute force search for very small patterns.
4682  if ( m_searchLast )
4683  {
4684  for ( size_type i = endIndex-m_patternLength; ; --i )
4685  {
4686  const_iterator t = text + i;
4687  const_iterator p = m_pattern;
4688  for ( int j = m_patternLength; ; ++t, ++p )
4689  {
4690  if ( R::ToCaseFolded( *t ) != R::ToCaseFolded( *p ) )
4691  break;
4692  if ( --j == 0 )
4693  return i;
4694  }
4695  if ( i == startIndex )
4696  break;
4697  }
4698  }
4699  else
4700  {
4701  for ( size_type i = startIndex, r = endIndex-m_patternLength; ; ++i )
4702  {
4703  const_iterator t = text + i;
4704  const_iterator p = m_pattern;
4705  for ( int j = m_patternLength; ; ++t, ++p )
4706  {
4707  if ( R::ToCaseFolded( *t ) != R::ToCaseFolded( *p ) )
4708  break;
4709  if ( --j == 0 )
4710  return i;
4711  }
4712  if ( i == r )
4713  break;
4714  }
4715  }
4716  }
4717  }
4718  return endIndex;
4719  }
4720 
4721  private:
4722 
4723  int m_skipList[ 256 ];
4724  const_iterator m_pattern;
4725  int m_patternLength;
4726  bool m_caseSensitive : 1;
4727  bool m_searchLast : 1;
4728  bool m_useBoyerMoore : 1;
4729 
4730  void InitSkipList()
4731  {
4732  ::memset( m_skipList, 0xff, sizeof( m_skipList ) ); // fill with -1
4733  if ( m_searchLast )
4734  {
4735  const_iterator p = m_pattern + m_patternLength;
4736  if ( m_caseSensitive )
4737  for ( int i = 0; i < m_patternLength; ++i )
4738  m_skipList[uint8( *--p )] = i;
4739  else
4740  for ( int i = 0; i < m_patternLength; ++i )
4741  m_skipList[uint8( R::ToCaseFolded( *--p ) )] = i;
4742  }
4743  else
4744  {
4745  const_iterator p = m_pattern;
4746  if ( m_caseSensitive )
4747  for ( int i = 0; i < m_patternLength; ++i )
4748  m_skipList[uint8( *p++ )] = i;
4749  else
4750  for ( int i = 0; i < m_patternLength; ++i )
4751  m_skipList[uint8( R::ToCaseFolded( *p++ ) )] = i;
4752  }
4753  }
4754  };
4755 
4756  // -------------------------------------------------------------------------
4757 
4763  class PCL_CLASS Data : public ReferenceCounter
4764  {
4765  private:
4766 
4767 #ifndef __PCL_NO_STRING_FREE_LIST
4768  static Data* freeList;
4769  static AtomicInt freeLock;
4770 #endif
4771 
4772  public:
4773 
4774  iterator string = nullptr;
4775  iterator end = nullptr;
4776  iterator capacity = nullptr;
4777  allocator alloc;
4778 
4782  Data() = default;
4783 
4787  Data( size_type len )
4788  {
4789  Allocate( len );
4790  }
4791 
4796  Data( size_type len, size_type total )
4797  {
4798  Allocate( len, total );
4799  }
4800 
4804  ~Data()
4805  {
4806  Deallocate();
4807  }
4808 
4819  void Allocate( size_type len, size_type total )
4820  {
4821  total = (len <= total) ? alloc.PagedLength( total+1 ) : len+1; // +1 is room for a null terminating character
4822  string = alloc.Allocate( total );
4823  capacity = string + total;
4824  SetLength( len );
4825  }
4826 
4831  void Allocate( size_type len )
4832  {
4833  Allocate( len, len );
4834  }
4835 
4844  void Reserve( size_type len, size_type total )
4845  {
4846  PCL_PRECONDITION( len <= total )
4847  string = alloc.Allocate( total+1 );
4848  capacity = string + total+1;
4849  SetLength( pcl::Min( len, total ) );
4850  }
4851 
4855  void Deallocate()
4856  {
4857  PCL_CHECK( (string == nullptr) ? end == nullptr : string < end )
4858  if ( string != nullptr )
4859  {
4860  alloc.Deallocate( string );
4861  Reset();
4862  }
4863  }
4864 
4869  bool ShouldReallocate( size_type len ) const
4870  {
4871  size_type m = capacity - string;
4872  return m <= len || alloc.ReallocatedLength( m, len+1 ) < (m >> 1);
4873  }
4874 
4879  void SetLength( size_type len )
4880  {
4881  *(end = (string + len)) = R::Null();
4882  }
4883 
4887  void Reset()
4888  {
4889  string = end = capacity = nullptr;
4890  }
4891 
4898 #ifndef __PCL_NO_STRING_FREE_LIST
4899  static Data* NextFree()
4900  {
4901  if ( freeLock.TestAndSet( 0, 1 ) )
4902  {
4903  Data* data = freeList;
4904  if ( data != nullptr )
4905  freeList = reinterpret_cast<Data*>( data->string );
4906  freeLock.Store( 0 );
4907  return data;
4908  }
4909  return nullptr;
4910  }
4911 #endif // !__PCL_NO_STRING_FREE_LIST
4912 
4920  static Data* New()
4921  {
4922 #ifndef __PCL_NO_STRING_FREE_LIST
4923  Data* data = NextFree();
4924  if ( data != nullptr )
4925  {
4926  data->string = nullptr;
4927  return data;
4928  }
4929 #endif // !__PCL_NO_STRING_FREE_LIST
4930  return new Data;
4931  }
4932 
4940  static Data* New( size_type len )
4941  {
4942 #ifndef __PCL_NO_STRING_FREE_LIST
4943  Data* data = NextFree();
4944  if ( data != nullptr )
4945  {
4946  data->Allocate( len ); // ### FIXME: If allocation fails, data is a leak.
4947  return data;
4948  }
4949 #endif // !__PCL_NO_STRING_FREE_LIST
4950  return new Data( len );
4951  }
4952 
4960  static Data* New( size_type len, size_type total )
4961  {
4962 #ifndef __PCL_NO_STRING_FREE_LIST
4963  Data* data = NextFree();
4964  if ( data != nullptr )
4965  {
4966  data->Allocate( len, total ); // ### FIXME: If allocation fails, data is a leak.
4967  return data;
4968  }
4969 #endif // !__PCL_NO_STRING_FREE_LIST
4970  return new Data( len, total );
4971  }
4972 
4980  static void Dispose( Data* data )
4981  {
4982  PCL_PRECONDITION( data != nullptr )
4983  PCL_CHECK( data->RefCount() == 0 )
4984 #ifndef __PCL_NO_STRING_FREE_LIST
4985  if ( freeLock.TestAndSet( 0, 1 ) )
4986  {
4987  data->Attach();
4988  data->Deallocate();
4989  data->string = reinterpret_cast<iterator>( freeList );
4990  freeList = data;
4991  freeLock.Store( 0 );
4992  }
4993  else
4994 #endif // !__PCL_NO_STRING_FREE_LIST
4995  delete data;
4996  }
4997 
5005  static size_type DeleteFreeList()
5006  {
5007  size_type count = 0;
5008 #ifndef __PCL_NO_STRING_FREE_LIST
5009  while ( freeList != nullptr )
5010  {
5011  Data* data = freeList;
5012  freeList = reinterpret_cast<Data*>( data->string );
5013  data->string = nullptr;
5014  delete data;
5015  ++count;
5016  }
5017 #endif // !__PCL_NO_STRING_FREE_LIST
5018  return count;
5019  }
5020  };
5021 
5022  /*
5023  * The reference-counted string data.
5024  */
5025  Data* m_data = nullptr;
5026 };
5027 
5028 #ifndef __PCL_NO_STRING_FREE_LIST
5029 
5030 template <class T, class R, class A>
5032 
5033 template <class T, class R, class A>
5035 
5036 #endif // !__PCL_NO_STRING_FREE_LIST
5037 
5041 template <class T, class R, class A> inline
5043 {
5044  s1.Swap( s2 );
5045 }
5046 
5047 // ----------------------------------------------------------------------------
5048 
5053 // ----------------------------------------------------------------------------
5054 
5059 template <class T, class R1, class A1, class R2, class A2> inline
5061 {
5062  return s1.CompareCodePoints( s2 ) == 0;
5063 }
5064 
5072 template <class T, class R1, class A1, class R2, class A2> inline
5073 bool operator <( const GenericString<T,R1,A1>& s1, const GenericString<T,R2,A2>& s2 )
5074 {
5075  return s1.CompareCodePoints( s2 ) < 0;
5076 }
5077 
5085 template <class T, class R1, class A1, class R2, class A2> inline
5086 bool operator <=( const GenericString<T,R1,A1>& s1, const GenericString<T,R2,A2>& s2 )
5087 {
5088  return s1.CompareCodePoints( s2 ) <= 0;
5089 }
5090 
5098 template <class T, class R1, class A1, class R2, class A2> inline
5100 {
5101  return s1.CompareCodePoints( s2 ) > 0;
5102 }
5103 
5111 template <class T, class R1, class A1, class R2, class A2> inline
5113 {
5114  return s1.CompareCodePoints( s2 ) >= 0;
5115 }
5116 
5117 // ----------------------------------------------------------------------------
5118 
5123 template <class T, class R, class A> inline
5125 {
5126  return s1.CompareCodePoints( t2 ) == 0;
5127 }
5128 
5136 template <class T, class R, class A> inline
5137 bool operator <( const GenericString<T,R,A>& s1, typename GenericString<T,R,A>::const_c_string t2 )
5138 {
5139  return s1.CompareCodePoints( t2 ) < 0;
5140 }
5141 
5149 template <class T, class R, class A> inline
5150 bool operator <=( const GenericString<T,R,A>& s1, typename GenericString<T,R,A>::const_c_string t2 )
5151 {
5152  return s1.CompareCodePoints( t2 ) <= 0;
5153 }
5154 
5162 template <class T, class R, class A> inline
5164 {
5165  return s1.CompareCodePoints( t2 ) > 0;
5166 }
5167 
5175 template <class T, class R, class A> inline
5177 {
5178  return s1.CompareCodePoints( t2 ) >= 0;
5179 }
5180 
5181 // ----------------------------------------------------------------------------
5182 
5187 template <class T, class R, class A> inline
5189 {
5190  return s2.CompareCodePoints( t1 ) == 0;
5191 }
5192 
5200 template <class T, class R, class A> inline
5201 bool operator <( typename GenericString<T,R,A>::const_c_string t1, const GenericString<T,R,A>& s2 )
5202 {
5203  return s2.CompareCodePoints( t1 ) > 0;
5204 }
5205 
5213 template <class T, class R, class A> inline
5214 bool operator <=( typename GenericString<T,R,A>::const_c_string t1, const GenericString<T,R,A>& s2 )
5215 {
5216  return s2.CompareCodePoints( t1 ) >= 0;
5217 }
5218 
5226 template <class T, class R, class A> inline
5228 {
5229  return s2.CompareCodePoints( t1 ) < 0;
5230 }
5231 
5239 template <class T, class R, class A> inline
5241 {
5242  return s2.CompareCodePoints( t1 ) <= 0;
5243 }
5244 
5245 // ----------------------------------------------------------------------------
5246 
5251 template <class T, class R, class A> inline
5253 {
5254  return s1.CompareCodePoints( c2 ) == 0;
5255 }
5256 
5264 template <class T, class R, class A> inline
5265 bool operator <( const GenericString<T,R,A>& s1, typename GenericString<T,R,A>::char_type c2 )
5266 {
5267  return s1.CompareCodePoints( c2 ) < 0;
5268 }
5269 
5277 template <class T, class R, class A> inline
5278 bool operator <=( const GenericString<T,R,A>& s1, typename GenericString<T,R,A>::char_type c2 )
5279 {
5280  return s1.CompareCodePoints( c2 ) <= 0;
5281 }
5282 
5290 template <class T, class R, class A> inline
5292 {
5293  return s1.CompareCodePoints( c2 ) > 0;
5294 }
5295 
5303 template <class T, class R, class A> inline
5305 {
5306  return s1.CompareCodePoints( c2 ) >= 0;
5307 }
5308 
5309 // ----------------------------------------------------------------------------
5310 
5315 template <class T, class R, class A> inline
5317 {
5318  return s2.CompareCodePoints( c1 ) == 0;
5319 }
5320 
5328 template <class T, class R, class A> inline
5329 bool operator <( typename GenericString<T,R,A>::char_type c1, const GenericString<T,R,A>& s2 )
5330 {
5331  return s2.CompareCodePoints( c1 ) > 0;
5332 }
5333 
5341 template <class T, class R, class A> inline
5342 bool operator <=( typename GenericString<T,R,A>::char_type c1, const GenericString<T,R,A>& s2 )
5343 {
5344  return s2.CompareCodePoints( c1 ) >= 0;
5345 }
5346 
5354 template <class T, class R, class A> inline
5356 {
5357  return s2.CompareCodePoints( c1 ) < 0;
5358 }
5359 
5367 template <class T, class R, class A> inline
5369 {
5370  return s2.CompareCodePoints( c1 ) <= 0;
5371 }
5372 
5373 // ----------------------------------------------------------------------------
5374 
5387 class PCL_CLASS IsoString : public GenericString<char, IsoCharTraits, StandardAllocator>
5388 {
5389 public:
5390 
5396 
5401 
5406 
5411 
5416 
5421 
5426 
5431 
5436 
5441 
5446 
5454 
5459 
5464 
5469 
5473  typedef ustring_base::const_c_string const_c_ustring;
5474 
5479 
5484 
5485  // -------------------------------------------------------------------------
5486 
5491  {
5492  }
5493 
5498  IsoString( const string_base& s ) : string_base( s )
5499  {
5500  }
5501 
5505  IsoString( const IsoString& s ) : string_base( s )
5506  {
5507  }
5508 
5513  IsoString( string_base&& s ) : string_base( std::move( s ) )
5514  {
5515  }
5516 
5520  IsoString( const IsoString&& s ) : string_base( std::move( s ) )
5521  {
5522  }
5523 
5531  explicit
5533  {
5534  (void)operator =( s );
5535  }
5536 
5540  IsoString( const_c_string t ) : string_base( t )
5541  {
5542  }
5543 
5548  IsoString( const_c_string t, size_type i, size_type n ) : string_base( t, i, n )
5549  {
5550  }
5551 
5555  IsoString( char_type c, size_type n = 1 ) : string_base( c, n )
5556  {
5557  }
5558 
5563  IsoString( const_iterator i, const_iterator j ) : string_base( i, j )
5564  {
5565  }
5566 
5575  IsoString( std::initializer_list<char_type> l ) : IsoString( l.begin(), l.end() )
5576  {
5577  }
5578 
5588  explicit
5589  IsoString( const_c_ustring t ) : string_base()
5590  {
5591  (void)operator =( t );
5592  }
5593 
5604  IsoString( const_c_ustring t, size_type i, size_type n );
5605 
5613  explicit
5614  IsoString( const ByteArray& B ) :
5615  IsoString( const_iterator( B.Begin() ), const_iterator( B.End() ) )
5616  {
5617  }
5618 
5622  explicit
5623  IsoString( bool x ) : string_base( x ? "true" : "false" )
5624  {
5625  }
5626 
5631  explicit
5632  IsoString( short x ) : string_base()
5633  {
5634  (void)Format( "%hd", x );
5635  }
5636 
5641  explicit
5642  IsoString( unsigned short x ) : string_base()
5643  {
5644  (void)Format( "%hu", x );
5645  }
5646 
5651  explicit
5652  IsoString( int x ) : string_base()
5653  {
5654  (void)Format( "%i", x );
5655  }
5656 
5661  explicit
5662  IsoString( unsigned int x ) : string_base()
5663  {
5664  (void)Format( "%u", x );
5665  }
5666 
5671  explicit
5672  IsoString( long x ) : string_base()
5673  {
5674  (void)Format( "%ld", x );
5675  }
5676 
5681  explicit
5682  IsoString( unsigned long x ) : string_base()
5683  {
5684  (void)Format( "%lu", x );
5685  }
5686 
5691  explicit
5692  IsoString( long long x ) : string_base()
5693  {
5694  (void)Format( "%lli", x );
5695  }
5696 
5701  explicit
5702  IsoString( unsigned long long x ) : string_base()
5703  {
5704  (void)Format( "%llu", x );
5705  }
5706 
5711  explicit
5712  IsoString( float x ) : string_base()
5713  {
5714  (void)Format( "%.7g", x );
5715  }
5716 
5721  explicit
5722  IsoString( double x ) : string_base()
5723  {
5724  (void)Format( "%.16g", x );
5725  }
5726 
5731  explicit
5732  IsoString( long double x ) : string_base()
5733  {
5734 #ifdef _MSC_VER
5735  (void)Format( "%.16Lg", x );
5736 #else
5737  (void)Format( "%.18Lg", x );
5738 #endif
5739  }
5740 
5741 #ifndef __PCL_NO_STRING_COMPLEX
5742 
5747  explicit
5749  {
5750  (void)Format( "{%.7g,%.7g}", x.Real(), x.Imag() );
5751  }
5752 
5757  explicit
5759  {
5760  (void)Format( "{%.16g,%.16g}", x.Real(), x.Imag() );
5761  }
5762 
5767  explicit
5769  {
5770 #ifdef _MSC_VER
5771  (void)Format( "{%.16Lg,%.16Lg}", x.Real(), x.Imag() );
5772 #else
5773  (void)Format( "{%.18Lg,%.18Lg}", x.Real(), x.Imag() );
5774 #endif
5775  }
5776 
5777 #endif // !__PCL_NO_STRING_COMPLEX
5778 
5779 #ifdef __PCL_QT_INTERFACE
5780 
5781  explicit
5782  IsoString( const QString& qs ) :
5783  string_base( qs.isEmpty() ? iterator( nullptr ) : iterator( PCL_GET_CHARPTR_FROM_QSTRING( qs ) ) )
5784  {
5785  }
5786 
5787  explicit
5788  IsoString( const QByteArray& qb ) :
5789  string_base( qb.isEmpty() ? iterator( nullptr ) : iterator( PCL_GET_CHARPTR_FROM_QBYTEARRAY( qb ) ) )
5790  {
5791  }
5792 
5793  explicit
5794  IsoString( const QDate& qd ) :
5795  string_base( iterator( PCL_GET_CHARPTR_FROM_QSTRING( qd.toString( PCL_QDATE_FMT_STR ) ) ) )
5796  {
5797  }
5798 
5799  explicit
5800  IsoString( const QDateTime& qdt ) :
5801  string_base( iterator( PCL_GET_CHARPTR_FROM_QSTRING( qdt.toString( PCL_QDATETIME_FMT_STR ) ) ) )
5802  {
5803  }
5804 
5805 #endif
5806 
5807  // -------------------------------------------------------------------------
5808 
5812  IsoString& operator =( const IsoString& s )
5813  {
5814  Assign( s );
5815  return *this;
5816  }
5817 
5821  IsoString& operator =( IsoString&& s )
5822  {
5823  Transfer( s );
5824  return *this;
5825  }
5826 
5831  IsoString& operator =( const string_base& s )
5832  {
5833  Assign( s );
5834  return *this;
5835  }
5836 
5841  IsoString& operator =( string_base&& s )
5842  {
5843  Transfer( s );
5844  return *this;
5845  }
5846 
5857  IsoString& operator =( const ustring_base& s )
5858  {
5859  return operator =( s.Begin() );
5860  }
5861 
5866  IsoString& operator =( const_c_string t )
5867  {
5868  Assign( t );
5869  return *this;
5870  }
5871 
5876  IsoString& operator =( char_type c )
5877  {
5878  Assign( c, 1 );
5879  return *this;
5880  }
5881 
5892  IsoString& operator =( const_c_ustring t );
5893 
5894 #ifdef __PCL_QT_INTERFACE
5895 
5896  IsoString& operator =( const QString& qs )
5897  {
5898  if ( qs.isEmpty() )
5899  Clear();
5900  else
5901  Assign( PCL_GET_CHARPTR_FROM_QSTRING( qs ) );
5902  return *this;
5903  }
5904 
5905  IsoString& operator =( const QByteArray& qb )
5906  {
5907  if ( qb.isEmpty() )
5908  Clear();
5909  else
5910  Assign( PCL_GET_CHARPTR_FROM_QBYTEARRAY( qb ) );
5911  return *this;
5912  }
5913 
5914  IsoString& operator =( const QDate& qd )
5915  {
5916  Assign( PCL_GET_CHARPTR_FROM_QSTRING( qd.toString( PCL_QDATE_FMT_STR ) ) );
5917  return *this;
5918  }
5919 
5920  IsoString& operator =( const QDateTime& qdt )
5921  {
5922  Assign( PCL_GET_CHARPTR_FROM_QSTRING( qdt.toString( PCL_QDATETIME_FMT_STR ) ) );
5923  return *this;
5924  }
5925 
5926 #endif
5927 
5928  // -------------------------------------------------------------------------
5929 
5930  IsoString SetToLength( size_type n ) const
5931  {
5932  return string_base::SetToLength( n );
5933  }
5934 
5935  IsoString ResizedToNullTerminated() const
5936  {
5937  return string_base::ResizedToNullTerminated();
5938  }
5939 
5940  IsoString Squeezed() const
5941  {
5942  return string_base::Squeezed();
5943  }
5944 
5945  // -------------------------------------------------------------------------
5946 
5947  IsoString Substring( size_type i, size_type n = maxPos ) const
5948  {
5949  return string_base::Substring( i, n );
5950  }
5951 
5952  IsoString Left( size_type n ) const
5953  {
5954  return string_base::Left( n );
5955  }
5956 
5957  IsoString Right( size_type n ) const
5958  {
5959  return string_base::Right( n );
5960  }
5961 
5962  IsoString Suffix( size_type i ) const
5963  {
5964  return string_base::Suffix( i );
5965  }
5966 
5967  IsoString Prefix( size_type i ) const
5968  {
5969  return string_base::Prefix( i );
5970  }
5971 
5972  // -------------------------------------------------------------------------
5973 
5974  IsoString Trimmed() const
5975  {
5976  return string_base::Trimmed();
5977  }
5978 
5979  IsoString TrimmedLeft() const
5980  {
5981  return string_base::TrimmedLeft();
5982  }
5983 
5984  IsoString TrimmedRight() const
5985  {
5986  return string_base::TrimmedRight();
5987  }
5988 
5989  // -------------------------------------------------------------------------
5990 
5991  IsoString LeftJustified( size_type width, char_type fill = IsoCharTraits::Blank() ) const
5992  {
5993  return string_base::LeftJustified( width, fill );
5994  }
5995 
5996  IsoString RightJustified( size_type width, char_type fill = IsoCharTraits::Blank() ) const
5997  {
5998  return string_base::RightJustified( width, fill );
5999  }
6000 
6001  IsoString CenterJustified( size_type width, char_type fill = IsoCharTraits::Blank() ) const
6002  {
6003  return string_base::CenterJustified( width, fill );
6004  }
6005 
6006  // -------------------------------------------------------------------------
6007 
6008  IsoString Enclosed( char_type c ) const
6009  {
6010  return string_base::Enclosed( c );
6011  }
6012 
6013  IsoString SingleQuoted() const
6014  {
6015  return string_base::SingleQuoted();
6016  }
6017 
6018  IsoString DoubleQuoted() const
6019  {
6020  return string_base::DoubleQuoted();
6021  }
6022 
6023  IsoString Unquoted() const
6024  {
6025  return string_base::Unquoted();
6026  }
6027 
6028  // -------------------------------------------------------------------------
6029 
6030  IsoString CaseFolded() const
6031  {
6032  return string_base::CaseFolded();
6033  }
6034 
6035  IsoString Lowercase() const
6036  {
6037  return string_base::Lowercase();
6038  }
6039 
6040  IsoString Uppercase() const
6041  {
6042  return string_base::Uppercase();
6043  }
6044 
6045  // -------------------------------------------------------------------------
6046 
6047  IsoString Reversed() const
6048  {
6049  return string_base::Reversed();
6050  }
6051 
6052  IsoString Sorted() const
6053  {
6054  return string_base::Sorted();
6055  }
6056 
6057  template <class BP>
6058  IsoString Sorted( BP p ) const
6059  {
6060  return string_base::Sorted( p );
6061  }
6062 
6063  // -------------------------------------------------------------------------
6064 
6074  template <class C>
6075  IsoString& ToSeparated( const C& c, char_type separator )
6076  {
6077  Clear();
6078  return c.ToSeparated( *this, separator );
6079  }
6080 
6097  template <class C, class AF>
6098  IsoString& ToSeparated( const C& c, char_type separator, AF append )
6099  {
6100  Clear();
6101  return c.ToSeparated( *this, separator, append );
6102  }
6103 
6113  template <class C>
6114  IsoString& ToSeparated( const C& c, const IsoString& separator )
6115  {
6116  Clear();
6117  return c.ToSeparated( *this, separator );
6118  }
6119 
6136  template <class C, class AF>
6137  IsoString& ToSeparated( const C& c, const IsoString& separator, AF append )
6138  {
6139  Clear();
6140  return c.ToSeparated( *this, separator, append );
6141  }
6142 
6152  template <class C>
6153  IsoString& ToSeparated( const C& c, const_c_string separator )
6154  {
6155  return ToSeparated( c, IsoString( separator ) );
6156  }
6157 
6174  template <class C, class AF>
6175  IsoString& ToSeparated( const C& c, const_c_string separator, AF append )
6176  {
6177  return ToSeparated( c, IsoString( separator ), append );
6178  }
6179 
6189  template <class C>
6191  {
6192  return ToSeparated( c, IsoCharTraits::Comma() );
6193  }
6194 
6204  template <class C>
6206  {
6207  return ToSeparated( c, IsoCharTraits::Colon() );
6208  }
6209 
6219  template <class C>
6221  {
6222  return ToSeparated( c, IsoCharTraits::Blank() );
6223  }
6224 
6234  template <class C>
6235  IsoString& ToTabSeparated( const C& c )
6236  {
6237  return ToSeparated( c, IsoCharTraits::Tab() );
6238  }
6239 
6249  template <class C>
6251  {
6252  return ToSeparated( c, IsoCharTraits::LF() );
6253  }
6254 
6264  template <class C>
6266  {
6267  return ToSeparated( c, IsoCharTraits::Null() );
6268  }
6269 
6278  template <class C>
6279  IsoString& ToHyphenated( const C& c )
6280  {
6281  return ToSeparated( c, IsoCharTraits::Hyphen() );
6282  }
6283 
6284  // -------------------------------------------------------------------------
6285 
6300  IsoString& ToEncodedHTMLSpecialChars();
6301 
6309  {
6310  return IsoString( *this ).ToEncodedHTMLSpecialChars();
6311  }
6312 
6329  IsoString& ToDecodedHTMLSpecialChars();
6330 
6339  {
6340  return IsoString( *this ).ToDecodedHTMLSpecialChars();
6341  }
6342 
6354  static IsoString ToURLEncoded( const void* data, size_type length );
6355 
6368  template <class C>
6369  static IsoString ToURLEncoded( const C& c )
6370  {
6371  return ToURLEncoded( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
6372  }
6373 
6383  IsoString& ToURLEncoded();
6384 
6392  {
6393  return IsoString( *this ).ToURLEncoded();
6394  }
6395 
6407  static ByteArray FromURLEncoded( const void* data, size_type length );
6408 
6416  template <class C>
6417  static ByteArray FromURLEncoded( const C& c )
6418  {
6419  return FromURLEncoded( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
6420  }
6421 
6434  {
6435  return FromURLEncoded( Begin(), Length() );
6436  }
6437 
6449  static IsoString ToURLDecoded( const void* data, size_type length );
6450 
6457  template <class C>
6458  static IsoString ToURLDecoded( const C& c )
6459  {
6460  return ToURLDecoded( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
6461  }
6462 
6472  IsoString& ToURLDecoded();
6473 
6481  {
6482  return IsoString( *this ).ToURLDecoded();
6483  }
6484 
6485  // -------------------------------------------------------------------------
6486 
6487 #ifdef __PCL_QT_INTERFACE
6488 
6489  operator QString() const
6490  {
6491  return QString( c_str() );
6492  }
6493 
6494  operator QByteArray() const
6495  {
6496  return QByteArray( c_str() );
6497  }
6498 
6499  operator QDate() const
6500  {
6501  return QDate::fromString( c_str(), PCL_QDATE_FMT_STR );
6502  }
6503 
6504  operator QDateTime() const
6505  {
6506  return QDateTime::fromString( c_str(), PCL_QDATETIME_FMT_STR );
6507  }
6508 
6509 #endif
6510 
6522  IsoString& Format( const_c_string fmt, ... )
6523  {
6524  va_list paramList;
6525  va_start( paramList, fmt );
6526 
6527  (void)VFormat( fmt, paramList );
6528 
6529  va_end( paramList );
6530  return *this;
6531  }
6532 
6544  IsoString& AppendFormat( const_c_string fmt, ... )
6545  {
6546  va_list paramList;
6547  va_start( paramList, fmt );
6548 
6549  (void)AppendVFormat( fmt, paramList );
6550 
6551  va_end( paramList );
6552  return *this;
6553  }
6554 
6567  int VFormat( const_c_string fmt, va_list paramList );
6568 
6581  int AppendVFormat( const_c_string fmt, va_list paramList );
6582 
6583  // -------------------------------------------------------------------------
6584 
6595  {
6596  ustring_base s;
6597  s.SetLength( Length() );
6598  uchar_iterator p = s.Begin();
6599  for ( const_iterator i = m_data->string; i < m_data->end; ++p, ++i )
6600  *p = uchar_type( *i );
6601  return s;
6602  }
6603 
6611  ustring_base UTF8ToUTF16( size_type i = 0, size_type n = maxPos ) const; // implemented inline after String
6612 
6628  ustring_base MBSToWCS() const;
6629 
6630 #ifdef __PCL_QT_INTERFACE
6631 
6632  QString ToQString() const
6633  {
6634  return operator QString();
6635  }
6636 
6637  QByteArray ToQByteArray() const
6638  {
6639  return operator QByteArray();
6640  }
6641 
6642  QDate ToQDate() const
6643  {
6644  return operator QDate();
6645  }
6646 
6647  QDateTime ToQDateTime() const
6648  {
6649  return operator QDateTime();
6650  }
6651 
6652 #endif
6653 
6664  bool ToBool() const;
6665 
6680  bool TryToBool( bool& value ) const;
6681 
6695  float ToFloat() const;
6696 
6711  bool TryToFloat( float& value ) const;
6712 
6736  double ToDouble() const;
6737 
6752  bool TryToDouble( double& value ) const;
6753 
6771  long ToInt() const
6772  {
6773  return ToInt( 0 );
6774  }
6775 
6799  bool TryToInt( int& value ) const
6800  {
6801  return TryToInt( value, 0 );
6802  }
6803 
6830  long ToInt( int base ) const;
6831 
6849  bool TryToInt( int& value, int base ) const;
6850 
6868  unsigned long ToUInt() const
6869  {
6870  return ToUInt( 0 );
6871  }
6872 
6896  bool TryToUInt( unsigned& value ) const
6897  {
6898  return TryToUInt( value, 0 );
6899  }
6900 
6917  unsigned long ToUInt( int base ) const;
6918 
6936  bool TryToUInt( unsigned& value, int base ) const;
6937 
6952  long long ToInt64() const
6953  {
6954  return ToInt64( 0 );
6955  }
6956 
6981  bool TryToInt64( long long& value ) const
6982  {
6983  return TryToInt64( value, 0 );
6984  }
6985 
7000  long long ToInt64( int base ) const;
7001 
7019  bool TryToInt64( long long& value, int base ) const;
7020 
7035  unsigned long long ToUInt64() const
7036  {
7037  return ToUInt64( 0 );
7038  }
7039 
7064  bool TryToUInt64( unsigned long long& value ) const
7065  {
7066  return TryToUInt64( value, 0 );
7067  }
7068 
7083  unsigned long long ToUInt64( int base ) const;
7084 
7102  bool TryToUInt64( unsigned long long& value, int base ) const;
7103 
7131  double SexagesimalToDouble( const IsoString& separator = ':' ) const
7132  {
7133  int sign, s1, s2; double s3;
7134  ParseSexagesimal( sign, s1, s2, s3, separator );
7135  return sign*(s1 + (s2 + s3/60)/60);
7136  }
7137 
7138  double SexagesimalToDouble( char separator ) const
7139  {
7140  return SexagesimalToDouble( IsoString( separator ) );
7141  }
7142 
7143  double SexagesimalToDouble( const ustring_base& separator ) const
7144  {
7145  return SexagesimalToDouble( IsoString( separator ) );
7146  }
7147 
7161  double SexagesimalToDouble( const Array<char_type>& separators ) const
7162  {
7163  int sign, s1, s2; double s3;
7164  ParseSexagesimal( sign, s1, s2, s3, separators );
7165  return sign*(s1 + (s2 + s3/60)/60);
7166  }
7167 
7185  bool TrySexagesimalToDouble( double& value, const IsoString& separator = ':' ) const
7186  {
7187  int sign, s1, s2; double s3;
7188  if ( TryParseSexagesimal( sign, s1, s2, s3, separator ) )
7189  {
7190  value = sign*(s1 + (s2 + s3/60)/60);
7191  return true;
7192  }
7193  return false;
7194  }
7195 
7196  bool TrySexagesimalToDouble( double& value, char separator ) const
7197  {
7198  return TrySexagesimalToDouble( value, IsoString( separator ) );
7199  }
7200 
7201  bool TrySexagesimalToDouble( double& value, const ustring_base& separator ) const
7202  {
7203  return TrySexagesimalToDouble( value, IsoString( separator ) );
7204  }
7205 
7218  bool TrySexagesimalToDouble( double& value, const Array<char_type>& separators ) const
7219  {
7220  int sign, s1, s2; double s3;
7221  if ( TryParseSexagesimal( sign, s1, s2, s3, separators ) )
7222  {
7223  value = sign*(s1 + (s2 + s3/60)/60);
7224  return true;
7225  }
7226  return false;
7227  }
7228 
7255  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const IsoString& separator = ':' ) const;
7256 
7257  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, char separator ) const
7258  {
7259  ParseSexagesimal( sign, s1, s2, s3, IsoString( separator ) );
7260  }
7261 
7262  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const ustring_base& separator ) const
7263  {
7264  ParseSexagesimal( sign, s1, s2, s3, IsoString( separator ) );
7265  }
7266 
7281  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const Array<char_type>& separators ) const;
7282 
7297  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const IsoString& separator = ':' ) const;
7298 
7299  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, char separator ) const
7300  {
7301  return TryParseSexagesimal( sign, s1, s2, s3, IsoString( separator ) );
7302  }
7303 
7304  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const ustring_base& separator ) const
7305  {
7306  return TryParseSexagesimal( sign, s1, s2, s3, IsoString( separator ) );
7307  }
7308 
7322  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const Array<char_type>& separators ) const;
7323 
7348  static IsoString ToSexagesimal( int sign, double s1, double s2, double s3,
7350 
7362  {
7363  return ToSexagesimal( (d < 0) ? -1 : +1, Abs( d ), 0, 0, options );
7364  }
7365 
7389  void ParseISO8601DateTime( int& year, int& month, int& day, double& dayf, double& tz ) const;
7390 
7404  bool TryParseISO8601DateTime( int& year, int& month, int& day, double& dayf, double& tz ) const;
7405 
7429  static IsoString ToISO8601DateTime( int year, int month, int day, double dayf, double tz = 0,
7431 
7442  static IsoString CurrentUTCISO8601DateTime( const ISO8601ConversionOptions& options = ISO8601ConversionOptions() );
7443 
7454  static IsoString CurrentLocalISO8601DateTime( const ISO8601ConversionOptions& options = ISO8601ConversionOptions() );
7455 
7463  static IsoString ToHex( const void* data, size_type length );
7464 
7477  template <class C>
7478  static IsoString ToHex( const C& c )
7479  {
7480  return ToHex( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
7481  }
7482 
7493  static IsoString ToBase64( const void* data, size_type length );
7494 
7507  template <class C>
7508  static IsoString ToBase64( const C& c )
7509  {
7510  return ToBase64( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
7511  }
7512 
7521  {
7522  return ByteArray( Begin(), End() );
7523  }
7524 
7537  ByteArray FromHex() const;
7538 
7551  ByteArray FromBase64() const;
7552 
7559  static IsoString Random( size_type n, RandomizationOptions options = RandomizationOption::Default );
7560 
7572  static IsoString UUID();
7573 };
7574 
7575 // ----------------------------------------------------------------------------
7576 
7586 {
7587  IsoString s( s1 );
7588  s.Append( s2 );
7589  return s;
7590 }
7591 
7598 {
7599  s1.Append( s2 );
7600  return IsoString( std::move( s1 ) );
7601 }
7602 
7609 {
7610  s1.Append( s2 );
7611  return std::move( s1 );
7612 }
7613 
7620 {
7621  s2.Prepend( s1 );
7622  return IsoString( std::move( s2 ) );
7623 }
7624 
7631 {
7632  s2.Prepend( s1 );
7633  return std::move( s2 );
7634 }
7635 
7642 {
7643  s1.Append( s2 );
7644  return IsoString( std::move( s1 ) );
7645 }
7646 
7653 {
7654  s1.Append( s2 );
7655  return std::move( s1 );
7656 }
7657 
7664 {
7665  s1.Append( s2 );
7666  return IsoString( std::move( s1 ) );
7667 }
7668 
7675 {
7676  s1.Append( s2 );
7677  return std::move( s1 );
7678 }
7679 
7680 // ----------------------------------------------------------------------------
7681 
7688 {
7689  IsoString s = s1;
7690  s.Append( t2 );
7691  return s;
7692 }
7693 
7700 {
7701  s1.Append( t2 );
7702  return IsoString( std::move( s1 ) );
7703 }
7704 
7711 {
7712  s1.Append( t2 );
7713  return std::move( s1 );
7714 }
7715 
7722 {
7723  IsoString s = s2;
7724  s.Prepend( t1 );
7725  return s;
7726 }
7727 
7734 {
7735  s2.Prepend( t1 );
7736  return IsoString( std::move( s2 ) );
7737 }
7738 
7745 {
7746  s2.Prepend( t1 );
7747  return std::move( s2 );
7748 }
7749 
7750 // ----------------------------------------------------------------------------
7751 
7758 {
7759  IsoString s = s1;
7760  s.Append( c2 );
7761  return s;
7762 }
7763 
7770 {
7771  s1.Append( c2 );
7772  return IsoString( std::move( s1 ) );
7773 }
7774 
7781 {
7782  s1.Append( c2 );
7783  return std::move( s1 );
7784 }
7785 
7792 {
7793  IsoString s = s2;
7794  s.Prepend( c1 );
7795  return s;
7796 }
7797 
7804 {
7805  s2.Prepend( c1 );
7806  return IsoString( std::move( s2 ) );
7807 }
7808 
7815 {
7816  s2.Prepend( c1 );
7817  return std::move( s2 );
7818 }
7819 
7820 // ----------------------------------------------------------------------------
7821 
7828 {
7829  s1.Append( s2 );
7830  return s1;
7831 }
7832 
7839 {
7840  s1.Append( s2 );
7841  return s1;
7842 }
7843 
7850 {
7851  s1.Append( t2 );
7852  return s1;
7853 }
7854 
7861 {
7862  s1.Append( t2 );
7863  return s1;
7864 }
7865 
7872 {
7873  s1.Append( c2 );
7874  return s1;
7875 }
7876 
7883 {
7884  s1.Append( c2 );
7885  return s1;
7886 }
7887 
7888 // ----------------------------------------------------------------------------
7889 
7890 #ifndef __PCL_NO_STRING_OSTREAM
7891 
7892 inline std::ostream& operator <<( std::ostream& o, const IsoString& s )
7893 {
7894  return o << s.c_str();
7895 }
7896 
7897 #endif
7898 
7899 // ----------------------------------------------------------------------------
7900 
7911 class PCL_CLASS String : public GenericString<char16_type, CharTraits, StandardAllocator>
7912 {
7913 public:
7914 
7920 
7925 
7930 
7935 
7940 
7945 
7950 
7951  /*
7952  * Null-terminated UTF-16 string - C++11 compatibility.
7953  */
7954  typedef char16_t* c16_string;
7955 
7956  /*
7957  * Immutable null-terminated UTF-16 string - C++11 compatibility.
7958  */
7959  typedef const char16_t* const_c16_string;
7960 
7965 
7970 
7975 
7980 
7990 
7995 
8000 
8005 
8010 
8015 
8020 
8021  // -------------------------------------------------------------------------
8022 
8027  {
8028  }
8029 
8034  String( const string_base& s ) : string_base( s )
8035  {
8036  }
8037 
8041  String( const String& s ) : string_base( s )
8042  {
8043  }
8044 
8049  String( string_base&& s ) : string_base( std::move( s ) )
8050  {
8051  }
8052 
8056  String( String&& s ) : string_base( std::move( s ) )
8057  {
8058  }
8059 
8065  {
8066  Assign( s );
8067  }
8068 
8072  String( const_iterator t ) : string_base( t )
8073  {
8074  }
8075 
8080  String( const_iterator t, size_type i, size_type n ) : string_base( t, i, n )
8081  {
8082  }
8083 
8087  String( char_type c, size_type n ) : string_base( c, n )
8088  {
8089  }
8090 
8095  String( const_iterator i, const_iterator j ) : string_base( i, j )
8096  {
8097  }
8098 
8107  String( std::initializer_list<char_type> l ) : String( l.begin(), l.end() )
8108  {
8109  }
8110 
8115  String( const char16_t* t ) : string_base( reinterpret_cast<const_iterator>( t ) )
8116  {
8117  }
8118 
8124  String( const char16_t* t, size_type i, size_type n ) : string_base( reinterpret_cast<const_iterator>( t ), i, n )
8125  {
8126  }
8127 
8131  String( char16_t c, size_type n ) : string_base( char_type( c ), n )
8132  {
8133  }
8134 
8139  String( const wchar_t* t ) : string_base()
8140  {
8141  Assign( t );
8142  }
8143 
8149  String( const wchar_t* t, size_type i, size_type n ) : string_base()
8150  {
8151  Assign( t, i, n );
8152  }
8153 
8157  String( wchar_t c, size_type n ) : string_base( char_type( c ), n )
8158  {
8159  }
8160 
8165  String( const_c_string8 t ) : string_base()
8166  {
8167  Assign( t );
8168  }
8169 
8175  String( const_c_string8 t, size_type i, size_type n ) : string_base()
8176  {
8177  Assign( t, i, n );
8178  }
8179 
8184  String( const_char8_iterator i, const_char8_iterator j ) : string_base()
8185  {
8186  Assign( i, j );
8187  }
8188 
8197  String( std::initializer_list<char8_type> l ) : String( l.begin(), l.end() )
8198  {
8199  }
8200 
8205  String( char8_type c, size_type n = 1 ) : string_base( char_type( c ), n )
8206  {
8207  }
8208 
8212  explicit
8213  String( bool x ) : string_base()
8214  {
8215  Assign( x ? "true" : "false" );
8216  }
8217 
8222  explicit
8223  String( short x ) : string_base()
8224  {
8225  (void)Format( L"%hd", x );
8226  }
8227 
8232  explicit
8233  String( unsigned short x ) : string_base()
8234  {
8235  (void)Format( L"%hu", x );
8236  }
8237 
8242  explicit
8243  String( int x ) : string_base()
8244  {
8245  (void)Format( L"%i", x );
8246  }
8247 
8252  explicit
8253  String( unsigned int x ) : string_base()
8254  {
8255  (void)Format( L"%u", x );
8256  }
8257 
8262  explicit
8263  String( long x ) : string_base()
8264  {
8265  (void)Format( L"%ld", x );
8266  }
8267 
8272  explicit
8273  String( unsigned long x ) : string_base()
8274  {
8275  (void)Format( L"%lu", x );
8276  }
8277 
8282  explicit
8283  String( long long x ) : string_base()
8284  {
8285  (void)Format( L"%lli", x );
8286  }
8287 
8292  explicit
8293  String( unsigned long long x ) : string_base()
8294  {
8295  (void)Format( L"%llu", x );
8296  }
8297 
8302  explicit
8303  String( float x ) : string_base()
8304  {
8305  (void)Format( L"%.7g", x );
8306  }
8307 
8312  explicit
8313  String( double x ) : string_base()
8314  {
8315  (void)Format( L"%.16g", x );
8316  }
8317 
8322  explicit
8323  String( long double x ) : string_base()
8324  {
8325 #ifdef _MSC_VER
8326  (void)Format( L"%.16Lg", x );
8327 #else
8328  (void)Format( L"%.18Lg", x );
8329 #endif
8330  }
8331 
8332 #ifndef __PCL_NO_STRING_COMPLEX
8333 
8337  explicit
8339  {
8340  (void)Format( L"{%.7g,%.7g}", x.Real(), x.Imag() );
8341  }
8342 
8346  explicit
8348  {
8349  (void)Format( L"{%.16g,%.16g}", x.Real(), x.Imag() );
8350  }
8351 
8355  explicit
8357  {
8358 #ifdef _MSC_VER
8359  (void)Format( L"{%.16Lg,%.16Lg}", x.Real(), x.Imag() );
8360 #else
8361  (void)Format( L"{%.18Lg,%.18Lg}", x.Real(), x.Imag() );
8362 #endif
8363  }
8364 
8365 #endif // !__PCL_NO_STRING_COMPLEX
8366 
8367 #ifdef __PCL_QT_INTERFACE
8368 
8369  explicit
8370  String( const QString& qs ) :
8371  string_base( qs.isEmpty() ? iterator( nullptr ) : iterator( PCL_GET_CHAR16PTR_FROM_QSTRING( qs ) ) )
8372  {
8373  }
8374 
8375  explicit
8376  String( const QDate& qd ) :
8377  string_base( iterator( PCL_GET_CHAR16PTR_FROM_QSTRING( qd.toString( PCL_QDATE_FMT_STR ) ) ) )
8378  {
8379  }
8380 
8381  explicit
8382  String( const QDateTime& qdt ) :
8383  string_base( iterator( PCL_GET_CHAR16PTR_FROM_QSTRING( qdt.toString( PCL_QDATETIME_FMT_STR ) ) ) )
8384  {
8385  }
8386 
8387 #endif
8388 
8389  // -------------------------------------------------------------------------
8390 
8394  String& operator =( const String& s )
8395  {
8396  string_base::Assign( s );
8397  return *this;
8398  }
8399 
8403  String& operator =( String&& s )
8404  {
8405  string_base::Transfer( s );
8406  return *this;
8407  }
8408 
8413  String& operator =( const string_base& s )
8414  {
8415  string_base::Assign( s );
8416  return *this;
8417  }
8418 
8423  String& operator =( string_base&& s )
8424  {
8425  string_base::Transfer( s );
8426  return *this;
8427  }
8428 
8433  String& operator =( const string8_base& s )
8434  {
8435  Assign( s );
8436  return *this;
8437  }
8438 
8443  String& operator =( const_iterator t )
8444  {
8445  string_base::Assign( t );
8446  return *this;
8447  }
8448 
8453  String& operator =( char_type c )
8454  {
8455  string_base::Assign( c );
8456  return *this;
8457  }
8458 
8463  String& operator =( const char16_t* t )
8464  {
8465  string_base::Assign( reinterpret_cast<const_iterator>( t ) );
8466  return *this;
8467  }
8468 
8473  String& operator =( char16_t c )
8474  {
8475  string_base::Assign( char_type( c ) );
8476  return *this;
8477  }
8478 
8483  String& operator =( const wchar_t* t )
8484  {
8485  Assign( t );
8486  return *this;
8487  }
8488 
8493  String& operator =( wchar_t c )
8494  {
8495  Assign( c );
8496  return *this;
8497  }
8498 
8503  String& operator =( const_c_string8 t )
8504  {
8505  Assign( t );
8506  return *this;
8507  }
8508 
8513  String& operator =( char8_type c )
8514  {
8515  Assign( c );
8516  return *this;
8517  }
8518 
8519 #ifdef __PCL_QT_INTERFACE
8520 
8521  String& operator =( const QString& qs )
8522  {
8523  if ( qs.isEmpty() )
8524  Clear();
8525  else
8526  string_base::Assign( PCL_GET_CHAR16PTR_FROM_QSTRING( qs ) );
8527  return *this;
8528  }
8529 
8530  String& operator =( const QDate& qd )
8531  {
8532  string_base::Assign( PCL_GET_CHAR16PTR_FROM_QSTRING( qd.toString( PCL_QDATE_FMT_STR ) ) );
8533  return *this;
8534  }
8535 
8536  String& operator =( const QDateTime& qdt )
8537  {
8538  string_base::Assign( PCL_GET_CHAR16PTR_FROM_QSTRING( qdt.toString( PCL_QDATETIME_FMT_STR ) ) );
8539  return *this;
8540  }
8541 
8542 #endif
8543 
8544  // -------------------------------------------------------------------------
8545 
8549  void Assign( const String& s )
8550  {
8551  string_base::Assign( s );
8552  }
8553 
8558  void Assign( const String& s, size_type i, size_type n )
8559  {
8560  string_base::Assign( s, i, n );
8561  }
8562 
8566  void Assign( const_iterator t )
8567  {
8568  string_base::Assign( t );
8569  }
8570 
8575  void Assign( const_iterator i, const_iterator j )
8576  {
8577  string_base::Assign( i, j );
8578  }
8579 
8586  void Assign( std::initializer_list<char_type> l )
8587  {
8588  Assign( l.begin(), l.end() );
8589  }
8590 
8596  void Assign( const_iterator t, size_type i, size_type n )
8597  {
8598  string_base::Assign( t, i, n );
8599  }
8600 
8604  void Assign( char_type c, size_type n = 1 )
8605  {
8606  string_base::Assign( c, n );
8607  }
8608 
8612  void Assign( const char16_t* t )
8613  {
8614  string_base::Assign( reinterpret_cast<const_iterator>( t ) );
8615  }
8616 
8622  void Assign( const char16_t* t, size_type i, size_type n )
8623  {
8624  string_base::Assign( reinterpret_cast<const_iterator>( t ), i, n );
8625  }
8626 
8630  void Assign( char16_t c, size_type n = 1 )
8631  {
8632  string_base::Assign( char_type( c ), n );
8633  }
8634 
8638  void Assign( const wchar_t* t );
8639 
8645  void Assign( const wchar_t* t, size_type i, size_type n );
8646 
8650  void Assign( wchar_t c, size_type n = 1 )
8651  {
8652  string_base::Assign( char_type( c ), n );
8653  }
8654 
8658  void Assign( const string8_base& s )
8659  {
8660  size_type n = s.Length();
8661  if ( n > 0 )
8662  {
8663  MaybeReallocate( n );
8664  const_char8_iterator t = s.Begin();
8665  for ( iterator i = m_data->string; i < m_data->end; ++i, ++t )
8666  *i = char_type( uint8( *t ) );
8667  }
8668  else
8669  Clear();
8670  }
8671 
8676  void Assign( const_c_string8 t )
8677  {
8678  size_type n = char8_traits::Length( t );
8679  if ( n > 0 )
8680  {
8681  MaybeReallocate( n );
8682  for ( iterator i = m_data->string; i < m_data->end; ++i, ++t )
8683  *i = char_type( uint8( *t ) );
8684  }
8685  else
8686  Clear();
8687  }
8688 
8694  void Assign( const_c_string8 t, size_type i, size_type n )
8695  {
8696  size_type len = char8_traits::Length( t );
8697  if ( i < len )
8698  {
8699  n = pcl::Min( n, len-i );
8700  MaybeReallocate( n );
8701  t += i;
8702  for ( iterator i = m_data->string; i < m_data->end; ++i, ++t )
8703  *i = char_type( uint8( *t ) );
8704  }
8705  else
8706  Clear();
8707  }
8708 
8713  void Assign( const_char8_iterator p, const_char8_iterator q )
8714  {
8715  if ( p < q )
8716  {
8717  MaybeReallocate( q - p );
8718  for ( iterator i = m_data->string; i < m_data->end; ++i, ++p )
8719  *i = char_type( uint8( *p ) );
8720  }
8721  else
8722  Clear();
8723  }
8724 
8732  void Assign( std::initializer_list<char8_type> l )
8733  {
8734  Assign( l.begin(), l.end() );
8735  }
8736 
8740  void Assign( char8_type c, size_type n = 1 )
8741  {
8742  string_base::Assign( char_type( c ), n );
8743  }
8744 
8745  // -------------------------------------------------------------------------
8746 
8747  void Insert( size_type i, const String& s )
8748  {
8749  string_base::Insert( i, s );
8750  }
8751 
8752  void Insert( size_type i, const_iterator p, const_iterator q )
8753  {
8754  string_base::Insert( i, p, q );
8755  }
8756 
8757  void Insert( size_type i, const_iterator t )
8758  {
8759  string_base::Insert( i, t );
8760  }
8761 
8762  void Insert( size_type i, const_iterator t, size_type n )
8763  {
8764  string_base::Insert( i, t, n );
8765  }
8766 
8767  void Insert( size_type i, char_type c, size_type n = 1 )
8768  {
8769  string_base::Insert( i, c, n );
8770  }
8771 
8772  void Insert( size_type i, const char16_t* t )
8773  {
8774  string_base::Insert( i, reinterpret_cast<const_iterator>( t ) );
8775  }
8776 
8777  void Insert( size_type i, char16_t c, size_type n = 1 )
8778  {
8779  string_base::Insert( i, String( c, n ) );
8780  }
8781 
8782  void Insert( size_type i, const wchar_t* t )
8783  {
8784 #ifdef __PCL_WINDOWS
8785  string_base::Insert( i, reinterpret_cast<const_iterator>( t ) );
8786 #else
8787  string_base::Insert( i, String( t ) );
8788 #endif
8789  }
8790 
8791  void Insert( size_type i, wchar_t c, size_type n = 1 )
8792  {
8793  string_base::Insert( i, String( c, n ) );
8794  }
8795 
8796  void Insert( size_type i, const string8_base& s, size_type n )
8797  {
8798  n = pcl::Min( n, s.Length() );
8799  if ( n > 0 )
8800  {
8801  UninitializedGrow( i, n ); // -> 0 <= i <= len
8802  const_char8_iterator t = s.Begin();
8803  for ( iterator p = m_data->string+i, q = p+n; p < q; ++p, ++t )
8804  *p = char_type( uint8( *t ) );
8805  }
8806  }
8807 
8808  void Insert( size_type i, const string8_base& s )
8809  {
8810  size_type n = s.Length();
8811  if ( n > 0 )
8812  {
8813  UninitializedGrow( i, n ); // -> 0 <= i <= len
8814  const_char8_iterator t = s.Begin();
8815  for ( iterator p = m_data->string+i, q = p+n; p < q; ++p, ++t )
8816  *p = char_type( uint8( *t ) );
8817  }
8818  }
8819 
8820  void Insert( size_type i, const_c_string8 t )
8821  {
8822  size_type n = char8_traits::Length( t );
8823  if ( n > 0 )
8824  {
8825  UninitializedGrow( i, n ); // -> 0 <= i <= len
8826  for ( iterator p = m_data->string+i, q = p+n; p < q; ++p, ++t )
8827  *p = char_type( uint8( *t ) );
8828  }
8829  }
8830 
8831  void Insert( size_type i, const_c_string8 t, size_type n )
8832  {
8833  n = pcl::Min( n, char8_traits::Length( t ) );
8834  if ( n > 0 )
8835  {
8836  UninitializedGrow( i, n ); // -> 0 <= i <= len
8837  for ( iterator p = m_data->string+i, q = p+n; p < q; ++p, ++t )
8838  *p = char_type( uint8( *t ) );
8839  }
8840  }
8841 
8842  void Insert( size_type i, const_char8_iterator p, const_char8_iterator q )
8843  {
8844  if ( p < q )
8845  {
8846  size_type n = q - p;
8847  UninitializedGrow( i, n ); // -> 0 <= i <= len
8848  for ( iterator r = m_data->string+i, s = r+n; r < s; ++r, ++p )
8849  *r = char_type( uint8( *p ) );
8850  }
8851  }
8852 
8853  void Insert( size_type i, char8_type c, size_type n = 1 )
8854  {
8855  string_base::Insert( i, char_type( c ), n );
8856  }
8857 
8858  // -------------------------------------------------------------------------
8859 
8860  void Append( const String& s )
8861  {
8862  string_base::Append( s );
8863  }
8864 
8865  String& operator +=( const String& s )
8866  {
8867  Append( s );
8868  return *this;
8869  }
8870 
8871  void Append( const_iterator i, const_iterator j )
8872  {
8873  string_base::Append( i, j );
8874  }
8875 
8876  void Append( const_iterator t )
8877  {
8878  string_base::Append( t );
8879  }
8880 
8881  String& operator +=( const_iterator t )
8882  {
8883  Append( t );
8884  return *this;
8885  }
8886 
8887  void Append( const_iterator t, size_type n )
8888  {
8889  string_base::Append( t, n );
8890  }
8891 
8892  void Append( char_type c, size_type n = 1 )
8893  {
8894  string_base::Append( c, n );
8895  }
8896 
8897  String& operator +=( char_type c )
8898  {
8899  Append( c );
8900  return *this;
8901  }
8902 
8903  void Append( const char16_t* t )
8904  {
8905  string_base::Append( reinterpret_cast<const_iterator>( t ) );
8906  }
8907 
8908  String& operator +=( const char16_t* t )
8909  {
8910  Append( t );
8911  return *this;
8912  }
8913 
8914  void Append( char16_t c, size_type n = 1 )
8915  {
8916  string_base::Append( char_type( c ), n );
8917  }
8918 
8919  String& operator +=( char16_t c )
8920  {
8921  Append( c );
8922  return *this;
8923  }
8924 
8925  void Append( const wchar_t* t )
8926  {
8927 #ifdef __PCL_WINDOWS
8928  string_base::Append( reinterpret_cast<const_iterator>( t ) );
8929 #else
8930  string_base::Append( String( t ) );
8931 #endif
8932  }
8933 
8934  String& operator +=( const wchar_t* t )
8935  {
8936  Append( t );
8937  return *this;
8938  }
8939 
8940  void Append( wchar_t c, size_type n = 1 )
8941  {
8942  string_base::Append( char_type( c ), n );
8943  }
8944 
8945  String& operator +=( wchar_t c )
8946  {
8947  Append( c );
8948  return *this;
8949  }
8950 
8951  void Append( const string8_base& s )
8952  {
8953  Insert( maxPos, s );
8954  }
8955 
8956  String& operator +=( const string8_base& s )
8957  {
8958  Append( s );
8959  return *this;
8960  }
8961 
8962  void Append( const string8_base& s, size_type n )
8963  {
8964  Insert( maxPos, s, n );
8965  }
8966 
8967  void Append( const_c_string8 t )
8968  {
8969  Insert( maxPos, t );
8970  }
8971 
8972  String& operator +=( const_c_string8 t )
8973  {
8974  Append( t );
8975  return *this;
8976  }
8977 
8978  void Append( const_c_string8 t, size_type n )
8979  {
8980  Insert( maxPos, t, n );
8981  }
8982 
8983  void Append( const_char8_iterator p, const_char8_iterator q )
8984  {
8985  Insert( maxPos, p, q );
8986  }
8987 
8988  void Append( char8_type c, size_type n = 1 )
8989  {
8990  string_base::Append( char_type( c ), n );
8991  }
8992 
8993  String& operator +=( char8_type c )
8994  {
8995  Append( c );
8996  return *this;
8997  }
8998 
8999  void Add( const String& s )
9000  {
9001  Append( s );
9002  }
9003 
9004  void Add( const_iterator i, const_iterator j )
9005  {
9006  Append( i, j );
9007  }
9008 
9009  void Add( const_iterator t )
9010  {
9011  Append( t );
9012  }
9013 
9014  void Add( const_iterator t, size_type n )
9015  {
9016  Append( t, n );
9017  }
9018 
9019  void Add( char_type c, size_type n = 1 )
9020  {
9021  Append( c, n );
9022  }
9023 
9024  void Add( const char16_t* t )
9025  {
9026  Append( t );
9027  }
9028 
9029  void Add( char16_t c, size_type n = 1 )
9030  {
9031  Append( c, n );
9032  }
9033 
9034  void Add( const wchar_t* t )
9035  {
9036  Append( t );
9037  }
9038 
9039  void Add( wchar_t c, size_type n = 1 )
9040  {
9041  Append( c, n );
9042  }
9043 
9044  void Add( const string8_base& s )
9045  {
9046  Append( s );
9047  }
9048 
9049  void Add( const string8_base& s, size_type n )
9050  {
9051  Append( s, n );
9052  }
9053 
9054  void Add( const_c_string8 t )
9055  {
9056  Append( t );
9057  }
9058 
9059  void Add( const_c_string8 t, size_type n )
9060  {
9061  Append( t, n );
9062  }
9063 
9064  void Add( const_char8_iterator p, const_char8_iterator q )
9065  {
9066  Append( p, q );
9067  }
9068 
9069  void Add( char8_type c, size_type n = 1 )
9070  {
9071  Append( c, n );
9072  }
9073 
9074  // -------------------------------------------------------------------------
9075 
9076  void Prepend( const String& s )
9077  {
9078  string_base::Prepend( s );
9079  }
9080 
9081  String& operator -=( const String& s )
9082  {
9083  Prepend( s );
9084  return *this;
9085  }
9086 
9087  void Prepend( const_iterator i, const_iterator j )
9088  {
9089  string_base::Prepend( i, j );
9090  }
9091 
9092  void Prepend( const_iterator t )
9093  {
9094  string_base::Prepend( t );
9095  }
9096 
9097  String& operator -=( const_iterator t )
9098  {
9099  Prepend( t );
9100  return *this;
9101  }
9102 
9103  void Prepend( const_iterator t, size_type n )
9104  {
9105  string_base::Prepend( t, n );
9106  }
9107 
9108  void Prepend( char_type c, size_type n = 1 )
9109  {
9110  string_base::Prepend( c, n );
9111  }
9112 
9113  String& operator -=( char_type c )
9114  {
9115  Prepend( c );
9116  return *this;
9117  }
9118 
9119  void Prepend( const char16_t* t )
9120  {
9121  string_base::Prepend( reinterpret_cast<const_iterator>( t ) );
9122  }
9123 
9124  String& operator -=( const char16_t* t )
9125  {
9126  Prepend( t );
9127  return *this;
9128  }
9129 
9130  void Prepend( char16_t c, size_type n = 1 )
9131  {
9132  string_base::Prepend( char_type( c ), n );
9133  }
9134 
9135  String& operator -=( char16_t c )
9136  {
9137  Prepend( c );
9138  return *this;
9139  }
9140 
9141  void Prepend( const wchar_t* t )
9142  {
9143 #ifdef __PCL_WINDOWS
9144  string_base::Prepend( reinterpret_cast<const_iterator>( t ) );
9145 #else
9146  string_base::Prepend( String( t ) );
9147 #endif
9148  }
9149 
9150  String& operator -=( const wchar_t* t )
9151  {
9152  Prepend( t );
9153  return *this;
9154  }
9155 
9156  void Prepend( wchar_t c, size_type n = 1 )
9157  {
9158  string_base::Prepend( char_type( c ), n );
9159  }
9160 
9161  String& operator -=( wchar_t c )
9162  {
9163  Prepend( c );
9164  return *this;
9165  }
9166 
9167  void Prepend( const string8_base& s )
9168  {
9169  Insert( 0, s );
9170  }
9171 
9172  String& operator -=( const string8_base& s )
9173  {
9174  Prepend( s );
9175  return *this;
9176  }
9177 
9178  void Prepend( const string8_base& s, size_type n )
9179  {
9180  Insert( 0, s, n );
9181  }
9182 
9183  void Prepend( const_c_string8 t )
9184  {
9185  Insert( 0, t );
9186  }
9187 
9188  String& operator -=( const_c_string8 t )
9189  {
9190  Prepend( t );
9191  return *this;
9192  }
9193 
9194  void Prepend( const_c_string8 t, size_type n )
9195  {
9196  Insert( 0, t, n );
9197  }
9198 
9199  void Prepend( const_char8_iterator p, const_char8_iterator q )
9200  {
9201  Insert( 0, p, q );
9202  }
9203 
9204  void Prepend( char8_type c, size_type n = 1 )
9205  {
9206  string_base::Prepend( String( c, n ) );
9207  }
9208 
9209  String& operator -=( char8_type c )
9210  {
9211  Prepend( c );
9212  return *this;
9213  }
9214 
9215  // -------------------------------------------------------------------------
9216 
9217  void Replace( size_type i, size_type n, const String& s )
9218  {
9219  string_base::Replace( i, n, s );
9220  }
9221 
9222  void Replace( size_type i, size_type n, const_iterator t )
9223  {
9224  string_base::Replace( i, n, t );
9225  }
9226 
9227  void Replace( size_type i, size_type n, char_type c, size_type nc = 1 )
9228  {
9229  string_base::Replace( i, n, c, nc );
9230  }
9231 
9232  void Replace( size_type i, size_type n, const char16_t* t )
9233  {
9234  string_base::Replace( i, n, reinterpret_cast<const_iterator>( t ) );
9235  }
9236 
9237  void Replace( size_type i, size_type n, char16_t c, size_type nc = 1 )
9238  {
9239  string_base::Replace( i, n, char_type( c ), nc );
9240  }
9241 
9242  void Replace( size_type i, size_type n, const wchar_t* t )
9243  {
9244 #ifdef __PCL_WINDOWS
9245  string_base::Replace( i, n, reinterpret_cast<const_iterator>( t ) );
9246 #else
9247  string_base::Replace( i, n, String( t ) );
9248 #endif
9249  }
9250 
9251  void Replace( size_type i, size_type n, wchar_t c, size_type nc = 1 )
9252  {
9253  string_base::Replace( i, n, char_type( c ), nc );
9254  }
9255 
9256  void Replace( size_type i, size_type n, const_c_string8 t )
9257  {
9258  if ( n > 0 )
9259  {
9260  size_type len = Length();
9261  if ( i < len )
9262  {
9263  n = pcl::Min( n, len-i );
9264  if ( n == len )
9265  Assign( t );
9266  else
9267  {
9268  size_type nt = char8_traits::Length( t );
9269  if ( nt > 0 )
9270  {
9271  if ( n < nt )
9272  UninitializedGrow( i, nt-n );
9273  else if ( nt < n )
9274  Delete( i, n-nt );
9275  else
9276  EnsureUnique();
9277 
9278  for ( iterator p = m_data->string+i, q = p+nt; p < q; ++p, ++t )
9279  *p = char_type( *t );
9280  }
9281  else
9282  Delete( i, n );
9283  }
9284  }
9285  }
9286  }
9287 
9288  void Replace( size_type i, size_type n, char8_type c, size_type nc = 1 )
9289  {
9290  string_base::Replace( i, n, char_type( c ), nc );
9291  }
9292 
9293  // -------------------------------------------------------------------------
9294 
9295  void ReplaceChar( char_type c1, char_type c2, size_type i = 0, size_type n = maxPos )
9296  {
9297  string_base::ReplaceChar( c1, c2, i, n );
9298  }
9299 
9300  void ReplaceCharIC( char_type c1, char_type c2, size_type i = 0, size_type n = maxPos )
9301  {
9302  string_base::ReplaceCharIC( c1, c2, i, n );
9303  }
9304 
9305  void ReplaceChar( char16_t c1, char16_t c2, size_type i = 0, size_type n = maxPos )
9306  {
9307  string_base::ReplaceChar( char_type( c1 ), char_type( c2 ), i, n );
9308  }
9309 
9310  void ReplaceCharIC( char16_t c1, char16_t c2, size_type i = 0, size_type n = maxPos )
9311  {
9312  string_base::ReplaceCharIC( char_type( c1 ), char_type( c2 ), i, n );
9313  }
9314 
9315  void ReplaceChar( wchar_t c1, wchar_t c2, size_type i = 0, size_type n = maxPos )
9316  {
9317  string_base::ReplaceChar( char_type( c1 ), char_type( c2 ), i, n );
9318  }
9319 
9320  void ReplaceCharIC( wchar_t c1, wchar_t c2, size_type i = 0, size_type n = maxPos )
9321  {
9322  string_base::ReplaceCharIC( char_type( c1 ), char_type( c2 ), i, n );
9323  }
9324 
9325  void ReplaceChar( char8_type c1, char8_type c2, size_type i = 0, size_type n = maxPos )
9326  {
9327  string_base::ReplaceChar( char_type( c1 ), char_type( c2 ), i, n );
9328  }
9329 
9330  void ReplaceCharIC( char8_type c1, char8_type c2, size_type i = 0, size_type n = maxPos )
9331  {
9332  string_base::ReplaceCharIC( char_type( c1 ), char_type( c2 ), i, n );
9333  }
9334 
9335  // -------------------------------------------------------------------------
9336 
9337  void ReplaceString( const String& s1, const String& s2, size_type i = 0 )
9338  {
9339  string_base::ReplaceString( s1, s2, i );
9340  }
9341 
9342  void ReplaceStringIC( const String& s1, const String& s2, size_type i = 0 )
9343  {
9344  string_base::ReplaceStringIC( s1, s2, i );
9345  }
9346 
9347  void ReplaceString( const_iterator t1, const_iterator t2, size_type i = 0 )
9348  {
9349  string_base::ReplaceString( t1, t2, i );
9350  }
9351 
9352  void ReplaceStringIC( const_iterator t1, const_iterator t2, size_type i = 0 )
9353  {
9354  string_base::ReplaceStringIC( t1, t2, i );
9355  }
9356 
9357  void ReplaceString( const char16_t* t1, const char16_t* t2, size_type i = 0 )
9358  {
9359  string_base::ReplaceString( reinterpret_cast<const_iterator>( t1 ),
9360  reinterpret_cast<const_iterator>( t2 ), i );
9361  }
9362 
9363  void ReplaceStringIC( const char16_t* t1, const char16_t* t2, size_type i = 0 )
9364  {
9365  string_base::ReplaceStringIC( reinterpret_cast<const_iterator>( t1 ),
9366  reinterpret_cast<const_iterator>( t2 ), i );
9367  }
9368 
9369  void ReplaceString( const wchar_t* t1, const wchar_t* t2, size_type i = 0 )
9370  {
9371 #ifdef __PCL_WINDOWS
9372  string_base::ReplaceString( reinterpret_cast<const_iterator>( t1 ),
9373  reinterpret_cast<const_iterator>( t2 ), i );
9374 #else
9375  string_base::ReplaceString( String( t1 ), String( t2 ), i );
9376 #endif
9377  }
9378 
9379  void ReplaceStringIC( const wchar_t* t1, const wchar_t* t2, size_type i = 0 )
9380  {
9381 #ifdef __PCL_WINDOWS
9382  string_base::ReplaceStringIC( reinterpret_cast<const_iterator>( t1 ),
9383  reinterpret_cast<const_iterator>( t2 ), i );
9384 #else
9385  string_base::ReplaceStringIC( String( t1 ), String( t2 ), i );
9386 #endif
9387  }
9388 
9389  void ReplaceString( const_c_string8 t1, const_c_string8 t2, size_type i = 0 )
9390  {
9391  string_base::ReplaceString( String( t1 ), String( t2 ), i );
9392  }
9393 
9394  void ReplaceStringIC( const_c_string8 t1, const_c_string8 t2, size_type i = 0 )
9395  {
9396  string_base::ReplaceStringIC( String( t1 ), String( t2 ), i );
9397  }
9398 
9399  // -------------------------------------------------------------------------
9400 
9401  void DeleteChar( char_type c, size_type i = 0 )
9402  {
9403  string_base::DeleteChar( c, i );
9404  }
9405 
9406  void DeleteCharIC( char_type c, size_type i = 0 )
9407  {
9408  string_base::DeleteCharIC( c, i );
9409  }
9410 
9411  void DeleteChar( char16_t c, size_type i = 0 )
9412  {
9413  string_base::DeleteChar( char_type( c ), i );
9414  }
9415 
9416  void DeleteCharIC( char16_t c, size_type i = 0 )
9417  {
9418  string_base::DeleteCharIC( char_type( c ), i );
9419  }
9420 
9421  void DeleteChar( wchar_t c, size_type i = 0 )
9422  {
9423  string_base::DeleteChar( char_type( c ), i );
9424  }
9425 
9426  void DeleteCharIC( wchar_t c, size_type i = 0 )
9427  {
9428  string_base::DeleteCharIC( char_type( c ), i );
9429  }
9430 
9431  void DeleteChar( char8_type c, size_type i = 0 )
9432  {
9433  string_base::DeleteChar( char_type( c ), i );
9434  }
9435 
9436  void DeleteCharIC( char8_type c, size_type i = 0 )
9437  {
9438  string_base::DeleteCharIC( char_type( c ), i );
9439  }
9440 
9441  // -------------------------------------------------------------------------
9442 
9443  void DeleteString( const String& s, size_type i = 0 )
9444  {
9445  string_base::DeleteString( s, i );
9446  }
9447 
9448  void DeleteStringIC( const String& s, size_type i = 0 )
9449  {
9450  string_base::DeleteStringIC( s, i );
9451  }
9452 
9453  void DeleteString( const_iterator t, size_type i = 0 )
9454  {
9455  string_base::DeleteString( t, i );
9456  }
9457 
9458  void DeleteStringIC( const_iterator t, size_type i = 0 )
9459  {
9460  string_base::DeleteStringIC( t, i );
9461  }
9462 
9463  void DeleteString( const char16_t* t, size_type i = 0 )
9464  {
9465  string_base::DeleteString( reinterpret_cast<const_iterator>( t ), i );
9466  }
9467 
9468  void DeleteStringIC( const char16_t* t, size_type i = 0 )
9469  {
9470  string_base::DeleteStringIC( reinterpret_cast<const_iterator>( t ), i );
9471  }
9472 
9473  void DeleteString( const wchar_t* t, size_type i = 0 )
9474  {
9475 #ifdef __PCL_WINDOWS
9476  string_base::DeleteString( reinterpret_cast<const_iterator>( t ), i );
9477 #else
9478  string_base::DeleteString( String( t ), i );
9479 #endif
9480  }
9481 
9482  void DeleteStringIC( const wchar_t* t, size_type i = 0 )
9483  {
9484 #ifdef __PCL_WINDOWS
9485  string_base::DeleteStringIC( reinterpret_cast<const_iterator>( t ), i );
9486 #else
9487  string_base::DeleteStringIC( String( t ), i );
9488 #endif
9489  }
9490 
9491  void DeleteString( const_c_string8 t, size_type i = 0 )
9492  {
9493  string_base::DeleteString( String( t ), i );
9494  }
9495 
9496  void DeleteStringIC( const_c_string8 t, size_type i = 0 )
9497  {
9498  string_base::DeleteStringIC( String( t ), i );
9499  }
9500 
9501  // -------------------------------------------------------------------------
9502 
9503  bool StartsWith( const String& s ) const
9504  {
9505  return string_base::StartsWith( s );
9506  }
9507 
9508  bool StartsWith( const_iterator t ) const
9509  {
9510  return string_base::StartsWith( t );
9511  }
9512 
9513  bool StartsWith( char_type c ) const
9514  {
9515  return string_base::StartsWith( c );
9516  }
9517 
9518  bool StartsWithIC( const String& s ) const
9519  {
9520  return string_base::StartsWithIC( s );
9521  }
9522 
9523  bool StartsWithIC( const_iterator t ) const
9524  {
9525  return string_base::StartsWithIC( t );
9526  }
9527 
9528  bool StartsWithIC( char_type c ) const
9529  {
9530  return string_base::StartsWithIC( c );
9531  }
9532 
9533  bool StartsWith( const char16_t* t ) const
9534  {
9535  return string_base::StartsWith( reinterpret_cast<const_iterator>( t ) );
9536  }
9537 
9538  bool StartsWith( char16_t c ) const
9539  {
9540  return string_base::StartsWith( char_type( c ) );
9541  }
9542 
9543  bool StartsWithIC( const char16_t* t ) const
9544  {
9545  return string_base::StartsWithIC( reinterpret_cast<const_iterator>( t ) );
9546  }
9547 
9548  bool StartsWithIC( char16_t c ) const
9549  {
9550  return string_base::StartsWithIC( char_type( c ) );
9551  }
9552 
9553  bool StartsWith( const wchar_t* t ) const
9554  {
9555 #ifdef __PCL_WINDOWS
9556  return string_base::StartsWith( reinterpret_cast<const_iterator>( t ) );
9557 #else
9558  return string_base::StartsWith( String( t ) );
9559 #endif
9560  }
9561 
9562  bool StartsWith( wchar_t c ) const
9563  {
9564  return string_base::StartsWith( char_type( c ) );
9565  }
9566 
9567  bool StartsWithIC( const wchar_t* t ) const
9568  {
9569 #ifdef __PCL_WINDOWS
9570  return string_base::StartsWithIC( reinterpret_cast<const_iterator>( t ) );
9571 #else
9572  return string_base::StartsWithIC( String( t ) );
9573 #endif
9574  }
9575 
9576  bool StartsWithIC( wchar_t c ) const
9577  {
9578  return string_base::StartsWithIC( char_type( c ) );
9579  }
9580 
9581  bool StartsWith( const_c_string8 t ) const
9582  {
9583  size_type n = char8_traits::Length( t );
9584  if ( n == 0 || Length() < n )
9585  return false;
9586  for ( const_iterator p = m_data->string, q = p+n; p < q; ++p, ++t )
9587  if ( *p != char_type( *t ) )
9588  return false;
9589  return true;
9590  }
9591 
9592  bool StartsWith( char8_type c ) const
9593  {
9594  return string_base::StartsWith( char_type( c ) );
9595  }
9596 
9597  bool StartsWithIC( const_c_string8 t ) const
9598  {
9599  size_type n = char8_traits::Length( t );
9600  if ( n == 0 || Length() < n )
9601  return false;
9602  for ( const_iterator p = m_data->string, q = p+n; p < q; ++p, ++t )
9603  if ( char_traits::ToCaseFolded( *p ) != char_type( char8_traits::ToCaseFolded( *t ) ) )
9604  return false;
9605  return true;
9606  }
9607 
9608  bool StartsWithIC( char8_type c ) const
9609  {
9610  return string_base::StartsWithIC( char_type( c ) );
9611  }
9612 
9613  // -------------------------------------------------------------------------
9614 
9615  bool EndsWith( const String& s ) const
9616  {
9617  return string_base::EndsWith( s );
9618  }
9619 
9620  bool EndsWith( const_iterator t ) const
9621  {
9622  return string_base::EndsWith( t );
9623  }
9624 
9625  bool EndsWith( char_type c ) const
9626  {
9627  return string_base::EndsWith( c );
9628  }
9629 
9630  bool EndsWithIC( const String& s ) const
9631  {
9632  return string_base::EndsWithIC( s );
9633  }
9634 
9635  bool EndsWithIC( const_iterator t ) const
9636  {
9637  return string_base::EndsWithIC( t );
9638  }
9639 
9640  bool EndsWithIC( char_type c ) const
9641  {
9642  return string_base::EndsWithIC( c );
9643  }
9644 
9645  bool EndsWith( const char16_t* t ) const
9646  {
9647  return string_base::EndsWith( reinterpret_cast<const_iterator>( t ) );
9648  }
9649 
9650  bool EndsWith( char16_t c ) const
9651  {
9652  return string_base::EndsWith( char_type( c ) );
9653  }
9654 
9655  bool EndsWithIC( const char16_t* t ) const
9656  {
9657  return string_base::EndsWithIC( reinterpret_cast<const_iterator>( t ) );
9658  }
9659 
9660  bool EndsWithIC( char16_t c ) const
9661  {
9662  return string_base::EndsWithIC( char_type( c ) );
9663  }
9664 
9665  bool EndsWith( const wchar_t* t ) const
9666  {
9667 #ifdef __PCL_WINDOWS
9668  return string_base::EndsWith( reinterpret_cast<const_iterator>( t ) );
9669 #else
9670  return string_base::EndsWith( String( t ) );
9671 #endif
9672  }
9673 
9674  bool EndsWith( wchar_t c ) const
9675  {
9676  return string_base::EndsWith( char_type( c ) );
9677  }
9678 
9679  bool EndsWithIC( const wchar_t* t ) const
9680  {
9681 #ifdef __PCL_WINDOWS
9682  return string_base::EndsWithIC( reinterpret_cast<const_iterator>( t ) );
9683 #else
9684  return string_base::EndsWithIC( String( t ) );
9685 #endif
9686  }
9687 
9688  bool EndsWithIC( wchar_t c ) const
9689  {
9690  return string_base::EndsWithIC( char_type( c ) );
9691  }
9692 
9693  bool EndsWith( const_c_string8 t ) const
9694  {
9695  size_type n = char8_traits::Length( t );
9696  if ( n == 0 || Length() < n )
9697  return false;
9698  for ( const_iterator p = m_data->end-n; p < m_data->end; ++p, ++t )
9699  if ( *p != char_type( *t ) )
9700  return false;
9701  return true;
9702  }
9703 
9704  bool EndsWith( char8_type c ) const
9705  {
9706  return string_base::EndsWith( char_type( c ) );
9707  }
9708 
9709  bool EndsWithIC( const_c_string8 t ) const
9710  {
9711  size_type n = char8_traits::Length( t );
9712  if ( n == 0 || Length() < n )
9713  return false;
9714  for ( const_iterator p = m_data->end-n; p < m_data->end; ++p, ++t )
9715  if ( char_traits::ToCaseFolded( *p ) != char_type( char8_traits::ToCaseFolded( *t ) ) )
9716  return false;
9717  return true;
9718  }
9719 
9720  bool EndsWithIC( char8_type c ) const
9721  {
9722  return string_base::EndsWithIC( char_type( c ) );
9723  }
9724 
9725  // -------------------------------------------------------------------------
9726 
9727  size_type FindFirst( const String& s, size_type i = 0 ) const
9728  {
9729  return string_base::FindFirst( s, i );
9730  }
9731 
9732  size_type FindFirst( const_iterator t, size_type i = 0 ) const
9733  {
9734  return string_base::FindFirst( t, i );
9735  }
9736 
9737  size_type FindFirst( char_type c, size_type i = 0 ) const
9738  {
9739  return string_base::FindFirst( c, i );
9740  }
9741 
9742  size_type FindFirstIC( const String& s, size_type i = 0 ) const
9743  {
9744  return string_base::FindFirstIC( s, i );
9745  }
9746 
9747  size_type FindFirstIC( const_iterator t, size_type i = 0 ) const
9748  {
9749  return string_base::FindFirstIC( t, i );
9750  }
9751 
9752  size_type FindFirstIC( char_type c, size_type i = 0 ) const
9753  {
9754  return string_base::FindFirstIC( c, i );
9755  }
9756 
9757  size_type FindFirst( const char16_t* t, size_type i = 0 ) const
9758  {
9759  return string_base::FindFirst( reinterpret_cast<const_iterator>( t ), i );
9760  }
9761 
9762  size_type FindFirst( char16_t c, size_type i = 0 ) const
9763  {
9764  return string_base::FindFirst( char_type( c ), i );
9765  }
9766 
9767  size_type FindFirstIC( const char16_t* t, size_type i = 0 ) const
9768  {
9769  return string_base::FindFirstIC( reinterpret_cast<const_iterator>( t ), i );
9770  }
9771 
9772  size_type FindFirstIC( char16_t c, size_type i = 0 ) const
9773  {
9774  return string_base::FindFirstIC( char_type( c ), i );
9775  }
9776 
9777  size_type FindFirst( const wchar_t* t, size_type i = 0 ) const
9778  {
9779 #ifdef __PCL_WINDOWS
9780  return string_base::FindFirst( reinterpret_cast<const_iterator>( t ), i );
9781 #else
9782  return string_base::FindFirst( String( t ), i );
9783 #endif
9784  }
9785 
9786  size_type FindFirst( wchar_t c, size_type i = 0 ) const
9787  {
9788  return string_base::FindFirst( char_type( c ), i );
9789  }
9790 
9791  size_type FindFirstIC( const wchar_t* t, size_type i = 0 ) const
9792  {
9793 #ifdef __PCL_WINDOWS
9794  return string_base::FindFirstIC( reinterpret_cast<const_iterator>( t ), i );
9795 #else
9796  return string_base::FindFirstIC( String( t ), i );
9797 #endif
9798  }
9799 
9800  size_type FindFirstIC( wchar_t c, size_type i = 0 ) const
9801  {
9802  return string_base::FindFirstIC( char_type( c ), i );
9803  }
9804 
9805  size_type FindFirst( const_c_string8 t, size_type i = 0 ) const
9806  {
9807  return string_base::FindFirst( String( t ), i );
9808  }
9809 
9810  size_type FindFirst( char8_type c, size_type i = 0 ) const
9811  {
9812  return string_base::FindFirst( char_type( c ), i );
9813  }
9814 
9815  size_type FindFirstIC( const_c_string8 t, size_type i = 0 ) const
9816  {
9817  return string_base::FindFirstIC( String( t ), i );
9818  }
9819 
9820  size_type FindFirstIC( char8_type c, size_type i = 0 ) const
9821  {
9822  return string_base::FindFirstIC( char_type( c ), i );
9823  }
9824 
9825  //
9826 
9827  size_type Find( const String& s, size_type i = 0 ) const
9828  {
9829  return FindFirst( s, i );
9830  }
9831 
9832  size_type Find( const_iterator t, size_type i = 0 ) const
9833  {
9834  return FindFirst( t, i );
9835  }
9836 
9837  size_type Find( char_type c, size_type i = 0 ) const
9838  {
9839  return FindFirst( c, i );
9840  }
9841 
9842  size_type Find( const char16_t* t, size_type i = 0 ) const
9843  {
9844  return FindFirst( t, i );
9845  }
9846 
9847  size_type Find( char16_t c, size_type i = 0 ) const
9848  {
9849  return FindFirst( c, i );
9850  }
9851 
9852  size_type Find( const wchar_t* t, size_type i = 0 ) const
9853  {
9854  return FindFirst( t, i );
9855  }
9856 
9857  size_type Find( wchar_t c, size_type i = 0 ) const
9858  {
9859  return FindFirst( c, i );
9860  }
9861 
9862  size_type Find( const_c_string8 t, size_type i = 0 ) const
9863  {
9864  return FindFirst( t, i );
9865  }
9866 
9867  size_type Find( char8_type c, size_type i = 0 ) const
9868  {
9869  return FindFirst( c, i );
9870  }
9871 
9872  size_type FindIC( const String& s, size_type i = 0 ) const
9873  {
9874  return FindFirstIC( s, i );
9875  }
9876 
9877  size_type FindIC( const_iterator t, size_type i = 0 ) const
9878  {
9879  return FindFirstIC( t, i );
9880  }
9881 
9882  size_type FindIC( char_type c, size_type i = 0 ) const
9883  {
9884  return FindFirstIC( c, i );
9885  }
9886 
9887  size_type FindIC( const char16_t* t, size_type i = 0 ) const
9888  {
9889  return FindFirstIC( t, i );
9890  }
9891 
9892  size_type FindIC( char16_t c, size_type i = 0 ) const
9893  {
9894  return FindFirstIC( c, i );
9895  }
9896 
9897  size_type FindIC( const wchar_t* t, size_type i = 0 ) const
9898  {
9899  return FindFirstIC( t, i );
9900  }
9901 
9902  size_type FindIC( wchar_t c, size_type i = 0 ) const
9903  {
9904  return FindFirstIC( c, i );
9905  }
9906 
9907  size_type FindIC( const_c_string8 t, size_type i = 0 ) const
9908  {
9909  return FindFirstIC( t, i );
9910  }
9911 
9912  size_type FindIC( char8_type c, size_type i = 0 ) const
9913  {
9914  return FindFirstIC( c, i );
9915  }
9916 
9917  // -------------------------------------------------------------------------
9918 
9919  size_type FindLast( const String& s, size_type r = maxPos ) const
9920  {
9921  return string_base::FindLast( s, r );
9922  }
9923 
9924  size_type FindLast( const_iterator t, size_type r = maxPos ) const
9925  {
9926  return string_base::FindLast( t, r );
9927  }
9928 
9929  size_type FindLast( char_type c, size_type r = maxPos ) const
9930  {
9931  return string_base::FindLast( c, r );
9932  }
9933 
9934  size_type FindLastIC( const String& s, size_type r = maxPos ) const
9935  {
9936  return string_base::FindLastIC( s, r );
9937  }
9938 
9939  size_type FindLastIC( const_iterator t, size_type r = maxPos ) const
9940  {
9941  return string_base::FindLastIC( t, r );
9942  }
9943 
9944  size_type FindLastIC( char_type c, size_type r = maxPos ) const
9945  {
9946  return string_base::FindLastIC( c, r );
9947  }
9948 
9949  size_type FindLast( const char16_t* t, size_type r = maxPos ) const
9950  {
9951  return string_base::FindLast( reinterpret_cast<const_iterator>( t ), r );
9952  }
9953 
9954  size_type FindLast( char16_t c, size_type r = maxPos ) const
9955  {
9956  return string_base::FindLast( char_type( c ), r );
9957  }
9958 
9959  size_type FindLastIC( const char16_t* t, size_type r = maxPos ) const
9960  {
9961  return string_base::FindLastIC( reinterpret_cast<const_iterator>( t ), r );
9962  }
9963 
9964  size_type FindLastIC( char16_t c, size_type r = maxPos ) const
9965  {
9966  return string_base::FindLastIC( char_type( c ), r );
9967  }
9968 
9969  size_type FindLast( const wchar_t* t, size_type r = maxPos ) const
9970  {
9971 #ifdef __PCL_WINDOWS
9972  return string_base::FindLast( reinterpret_cast<const_iterator>( t ), r );
9973 #else
9974  return string_base::FindLast( String( t ), r );
9975 #endif
9976  }
9977 
9978  size_type FindLast( wchar_t c, size_type r = maxPos ) const
9979  {
9980  return string_base::FindLast( char_type( c ), r );
9981  }
9982 
9983  size_type FindLastIC( const wchar_t* t, size_type r = maxPos ) const
9984  {
9985 #ifdef __PCL_WINDOWS
9986  return string_base::FindLastIC( reinterpret_cast<const_iterator>( t ), r );
9987 #else
9988  return string_base::FindLastIC( String( t ), r );
9989 #endif
9990  }
9991 
9992  size_type FindLastIC( wchar_t c, size_type r = maxPos ) const
9993  {
9994  return string_base::FindLastIC( char_type( c ), r );
9995  }
9996 
9997  size_type FindLast( const_c_string8 t, size_type r = maxPos ) const
9998  {
9999  return string_base::FindLast( String( t ), r );
10000  }
10001 
10002  size_type FindLast( char8_type c, size_type r = maxPos ) const
10003  {
10004  return string_base::FindLast( char_type( c ), r );
10005  }
10006 
10007  size_type FindLastIC( const_c_string8 t, size_type r = maxPos ) const
10008  {
10009  return string_base::FindLastIC( String( t ), r );
10010  }
10011 
10012  size_type FindLastIC( char8_type c, size_type r = maxPos ) const
10013  {
10014  return string_base::FindLastIC( char_type( c ), r );
10015  }
10016 
10017  // -------------------------------------------------------------------------
10018 
10019  bool Contains( const String& s ) const
10020  {
10021  return string_base::Contains( s );
10022  }
10023 
10024  bool Contains( const_iterator t ) const
10025  {
10026  return string_base::Contains( t );
10027  }
10028 
10029  bool Contains( char_type c ) const
10030  {
10031  return string_base::Contains( c );
10032  }
10033 
10034  bool ContainsIC( const String& s ) const
10035  {
10036  return string_base::ContainsIC( s );
10037  }
10038 
10039  bool ContainsIC( const_iterator t ) const
10040  {
10041  return string_base::ContainsIC( t );
10042  }
10043 
10044  bool ContainsIC( char_type c ) const
10045  {
10046  return string_base::ContainsIC( c );
10047  }
10048 
10049  bool Contains( const char16_t* t ) const
10050  {
10051  return string_base::Contains( reinterpret_cast<const_iterator>( t ) );
10052  }
10053 
10054  bool Contains( char16_t c ) const
10055  {
10056  return string_base::Contains( char_type( c ) );
10057  }
10058 
10059  bool ContainsIC( const char16_t* t ) const
10060  {
10061  return string_base::ContainsIC( reinterpret_cast<const_iterator>( t ) );
10062  }
10063 
10064  bool ContainsIC( char16_t c ) const
10065  {
10066  return string_base::ContainsIC( char_type( c ) );
10067  }
10068 
10069  bool Contains( const wchar_t* t ) const
10070  {
10071 #ifdef __PCL_WINDOWS
10072  return string_base::Contains( reinterpret_cast<const_iterator>( t ) );
10073 #else
10074  return string_base::Contains( String( t ) );
10075 #endif
10076  }
10077 
10078  bool Contains( wchar_t c ) const
10079  {
10080  return string_base::Contains( char_type( c ) );
10081  }
10082 
10083  bool ContainsIC( const wchar_t* t ) const
10084  {
10085 #ifdef __PCL_WINDOWS
10086  return string_base::ContainsIC( reinterpret_cast<const_iterator>( t ) );
10087 #else
10088  return string_base::ContainsIC( String( t ) );
10089 #endif
10090  }
10091 
10092  bool ContainsIC( wchar_t c ) const
10093  {
10094  return string_base::ContainsIC( char_type( c ) );
10095  }
10096 
10097  bool Contains( const_c_string8 t ) const
10098  {
10099  return string_base::Contains( String( t ) );
10100  }
10101 
10102  bool Contains( char8_type c ) const
10103  {
10104  return string_base::Contains( char_type( c ) );
10105  }
10106 
10107  bool ContainsIC( const_c_string8 t ) const
10108  {
10109  return string_base::ContainsIC( String( t ) );
10110  }
10111 
10112  bool ContainsIC( char8_type c ) const
10113  {
10114  return string_base::ContainsIC( char_type( c ) );
10115  }
10116 
10117  // -------------------------------------------------------------------------
10118 
10119  int CompareCodePoints( const String& s, bool caseSensitive = true ) const
10120  {
10121  return string_base::CompareCodePoints( s, caseSensitive );
10122  }
10123 
10124  int CompareCodePoints( const_iterator t, bool caseSensitive = true ) const
10125  {
10126  return string_base::CompareCodePoints( t, caseSensitive );
10127  }
10128 
10129  int CompareCodePoints( char_type c, bool caseSensitive = true ) const
10130  {
10131  return string_base::CompareCodePoints( c, caseSensitive );
10132  }
10133 
10134  int CompareCodePoints( const char16_t* t, bool caseSensitive = true ) const
10135  {
10136  return string_base::CompareCodePoints( reinterpret_cast<const_iterator>( t ), caseSensitive );
10137  }
10138 
10139  int CompareCodePoints( char16_t c, bool caseSensitive = true ) const
10140  {
10141  return string_base::CompareCodePoints( char_type( c ), caseSensitive );
10142  }
10143 
10144  int CompareCodePoints( const wchar_t* t, bool caseSensitive = true ) const
10145  {
10146 #ifdef __PCL_WINDOWS
10147  return string_base::CompareCodePoints( reinterpret_cast<const_iterator>( t ), caseSensitive );
10148 #else
10149  return string_base::CompareCodePoints( String( t ), caseSensitive );
10150 #endif
10151  }
10152 
10153  int CompareCodePoints( wchar_t c, bool caseSensitive = true ) const
10154  {
10155  return string_base::CompareCodePoints( char_type( c ), caseSensitive );
10156  }
10157 
10158  int CompareCodePoints( const_c_string8 t, bool caseSensitive = true ) const
10159  {
10160  return string_base::CompareCodePoints( String( t ), caseSensitive );
10161  }
10162 
10163  int CompareCodePoints( char8_type c, bool caseSensitive = true ) const
10164  {
10165  return string_base::CompareCodePoints( char_type( c ), caseSensitive );
10166  }
10167 
10168  // -------------------------------------------------------------------------
10169 
10170  int Compare( const String& s, bool caseSensitive = true, bool localeAware = true ) const
10171  {
10172  return string_base::Compare( s, caseSensitive, localeAware );
10173  }
10174 
10175  int Compare( const_iterator t, bool caseSensitive = true, bool localeAware = true ) const
10176  {
10177  return string_base::Compare( t, caseSensitive, localeAware );
10178  }
10179 
10180  int Compare( char_type c, bool caseSensitive = true, bool localeAware = true ) const
10181  {
10182  return string_base::Compare( c, caseSensitive, localeAware );
10183  }
10184 
10185  int CompareIC( const String& s, bool localeAware = true ) const
10186  {
10187  return string_base::CompareIC( s, localeAware );
10188  }
10189 
10190  int CompareIC( const_iterator t, bool localeAware = true ) const
10191  {
10192  return string_base::CompareIC( t, localeAware );
10193  }
10194 
10195  int CompareIC( char_type c, bool localeAware = true ) const
10196  {
10197  return string_base::CompareIC( c, localeAware );
10198  }
10199 
10200  int Compare( const char16_t* t, bool caseSensitive = true, bool localeAware = true ) const
10201  {
10202  return string_base::Compare( reinterpret_cast<const_iterator>( t ), caseSensitive, localeAware );
10203  }
10204 
10205  int Compare( char16_t c, bool caseSensitive = true, bool localeAware = true ) const
10206  {
10207  return string_base::Compare( char_type( c ), caseSensitive, localeAware );
10208  }
10209 
10210  int CompareIC( const char16_t* t, bool localeAware = true ) const
10211  {
10212  return string_base::CompareIC( reinterpret_cast<const_iterator>( t ), localeAware );
10213  }
10214 
10215  int CompareIC( char16_t c, bool localeAware = true ) const
10216  {
10217  return string_base::CompareIC( char_type( c ), localeAware );
10218  }
10219 
10220  int Compare( const wchar_t* t, bool caseSensitive = true, bool localeAware = true ) const
10221  {
10222 #ifdef __PCL_WINDOWS
10223  return string_base::Compare( reinterpret_cast<const_iterator>( t ), caseSensitive, localeAware );
10224 #else
10225  return string_base::Compare( String( t ), caseSensitive, localeAware );
10226 #endif
10227  }
10228 
10229  int Compare( wchar_t c, bool caseSensitive = true, bool localeAware = true ) const
10230  {
10231  return string_base::Compare( char_type( c ), caseSensitive, localeAware );
10232  }
10233 
10234  int CompareIC( const wchar_t* t, bool localeAware = true ) const
10235  {
10236 #ifdef __PCL_WINDOWS
10237  return string_base::CompareIC( reinterpret_cast<const_iterator>( t ), localeAware );
10238 #else
10239  return string_base::CompareIC( String( t ), localeAware );
10240 #endif
10241  }
10242 
10243  int CompareIC( wchar_t c, bool localeAware = true ) const
10244  {
10245  return string_base::CompareIC( char_type( c ), localeAware );
10246  }
10247 
10248  int Compare( const_c_string8 t, bool caseSensitive = true, bool localeAware = true ) const
10249  {
10250  return string_base::Compare( String( t ), caseSensitive, localeAware );
10251  }
10252 
10253  int Compare( char8_type c, bool caseSensitive = true, bool localeAware = true ) const
10254  {
10255  return string_base::Compare( char_type( c ), caseSensitive, localeAware );
10256  }
10257 
10258  int CompareIC( const_c_string8 t, bool localeAware = true ) const
10259  {
10260  return string_base::CompareIC( String( t ), localeAware );
10261  }
10262 
10263  int CompareIC( char8_type c, bool localeAware = true ) const
10264  {
10265  return string_base::CompareIC( char_type( c ), localeAware );
10266  }
10267 
10268  // -------------------------------------------------------------------------
10269 
10270  bool WildMatch( const String& pattern, bool caseSensitive = true ) const
10271  {
10272  return string_base::WildMatch( pattern, caseSensitive );
10273  }
10274 
10275  bool WildMatchIC( const String& pattern ) const
10276  {
10277  return string_base::WildMatchIC( pattern );
10278  }
10279 
10280  bool WildMatch( const_iterator pattern, bool caseSensitive = true ) const
10281  {
10282  return string_base::WildMatch( pattern, caseSensitive );
10283  }
10284 
10285  bool WildMatchIC( const_iterator pattern ) const
10286  {
10287  return string_base::WildMatchIC( pattern );
10288  }
10289 
10290  bool WildMatch( const string8_base& pattern, bool caseSensitive = true ) const
10291  {
10292  return char_traits::WildMatch( m_data->string, Length(), pattern.Begin(), pattern.Length(), caseSensitive );
10293  }
10294 
10295  bool WildMatchIC( const string8_base& pattern ) const
10296  {
10297  return char_traits::WildMatch( m_data->string, Length(), pattern.Begin(), pattern.Length(), false/*caseSensitive*/ );
10298  }
10299 
10300  bool WildMatch( const_c_string8 pattern, bool caseSensitive = true ) const
10301  {
10302  return char_traits::WildMatch( m_data->string, Length(), pattern, char8_traits::Length( pattern ), caseSensitive );
10303  }
10304 
10305  bool WildMatchIC( const_c_string8 pattern ) const
10306  {
10307  return char_traits::WildMatch( m_data->string, Length(), pattern, char8_traits::Length( pattern ), false/*caseSensitive*/ );
10308  }
10309 
10310  // -------------------------------------------------------------------------
10311 
10312  String SetToLength( size_type n ) const
10313  {
10314  return string_base::SetToLength( n );
10315  }
10316 
10317  String ResizedToNullTerminated() const
10318  {
10319  return string_base::ResizedToNullTerminated();
10320  }
10321 
10322  String Squeezed() const
10323  {
10324  return string_base::Squeezed();
10325  }
10326 
10327  // -------------------------------------------------------------------------
10328 
10329  String Substring( size_type i, size_type n = maxPos ) const
10330  {
10331  return string_base::Substring( i, n );
10332  }
10333 
10334  String Left( size_type n ) const
10335  {
10336  return string_base::Left( n );
10337  }
10338 
10339  String Right( size_type n ) const
10340  {
10341  return string_base::Right( n );
10342  }
10343 
10344  String Suffix( size_type i ) const
10345  {
10346  return string_base::Suffix( i );
10347  }
10348 
10349  String Prefix( size_type i ) const
10350  {
10351  return string_base::Prefix( i );
10352  }
10353 
10354  // -------------------------------------------------------------------------
10355 
10356  template <class C>
10357  size_type Break( C& list, const String& s, bool trim = false, size_type i = 0 ) const
10358  {
10359  return string_base::Break( list, s, trim, i );
10360  }
10361 
10362  template <class C>
10363  size_type Break( C& list, const string8_base& s, bool trim = false, size_type i = 0 ) const
10364  {
10365  return string_base::Break( list, String( s ), trim, i );
10366  }
10367 
10368  template <class C>
10369  size_type Break( C& list, const_c_string8 s, bool trim = false, size_type i = 0 ) const
10370  {
10371  return string_base::Break( list, String( s ), trim, i );
10372  }
10373 
10374  template <class C>
10375  size_type Break( C& list, char_type c, bool trim = false, size_type i = 0 ) const
10376  {
10377  return string_base::Break( list, c, trim, i );
10378  }
10379 
10380  template <class C>
10381  size_type Break( C& list, char8_type c, bool trim = false, size_type i = 0 ) const
10382  {
10383  return string_base::Break( list, char_type( c ), trim, i );
10384  }
10385 
10386  template <class C, typename S>
10387  size_type Break( C& list, const Array<S>& ca, bool trim = false, size_type i = 0 ) const
10388  {
10389  return string_base::Break( list, ca, trim, i );
10390  }
10391 
10392  // -------------------------------------------------------------------------
10393 
10394  template <class C>
10395  size_type BreakIC( C& list, const String& s, bool trim = false, size_type i = 0 ) const
10396  {
10397  return string_base::BreakIC( list, s, trim, i );
10398  }
10399 
10400  template <class C>
10401  size_type BreakIC( C& list, const string8_base& s, bool trim = false, size_type i = 0 ) const
10402  {
10403  return string_base::BreakIC( list, String( s ), trim, i );
10404  }
10405 
10406  template <class C>
10407  size_type BreakIC( C& list, const_c_string8 s, bool trim = false, size_type i = 0 ) const
10408  {
10409  return string_base::BreakIC( list, String( s ), trim, i );
10410  }
10411 
10412  template <class C>
10413  size_type BreakIC( C& list, char_type c, bool trim = false, size_type i = 0 ) const
10414  {
10415  return string_base::BreakIC( list, c, trim, i );
10416  }
10417 
10418  template <class C>
10419  size_type BreakIC( C& list, char8_type c, bool trim = false, size_type i = 0 ) const
10420  {
10421  return string_base::BreakIC( list, char_type( c ), trim, i );
10422  }
10423 
10424  // -------------------------------------------------------------------------
10425 
10426  String Trimmed() const
10427  {
10428  return string_base::Trimmed();
10429  }
10430 
10431  String TrimmedLeft() const
10432  {
10433  return string_base::TrimmedLeft();
10434  }
10435 
10436  String TrimmedRight() const
10437  {
10438  return string_base::TrimmedRight();
10439  }
10440 
10441  // -------------------------------------------------------------------------
10442 
10443  String LeftJustified( size_type width, char_type fill = CharTraits::Blank() ) const
10444  {
10445  return string_base::LeftJustified( width, fill );
10446  }
10447 
10448  String RightJustified( size_type width, char_type fill = CharTraits::Blank() ) const
10449  {
10450  return string_base::RightJustified( width, fill );
10451  }
10452 
10453  String CenterJustified( size_type width, char_type fill = CharTraits::Blank() ) const
10454  {
10455  return string_base::CenterJustified( width, fill );
10456  }
10457 
10458  // -------------------------------------------------------------------------
10459 
10460  String Enclosed( char_type c ) const
10461  {
10462  return string_base::Enclosed( c );
10463  }
10464 
10465  String SingleQuoted() const
10466  {
10467  return string_base::SingleQuoted();
10468  }
10469 
10470  String DoubleQuoted() const
10471  {
10472  return string_base::DoubleQuoted();
10473  }
10474 
10475  String Unquoted() const
10476  {
10477  return string_base::Unquoted();
10478  }
10479 
10480  // -------------------------------------------------------------------------
10481 
10482  String CaseFolded() const
10483  {
10484  return string_base::CaseFolded();
10485  }
10486 
10487  String Lowercase() const
10488  {
10489  return string_base::Lowercase();
10490  }
10491 
10492  String Uppercase() const
10493  {
10494  return string_base::Uppercase();
10495  }
10496 
10497  // -------------------------------------------------------------------------
10498 
10499  String Reversed() const
10500  {
10501  return string_base::Reversed();
10502  }
10503 
10504  String Sorted() const
10505  {
10506  return string_base::Sorted();
10507  }
10508 
10509  template <class BP>
10510  String Sorted( BP p ) const
10511  {
10512  return string_base::Sorted( p );
10513  }
10514 
10515  // -------------------------------------------------------------------------
10516 
10526  template <class C>
10527  String& ToSeparated( const C& c, char_type separator )
10528  {
10529  Clear();
10530  return c.ToSeparated( *this, separator );
10531  }
10532 
10549  template <class C, class AF>
10550  String& ToSeparated( const C& c, char_type separator, AF append )
10551  {
10552  Clear();
10553  return c.ToSeparated( *this, separator, append );
10554  }
10555 
10565  template <class C>
10566  String& ToSeparated( const C& c, const String& separator )
10567  {
10568  Clear();
10569  return c.ToSeparated( *this, separator );
10570  }
10571 
10588  template <class C, class AF>
10589  String& ToSeparated( const C& c, const String& separator, AF append )
10590  {
10591  Clear();
10592  return c.ToSeparated( *this, separator, append );
10593  }
10594 
10604  template <class C>
10605  String& ToSeparated( const C& c, const_c_string separator )
10606  {
10607  return ToSeparated( c, String( separator ) );
10608  }
10609 
10626  template <class C, class AF>
10627  String& ToSeparated( const C& c, const_c_string separator, AF append )
10628  {
10629  return ToSeparated( c, String( separator ), append );
10630  }
10631 
10642  template <class C>
10643  String& ToSeparated( const C& c, const_c_string8 separator )
10644  {
10645  return ToSeparated( c, String( separator ) );
10646  }
10647 
10664  template <class C, class AF>
10665  String& ToSeparated( const C& c, const_c_string8 separator, AF append )
10666  {
10667  return ToSeparated( c, String( separator ), append );
10668  }
10669 
10679  template <class C>
10680  String& ToCommaSeparated( const C& c )
10681  {
10682  return ToSeparated( c, CharTraits::Comma() );
10683  }
10684 
10694  template <class C>
10695  String& ToColonSeparated( const C& c )
10696  {
10697  return ToSeparated( c, CharTraits::Colon() );
10698  }
10699 
10709  template <class C>
10710  String& ToSpaceSeparated( const C& c )
10711  {
10712  return ToSeparated( c, CharTraits::Blank() );
10713  }
10714 
10724  template <class C>
10725  String& ToTabSeparated( const C& c )
10726  {
10727  return ToSeparated( c, CharTraits::Tab() );
10728  }
10729 
10739  template <class C>
10741  {
10742  retur