PCL
String.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.4.0
6 // ----------------------------------------------------------------------------
7 // pcl/String.h - Released 2020-07-31T19:33:04Z
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-2020 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 
542  : m_data( s.m_data )
543  {
544  m_data->Attach();
545  }
546 
551  : m_data( s.m_data )
552  {
553  s.m_data = nullptr;
554  }
555 
560  GenericString( const_c_string t )
561  {
562  size_type len = R::Length( t );
563  if ( len > 0 )
564  {
565  m_data = Data::New( len );
566  R::Copy( m_data->string, t, len );
567  }
568  else
569  m_data = Data::New();
570  }
571 
589  GenericString( const_iterator i, const_iterator j )
590  {
591  if ( i < j )
592  {
593  size_type len = j - i;
594  m_data = Data::New( len );
595  R::Copy( m_data->string, i, len );
596  }
597  else
598  m_data = Data::New();
599  }
600 
609  GenericString( std::initializer_list<char_type> l )
610  : GenericString( l.begin(), l.end() )
611  {
612  }
613 
618  GenericString( const_c_string t, size_type i, size_type n )
619  {
620  size_type len = R::Length( t );
621  if ( i < len && (n = pcl::Min( n, len-i )) > 0 )
622  {
623  m_data = Data::New( n );
624  R::Copy( m_data->string, t+i, n );
625  }
626  else
627  m_data = Data::New();
628  }
629 
633  GenericString( char_type c, size_type n = 1 )
634  {
635  if ( n > 0 )
636  {
637  m_data = Data::New( n );
638  R::Fill( m_data->string, c, n );
639  }
640  else
641  m_data = Data::New();
642  }
643 
649  {
650  if ( m_data != nullptr )
651  {
652  DetachFromData();
653  m_data = nullptr;
654  }
655  }
656 
662  bool IsUnique() const
663  {
664  return m_data->IsUnique();
665  }
666 
674  bool IsAliasOf( const GenericString& s ) const
675  {
676  return m_data == s.m_data;
677  }
678 
689  {
690  if ( !IsUnique() )
691  {
692  size_type len = Length();
693  Data* newData = Data::New( len );
694  if ( len > 0 )
695  R::Copy( newData->string, m_data->string, len );
696  DetachFromData();
697  m_data = newData;
698  }
699  }
700 
709  {
710  return R::BytesPerChar();
711  }
712 
719  size_type Size() const
720  {
721  return Length()*BytesPerChar();
722  }
723 
731  {
732  return m_data->end - m_data->string;
733  }
734 
744  {
745  return m_data->capacity - m_data->string;
746  }
747 
756  {
757  return m_data->capacity - m_data->end;
758  }
759 
776  bool IsValid() const
777  {
778  return m_data != nullptr;
779  }
780 
788  bool IsEmpty() const
789  {
790  return m_data->string == m_data->end;
791  }
792 
802  {
803  return 0;
804  }
805 
815  {
816  PCL_PRECONDITION( !IsEmpty() )
817  return Length()-1;
818  }
819 
825  const allocator& GetAllocator() const
826  {
827  return m_data->alloc;
828  }
829 
839  void SetAllocator( const allocator& a )
840  {
841  EnsureUnique();
842  m_data->alloc = a;
843  }
844 
857  iterator At( size_type i )
858  {
859  PCL_PRECONDITION( i < Length() )
860  EnsureUnique();
861  return m_data->string + i;
862  }
863 
873  const_iterator At( size_type i ) const
874  {
875  PCL_PRECONDITION( i < Length() )
876  return m_data->string + i;
877  }
878 
891  char_type& operator []( size_type i )
892  {
893  return *At( i );
894  }
895 
905  char_type operator []( size_type i ) const
906  {
907  return *At( i );
908  }
909 
917  char_type& operator *()
918  {
919  EnsureUnique();
920  return *m_data->string;
921  }
922 
930  char_type operator *() const
931  {
932  return *m_data->string;
933  }
934 
946  iterator Begin()
947  {
948  EnsureUnique();
949  return m_data->string;
950  }
951 
960  const_iterator Begin() const
961  {
962  return m_data->string;
963  }
964 
976  iterator End()
977  {
978  EnsureUnique();
979  return m_data->end;
980  }
981 
990  const_iterator End() const
991  {
992  return m_data->end;
993  }
994 
1009  {
1010  EnsureUnique();
1011  return (m_data->string < m_data->end) ? m_data->end-1 : nullptr;
1012  }
1013 
1025  {
1026  return (m_data->string < m_data->end) ? m_data->end-1 : nullptr;
1027  }
1028 
1043  {
1044  EnsureUnique();
1045  return (m_data->string < m_data->end) ? m_data->string-1 : nullptr;
1046  }
1047 
1059  {
1060  return (m_data->string < m_data->end) ? m_data->string-1 : nullptr;
1061  }
1062 
1073  size_type IndexAt( const_iterator i ) const
1074  {
1075  PCL_PRECONDITION( i >= m_data->string )
1076  return i - m_data->string;
1077  }
1078 
1079 #ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
1080 
1083  iterator begin()
1084  {
1085  return Begin();
1086  }
1087 
1091  const_iterator begin() const
1092  {
1093  return Begin();
1094  }
1095 
1099  iterator end()
1100  {
1101  return End();
1102  }
1103 
1107  const_iterator end() const
1108  {
1109  return End();
1110  }
1111 #endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
1112 
1120  const_c_string c_str() const
1121  {
1122  static const char_type theNullChar = char_traits::Null();
1123  return IsEmpty() ? &theNullChar : Begin();
1124  }
1125 
1131  GenericString& operator =( const GenericString& s )
1132  {
1133  Assign( s );
1134  return *this;
1135  }
1136 
1151  void Assign( const GenericString& s )
1152  {
1153  s.m_data->Attach();
1154  DetachFromData();
1155  m_data = s.m_data;
1156  }
1157 
1163  GenericString& operator =( GenericString&& s )
1164  {
1165  Transfer( s );
1166  return *this;
1167  }
1168 
1183  {
1184  DetachFromData();
1185  m_data = s.m_data;
1186  s.m_data = nullptr;
1187  }
1188 
1195  {
1196  DetachFromData();
1197  m_data = s.m_data;
1198  s.m_data = nullptr;
1199  }
1200 
1205  GenericString& operator =( const_c_string t )
1206  {
1207  Assign( t );
1208  return *this;
1209  }
1210 
1215  GenericString& operator =( char_type c )
1216  {
1217  Assign( c, 1 );
1218  return *this;
1219  }
1220 
1225  void Assign( const GenericString& s, size_type i, size_type n )
1226  {
1227  Transfer( s.Substring( i, n ) );
1228  }
1229 
1237  void Assign( const_c_string t )
1238  {
1239  size_type len = R::Length( t );
1240  if ( len > 0 )
1241  {
1242  MaybeReallocate( len );
1243  R::Copy( m_data->string, t, len );
1244  }
1245  else
1246  Clear();
1247  }
1248 
1269  void Assign( const_iterator i, const_iterator j )
1270  {
1271  if ( i < j )
1272  {
1273  size_type len = j - i;
1274  MaybeReallocate( len );
1275  R::Copy( m_data->string, i, len );
1276  }
1277  else
1278  Clear();
1279  }
1280 
1287  void Assign( std::initializer_list<char_type> l )
1288  {
1289  Assign( l.begin(), l.end() );
1290  }
1291 
1305  void Assign( const_c_string t, size_type i, size_type n )
1306  {
1307  size_type len = R::Length( t );
1308  if ( i < len && (n = pcl::Min( n, len-i )) > 0 )
1309  {
1310  MaybeReallocate( n );
1311  R::Copy( m_data->string, t+i, n );
1312  }
1313  else
1314  Clear();
1315  }
1316 
1322  void Assign( char_type c, size_type n = 1 )
1323  {
1324  if ( !R::IsNull( c ) && n > 0 )
1325  {
1326  MaybeReallocate( n );
1327  R::Fill( m_data->string, c, n );
1328  }
1329  else
1330  Clear();
1331  }
1332 
1336  void Swap( GenericString& s )
1337  {
1338  pcl::Swap( m_data, s.m_data );
1339  }
1340 
1350  void Fill( char_type c )
1351  {
1352  size_type len = Length();
1353  if ( len > 0 )
1354  {
1355  if ( !IsUnique() )
1356  {
1357  Data* newData = Data::New( len );
1358  DetachFromData();
1359  m_data = newData;
1360  }
1361  R::Fill( m_data->string, c, len );
1362  }
1363  }
1364 
1379  void Fill( char_type c, size_type i, size_type n = maxPos )
1380  {
1381  size_type len = Length();
1382  if ( i < len )
1383  {
1384  n = pcl::Min( n, len-i );
1385  if ( n < len )
1386  EnsureUnique();
1387  else if ( !IsUnique() )
1388  {
1389  Data* newData = Data::New( len );
1390  DetachFromData();
1391  m_data = newData;
1392  }
1393  R::Fill( m_data->string+i, c, n );
1394  }
1395  }
1396 
1418  void SecureFill( char c = '\0' )
1419  {
1420  volatile char* s = reinterpret_cast<volatile char*>( m_data->string );
1421  for ( size_type n = Capacity()*sizeof( char_type ); n > 0; --n )
1422  *s++ = c;
1423  }
1424 
1432  void Reserve( size_type n )
1433  {
1434  if ( n > 0 )
1435  if ( IsUnique() )
1436  {
1437  if ( Capacity() < n+1 )
1438  {
1439  iterator old = m_data->string;
1440  size_type len = Length();
1441  m_data->Reserve( len, n );
1442  if ( old != nullptr )
1443  {
1444  if ( len > 0 )
1445  R::Copy( m_data->string, old, len );
1446  m_data->alloc.Deallocate( old );
1447  }
1448  }
1449  }
1450  else
1451  {
1452  size_type len = Length();
1453  Data* newData = Data::New(); // ### FIXME: unlikely, but this is a potential leak
1454  newData->Reserve( len, pcl::Max( len, n ) );
1455  if ( len > 0 )
1456  R::Copy( newData->string, m_data->string, len );
1457  DetachFromData();
1458  m_data = newData;
1459  }
1460  }
1461 
1476  {
1477  if ( n != Length() )
1478  {
1479  if ( n > 0 )
1480  {
1481  if ( !IsUnique() || m_data->ShouldReallocate( n ) )
1482  {
1483  Data* newData = Data::New( n );
1484  size_type m = Capacity();
1485  if ( m > 0 )
1486  R::Copy( newData->string, m_data->string, pcl::Min( n, m ) );
1487  DetachFromData();
1488  m_data = newData;
1489  }
1490  else
1491  m_data->SetLength( n );
1492  }
1493  else
1494  Clear();
1495  }
1496  else
1497  EnsureUnique();
1498  }
1499 
1506  {
1507  // NB: This can be done more efficiently if this string is unique.
1508  GenericString s( *this );
1509  s.SetLength( n );
1510  return s;
1511  }
1512 
1522  {
1523  SetLength( R::Length( m_data->string ) );
1524  }
1525 
1531  {
1532  GenericString s( *this );
1534  return s;
1535  }
1536 
1549  void Squeeze()
1550  {
1551  if ( Available() > 0 )
1552  {
1553  size_type len = Length();
1554  if ( len > 0 )
1555  {
1556  if ( IsUnique() )
1557  {
1558  iterator old = m_data->string;
1559  m_data->Allocate( len, 0 );
1560  R::Copy( m_data->string, old, len );
1561  m_data->alloc.Deallocate( old );
1562  }
1563  else
1564  {
1565  Data* newData = Data::New( len, 0 );
1566  R::Copy( newData->string, m_data->string, len );
1567  DetachFromData();
1568  m_data = newData;
1569  }
1570  }
1571  else
1572  Clear();
1573  }
1574  }
1575 
1581  {
1582  // NB: This can be done more efficiently if this string is unique.
1583  GenericString s( *this );
1584  s.Squeeze();
1585  return s;
1586  }
1587 
1600  c_string Release()
1601  {
1602  EnsureUnique();
1603  iterator string = m_data->string;
1604  m_data->Reset();
1605  return string;
1606  }
1607 
1624  void c_copy( iterator dst, size_type maxCharsToCopy, size_type i = 0 ) const
1625  {
1626  if ( dst != nullptr )
1627  if ( maxCharsToCopy > 0 )
1628  {
1629  if ( --maxCharsToCopy > 0 )
1630  {
1631  size_type len = Length();
1632  if ( i < len )
1633  {
1634  size_type n = pcl::Min( maxCharsToCopy, len-i );
1635  R::Copy( dst, m_data->string+i, n );
1636  dst += n;
1637  }
1638  }
1639 
1640  *dst = R::Null();
1641  }
1642  }
1643 
1647  template <class R1, class A1>
1649  {
1650  size_type n = s.Length();
1651  if ( n > 0 )
1652  {
1653  UninitializedGrow( i, n ); // -> 0 <= i <= len
1654  R::Copy( m_data->string+i, s.m_data->string, n );
1655  }
1656  }
1657 
1665  void Insert( size_type i, const_iterator p, const_iterator q )
1666  {
1667  if ( p < q )
1668  {
1669  size_type n = q - p;
1670  UninitializedGrow( i, n ); // -> 0 <= i <= len
1671  R::Copy( m_data->string+i, p, n );
1672  }
1673  }
1674 
1679  void Insert( size_type i, const_c_string t )
1680  {
1681  size_type n = R::Length( t );
1682  if ( n > 0 )
1683  {
1684  UninitializedGrow( i, n ); // -> 0 <= i <= len
1685  R::Copy( m_data->string+i, t, n );
1686  }
1687  }
1688 
1693  void Insert( size_type i, const_c_string t, size_type n )
1694  {
1695  if ( (n = pcl::Min( n, R::Length( t ) )) > 0 )
1696  {
1697  UninitializedGrow( i, n ); // -> 0 <= i <= len
1698  R::Copy( m_data->string+i, t, n );
1699  }
1700  }
1701 
1705  void Insert( size_type i, char_type c, size_type n = 1 )
1706  {
1707  if ( n > 0 )
1708  {
1709  UninitializedGrow( i, n ); // -> 0 <= i <= len
1710  R::Fill( m_data->string+i, c, n );
1711  }
1712  }
1713 
1717  template <class R1, class A1>
1719  {
1720  Insert( maxPos, s );
1721  }
1722 
1727  template <class R1, class A1>
1728  GenericString& operator +=( const GenericString<T,R1,A1>& s )
1729  {
1730  Append( s );
1731  return *this;
1732  }
1733 
1741  void Append( const_iterator i, const_iterator j )
1742  {
1743  Insert( maxPos, i, j );
1744  }
1745 
1750  void Append( const_c_string t, size_type n )
1751  {
1752  Insert( maxPos, t, n );
1753  }
1754 
1758  void Append( const_c_string t )
1759  {
1760  Insert( maxPos, t );
1761  }
1762 
1767  GenericString& operator +=( const_c_string t )
1768  {
1769  Append( t );
1770  return *this;
1771  }
1772 
1776  void Append( char_type c, size_type n = 1 )
1777  {
1778  Insert( maxPos, c, n );
1779  }
1780 
1785  template <class R1, class A1>
1786  void Add( const GenericString<T,R1,A1>& s )
1787  {
1788  Append( s );
1789  }
1790 
1795  void Add( const_iterator i, const_iterator j )
1796  {
1797  Append( i, j );
1798  }
1799 
1804  void Add( const_c_string t, size_type n )
1805  {
1806  Append( t, n );
1807  }
1808 
1813  void Add( const_c_string t )
1814  {
1815  Append( t );
1816  }
1817 
1822  void Add( char_type c, size_type n = 1 )
1823  {
1824  Append( c, n );
1825  }
1826 
1831  GenericString& operator +=( char_type c )
1832  {
1833  Append( c );
1834  return *this;
1835  }
1836 
1841  template <class R1, class A1>
1843  {
1844  Insert( 0, s );
1845  }
1846 
1851  template <class R1, class A1>
1852  GenericString& operator -=( const GenericString<T,R1,A1>& s )
1853  {
1854  Prepend( s );
1855  return *this;
1856  }
1857 
1865  void Prepend( const_iterator i, const_iterator j )
1866  {
1867  Insert( 0, i, j );
1868  }
1869 
1874  void Prepend( const_c_string t, size_type n )
1875  {
1876  Insert( 0, t, n );
1877  }
1878 
1883  void Prepend( const_c_string t )
1884  {
1885  Insert( 0, t );
1886  }
1887 
1892  GenericString& operator -=( const_c_string t )
1893  {
1894  Prepend( t );
1895  return *this;
1896  }
1897 
1901  void Prepend( char_type c, size_type n = 1 )
1902  {
1903  Insert( 0, c, n );
1904  }
1905 
1910  GenericString& operator -=( char_type c )
1911  {
1912  Prepend( c );
1913  return *this;
1914  }
1915 
1920  template <class R1, class A1>
1922  {
1923  if ( n > 0 )
1924  {
1925  size_type len = Length();
1926  if ( i < len )
1927  {
1928  n = pcl::Min( n, len-i );
1929  if ( n != len )
1930  {
1931  size_type ns = s.Length();
1932  if ( ns > 0 )
1933  {
1934  if ( n < ns )
1935  UninitializedGrow( i, ns-n );
1936  else if ( ns < n )
1937  Delete( i, n-ns );
1938  else
1939  EnsureUnique();
1940 
1941  R::Copy( m_data->string+i, s.m_data->string, ns );
1942  }
1943  else
1944  Delete( i, n );
1945  }
1946  else
1947  Assign( s );
1948  }
1949  }
1950  }
1951 
1960  void Replace( size_type i, size_type n, const_c_string t )
1961  {
1962  if ( n > 0 )
1963  {
1964  size_type len = Length();
1965  if ( i < len )
1966  {
1967  n = pcl::Min( n, len-i );
1968  if ( n != len )
1969  {
1970  size_type nt = R::Length( t );
1971  if ( nt > 0 )
1972  {
1973  if ( n < nt )
1974  UninitializedGrow( i, nt-n );
1975  else if ( nt < n )
1976  Delete( i, n-nt );
1977  else
1978  EnsureUnique();
1979 
1980  R::Copy( m_data->string+i, t, nt );
1981  }
1982  else
1983  Delete( i, n );
1984  }
1985  else
1986  Assign( t );
1987  }
1988  }
1989  }
1990 
1995  void Replace( size_type i, size_type n, char_type c, size_type nc = 1 )
1996  {
1997  if ( n > 0 )
1998  {
1999  size_type len = Length();
2000  if ( i < len )
2001  {
2002  n = pcl::Min( n, len-i );
2003  if ( n != len )
2004  {
2005  if ( nc > 0 )
2006  {
2007  if ( n < nc )
2008  UninitializedGrow( i, nc-n );
2009  else if ( nc < n )
2010  Delete( i, n-nc );
2011  else
2012  EnsureUnique();
2013 
2014  R::Fill( m_data->string+i, c, nc );
2015  }
2016  else
2017  Delete( i, n );
2018  }
2019  else
2020  Assign( c, nc );
2021  }
2022  }
2023  }
2024 
2030  void ReplaceChar( char_type c1, char_type c2, size_type i = 0, size_type n = maxPos )
2031  {
2032  ReplaceChar( c1, c2, i, n, true/*case*/ );
2033  }
2034 
2042  void ReplaceCharIC( char_type c1, char_type c2, size_type i = 0, size_type n = maxPos )
2043  {
2044  ReplaceChar( c1, c2, i, n, false/*case*/ );
2045  }
2046 
2052  template <class R1, class A1, class R2, class A2>
2054  const GenericString<T,R2,A2>& s2, size_type i = 0 )
2055  {
2056  ReplaceString( s1.m_data->string, s1.Length(), s2.m_data->string, s2.Length(), i, true/*case*/ );
2057  }
2058 
2064  void ReplaceString( const_c_string t1, const_c_string t2, size_type i = 0 )
2065  {
2066  ReplaceString( t1, R::Length( t1 ), t2, R::Length( t2 ), i, true/*case*/ );
2067  }
2068 
2076  template <class R1, class A1, class R2, class A2>
2078  const GenericString<T,R2,A2>& s2, size_type i = 0 )
2079  {
2080  ReplaceString( s1.m_data->string, s1.Length(), s2.m_data->string, s2.Length(), i, false/*case*/ );
2081  }
2082 
2090  void ReplaceStringIC( const_c_string t1, const_c_string t2, size_type i = 0 )
2091  {
2092  ReplaceString( t1, R::Length( t1 ), t2, R::Length( t2 ), i, false/*case*/ );
2093  }
2094 
2099  void Delete( size_type i, size_type n = 1 )
2100  {
2101  if ( n > 0 )
2102  {
2103  size_type len = Length();
2104  if ( i < len )
2105  {
2106  n = pcl::Min( n, len-i );
2107  if ( n < len )
2108  {
2109  size_type newLen = len-n;
2110  if ( !IsUnique() || m_data->ShouldReallocate( newLen ) )
2111  {
2112  Data* newData = Data::New( newLen );
2113  if ( i > 0 )
2114  R::Copy( newData->string, m_data->string, i );
2115  if ( i < newLen )
2116  R::Copy( newData->string+i, m_data->string+i+n, newLen-i );
2117  DetachFromData();
2118  m_data = newData;
2119  }
2120  else
2121  {
2122  if ( i < newLen )
2123  R::CopyOverlapped( m_data->string+i, m_data->string+i+n, newLen-i );
2124  m_data->SetLength( newLen );
2125  }
2126  }
2127  else
2128  Clear();
2129  }
2130  }
2131  }
2132 
2138  {
2139  Delete( i, maxPos );
2140  }
2141 
2147  {
2148  Delete( 0, i );
2149  }
2150 
2156  void DeleteChar( char_type c, size_type i = 0 )
2157  {
2158  ReplaceString( &c, 1, nullptr, 0, i, true/*case*/ );
2159  }
2160 
2168  void DeleteCharIC( char_type c, size_type i = 0 )
2169  {
2170  ReplaceString( &c, 1, nullptr, 0, i, false/*case*/ );
2171  }
2172 
2178  template <class R1, class A1>
2180  {
2181  ReplaceString( s.m_data->string, s.Length(), nullptr, 0, i, true/*case*/ );
2182  }
2183 
2189  void DeleteString( const_c_string t, size_type i = 0 )
2190  {
2191  ReplaceString( t, R::Length( t ), nullptr, 0, i, true/*case*/ );
2192  }
2193 
2201  template <class R1, class A1>
2203  {
2204  ReplaceString( s.m_data->string, s.Length(), nullptr, 0, i, false/*case*/ );
2205  }
2206 
2214  void DeleteStringIC( const_c_string t, size_type i = 0 )
2215  {
2216  ReplaceString( t, R::Length( t ), nullptr, 0, i, false/*case*/ );
2217  }
2218 
2228  void Clear()
2229  {
2230  if ( !IsEmpty() )
2231  if ( IsUnique() )
2232  m_data->Deallocate();
2233  else
2234  {
2235  Data* newData = Data::New();
2236  DetachFromData();
2237  m_data = newData;
2238  }
2239  }
2240 
2246  {
2247  size_type len = Length();
2248  if ( i < len )
2249  {
2250  n = pcl::Min( n, len-i );
2251  if ( n > 0 )
2252  {
2253  if ( n < len )
2254  {
2255  GenericString t;
2256  t.m_data->Allocate( n );
2257  R::Copy( t.m_data->string, m_data->string+i, n );
2258  return t;
2259  }
2260  return *this;
2261  }
2262  }
2263  return GenericString();
2264  }
2265 
2271  {
2272  size_type len = Length();
2273  n = pcl::Min( n, len );
2274  if ( n > 0 )
2275  {
2276  if ( n < len )
2277  {
2278  GenericString t;
2279  t.m_data->Allocate( n );
2280  R::Copy( t.m_data->string, m_data->string, n );
2281  return t;
2282  }
2283  return *this;
2284  }
2285  return GenericString();
2286  }
2287 
2293  {
2294  size_type len = Length();
2295  n = pcl::Min( n, len );
2296  if ( n > 0 )
2297  {
2298  if ( n < len )
2299  {
2300  GenericString t;
2301  t.m_data->Allocate( n );
2302  R::Copy( t.m_data->string, m_data->string+len-n, n );
2303  return t;
2304  }
2305  return *this;
2306  }
2307  return GenericString();
2308  }
2309 
2317  {
2318  return Substring( i );
2319  }
2320 
2328  {
2329  return Left( (i > 0) ? i-1 : 0 );
2330  }
2331 
2349  template <class C, class R1, class A1>
2350  size_type Break( C& list, const GenericString<T,R1,A1>& s, bool trim = false, size_type i = 0 ) const
2351  {
2352  size_type count = 0;
2353  size_type len = Length();
2354  if ( i < len )
2355  {
2356  size_type n = s.Length();
2357  if ( n > 0 )
2358  for ( SearchEngine S( s.m_data->string, n, true/*case*/ ); ; )
2359  {
2360  size_type j = S( m_data->string, i, len );
2361 
2362  GenericString t;
2363  if ( i < j )
2364  {
2365  const_iterator l = m_data->string + i;
2366  size_type m = j - i;
2367  if ( trim )
2368  {
2369  const_iterator r = l + m;
2370  l = R::SearchTrimLeft( l, r );
2371  m = R::SearchTrimRight( l, r ) - l;
2372  }
2373  if ( m > 0 )
2374  {
2375  t.m_data->Allocate( m );
2376  R::Copy( t.m_data->string, l, m );
2377  }
2378  }
2379  list.Add( t );
2380  ++count;
2381 
2382  if ( j == len )
2383  break;
2384 
2385  i = j + n;
2386  }
2387  }
2388  return count;
2389  }
2390 
2409  template <class C>
2410  size_type Break( C& list, const_c_string s, bool trim = false, size_type i = 0 ) const
2411  {
2412  size_type count = 0;
2413  size_type len = Length();
2414  if ( i < len )
2415  {
2416  size_type n = R::Length( s );
2417  if ( n > 0 )
2418  for ( SearchEngine S( s, n, true/*case*/ ); ; )
2419  {
2420  size_type j = S( m_data->string, i, len );
2421 
2422  GenericString t;
2423  if ( i < j )
2424  {
2425  const_iterator l = m_data->string + i;
2426  size_type m = j - i;
2427  if ( trim )
2428  {
2429  const_iterator r = l + m;
2430  l = R::SearchTrimLeft( l, r );
2431  m = R::SearchTrimRight( l, r ) - l;
2432  }
2433  if ( m > 0 )
2434  {
2435  t.m_data->Allocate( m );
2436  R::Copy( t.m_data->string, l, m );
2437  }
2438  }
2439  list.Add( t );
2440  ++count;
2441 
2442  if ( j == len )
2443  break;
2444 
2445  i = j + n;
2446  }
2447  }
2448  return count;
2449  }
2450 
2469  template <class C>
2470  size_type Break( C& list, char_type c, bool trim = false, size_type i = 0 ) const
2471  {
2472  size_type count = 0;
2473  size_type len = Length();
2474  if ( i < len )
2475  {
2476  for ( ;; )
2477  {
2478  size_type j = i;
2479  for ( const_iterator p = m_data->string + i; j < len; ++j, ++p )
2480  if ( *p == c )
2481  break;
2482 
2483  GenericString t;
2484  if ( i < j )
2485  {
2486  const_iterator l = m_data->string + i;
2487  size_type m = j - i;
2488  if ( trim )
2489  {
2490  const_iterator r = l + m;
2491  l = R::SearchTrimLeft( l, r );
2492  m = R::SearchTrimRight( l, r ) - l;
2493  }
2494  if ( m > 0 )
2495  {
2496  t.m_data->Allocate( m );
2497  R::Copy( t.m_data->string, l, m );
2498  }
2499  }
2500  list.Add( t );
2501  ++count;
2502 
2503  if ( j == len )
2504  break;
2505 
2506  i = j + 1;
2507  }
2508  }
2509  return count;
2510  }
2511 
2534  template <class C, typename S>
2535  size_type Break( C& list, const Array<S>& ca, bool trim = false, size_type i = 0 ) const
2536  {
2537  size_type count = 0;
2538  if ( !ca.IsEmpty() )
2539  {
2540  size_type len = Length();
2541  if ( i < len )
2542  {
2543  for ( ;; )
2544  {
2545  size_type j = i;
2546  for ( const_iterator p = m_data->string + i; j < len; ++j, ++p )
2547  for ( auto c : ca )
2548  if ( *p == char_type( c ) )
2549  goto __Break_1;
2550 __Break_1:
2551  GenericString t;
2552  if ( i < j )
2553  {
2554  const_iterator l = m_data->string + i;
2555  size_type m = j - i;
2556  if ( trim )
2557  {
2558  const_iterator r = l + m;
2559  l = R::SearchTrimLeft( l, r );
2560  m = R::SearchTrimRight( l, r ) - l;
2561  }
2562  if ( m > 0 )
2563  {
2564  t.m_data->Allocate( m );
2565  R::Copy( t.m_data->string, l, m );
2566  }
2567  }
2568  list.Add( t );
2569  ++count;
2570 
2571  if ( j == len )
2572  break;
2573 
2574  i = j + 1;
2575  }
2576  }
2577  }
2578  return count;
2579  }
2580 
2601  template <class C, class R1, class A1>
2602  size_type BreakIC( C& list, const GenericString<T,R1,A1>& s, bool trim = false, size_type i = 0 ) const
2603  {
2604  size_type count = 0;
2605  size_type len = Length();
2606  if ( i < len )
2607  {
2608  size_type n = s.Length();
2609  if ( n > 0 )
2610  {
2611  for ( SearchEngine S( s.m_data->string, n, false/*case*/ ); ; )
2612  {
2613  size_type j = S( m_data->string, i, len );
2614 
2615  GenericString t;
2616  if ( i < j )
2617  {
2618  const_iterator l = m_data->string + i;
2619  size_type m = j - i;
2620  if ( trim )
2621  {
2622  const_iterator r = l + m;
2623  l = R::SearchTrimLeft( l, r );
2624  m = R::SearchTrimRight( l, r ) - l;
2625  }
2626  if ( m > 0 )
2627  {
2628  t.m_data->Allocate( m );
2629  R::Copy( t.m_data->string, l, m );
2630  }
2631  }
2632  list.Add( t );
2633  ++count;
2634 
2635  if ( j == len )
2636  break;
2637 
2638  i = j + n;
2639  }
2640  }
2641  }
2642  return count;
2643  }
2644 
2667  template <class C>
2668  size_type BreakIC( C& list, const_c_string s, bool trim = false, size_type i = 0 ) const
2669  {
2670  size_type count = 0;
2671  size_type len = Length();
2672  if ( i < len )
2673  {
2674  size_type n = R::Length( s );
2675  if ( n > 0 )
2676  {
2677  for ( SearchEngine S( s, n, false/*case*/ ); ; )
2678  {
2679  size_type j = S( m_data->string, i, len );
2680 
2681  GenericString t;
2682  if ( i < j )
2683  {
2684  const_iterator l = m_data->string + i;
2685  size_type m = j - i;
2686  if ( trim )
2687  {
2688  const_iterator r = l + m;
2689  l = R::SearchTrimLeft( l, r );
2690  m = R::SearchTrimRight( l, r ) - l;
2691  }
2692  if ( m > 0 )
2693  {
2694  t.m_data->Allocate( m );
2695  R::Copy( t.m_data->string, l, m );
2696  }
2697  }
2698  list.Add( t );
2699  ++count;
2700 
2701  if ( j == len )
2702  break;
2703 
2704  i = j + n;
2705  }
2706  }
2707  }
2708  return count;
2709  }
2710 
2732  template <class C>
2733  size_type BreakIC( C& list, char_type c, bool trim = false, size_type i = 0 ) const
2734  {
2735  size_type count = 0;
2736  size_type len = Length();
2737  if ( i < len )
2738  {
2739  c = R::ToCaseFolded( c );
2740  for ( ;; )
2741  {
2742  size_type j = i;
2743  for ( const_iterator p = m_data->string + i; j < len; ++j, ++p )
2744  if ( R::ToCaseFolded( *p ) == c )
2745  break;
2746 
2747  GenericString t;
2748  if ( i < j )
2749  {
2750  const_iterator l = m_data->string + i;
2751  size_type m = j - i;
2752  if ( trim )
2753  {
2754  const_iterator r = l + m;
2755  l = R::SearchTrimLeft( l, r );
2756  m = R::SearchTrimRight( l, r ) - l;
2757  }
2758  if ( m > 0 )
2759  {
2760  t.m_data->Allocate( m );
2761  R::Copy( t.m_data->string, l, m );
2762  }
2763  }
2764  list.Add( t );
2765  ++count;
2766 
2767  if ( j == len )
2768  break;
2769 
2770  i = j + 1;
2771  }
2772  }
2773  return count;
2774  }
2775 
2780  char_type FirstChar() const
2781  {
2782  return (m_data->string != nullptr) ? *m_data->string : R::Null();
2783  }
2784 
2789  char_type LastChar() const
2790  {
2791  return (m_data->string < m_data->end) ? *(m_data->end-1) : R::Null();
2792  }
2793 
2797  template <class R1, class A1>
2798  bool StartsWith( const GenericString<T,R1,A1>& s ) const
2799  {
2800  if ( s.IsEmpty() || Length() < s.Length() )
2801  return false;
2802  for ( const_iterator p = m_data->string, q = s.m_data->string; q < s.m_data->end; ++p, ++q )
2803  if ( *p != *q )
2804  return false;
2805  return true;
2806  }
2807 
2812  bool StartsWith( const_c_string t ) const
2813  {
2814  size_type n = R::Length( t );
2815  if ( n == 0 || Length() < n )
2816  return false;
2817  for ( const_iterator p = m_data->string, e = p+n; p < e; ++p, ++t )
2818  if ( *p != *t )
2819  return false;
2820  return true;
2821  }
2822 
2826  bool StartsWith( char_type c ) const
2827  {
2828  return m_data->string < m_data->end && *m_data->string == c;
2829  }
2830 
2835  template <class R1, class A1>
2836  bool StartsWithIC( const GenericString<T,R1,A1>& s ) const
2837  {
2838  if ( s.IsEmpty() || Length() < s.Length() )
2839  return false;
2840  for ( const_iterator p = m_data->string, q = s.m_data->string; q < s.m_data->end; ++p, ++q )
2841  if ( R::ToCaseFolded( *p ) != R::ToCaseFolded( *q ) )
2842  return false;
2843  return true;
2844  }
2845 
2850  bool StartsWithIC( const_c_string t ) const
2851  {
2852  size_type n = R::Length( t );
2853  if ( n == 0 || Length() < n )
2854  return false;
2855  for ( const_iterator p = m_data->string, e = p+n; p < e; ++p, ++t )
2856  if ( R::ToCaseFolded( *p ) != R::ToCaseFolded( *t ) )
2857  return false;
2858  return true;
2859  }
2860 
2865  bool StartsWithIC( char_type c ) const
2866  {
2867  return m_data->string < m_data->end && R::ToCaseFolded( *m_data->string ) == R::ToCaseFolded( c );
2868  }
2869 
2873  template <class R1, class A1>
2874  bool EndsWith( const GenericString<T,R1,A1>& s ) const
2875  {
2876  size_type n = s.Length();
2877  if ( n == 0 || Length() < n )
2878  return false;
2879  for ( const_iterator p = m_data->end-n, q = s.m_data->string; p < m_data->end; ++p, ++q )
2880  if ( *p != *q )
2881  return false;
2882  return true;
2883  }
2884 
2889  bool EndsWith( const_c_string t ) const
2890  {
2891  size_type n = R::Length( t );
2892  if ( n == 0 || Length() < n )
2893  return false;
2894  for ( const_iterator p = m_data->end-n; p < m_data->end; ++p, ++t )
2895  if ( *p != *t )
2896  return false;
2897  return true;
2898  }
2899 
2903  bool EndsWith( char_type c ) const
2904  {
2905  return m_data->string < m_data->end && *(m_data->end-1) == c;
2906  }
2907 
2912  template <class R1, class A1>
2913  bool EndsWithIC( const GenericString<T,R1,A1>& s ) const
2914  {
2915  size_type n = s.Length();
2916  if ( n == 0 || Length() < n )
2917  return false;
2918  for ( const_iterator p = m_data->end-n, q = s.m_data->string; p < m_data->end; ++p, ++q )
2919  if ( R::ToCaseFolded( *p ) != R::ToCaseFolded( *q ) )
2920  return false;
2921  return true;
2922  }
2923 
2928  bool EndsWithIC( const_c_string t ) const
2929  {
2930  size_type n = R::Length( t );
2931  if ( n == 0 || Length() < n )
2932  return false;
2933  for ( const_iterator p = m_data->end-n; p < m_data->end; ++p, ++t )
2934  if ( R::ToCaseFolded( *p ) != R::ToCaseFolded( *t ) )
2935  return false;
2936  return true;
2937  }
2938 
2943  bool EndsWithIC( char_type c ) const
2944  {
2945  return m_data->string < m_data->end && R::ToCaseFolded( *(m_data->end-1) ) == R::ToCaseFolded( c );
2946  }
2947 
2953  template <class R1, class A1>
2955  {
2956  size_type len = Length();
2957  i = SearchEngine( s.m_data->string, s.Length(), true/*case*/ )( m_data->string, i, len );
2958  return (i < len) ? i : notFound;
2959  }
2960 
2966  size_type FindFirst( const_c_string t, size_type i = 0 ) const
2967  {
2968  size_type len = Length();
2969  i = SearchEngine( t, R::Length( t ), true/*case*/ )( m_data->string, i, len );
2970  return (i < len) ? i : notFound;
2971  }
2972 
2978  size_type FindFirst( char_type c, size_type i = 0 ) const
2979  {
2980  for ( const_iterator p = m_data->string+i; p < m_data->end; ++p )
2981  if ( *p == c )
2982  return p - m_data->string;
2983  return notFound;
2984  }
2985 
2994  template <class R1, class A1>
2996  {
2997  size_type len = Length();
2998  i = SearchEngine( s.m_data->string, s.Length(), false/*case*/ )( m_data->string, i, len );
2999  return (i < len) ? i : notFound;
3000  }
3001 
3010  size_type FindFirstIC( const_c_string t, size_type i = 0 ) const
3011  {
3012  size_type len = Length();
3013  i = SearchEngine( t, R::Length( t ), false/*case*/ )( m_data->string, i, len );
3014  return (i < len) ? i : notFound;
3015  }
3016 
3025  size_type FindFirstIC( char_type c, size_type i = 0 ) const
3026  {
3027  c = R::ToCaseFolded( c );
3028  for ( const_iterator p = m_data->string+i; p < m_data->end; ++p )
3029  if ( R::ToCaseFolded( *p ) == c )
3030  return p - m_data->string;
3031  return notFound;
3032  }
3033 
3037  template <class R1, class A1>
3039  {
3040  return FindFirst( s, i );
3041  }
3042 
3046  size_type Find( const_c_string t, size_type i = 0 ) const
3047  {
3048  return FindFirst( t, i );
3049  }
3050 
3054  size_type Find( char_type c, size_type i = 0 ) const
3055  {
3056  return FindFirst( c, i );
3057  }
3058 
3062  template <class R1, class A1>
3064  {
3065  return FindFirstIC( s, i );
3066  }
3067 
3071  size_type FindIC( const_c_string t, size_type i = 0 ) const
3072  {
3073  return FindFirstIC( t, i );
3074  }
3075 
3079  size_type FindIC( char_type c, size_type i = 0 ) const
3080  {
3081  return FindFirstIC( c, i );
3082  }
3083 
3093  template <class R1, class A1>
3094  size_type FindLast( const GenericString<T,R1,A1>& s, size_type r = maxPos ) const
3095  {
3096  r = pcl::Min( r, Length() );
3097  size_type i = SearchEngine( s.m_data->string, s.Length(), true/*case*/, true/*last*/ )( m_data->string, 0, r );
3098  return (i < r) ? i : notFound;
3099  }
3100 
3110  size_type FindLast( const_c_string t, size_type r = maxPos ) const
3111  {
3112  r = pcl::Min( r, Length() );
3113  size_type i = SearchEngine( t, R::Length( t ), true/*case*/, true/*last*/ )( m_data->string, 0, r );
3114  return (i < r) ? i : notFound;
3115  }
3116 
3122  size_type FindLast( char_type c, size_type r = maxPos ) const
3123  {
3124  r = pcl::Min( r, Length() );
3125  for ( const_iterator p = m_data->string+r; r > 0; --r )
3126  if ( *--p == c )
3127  return r - 1;
3128  return notFound;
3129  }
3130 
3143  template <class R1, class A1>
3145  {
3146  r = pcl::Min( r, Length() );
3147  size_type i = SearchEngine( s.m_data->string, s.Length(), false/*case*/, true/*last*/ )( m_data->string, 0, r );
3148  return (i < r) ? i : notFound;
3149  }
3150 
3163  size_type FindLastIC( const_c_string t, size_type r = maxPos ) const
3164  {
3165  r = pcl::Min( r, Length() );
3166  size_type i = SearchEngine( t, R::Length( t ), false/*case*/, true/*last*/ )( m_data->string, 0, r );
3167  return (i < r) ? i : notFound;
3168  }
3169 
3178  size_type FindLastIC( char_type c, size_type r = maxPos ) const
3179  {
3180  c = R::ToCaseFolded( c );
3181  r = pcl::Min( r, Length() );
3182  for ( const_iterator p = m_data->string+r; r > 0; --r )
3183  if ( R::ToCaseFolded( *--p ) == c )
3184  return r - 1;
3185  return notFound;
3186  }
3187 
3191  template <class R1, class A1>
3192  bool Contains( const GenericString<T,R1,A1>& s ) const
3193  {
3194  return Find( s ) != notFound;
3195  }
3196 
3200  bool Contains( const_c_string t ) const
3201  {
3202  return Find( t ) != notFound;
3203  }
3204 
3208  bool Contains( char_type c ) const
3209  {
3210  return Find( c ) != notFound;
3211  }
3212 
3219  template <class R1, class A1>
3220  bool ContainsIC( const GenericString<T,R1,A1>& s ) const
3221  {
3222  return FindIC( s ) != notFound;
3223  }
3224 
3231  bool ContainsIC( const_c_string t ) const
3232  {
3233  return FindIC( t ) != notFound;
3234  }
3235 
3242  bool ContainsIC( char_type c ) const
3243  {
3244  return FindIC( c ) != notFound;
3245  }
3246 
3256  void Trim()
3257  {
3258  const_iterator l = R::SearchTrimLeft( m_data->string, m_data->end );
3259  const_iterator r = R::SearchTrimRight( l, m_data->end );
3260  if ( m_data->string < l || r < m_data->end )
3261  Trim( l, r - l );
3262  }
3263 
3273  void TrimLeft()
3274  {
3275  const_iterator l = R::SearchTrimLeft( m_data->string, m_data->end );
3276  if ( m_data->string < l )
3277  Trim( l, m_data->end - l );
3278  }
3279 
3289  void TrimRight()
3290  {
3291  const_iterator r = R::SearchTrimRight( m_data->string, m_data->end );
3292  if ( r < m_data->end )
3293  Trim( m_data->string, r - m_data->string );
3294  }
3295 
3302  {
3303  GenericString s( *this );
3304  s.Trim();
3305  return s;
3306  }
3307 
3314  {
3315  GenericString s( *this );
3316  s.TrimLeft();
3317  return s;
3318  }
3319 
3326  {
3327  GenericString s( *this );
3328  s.TrimRight();
3329  return s;
3330  }
3331 
3338  void EnsureEnclosed( char_type c )
3339  {
3340  int encloseLeft = 1;
3341  int encloseRight = 1;
3342  size_type len = Length();
3343  if ( len > 0 )
3344  {
3345  if ( *m_data->string == c )
3346  encloseLeft = 0;
3347  if ( *(m_data->end-1) == c )
3348  if ( len > 1 )
3349  encloseRight = 0;
3350  else
3351  encloseLeft = 0;
3352  }
3353  size_type n = len + encloseLeft + encloseRight;
3354  if ( n > len )
3355  {
3356  if ( !IsUnique() || m_data->ShouldReallocate( n ) )
3357  {
3358  Data* newData = Data::New( n );
3359  R::Copy( newData->string + encloseLeft, m_data->string, len );
3360  DetachFromData();
3361  m_data = newData;
3362  }
3363  else
3364  {
3365  m_data->SetLength( n );
3366  R::CopyOverlapped( m_data->string + encloseLeft, m_data->string, len );
3367  }
3368 
3369  if ( encloseLeft )
3370  *m_data->string = c;
3371  if ( encloseRight )
3372  *(m_data->end-1) = c;
3373  }
3374  }
3375 
3382  GenericString Enclosed( char_type c ) const
3383  {
3384  GenericString s( *this );
3385  s.EnsureEnclosed( c );
3386  return s;
3387  }
3388 
3396  {
3397  EnsureEnclosed( R::SingleQuote() );
3398  }
3399 
3407  {
3408  GenericString s( *this );
3409  s.EnsureSingleQuoted();
3410  return s;
3411  }
3412 
3420  {
3421  EnsureEnclosed( R::DoubleQuote() );
3422  }
3423 
3431  {
3432  GenericString s( *this );
3433  s.EnsureDoubleQuoted();
3434  return s;
3435  }
3436 
3450  void Unquote()
3451  {
3452  size_type len = Length();
3453  if ( len > 1 )
3454  if ( *m_data->string == R::SingleQuote() && *(m_data->end-1) == R::SingleQuote() ||
3455  *m_data->string == R::DoubleQuote() && *(m_data->end-1) == R::DoubleQuote() )
3456  if ( IsUnique() )
3457  {
3458  R::CopyOverlapped( m_data->string, m_data->string+1, len-2 );
3459  m_data->SetLength( len-2 );
3460  }
3461  else
3462  {
3463  Data* newData = Data::New( len-2 );
3464  R::Copy( newData->string, m_data->string+1, len-2 );
3465  DetachFromData();
3466  m_data = newData;
3467  }
3468  }
3469 
3475  {
3476  GenericString s( *this );
3477  s.Unquote();
3478  return s;
3479  }
3480 
3492  void JustifyLeft( size_type width, char_type fill = R::Blank() )
3493  {
3494  size_type len = Length();
3495  if ( len < width )
3496  Append( fill, width-len );
3497  }
3498 
3510  void JustifyRight( size_type width, char_type fill = R::Blank() )
3511  {
3512  size_type len = Length();
3513  if ( len < width )
3514  Prepend( fill, width-len );
3515  }
3516 
3529  void JustifyCenter( size_type width, char_type fill = R::Blank() )
3530  {
3531  size_type len = Length();
3532  if ( len < width )
3533  {
3534  size_type n = width-len;
3535  size_type n2 = n >> 1;
3536  Prepend( fill, n2 );
3537  Append( fill, n-n2 );
3538  }
3539  }
3540 
3547  GenericString LeftJustified( size_type width, char_type fill = R::Blank() ) const
3548  {
3549  GenericString s( *this );
3550  s.JustifyLeft( width, fill );
3551  return s;
3552  }
3553 
3560  GenericString RightJustified( size_type width, char_type fill = R::Blank() ) const
3561  {
3562  GenericString s( *this );
3563  s.JustifyRight( width, fill );
3564  return s;
3565  }
3566 
3573  GenericString CenterJustified( size_type width, char_type fill = R::Blank() ) const
3574  {
3575  GenericString s( *this );
3576  s.JustifyCenter( width, fill );
3577  return s;
3578  }
3579 
3603  template <class R1, class A1>
3604  int CompareCodePoints( const GenericString<T,R1,A1>& s, bool caseSensitive = true ) const
3605  {
3606  return R::CompareCodePoints( m_data->string, Length(), s.m_data->string, s.Length(), caseSensitive );
3607  }
3608 
3633  int CompareCodePoints( const_c_string t, bool caseSensitive = true ) const
3634  {
3635  return R::CompareCodePoints( m_data->string, Length(), t, R::Length( t ), caseSensitive );
3636  }
3637 
3665  int CompareCodePoints( char_type c, bool caseSensitive = true ) const
3666  {
3667  return R::CompareCodePoints( m_data->string, Length(), &c, 1, caseSensitive );
3668  }
3669 
3696  template <class R1, class A1>
3698  bool caseSensitive = true, bool localeAware = true ) const
3699  {
3700  return R::Compare( m_data->string, Length(), s.m_data->string, s.Length(), caseSensitive, localeAware );
3701  }
3702 
3730  int Compare( const_c_string t, bool caseSensitive = true, bool localeAware = true ) const
3731  {
3732  return R::Compare( m_data->string, Length(), t, R::Length( t ), caseSensitive, localeAware );
3733  }
3734 
3764  int Compare( char_type c, bool caseSensitive = true, bool localeAware = true ) const
3765  {
3766  return R::Compare( m_data->string, Length(), &c, 1, caseSensitive, localeAware );
3767  }
3768 
3789  template <class R1, class A1>
3790  int CompareIC( const GenericString<T,R1,A1>& s, bool localeAware = true ) const
3791  {
3792  return R::Compare( m_data->string, Length(), s.m_data->string, s.Length(), false/*caseSensitive*/, localeAware );
3793  }
3794 
3816  int CompareIC( const_c_string t, bool localeAware = true ) const
3817  {
3818  return R::Compare( m_data->string, Length(), t, R::Length( t ), false/*caseSensitive*/, localeAware );
3819  }
3820 
3845  int CompareIC( char_type c, bool localeAware = true ) const
3846  {
3847  return R::Compare( m_data->string, Length(), &c, 1, false/*caseSensitive*/, localeAware );
3848  }
3849 
3865  template <class R1, class A1>
3866  bool WildMatch( const GenericString<T,R1,A1>& pattern, bool caseSensitive = true ) const
3867  {
3868  return R::WildMatch( m_data->string, Length(), pattern.m_data->string, pattern.Length(), caseSensitive );
3869  }
3870 
3884  template <class R1, class A1>
3885  bool WildMatchIC( const GenericString<T,R1,A1>& pattern ) const
3886  {
3887  return R::WildMatch( m_data->string, Length(), pattern.m_data->string, pattern.Length(), false/*caseSensitive*/ );
3888  }
3889 
3905  bool WildMatch( const_c_string pattern, bool caseSensitive = true ) const
3906  {
3907  return R::WildMatch( m_data->string, Length(), pattern, R::Length( pattern ), caseSensitive );
3908  }
3909 
3924  bool WildMatchIC( const_c_string pattern ) const
3925  {
3926  return R::WildMatch( m_data->string, Length(), pattern, R::Length( pattern ), false/*caseSensitive*/ );
3927  }
3928 
3933  bool HasWildcards() const
3934  {
3935  for ( iterator i = m_data->string; i < m_data->end; ++i )
3936  if ( R::IsWildcard( *i ) )
3937  return true;
3938  return false;
3939  }
3940 
3946  {
3947  size_type len = Length();
3948  if ( len > 0 )
3949  {
3950  EnsureUnique();
3951  R::ToCaseFolded( m_data->string, len );
3952  }
3953  }
3954 
3960  {
3961  size_type len = Length();
3962  if ( len > 0 )
3963  {
3964  EnsureUnique();
3965  R::ToLowercase( m_data->string, len );
3966  }
3967  }
3968 
3974  {
3975  size_type len = Length();
3976  if ( len > 0 )
3977  {
3978  EnsureUnique();
3979  R::ToUppercase( m_data->string, len );
3980  }
3981  }
3982 
3988  {
3989  GenericString s( *this );
3990  s.ToCaseFolded();
3991  return s;
3992  }
3993 
3999  {
4000  GenericString s( *this );
4001  s.ToLowercase();
4002  return s;
4003  }
4004 
4010  {
4011  GenericString s( *this );
4012  s.ToUppercase();
4013  return s;
4014  }
4015 
4021  void Reverse()
4022  {
4023  if ( !IsEmpty() )
4024  {
4025  EnsureUnique();
4026  for ( iterator i = m_data->string, j = m_data->end; i < --j; ++i )
4027  pcl::Swap( *i, *j );
4028  }
4029  }
4030 
4035  {
4036  GenericString s( *this );
4037  s.Reverse();
4038  return s;
4039  }
4040 
4044  void Sort()
4045  {
4046  if ( !IsEmpty() )
4047  {
4048  EnsureUnique();
4049  pcl::Sort( m_data->string, m_data->end );
4050  }
4051  }
4052 
4058  {
4059  GenericString s( *this );
4060  s.Sort();
4061  return s;
4062  }
4063 
4069  template <class BP>
4070  void Sort( BP p )
4071  {
4072  if ( !IsEmpty() )
4073  {
4074  EnsureUnique();
4075  pcl::Sort( m_data->string, m_data->end, p );
4076  }
4077  }
4078 
4083  template <class BP>
4084  GenericString Sorted( BP p ) const
4085  {
4086  GenericString s( *this );
4087  s.Sort( p );
4088  return s;
4089  }
4090 
4105  bool IsNumeral() const
4106  {
4107  if ( IsEmpty() )
4108  return false;
4109  char_type c = *R::SearchTrimLeft( m_data->string, m_data->end );
4110  return R::IsDigit( c ) || R::IsSign( c ) || R::IsDecimalSeparator( c );
4111  }
4112 
4127  bool IsSymbol() const
4128  {
4129  if ( IsEmpty() )
4130  return false;
4131  char_type c = *R::SearchTrimLeft( m_data->string, m_data->end );
4132  return R::IsSymbolDigit( c );
4133  }
4134 
4151  {
4152  if ( IsEmpty() )
4153  {
4154  pos = 0;
4155  return false;
4156  }
4157  const_iterator i = m_data->string;
4158  if ( R::IsStartingSymbolDigit( *i ) )
4159  for ( ;; )
4160  {
4161  if ( ++i == m_data->end )
4162  return true;
4163  if ( !R::IsSymbolDigit( *i ) )
4164  break;
4165  }
4166  pos = i - m_data->string;
4167  return false;
4168  }
4169 
4181  bool IsValidIdentifier() const
4182  {
4183  if ( !IsEmpty() )
4184  if ( R::IsStartingSymbolDigit( *m_data->string ) )
4185  {
4186  for ( const_iterator i = m_data->string; ++i < m_data->end; )
4187  if ( !R::IsSymbolDigit( *i ) )
4188  return false;
4189  return true;
4190  }
4191  return false;
4192  }
4193 
4202  uint64 Hash64( uint64 seed = 0 ) const
4203  {
4204  return pcl::Hash64( m_data->string, Size(), seed );
4205  }
4206 
4215  uint32 Hash32( uint32 seed = 0 ) const
4216  {
4217  return pcl::Hash32( m_data->string, Size(), seed );
4218  }
4219 
4224  uint64 Hash( uint64 seed = 0 ) const
4225  {
4226  return Hash64( seed );
4227  }
4228 
4237  {
4238  return Data::DeleteFreeList();
4239  }
4240 
4241  // -------------------------------------------------------------------------
4242 
4243 protected:
4244 
4249  void DetachFromData()
4250  {
4251  if ( !m_data->Detach() )
4252  Data::Dispose( m_data );
4253  }
4254 
4266  void MaybeReallocate( size_type len )
4267  {
4268  if ( IsUnique() )
4269  {
4270  if ( m_data->ShouldReallocate( len ) )
4271  {
4272  m_data->Deallocate();
4273  m_data->Allocate( len );
4274  }
4275  else
4276  m_data->SetLength( len );
4277  }
4278  else
4279  {
4280  Data* newData = Data::New( len );
4281  DetachFromData();
4282  m_data = newData;
4283  }
4284  }
4285 
4294  void UninitializedGrow( size_type& i, size_type n )
4295  {
4296  size_type len = Length();
4297  size_type newLen = len+n;
4298  if ( newLen > len )
4299  {
4300  if ( i > len )
4301  i = len;
4302  if ( IsUnique() )
4303  {
4304  if ( size_type( m_data->capacity - m_data->string ) < newLen+1 )
4305  {
4306  iterator old = m_data->string;
4307  m_data->Allocate( newLen );
4308  if ( old != nullptr )
4309  {
4310  if ( i > 0 )
4311  R::Copy( m_data->string, old, i );
4312  if ( i < len )
4313  R::Copy( m_data->string+i+n, old+i, len-i );
4314  m_data->alloc.Deallocate( old );
4315  }
4316  }
4317  else
4318  {
4319  if ( i < len )
4320  R::CopyOverlapped( m_data->string+i+n, m_data->string+i, len-i );
4321  m_data->SetLength( newLen );
4322  }
4323  }
4324  else
4325  {
4326  Data* newData = Data::New( newLen );
4327  if ( i > 0 )
4328  R::Copy( newData->string, m_data->string, i );
4329  if ( i < len )
4330  R::Copy( newData->string+i+n, m_data->string+i, len-i );
4331  DetachFromData();
4332  m_data = newData;
4333  }
4334  }
4335  }
4336 
4341  void Trim( const_iterator left, size_type len )
4342  {
4343  if ( len > 0 )
4344  {
4345  if ( IsUnique() )
4346  {
4347  if ( m_data->ShouldReallocate( len ) )
4348  {
4349  iterator old = m_data->string;
4350  m_data->Allocate( len );
4351  R::Copy( m_data->string, left, len );
4352  if ( old != nullptr )
4353  m_data->alloc.Deallocate( old );
4354  }
4355  else
4356  {
4357  if ( left != m_data->string ) // trim left
4358  R::CopyOverlapped( m_data->string, left, len );
4359  m_data->SetLength( len ); // trim right
4360  }
4361  }
4362  else
4363  {
4364  Data* newData = Data::New( len );
4365  R::Copy( newData->string, left, len );
4366  DetachFromData();
4367  m_data = newData;
4368  }
4369  }
4370  else
4371  Clear();
4372  }
4373 
4378  void ReplaceChar( char_type c1, char_type c2, size_type i, size_type n, bool caseSensitive )
4379  {
4380  if ( n > 0 )
4381  {
4382  size_type len = Length();
4383  if ( i < len )
4384  {
4385  n = pcl::Min( n, len-i );
4386  if ( caseSensitive )
4387  {
4388  for ( iterator p = m_data->string + i, p1 = p + n; p < p1; ++p )
4389  if ( *p == c1 )
4390  {
4391  EnsureUnique();
4392  *p = c2;
4393  for ( ; ++p < p1; )
4394  if ( *p == c1 )
4395  *p = c2;
4396  break;
4397  }
4398  }
4399  else
4400  {
4401  c1 = R::ToCaseFolded( c1 );
4402  for ( iterator p = m_data->string + i, p1 = p + n; p < p1; ++p )
4403  if ( R::ToCaseFolded( *p ) == c1 )
4404  {
4405  EnsureUnique();
4406  *p = c2;
4407  for ( ; ++p < p1; )
4408  if ( R::ToCaseFolded( *p ) == c1 )
4409  *p = c2;
4410  break;
4411  }
4412  }
4413  }
4414  }
4415  }
4416 
4421  void ReplaceString( const_iterator t1, size_type n1, const_iterator t2, size_type n2, size_type i, bool caseSensitive )
4422  {
4423  if ( n1 > 0 )
4424  {
4425  size_type len = Length();
4426  if ( i < len )
4427  {
4428  SearchEngine S( t1, n1, caseSensitive );
4429  if ( n1 == n2 )
4430  {
4431  EnsureUnique();
4432  for ( size_type p = i; (p = S( m_data->string, p, len )) < len; p += n1 )
4433  R::Copy( m_data->string + p, t2, n2 );
4434  }
4435  else
4436  {
4437  Array<size_type> P;
4438  for ( size_type p = i; (p = S( m_data->string, p, len )) < len; p += n1 )
4439  P.Add( p );
4440  if ( !P.IsEmpty() )
4441  {
4442  size_type newLen = len;
4443  if ( n1 < n2 )
4444  newLen += P.Length()*(n2 - n1);
4445  else
4446  newLen -= P.Length()*(n1 - n2);
4447 
4448  if ( newLen > 0 )
4449  {
4450  Data* newData = Data::New( newLen );
4451  size_type targetIndex = 0;
4452  size_type sourceIndex = 0;
4453  for ( size_type p : P )
4454  {
4455  size_type n = p - sourceIndex;
4456  if ( n > 0 )
4457  R::Copy( newData->string+targetIndex, m_data->string+sourceIndex, n );
4458  R::Copy( newData->string+targetIndex+n, t2, n2 );
4459  targetIndex += n + n2;
4460  sourceIndex = p + n1;
4461  }
4462  if ( sourceIndex < len )
4463  R::Copy( newData->string+targetIndex, m_data->string+sourceIndex, len-sourceIndex );
4464  DetachFromData();
4465  m_data = newData;
4466  }
4467  else
4468  Clear();
4469  }
4470  }
4471  }
4472  }
4473  }
4474 
4492  class PCL_CLASS SearchEngine
4493  {
4494  public:
4495 
4506  SearchEngine( const_iterator pattern, size_type patternLength,
4507  bool caseSensitive = true, bool searchLast = false, bool useBoyerMoore = true )
4508  : m_pattern( pattern )
4509  , m_patternLength( int( patternLength ) )
4510  , m_caseSensitive( caseSensitive )
4511  , m_searchLast( searchLast )
4512  , m_useBoyerMoore( useBoyerMoore && m_patternLength > 3 )
4513  {
4514  if ( m_useBoyerMoore )
4515  InitSkipList();
4516  }
4517 
4530  size_type operator()( const_iterator text, size_type startIndex, size_type endIndex ) const
4531  {
4532  if ( endIndex <= startIndex
4533  || m_patternLength <= 0
4534  || endIndex-startIndex < size_type( m_patternLength )
4535  || text == nullptr
4536  || m_pattern == nullptr )
4537  return endIndex;
4538 
4539  if ( m_caseSensitive )
4540  {
4541  if ( m_useBoyerMoore )
4542  {
4543  if ( m_searchLast )
4544  {
4545  for ( size_type i = startIndex, r = endIndex-m_patternLength; i <= r; )
4546  {
4547  int skip = 0;
4548  const_iterator t = text + r - i;
4549  const_iterator p = m_pattern;
4550  for ( int j = m_patternLength; --j >= 0; )
4551  {
4552  char_type c = *t++;
4553  if ( c != *p++ )
4554  {
4555  skip = j - m_skipList[uint8( c )];
4556  if ( skip < 1 )
4557  skip = 1;
4558  break;
4559  }
4560  }
4561  if ( skip == 0 )
4562  return r - i;
4563  i += skip;
4564  }
4565  }
4566  else
4567  {
4568  for ( size_type i = startIndex, r = endIndex-m_patternLength; i <= r; )
4569  {
4570  int skip = 0;
4571  const_iterator t = text + i + m_patternLength;
4572  const_iterator p = m_pattern + m_patternLength;
4573  for ( int j = m_patternLength; --j >= 0; )
4574  {
4575  char_type c = *--t;
4576  if ( c != *--p )
4577  {
4578  // ### N.B.: Could do better with a precomputed pattern mismatch table.
4579  skip = j - m_skipList[uint8( c )];
4580  if ( skip < 1 )
4581  skip = 1;
4582  break;
4583  }
4584  }
4585  if ( skip == 0 )
4586  return i;
4587  i += skip;
4588  }
4589  }
4590  }
4591  else
4592  {
4593  // Use a brute force search for very small patterns.
4594  if ( m_searchLast )
4595  {
4596  for ( size_type i = endIndex-m_patternLength; ; --i )
4597  {
4598  const_iterator t = text + i;
4599  const_iterator p = m_pattern;
4600  for ( int j = m_patternLength; ; ++t, ++p )
4601  {
4602  if ( *t != *p )
4603  break;
4604  if ( --j == 0 )
4605  return i;
4606  }
4607  if ( i == startIndex )
4608  break;
4609  }
4610  }
4611  else
4612  {
4613  for ( size_type i = startIndex, r = endIndex-m_patternLength; ; ++i )
4614  {
4615  const_iterator t = text + i;
4616  const_iterator p = m_pattern;
4617  for ( int j = m_patternLength; ; ++t, ++p )
4618  {
4619  if ( *t != *p )
4620  break;
4621  if ( --j == 0 )
4622  return i;
4623  }
4624  if ( i == r )
4625  break;
4626  }
4627  }
4628  }
4629  }
4630  else
4631  {
4632  if ( m_useBoyerMoore )
4633  {
4634  if ( m_searchLast )
4635  {
4636  for ( size_type i = startIndex, r = endIndex-m_patternLength; i <= r; )
4637  {
4638  int skip = 0;
4639  const_iterator t = text + r - i;
4640  const_iterator p = m_pattern;
4641  for ( int j = m_patternLength; --j >= 0; )
4642  {
4643  char_type c = R::ToCaseFolded( *t++ );
4644  if ( c != R::ToCaseFolded( *p++ ) )
4645  {
4646  skip = j - m_skipList[uint8( c )];
4647  if ( skip < 1 )
4648  skip = 1;
4649  break;
4650  }
4651  }
4652  if ( skip == 0 )
4653  return r - i;
4654  i += skip;
4655  }
4656  }
4657  else
4658  {
4659  for ( size_type i = startIndex, r = endIndex-m_patternLength; i <= r; )
4660  {
4661  int skip = 0;
4662  const_iterator t = text + i + m_patternLength;
4663  const_iterator p = m_pattern + m_patternLength;
4664  for ( int j = m_patternLength; --j >= 0; )
4665  {
4666  char_type c = R::ToCaseFolded( *--t );
4667  if ( c != R::ToCaseFolded( *--p ) )
4668  {
4669  // ### N.B.: Could do better with a precomputed pattern mismatch table.
4670  skip = j - m_skipList[uint8( c )];
4671  if ( skip < 1 )
4672  skip = 1;
4673  break;
4674  }
4675  }
4676  if ( skip == 0 )
4677  return i;
4678  i += skip;
4679  }
4680  }
4681  }
4682  else
4683  {
4684  // Use a brute force search for very small patterns.
4685  if ( m_searchLast )
4686  {
4687  for ( size_type i = endIndex-m_patternLength; ; --i )
4688  {
4689  const_iterator t = text + i;
4690  const_iterator p = m_pattern;
4691  for ( int j = m_patternLength; ; ++t, ++p )
4692  {
4693  if ( R::ToCaseFolded( *t ) != R::ToCaseFolded( *p ) )
4694  break;
4695  if ( --j == 0 )
4696  return i;
4697  }
4698  if ( i == startIndex )
4699  break;
4700  }
4701  }
4702  else
4703  {
4704  for ( size_type i = startIndex, r = endIndex-m_patternLength; ; ++i )
4705  {
4706  const_iterator t = text + i;
4707  const_iterator p = m_pattern;
4708  for ( int j = m_patternLength; ; ++t, ++p )
4709  {
4710  if ( R::ToCaseFolded( *t ) != R::ToCaseFolded( *p ) )
4711  break;
4712  if ( --j == 0 )
4713  return i;
4714  }
4715  if ( i == r )
4716  break;
4717  }
4718  }
4719  }
4720  }
4721  return endIndex;
4722  }
4723 
4724  private:
4725 
4726  int m_skipList[ 256 ];
4727  const_iterator m_pattern;
4728  int m_patternLength;
4729  bool m_caseSensitive : 1;
4730  bool m_searchLast : 1;
4731  bool m_useBoyerMoore : 1;
4732 
4733  void InitSkipList()
4734  {
4735  ::memset( m_skipList, 0xff, sizeof( m_skipList ) ); // fill with -1
4736  if ( m_searchLast )
4737  {
4738  const_iterator p = m_pattern + m_patternLength;
4739  if ( m_caseSensitive )
4740  for ( int i = 0; i < m_patternLength; ++i )
4741  m_skipList[uint8( *--p )] = i;
4742  else
4743  for ( int i = 0; i < m_patternLength; ++i )
4744  m_skipList[uint8( R::ToCaseFolded( *--p ) )] = i;
4745  }
4746  else
4747  {
4748  const_iterator p = m_pattern;
4749  if ( m_caseSensitive )
4750  for ( int i = 0; i < m_patternLength; ++i )
4751  m_skipList[uint8( *p++ )] = i;
4752  else
4753  for ( int i = 0; i < m_patternLength; ++i )
4754  m_skipList[uint8( R::ToCaseFolded( *p++ ) )] = i;
4755  }
4756  }
4757  };
4758 
4759  // -------------------------------------------------------------------------
4760 
4766  class PCL_CLASS Data : public ReferenceCounter
4767  {
4768  private:
4769 
4770 #ifndef __PCL_NO_STRING_FREE_LIST
4771  static Data* freeList;
4772  static AtomicInt freeLock;
4773 #endif
4774 
4775  public:
4776 
4777  iterator string = nullptr;
4778  iterator end = nullptr;
4779  iterator capacity = nullptr;
4780  allocator alloc;
4781 
4785  Data() = default;
4786 
4790  Data( size_type len )
4791  {
4792  Allocate( len );
4793  }
4794 
4799  Data( size_type len, size_type total )
4800  {
4801  Allocate( len, total );
4802  }
4803 
4807  ~Data()
4808  {
4809  Deallocate();
4810  }
4811 
4822  void Allocate( size_type len, size_type total )
4823  {
4824  total = (len <= total) ? alloc.PagedLength( total+1 ) : len+1; // +1 is room for a null terminating character
4825  string = alloc.Allocate( total );
4826  capacity = string + total;
4827  SetLength( len );
4828  }
4829 
4834  void Allocate( size_type len )
4835  {
4836  Allocate( len, len );
4837  }
4838 
4847  void Reserve( size_type len, size_type total )
4848  {
4849  PCL_PRECONDITION( len <= total )
4850  string = alloc.Allocate( total+1 );
4851  capacity = string + total+1;
4852  SetLength( pcl::Min( len, total ) );
4853  }
4854 
4858  void Deallocate()
4859  {
4860  PCL_CHECK( (string == nullptr) ? end == nullptr : string < end )
4861  if ( string != nullptr )
4862  {
4863  alloc.Deallocate( string );
4864  Reset();
4865  }
4866  }
4867 
4872  bool ShouldReallocate( size_type len ) const
4873  {
4874  size_type m = capacity - string;
4875  return m <= len || alloc.ReallocatedLength( m, len+1 ) < (m >> 1);
4876  }
4877 
4882  void SetLength( size_type len )
4883  {
4884  *(end = (string + len)) = R::Null();
4885  }
4886 
4890  void Reset()
4891  {
4892  string = end = capacity = nullptr;
4893  }
4894 
4901 #ifndef __PCL_NO_STRING_FREE_LIST
4902  static Data* NextFree()
4903  {
4904  if ( freeLock.TestAndSet( 0, 1 ) )
4905  {
4906  Data* data = freeList;
4907  if ( data != nullptr )
4908  freeList = reinterpret_cast<Data*>( data->string );
4909  freeLock.Store( 0 );
4910  return data;
4911  }
4912  return nullptr;
4913  }
4914 #endif // !__PCL_NO_STRING_FREE_LIST
4915 
4923  static Data* New()
4924  {
4925 #ifndef __PCL_NO_STRING_FREE_LIST
4926  Data* data = NextFree();
4927  if ( data != nullptr )
4928  {
4929  data->string = nullptr;
4930  return data;
4931  }
4932 #endif // !__PCL_NO_STRING_FREE_LIST
4933  return new Data;
4934  }
4935 
4943  static Data* New( size_type len )
4944  {
4945 #ifndef __PCL_NO_STRING_FREE_LIST
4946  Data* data = NextFree();
4947  if ( data != nullptr )
4948  {
4949  data->Allocate( len ); // ### FIXME: If allocation fails, data is a leak.
4950  return data;
4951  }
4952 #endif // !__PCL_NO_STRING_FREE_LIST
4953  return new Data( len );
4954  }
4955 
4963  static Data* New( size_type len, size_type total )
4964  {
4965 #ifndef __PCL_NO_STRING_FREE_LIST
4966  Data* data = NextFree();
4967  if ( data != nullptr )
4968  {
4969  data->Allocate( len, total ); // ### FIXME: If allocation fails, data is a leak.
4970  return data;
4971  }
4972 #endif // !__PCL_NO_STRING_FREE_LIST
4973  return new Data( len, total );
4974  }
4975 
4983  static void Dispose( Data* data )
4984  {
4985  PCL_PRECONDITION( data != nullptr )
4986  PCL_CHECK( data->RefCount() == 0 )
4987 #ifndef __PCL_NO_STRING_FREE_LIST
4988  if ( freeLock.TestAndSet( 0, 1 ) )
4989  {
4990  data->Attach();
4991  data->Deallocate();
4992  data->string = reinterpret_cast<iterator>( freeList );
4993  freeList = data;
4994  freeLock.Store( 0 );
4995  }
4996  else
4997 #endif // !__PCL_NO_STRING_FREE_LIST
4998  delete data;
4999  }
5000 
5008  static size_type DeleteFreeList()
5009  {
5010  size_type count = 0;
5011 #ifndef __PCL_NO_STRING_FREE_LIST
5012  while ( freeList != nullptr )
5013  {
5014  Data* data = freeList;
5015  freeList = reinterpret_cast<Data*>( data->string );
5016  data->string = nullptr;
5017  delete data;
5018  ++count;
5019  }
5020 #endif // !__PCL_NO_STRING_FREE_LIST
5021  return count;
5022  }
5023  };
5024 
5025  /*
5026  * The reference-counted string data.
5027  */
5028  Data* m_data = nullptr;
5029 };
5030 
5031 #ifndef __PCL_NO_STRING_FREE_LIST
5032 
5033 template <class T, class R, class A>
5035 
5036 template <class T, class R, class A>
5038 
5039 #endif // !__PCL_NO_STRING_FREE_LIST
5040 
5044 template <class T, class R, class A> inline
5046 {
5047  s1.Swap( s2 );
5048 }
5049 
5050 // ----------------------------------------------------------------------------
5051 
5056 // ----------------------------------------------------------------------------
5057 
5062 template <class T, class R1, class A1, class R2, class A2> inline
5064 {
5065  return s1.CompareCodePoints( s2 ) == 0;
5066 }
5067 
5075 template <class T, class R1, class A1, class R2, class A2> inline
5076 bool operator <( const GenericString<T,R1,A1>& s1, const GenericString<T,R2,A2>& s2 )
5077 {
5078  return s1.CompareCodePoints( s2 ) < 0;
5079 }
5080 
5088 template <class T, class R1, class A1, class R2, class A2> inline
5089 bool operator <=( const GenericString<T,R1,A1>& s1, const GenericString<T,R2,A2>& s2 )
5090 {
5091  return s1.CompareCodePoints( s2 ) <= 0;
5092 }
5093 
5101 template <class T, class R1, class A1, class R2, class A2> inline
5103 {
5104  return s1.CompareCodePoints( s2 ) > 0;
5105 }
5106 
5114 template <class T, class R1, class A1, class R2, class A2> inline
5116 {
5117  return s1.CompareCodePoints( s2 ) >= 0;
5118 }
5119 
5120 // ----------------------------------------------------------------------------
5121 
5126 template <class T, class R, class A> inline
5128 {
5129  return s1.CompareCodePoints( t2 ) == 0;
5130 }
5131 
5139 template <class T, class R, class A> inline
5140 bool operator <( const GenericString<T,R,A>& s1, typename GenericString<T,R,A>::const_c_string t2 )
5141 {
5142  return s1.CompareCodePoints( t2 ) < 0;
5143 }
5144 
5152 template <class T, class R, class A> inline
5153 bool operator <=( const GenericString<T,R,A>& s1, typename GenericString<T,R,A>::const_c_string t2 )
5154 {
5155  return s1.CompareCodePoints( t2 ) <= 0;
5156 }
5157 
5165 template <class T, class R, class A> inline
5167 {
5168  return s1.CompareCodePoints( t2 ) > 0;
5169 }
5170 
5178 template <class T, class R, class A> inline
5180 {
5181  return s1.CompareCodePoints( t2 ) >= 0;
5182 }
5183 
5184 // ----------------------------------------------------------------------------
5185 
5190 template <class T, class R, class A> inline
5192 {
5193  return s2.CompareCodePoints( t1 ) == 0;
5194 }
5195 
5203 template <class T, class R, class A> inline
5204 bool operator <( typename GenericString<T,R,A>::const_c_string t1, const GenericString<T,R,A>& s2 )
5205 {
5206  return s2.CompareCodePoints( t1 ) > 0;
5207 }
5208 
5216 template <class T, class R, class A> inline
5217 bool operator <=( typename GenericString<T,R,A>::const_c_string t1, const GenericString<T,R,A>& s2 )
5218 {
5219  return s2.CompareCodePoints( t1 ) >= 0;
5220 }
5221 
5229 template <class T, class R, class A> inline
5231 {
5232  return s2.CompareCodePoints( t1 ) < 0;
5233 }
5234 
5242 template <class T, class R, class A> inline
5244 {
5245  return s2.CompareCodePoints( t1 ) <= 0;
5246 }
5247 
5248 // ----------------------------------------------------------------------------
5249 
5254 template <class T, class R, class A> inline
5256 {
5257  return s1.CompareCodePoints( c2 ) == 0;
5258 }
5259 
5267 template <class T, class R, class A> inline
5268 bool operator <( const GenericString<T,R,A>& s1, typename GenericString<T,R,A>::char_type c2 )
5269 {
5270  return s1.CompareCodePoints( c2 ) < 0;
5271 }
5272 
5280 template <class T, class R, class A> inline
5281 bool operator <=( const GenericString<T,R,A>& s1, typename GenericString<T,R,A>::char_type c2 )
5282 {
5283  return s1.CompareCodePoints( c2 ) <= 0;
5284 }
5285 
5293 template <class T, class R, class A> inline
5295 {
5296  return s1.CompareCodePoints( c2 ) > 0;
5297 }
5298 
5306 template <class T, class R, class A> inline
5308 {
5309  return s1.CompareCodePoints( c2 ) >= 0;
5310 }
5311 
5312 // ----------------------------------------------------------------------------
5313 
5318 template <class T, class R, class A> inline
5320 {
5321  return s2.CompareCodePoints( c1 ) == 0;
5322 }
5323 
5331 template <class T, class R, class A> inline
5332 bool operator <( typename GenericString<T,R,A>::char_type c1, const GenericString<T,R,A>& s2 )
5333 {
5334  return s2.CompareCodePoints( c1 ) > 0;
5335 }
5336 
5344 template <class T, class R, class A> inline
5345 bool operator <=( typename GenericString<T,R,A>::char_type c1, const GenericString<T,R,A>& s2 )
5346 {
5347  return s2.CompareCodePoints( c1 ) >= 0;
5348 }
5349 
5357 template <class T, class R, class A> inline
5359 {
5360  return s2.CompareCodePoints( c1 ) < 0;
5361 }
5362 
5370 template <class T, class R, class A> inline
5372 {
5373  return s2.CompareCodePoints( c1 ) <= 0;
5374 }
5375 
5376 // ----------------------------------------------------------------------------
5377 
5390 class PCL_CLASS IsoString : public GenericString<char, IsoCharTraits, StandardAllocator>
5391 {
5392 public:
5393 
5399 
5404 
5409 
5414 
5419 
5424 
5429 
5434 
5439 
5444 
5449 
5457 
5462 
5467 
5472 
5476  typedef ustring_base::const_c_string const_c_ustring;
5477 
5482 
5487 
5488  // -------------------------------------------------------------------------
5489 
5493  IsoString() = default;
5494 
5500  : string_base( s )
5501  {
5502  }
5503 
5507  IsoString( const IsoString& ) = default;
5508 
5514  : string_base( std::move( s ) )
5515  {
5516  }
5517 
5521  IsoString( IsoString&& ) = default;
5522 
5530  explicit
5532  {
5533  (void)operator =( s );
5534  }
5535 
5539  IsoString( const_c_string t )
5540  : string_base( t )
5541  {
5542  }
5543 
5548  IsoString( const_c_string t, size_type i, size_type n )
5549  : string_base( t, i, n )
5550  {
5551  }
5552 
5556  IsoString( char_type c, size_type n = 1 )
5557  : string_base( c, n )
5558  {
5559  }
5560 
5565  IsoString( const_iterator i, const_iterator j )
5566  : string_base( i, j )
5567  {
5568  }
5569 
5578  IsoString( std::initializer_list<char_type> l )
5579  : IsoString( l.begin(), l.end() )
5580  {
5581  }
5582 
5592  explicit
5593  IsoString( const_c_ustring t )
5594  {
5595  (void)operator =( t );
5596  }
5597 
5608  IsoString( const_c_ustring t, size_type i, size_type n );
5609 
5617  explicit
5618  IsoString( const ByteArray& B )
5619  : IsoString( const_iterator( B.Begin() ), const_iterator( B.End() ) )
5620  {
5621  }
5622 
5626  explicit
5627  IsoString( bool x )
5628  : string_base( x ? "true" : "false" )
5629  {
5630  }
5631 
5636  explicit
5637  IsoString( short x )
5638  {
5639  (void)Format( "%hd", x );
5640  }
5641 
5646  explicit
5647  IsoString( unsigned short x )
5648  {
5649  (void)Format( "%hu", x );
5650  }
5651 
5656  explicit
5657  IsoString( int x )
5658  {
5659  (void)Format( "%i", x );
5660  }
5661 
5666  explicit
5667  IsoString( unsigned int x )
5668  {
5669  (void)Format( "%u", x );
5670  }
5671 
5676  explicit
5677  IsoString( long x )
5678  {
5679  (void)Format( "%ld", x );
5680  }
5681 
5686  explicit
5687  IsoString( unsigned long x )
5688  {
5689  (void)Format( "%lu", x );
5690  }
5691 
5696  explicit
5697  IsoString( long long x )
5698  {
5699  (void)Format( "%lli", x );
5700  }
5701 
5706  explicit
5707  IsoString( unsigned long long x )
5708  {
5709  (void)Format( "%llu", x );
5710  }
5711 
5716  explicit
5717  IsoString( float x )
5718  {
5719  (void)Format( "%.7g", x );
5720  }
5721 
5726  explicit
5727  IsoString( double x )
5728  {
5729  (void)Format( "%.16g", x );
5730  }
5731 
5736  explicit
5737  IsoString( long double x )
5738  {
5739 #ifdef _MSC_VER
5740  (void)Format( "%.16Lg", x );
5741 #else
5742  (void)Format( "%.18Lg", x );
5743 #endif
5744  }
5745 
5746 #ifndef __PCL_NO_STRING_COMPLEX
5747 
5752  explicit
5754  {
5755  (void)Format( "{%.7g,%.7g}", x.Real(), x.Imag() );
5756  }
5757 
5762  explicit
5764  {
5765  (void)Format( "{%.16g,%.16g}", x.Real(), x.Imag() );
5766  }
5767 
5772  explicit
5774  {
5775 #ifdef _MSC_VER
5776  (void)Format( "{%.16Lg,%.16Lg}", x.Real(), x.Imag() );
5777 #else
5778  (void)Format( "{%.18Lg,%.18Lg}", x.Real(), x.Imag() );
5779 #endif
5780  }
5781 
5782 #endif // !__PCL_NO_STRING_COMPLEX
5783 
5784 #ifdef __PCL_QT_INTERFACE
5785 
5786  explicit
5787  IsoString( const QString& qs )
5788  : string_base( qs.isEmpty() ? iterator( nullptr ) : iterator( PCL_GET_CHARPTR_FROM_QSTRING( qs ) ) )
5789  {
5790  }
5791 
5792  explicit
5793  IsoString( const QByteArray& qb )
5794  : string_base( qb.isEmpty() ? iterator( nullptr ) : iterator( PCL_GET_CHARPTR_FROM_QBYTEARRAY( qb ) ) )
5795  {
5796  }
5797 
5798  explicit
5799  IsoString( const QDate& qd )
5800  : string_base( iterator( PCL_GET_CHARPTR_FROM_QSTRING( qd.toString( PCL_QDATE_FMT_STR ) ) ) )
5801  {
5802  }
5803 
5804  explicit
5805  IsoString( const QDateTime& qdt )
5806  : string_base( iterator( PCL_GET_CHARPTR_FROM_QSTRING( qdt.toString( PCL_QDATETIME_FMT_STR ) ) ) )
5807  {
5808  }
5809 
5810 #endif
5811 
5812  // -------------------------------------------------------------------------
5813 
5817  IsoString& operator =( const IsoString& s )
5818  {
5819  Assign( s );
5820  return *this;
5821  }
5822 
5826  IsoString& operator =( IsoString&& s )
5827  {
5828  Transfer( s );
5829  return *this;
5830  }
5831 
5836  IsoString& operator =( const string_base& s )
5837  {
5838  Assign( s );
5839  return *this;
5840  }
5841 
5846  IsoString& operator =( string_base&& s )
5847  {
5848  Transfer( s );
5849  return *this;
5850  }
5851 
5862  IsoString& operator =( const ustring_base& s )
5863  {
5864  return operator =( s.Begin() );
5865  }
5866 
5871  IsoString& operator =( const_c_string t )
5872  {
5873  Assign( t );
5874  return *this;
5875  }
5876 
5881  IsoString& operator =( char_type c )
5882  {
5883  Assign( c, 1 );
5884  return *this;
5885  }
5886 
5897  IsoString& operator =( const_c_ustring t );
5898 
5899 #ifdef __PCL_QT_INTERFACE
5900 
5901  IsoString& operator =( const QString& qs )
5902  {
5903  if ( qs.isEmpty() )
5904  Clear();
5905  else
5906  Assign( PCL_GET_CHARPTR_FROM_QSTRING( qs ) );
5907  return *this;
5908  }
5909 
5910  IsoString& operator =( const QByteArray& qb )
5911  {
5912  if ( qb.isEmpty() )
5913  Clear();
5914  else
5915  Assign( PCL_GET_CHARPTR_FROM_QBYTEARRAY( qb ) );
5916  return *this;
5917  }
5918 
5919  IsoString& operator =( const QDate& qd )
5920  {
5921  Assign( PCL_GET_CHARPTR_FROM_QSTRING( qd.toString( PCL_QDATE_FMT_STR ) ) );
5922  return *this;
5923  }
5924 
5925  IsoString& operator =( const QDateTime& qdt )
5926  {
5927  Assign( PCL_GET_CHARPTR_FROM_QSTRING( qdt.toString( PCL_QDATETIME_FMT_STR ) ) );
5928  return *this;
5929  }
5930 
5931 #endif
5932 
5933  // -------------------------------------------------------------------------
5934 
5935  IsoString SetToLength( size_type n ) const
5936  {
5937  return string_base::SetToLength( n );
5938  }
5939 
5940  IsoString ResizedToNullTerminated() const
5941  {
5942  return string_base::ResizedToNullTerminated();
5943  }
5944 
5945  IsoString Squeezed() const
5946  {
5947  return string_base::Squeezed();
5948  }
5949 
5950  // -------------------------------------------------------------------------
5951 
5952  IsoString Substring( size_type i, size_type n = maxPos ) const
5953  {
5954  return string_base::Substring( i, n );
5955  }
5956 
5957  IsoString Left( size_type n ) const
5958  {
5959  return string_base::Left( n );
5960  }
5961 
5962  IsoString Right( size_type n ) const
5963  {
5964  return string_base::Right( n );
5965  }
5966 
5967  IsoString Suffix( size_type i ) const
5968  {
5969  return string_base::Suffix( i );
5970  }
5971 
5972  IsoString Prefix( size_type i ) const
5973  {
5974  return string_base::Prefix( i );
5975  }
5976 
5977  // -------------------------------------------------------------------------
5978 
5979  IsoString Trimmed() const
5980  {
5981  return string_base::Trimmed();
5982  }
5983 
5984  IsoString TrimmedLeft() const
5985  {
5986  return string_base::TrimmedLeft();
5987  }
5988 
5989  IsoString TrimmedRight() const
5990  {
5991  return string_base::TrimmedRight();
5992  }
5993 
5994  // -------------------------------------------------------------------------
5995 
5996  IsoString LeftJustified( size_type width, char_type fill = IsoCharTraits::Blank() ) const
5997  {
5998  return string_base::LeftJustified( width, fill );
5999  }
6000 
6001  IsoString RightJustified( size_type width, char_type fill = IsoCharTraits::Blank() ) const
6002  {
6003  return string_base::RightJustified( width, fill );
6004  }
6005 
6006  IsoString CenterJustified( size_type width, char_type fill = IsoCharTraits::Blank() ) const
6007  {
6008  return string_base::CenterJustified( width, fill );
6009  }
6010 
6011  // -------------------------------------------------------------------------
6012 
6013  IsoString Enclosed( char_type c ) const
6014  {
6015  return string_base::Enclosed( c );
6016  }
6017 
6018  IsoString SingleQuoted() const
6019  {
6020  return string_base::SingleQuoted();
6021  }
6022 
6023  IsoString DoubleQuoted() const
6024  {
6025  return string_base::DoubleQuoted();
6026  }
6027 
6028  IsoString Unquoted() const
6029  {
6030  return string_base::Unquoted();
6031  }
6032 
6033  // -------------------------------------------------------------------------
6034 
6035  IsoString CaseFolded() const
6036  {
6037  return string_base::CaseFolded();
6038  }
6039 
6040  IsoString Lowercase() const
6041  {
6042  return string_base::Lowercase();
6043  }
6044 
6045  IsoString Uppercase() const
6046  {
6047  return string_base::Uppercase();
6048  }
6049 
6050  // -------------------------------------------------------------------------
6051 
6052  IsoString Reversed() const
6053  {
6054  return string_base::Reversed();
6055  }
6056 
6057  IsoString Sorted() const
6058  {
6059  return string_base::Sorted();
6060  }
6061 
6062  template <class BP>
6063  IsoString Sorted( BP p ) const
6064  {
6065  return string_base::Sorted( p );
6066  }
6067 
6068  // -------------------------------------------------------------------------
6069 
6079  template <class C>
6080  IsoString& ToSeparated( const C& c, char_type separator )
6081  {
6082  Clear();
6083  return c.ToSeparated( *this, separator );
6084  }
6085 
6102  template <class C, class AF>
6103  IsoString& ToSeparated( const C& c, char_type separator, AF append )
6104  {
6105  Clear();
6106  return c.ToSeparated( *this, separator, append );
6107  }
6108 
6118  template <class C>
6119  IsoString& ToSeparated( const C& c, const IsoString& separator )
6120  {
6121  Clear();
6122  return c.ToSeparated( *this, separator );
6123  }
6124 
6141  template <class C, class AF>
6142  IsoString& ToSeparated( const C& c, const IsoString& separator, AF append )
6143  {
6144  Clear();
6145  return c.ToSeparated( *this, separator, append );
6146  }
6147 
6157  template <class C>
6158  IsoString& ToSeparated( const C& c, const_c_string separator )
6159  {
6160  return ToSeparated( c, IsoString( separator ) );
6161  }
6162 
6179  template <class C, class AF>
6180  IsoString& ToSeparated( const C& c, const_c_string separator, AF append )
6181  {
6182  return ToSeparated( c, IsoString( separator ), append );
6183  }
6184 
6194  template <class C>
6196  {
6197  return ToSeparated( c, IsoCharTraits::Comma() );
6198  }
6199 
6209  template <class C>
6211  {
6212  return ToSeparated( c, IsoCharTraits::Colon() );
6213  }
6214 
6224  template <class C>
6226  {
6227  return ToSeparated( c, IsoCharTraits::Blank() );
6228  }
6229 
6239  template <class C>
6240  IsoString& ToTabSeparated( const C& c )
6241  {
6242  return ToSeparated( c, IsoCharTraits::Tab() );
6243  }
6244 
6254  template <class C>
6256  {
6257  return ToSeparated( c, IsoCharTraits::LF() );
6258  }
6259 
6269  template <class C>
6271  {
6272  return ToSeparated( c, IsoCharTraits::Null() );
6273  }
6274 
6283  template <class C>
6284  IsoString& ToHyphenated( const C& c )
6285  {
6286  return ToSeparated( c, IsoCharTraits::Hyphen() );
6287  }
6288 
6289  // -------------------------------------------------------------------------
6290 
6305  IsoString& ToEncodedHTMLSpecialChars();
6306 
6314  {
6315  return IsoString( *this ).ToEncodedHTMLSpecialChars();
6316  }
6317 
6334  IsoString& ToDecodedHTMLSpecialChars();
6335 
6344  {
6345  return IsoString( *this ).ToDecodedHTMLSpecialChars();
6346  }
6347 
6359  static IsoString ToURLEncoded( const void* data, size_type length );
6360 
6373  template <class C>
6374  static IsoString ToURLEncoded( const C& c )
6375  {
6376  return ToURLEncoded( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
6377  }
6378 
6388  IsoString& ToURLEncoded();
6389 
6397  {
6398  return IsoString( *this ).ToURLEncoded();
6399  }
6400 
6412  static ByteArray FromURLEncoded( const void* data, size_type length );
6413 
6421  template <class C>
6422  static ByteArray FromURLEncoded( const C& c )
6423  {
6424  return FromURLEncoded( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
6425  }
6426 
6439  {
6440  return FromURLEncoded( Begin(), Length() );
6441  }
6442 
6454  static IsoString ToURLDecoded( const void* data, size_type length );
6455 
6462  template <class C>
6463  static IsoString ToURLDecoded( const C& c )
6464  {
6465  return ToURLDecoded( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
6466  }
6467 
6477  IsoString& ToURLDecoded();
6478 
6486  {
6487  return IsoString( *this ).ToURLDecoded();
6488  }
6489 
6490  // -------------------------------------------------------------------------
6491 
6492 #ifdef __PCL_QT_INTERFACE
6493 
6494  operator QString() const
6495  {
6496  return QString( c_str() );
6497  }
6498 
6499  operator QByteArray() const
6500  {
6501  return QByteArray( c_str() );
6502  }
6503 
6504  operator QDate() const
6505  {
6506  return QDate::fromString( c_str(), PCL_QDATE_FMT_STR );
6507  }
6508 
6509  operator QDateTime() const
6510  {
6511  return QDateTime::fromString( c_str(), PCL_QDATETIME_FMT_STR );
6512  }
6513 
6514 #endif
6515 
6527  IsoString& Format( const_c_string fmt, ... )
6528  {
6529  va_list paramList;
6530  va_start( paramList, fmt );
6531 
6532  (void)VFormat( fmt, paramList );
6533 
6534  va_end( paramList );
6535  return *this;
6536  }
6537 
6549  IsoString& AppendFormat( const_c_string fmt, ... )
6550  {
6551  va_list paramList;
6552  va_start( paramList, fmt );
6553 
6554  (void)AppendVFormat( fmt, paramList );
6555 
6556  va_end( paramList );
6557  return *this;
6558  }
6559 
6572  int VFormat( const_c_string fmt, va_list paramList );
6573 
6586  int AppendVFormat( const_c_string fmt, va_list paramList );
6587 
6588  // -------------------------------------------------------------------------
6589 
6600  {
6601  ustring_base s;
6602  s.SetLength( Length() );
6603  uchar_iterator p = s.Begin();
6604  for ( const_iterator i = m_data->string; i < m_data->end; ++p, ++i )
6605  *p = uchar_type( *i );
6606  return s;
6607  }
6608 
6616  ustring_base UTF8ToUTF16( size_type i = 0, size_type n = maxPos ) const; // implemented inline after String
6617 
6633  ustring_base MBSToWCS() const;
6634 
6635 #ifdef __PCL_QT_INTERFACE
6636 
6637  QString ToQString() const
6638  {
6639  return operator QString();
6640  }
6641 
6642  QByteArray ToQByteArray() const
6643  {
6644  return operator QByteArray();
6645  }
6646 
6647  QDate ToQDate() const
6648  {
6649  return operator QDate();
6650  }
6651 
6652  QDateTime ToQDateTime() const
6653  {
6654  return operator QDateTime();
6655  }
6656 
6657 #endif
6658 
6669  bool ToBool() const;
6670 
6685  bool TryToBool( bool& value ) const;
6686 
6700  float ToFloat() const;
6701 
6716  bool TryToFloat( float& value ) const;
6717 
6741  double ToDouble() const;
6742 
6757  bool TryToDouble( double& value ) const;
6758 
6776  long ToInt() const
6777  {
6778  return ToInt( 0 );
6779  }
6780 
6804  bool TryToInt( int& value ) const
6805  {
6806  return TryToInt( value, 0 );
6807  }
6808 
6835  long ToInt( int base ) const;
6836 
6854  bool TryToInt( int& value, int base ) const;
6855 
6873  unsigned long ToUInt() const
6874  {
6875  return ToUInt( 0 );
6876  }
6877 
6901  bool TryToUInt( unsigned& value ) const
6902  {
6903  return TryToUInt( value, 0 );
6904  }
6905 
6922  unsigned long ToUInt( int base ) const;
6923 
6941  bool TryToUInt( unsigned& value, int base ) const;
6942 
6957  long long ToInt64() const
6958  {
6959  return ToInt64( 0 );
6960  }
6961 
6986  bool TryToInt64( long long& value ) const
6987  {
6988  return TryToInt64( value, 0 );
6989  }
6990 
7005  long long ToInt64( int base ) const;
7006 
7024  bool TryToInt64( long long& value, int base ) const;
7025 
7040  unsigned long long ToUInt64() const
7041  {
7042  return ToUInt64( 0 );
7043  }
7044 
7069  bool TryToUInt64( unsigned long long& value ) const
7070  {
7071  return TryToUInt64( value, 0 );
7072  }
7073 
7088  unsigned long long ToUInt64( int base ) const;
7089 
7107  bool TryToUInt64( unsigned long long& value, int base ) const;
7108 
7136  double SexagesimalToDouble( const IsoString& separator = ':' ) const
7137  {
7138  int sign, s1, s2; double s3;
7139  ParseSexagesimal( sign, s1, s2, s3, separator );
7140  return sign*(s1 + (s2 + s3/60)/60);
7141  }
7142 
7143  double SexagesimalToDouble( char separator ) const
7144  {
7145  return SexagesimalToDouble( IsoString( separator ) );
7146  }
7147 
7148  double SexagesimalToDouble( const ustring_base& separator ) const
7149  {
7150  return SexagesimalToDouble( IsoString( separator ) );
7151  }
7152 
7166  double SexagesimalToDouble( const Array<char_type>& separators ) const
7167  {
7168  int sign, s1, s2; double s3;
7169  ParseSexagesimal( sign, s1, s2, s3, separators );
7170  return sign*(s1 + (s2 + s3/60)/60);
7171  }
7172 
7190  bool TrySexagesimalToDouble( double& value, const IsoString& separator = ':' ) const
7191  {
7192  int sign, s1, s2; double s3;
7193  if ( TryParseSexagesimal( sign, s1, s2, s3, separator ) )
7194  {
7195  value = sign*(s1 + (s2 + s3/60)/60);
7196  return true;
7197  }
7198  return false;
7199  }
7200 
7201  bool TrySexagesimalToDouble( double& value, char separator ) const
7202  {
7203  return TrySexagesimalToDouble( value, IsoString( separator ) );
7204  }
7205 
7206  bool TrySexagesimalToDouble( double& value, const ustring_base& separator ) const
7207  {
7208  return TrySexagesimalToDouble( value, IsoString( separator ) );
7209  }
7210 
7223  bool TrySexagesimalToDouble( double& value, const Array<char_type>& separators ) const
7224  {
7225  int sign, s1, s2; double s3;
7226  if ( TryParseSexagesimal( sign, s1, s2, s3, separators ) )
7227  {
7228  value = sign*(s1 + (s2 + s3/60)/60);
7229  return true;
7230  }
7231  return false;
7232  }
7233 
7260  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const IsoString& separator = ':' ) const;
7261 
7262  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, char separator ) const
7263  {
7264  ParseSexagesimal( sign, s1, s2, s3, IsoString( separator ) );
7265  }
7266 
7267  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const ustring_base& separator ) const
7268  {
7269  ParseSexagesimal( sign, s1, s2, s3, IsoString( separator ) );
7270  }
7271 
7286  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const Array<char_type>& separators ) const;
7287 
7302  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const IsoString& separator = ':' ) const;
7303 
7304  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, char separator ) const
7305  {
7306  return TryParseSexagesimal( sign, s1, s2, s3, IsoString( separator ) );
7307  }
7308 
7309  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const ustring_base& separator ) const
7310  {
7311  return TryParseSexagesimal( sign, s1, s2, s3, IsoString( separator ) );
7312  }
7313 
7327  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const Array<char_type>& separators ) const;
7328 
7353  static IsoString ToSexagesimal( int sign, double s1, double s2, double s3,
7355 
7367  {
7368  return ToSexagesimal( (d < 0) ? -1 : +1, Abs( d ), 0, 0, options );
7369  }
7370 
7394  void ParseISO8601DateTime( int& year, int& month, int& day, double& dayf, double& tz ) const;
7395 
7409  bool TryParseISO8601DateTime( int& year, int& month, int& day, double& dayf, double& tz ) const;
7410 
7434  static IsoString ToISO8601DateTime( int year, int month, int day, double dayf, double tz = 0,
7436 
7447  static IsoString CurrentUTCISO8601DateTime( const ISO8601ConversionOptions& options = ISO8601ConversionOptions() );
7448 
7459  static IsoString CurrentLocalISO8601DateTime( const ISO8601ConversionOptions& options = ISO8601ConversionOptions() );
7460 
7468  static IsoString ToHex( const void* data, size_type length );
7469 
7482  template <class C>
7483  static IsoString ToHex( const C& c )
7484  {
7485  return ToHex( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
7486  }
7487 
7498  static IsoString ToBase64( const void* data, size_type length );
7499 
7512  template <class C>
7513  static IsoString ToBase64( const C& c )
7514  {
7515  return ToBase64( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
7516  }
7517 
7526  {
7527  return ByteArray( Begin(), End() );
7528  }
7529 
7542  ByteArray FromHex() const;
7543 
7556  ByteArray FromBase64() const;
7557 
7564  static IsoString Random( size_type n, RandomizationOptions options = RandomizationOption::Default );
7565 
7577  static IsoString UUID();
7578 };
7579 
7580 // ----------------------------------------------------------------------------
7581 
7591 {
7592  IsoString s( s1 );
7593  s.Append( s2 );
7594  return s;
7595 }
7596 
7603 {
7604  s1.Append( s2 );
7605  return IsoString( std::move( s1 ) );
7606 }
7607 
7614 {
7615  s1.Append( s2 );
7616  return std::move( s1 );
7617 }
7618 
7625 {
7626  s2.Prepend( s1 );
7627  return IsoString( std::move( s2 ) );
7628 }
7629 
7636 {
7637  s2.Prepend( s1 );
7638  return std::move( s2 );
7639 }
7640 
7647 {
7648  s1.Append( s2 );
7649  return IsoString( std::move( s1 ) );
7650 }
7651 
7658 {
7659  s1.Append( s2 );
7660  return std::move( s1 );
7661 }
7662 
7669 {
7670  s1.Append( s2 );
7671  return IsoString( std::move( s1 ) );
7672 }
7673 
7680 {
7681  s1.Append( s2 );
7682  return std::move( s1 );
7683 }
7684 
7685 // ----------------------------------------------------------------------------
7686 
7693 {
7694  IsoString s = s1;
7695  s.Append( t2 );
7696  return s;
7697 }
7698 
7705 {
7706  s1.Append( t2 );
7707  return IsoString( std::move( s1 ) );
7708 }
7709 
7716 {
7717  s1.Append( t2 );
7718  return std::move( s1 );
7719 }
7720 
7727 {
7728  IsoString s = s2;
7729  s.Prepend( t1 );
7730  return s;
7731 }
7732 
7739 {
7740  s2.Prepend( t1 );
7741  return IsoString( std::move( s2 ) );
7742 }
7743 
7750 {
7751  s2.Prepend( t1 );
7752  return std::move( s2 );
7753 }
7754 
7755 // ----------------------------------------------------------------------------
7756 
7763 {
7764  IsoString s = s1;
7765  s.Append( c2 );
7766  return s;
7767 }
7768 
7775 {
7776  s1.Append( c2 );
7777  return IsoString( std::move( s1 ) );
7778 }
7779 
7786 {
7787  s1.Append( c2 );
7788  return std::move( s1 );
7789 }
7790 
7797 {
7798  IsoString s = s2;
7799  s.Prepend( c1 );
7800  return s;
7801 }
7802 
7809 {
7810  s2.Prepend( c1 );
7811  return IsoString( std::move( s2 ) );
7812 }
7813 
7820 {
7821  s2.Prepend( c1 );
7822  return std::move( s2 );
7823 }
7824 
7825 // ----------------------------------------------------------------------------
7826 
7833 {
7834  s1.Append( s2 );
7835  return s1;
7836 }
7837 
7844 {
7845  s1.Append( s2 );
7846  return s1;
7847 }
7848 
7855 {
7856  s1.Append( t2 );
7857  return s1;
7858 }
7859 
7866 {
7867  s1.Append( t2 );
7868  return s1;
7869 }
7870 
7877 {
7878  s1.Append( c2 );
7879  return s1;
7880 }
7881 
7888 {
7889  s1.Append( c2 );
7890  return s1;
7891 }
7892 
7893 // ----------------------------------------------------------------------------
7894 
7895 #ifndef __PCL_NO_STRING_OSTREAM
7896 
7897 inline std::ostream& operator <<( std::ostream& o, const IsoString& s )
7898 {
7899  return o << s.c_str();
7900 }
7901 
7902 #endif
7903 
7904 // ----------------------------------------------------------------------------
7905 
7916 class PCL_CLASS String : public GenericString<char16_type, CharTraits, StandardAllocator>
7917 {
7918 public:
7919 
7925 
7930 
7935 
7940 
7945 
7950 
7955 
7956  /*
7957  * Null-terminated UTF-16 string - C++11 compatibility.
7958  */
7959  typedef char16_t* c16_string;
7960 
7961  /*
7962  * Immutable null-terminated UTF-16 string - C++11 compatibility.
7963  */
7964  typedef const char16_t* const_c16_string;
7965 
7970 
7975 
7980 
7985 
7995 
8000 
8005 
8010 
8015 
8020 
8025 
8026  // -------------------------------------------------------------------------
8027 
8031  String() = default;
8032 
8037  String( const string_base& s )
8038  : string_base( s )
8039  {
8040  }
8041 
8045  String( const String& ) = default;
8046 
8052  : string_base( std::move( s ) )
8053  {
8054  }
8055 
8059  String( String&& ) = default;
8060 
8065  String( const string8_base& s )
8066  {
8067  Assign( s );
8068  }
8069 
8073  String( const_iterator t )
8074  : string_base( t )
8075  {
8076  }
8077 
8082  String( const_iterator t, size_type i, size_type n )
8083  : string_base( t, i, n )
8084  {
8085  }
8086 
8090  String( char_type c, size_type n )
8091  : string_base( c, n )
8092  {
8093  }
8094 
8099  String( const_iterator i, const_iterator j )
8100  : string_base( i, j )
8101  {
8102  }
8103 
8112  String( std::initializer_list<char_type> l )
8113  : String( l.begin(), l.end() )
8114  {
8115  }
8116 
8121  String( const char16_t* t )
8122  : string_base( reinterpret_cast<const_iterator>( t ) )
8123  {
8124  }
8125 
8131  String( const char16_t* t, size_type i, size_type n )
8132  : string_base( reinterpret_cast<const_iterator>( t ), i, n )
8133  {
8134  }
8135 
8139  String( char16_t c, size_type n )
8140  : string_base( char_type( c ), n )
8141  {
8142  }
8143 
8148  String( const wchar_t* t )
8149  {
8150  Assign( t );
8151  }
8152 
8158  String( const wchar_t* t, size_type i, size_type n )
8159  {
8160  Assign( t, i, n );
8161  }
8162 
8166  String( wchar_t c, size_type n )
8167  : string_base( char_type( c ), n )
8168  {
8169  }
8170 
8175  String( const_c_string8 t )
8176  {
8177  Assign( t );
8178  }
8179 
8185  String( const_c_string8 t, size_type i, size_type n )
8186  {
8187  Assign( t, i, n );
8188  }
8189 
8194  String( const_char8_iterator i, const_char8_iterator j )
8195  {
8196  Assign( i, j );
8197  }
8198 
8207  String( std::initializer_list<char8_type> l )
8208  : String( l.begin(), l.end() )
8209  {
8210  }
8211 
8216  String( char8_type c, size_type n = 1 )
8217  : string_base( char_type( c ), n )
8218  {
8219  }
8220 
8224  explicit
8225  String( bool x )
8226  {
8227  Assign( x ? "true" : "false" );
8228  }
8229 
8234  explicit
8235  String( short x )
8236  {
8237  (void)Format( L"%hd", x );
8238  }
8239 
8244  explicit
8245  String( unsigned short x )
8246  {
8247  (void)Format( L"%hu", x );
8248  }
8249 
8254  explicit
8255  String( int x )
8256  {
8257  (void)Format( L"%i", x );
8258  }
8259 
8264  explicit
8265  String( unsigned int x )
8266  {
8267  (void)Format( L"%u", x );
8268  }
8269 
8274  explicit
8275  String( long x )
8276  {
8277  (void)Format( L"%ld", x );
8278  }
8279 
8284  explicit
8285  String( unsigned long x )
8286  {
8287  (void)Format( L"%lu", x );
8288  }
8289 
8294  explicit
8295  String( long long x )
8296  {
8297  (void)Format( L"%lli", x );
8298  }
8299 
8304  explicit
8305  String( unsigned long long x )
8306  {
8307  (void)Format( L"%llu", x );
8308  }
8309 
8314  explicit
8315  String( float x )
8316  {
8317  (void)Format( L"%.7g", x );
8318  }
8319 
8324  explicit
8325  String( double x )
8326  {
8327  (void)Format( L"%.16g", x );
8328  }
8329 
8334  explicit
8335  String( long double x )
8336  {
8337 #ifdef _MSC_VER
8338  (void)Format( L"%.16Lg", x );
8339 #else
8340  (void)Format( L"%.18Lg", x );
8341 #endif
8342  }
8343 
8344 #ifndef __PCL_NO_STRING_COMPLEX
8345 
8349  explicit
8351  {
8352  (void)Format( L"{%.7g,%.7g}", x.Real(), x.Imag() );
8353  }
8354 
8358  explicit
8360  {
8361  (void)Format( L"{%.16g,%.16g}", x.Real(), x.Imag() );
8362  }
8363 
8367  explicit
8369  {
8370 #ifdef _MSC_VER
8371  (void)Format( L"{%.16Lg,%.16Lg}", x.Real(), x.Imag() );
8372 #else
8373  (void)Format( L"{%.18Lg,%.18Lg}", x.Real(), x.Imag() );
8374 #endif
8375  }
8376 
8377 #endif // !__PCL_NO_STRING_COMPLEX
8378 
8379 #ifdef __PCL_QT_INTERFACE
8380 
8381  explicit
8382  String( const QString& qs )
8383  : string_base( qs.isEmpty() ? iterator( nullptr ) : iterator( PCL_GET_CHAR16PTR_FROM_QSTRING( qs ) ) )
8384  {
8385  }
8386 
8387  explicit
8388  String( const QDate& qd )
8389  : string_base( iterator( PCL_GET_CHAR16PTR_FROM_QSTRING( qd.toString( PCL_QDATE_FMT_STR ) ) ) )
8390  {
8391  }
8392 
8393  explicit
8394  String( const QDateTime& qdt )
8395  : string_base( iterator( PCL_GET_CHAR16PTR_FROM_QSTRING( qdt.toString( PCL_QDATETIME_FMT_STR ) ) ) )
8396  {
8397  }
8398 
8399 #endif
8400 
8401  // -------------------------------------------------------------------------
8402 
8406  String& operator =( const String& s )
8407  {
8408  string_base::Assign( s );
8409  return *this;
8410  }
8411 
8415  String& operator =( String&& s )
8416  {
8417  string_base::Transfer( s );
8418  return *this;
8419  }
8420 
8425  String& operator =( const string_base& s )
8426  {
8427  string_base::Assign( s );
8428  return *this;
8429  }
8430 
8435  String& operator =( string_base&& s )
8436  {
8437  string_base::Transfer( s );
8438  return *this;
8439  }
8440 
8445  String& operator =( const string8_base& s )
8446  {
8447  Assign( s );
8448  return *this;
8449  }
8450 
8455  String& operator =( const_iterator t )
8456  {
8457  string_base::Assign( t );
8458  return *this;
8459  }
8460 
8465  String& operator =( char_type c )
8466  {
8467  string_base::Assign( c );
8468  return *this;
8469  }
8470 
8475  String& operator =( const char16_t* t )
8476  {
8477  string_base::Assign( reinterpret_cast<const_iterator>( t ) );
8478  return *this;
8479  }
8480 
8485  String& operator =( char16_t c )
8486  {
8487  string_base::Assign( char_type( c ) );
8488  return *this;
8489  }
8490 
8495  String& operator =( const wchar_t* t )
8496  {
8497  Assign( t );
8498  return *this;
8499  }
8500 
8505  String& operator =( wchar_t c )
8506  {
8507  Assign( c );
8508  return *this;
8509  }
8510 
8515  String& operator =( const_c_string8 t )
8516  {
8517  Assign( t );
8518  return *this;
8519  }
8520 
8525  String& operator =( char8_type c )
8526  {
8527  Assign( c );
8528  return *this;
8529  }
8530 
8531 #ifdef __PCL_QT_INTERFACE
8532 
8533  String& operator =( const QString& qs )
8534  {
8535  if ( qs.isEmpty() )
8536  Clear();
8537  else
8538  string_base::Assign( PCL_GET_CHAR16PTR_FROM_QSTRING( qs ) );
8539  return *this;
8540  }
8541 
8542  String& operator =( const QDate& qd )
8543  {
8544  string_base::Assign( PCL_GET_CHAR16PTR_FROM_QSTRING( qd.toString( PCL_QDATE_FMT_STR ) ) );
8545  return *this;
8546  }
8547 
8548  String& operator =( const QDateTime& qdt )
8549  {
8550  string_base::Assign( PCL_GET_CHAR16PTR_FROM_QSTRING( qdt.toString( PCL_QDATETIME_FMT_STR ) ) );
8551  return *this;
8552  }
8553 
8554 #endif
8555 
8556  // -------------------------------------------------------------------------
8557 
8561  void Assign( const String& s )
8562  {
8563  string_base::Assign( s );
8564  }
8565 
8570  void Assign( const String& s, size_type i, size_type n )
8571  {
8572  string_base::Assign( s, i, n );
8573  }
8574 
8578  void Assign( const_iterator t )
8579  {
8580  string_base::Assign( t );
8581  }
8582 
8587  void Assign( const_iterator i, const_iterator j )
8588  {
8589  string_base::Assign( i, j );
8590  }
8591 
8598  void Assign( std::initializer_list<char_type> l )
8599  {
8600  Assign( l.begin(), l.end() );
8601  }
8602 
8608  void Assign( const_iterator t, size_type i, size_type n )
8609  {
8610  string_base::Assign( t, i, n );
8611  }
8612 
8616  void Assign( char_type c, size_type n = 1 )
8617  {
8618  string_base::Assign( c, n );
8619  }
8620 
8624  void Assign( const char16_t* t )
8625  {
8626  string_base::Assign( reinterpret_cast<const_iterator>( t ) );
8627  }
8628 
8634  void Assign( const char16_t* t, size_type i, size_type n )
8635  {
8636  string_base::Assign( reinterpret_cast<const_iterator>( t ), i, n );
8637  }
8638 
8642  void Assign( char16_t c, size_type n = 1 )
8643  {
8644  string_base::Assign( char_type( c ), n );
8645  }
8646 
8650  void Assign( const wchar_t* t );
8651 
8657  void Assign( const wchar_t* t, size_type i, size_type n );
8658 
8662  void Assign( wchar_t c, size_type n = 1 )
8663  {
8664  string_base::Assign( char_type( c ), n );
8665  }
8666 
8670  void Assign( const string8_base& s )
8671  {
8672  size_type n = s.Length();
8673  if ( n > 0 )
8674  {
8675  MaybeReallocate( n );
8676  const_char8_iterator t = s.Begin();
8677  for ( iterator i = m_data->string; i < m_data->end; ++i, ++t )
8678  *i = char_type( uint8( *t ) );
8679  }
8680  else
8681  Clear();
8682  }
8683 
8688  void Assign( const_c_string8 t )
8689  {
8690  size_type n = char8_traits::Length( t );
8691  if ( n > 0 )
8692  {
8693  MaybeReallocate( n );
8694  for ( iterator i = m_data->string; i < m_data->end; ++i, ++t )
8695  *i = char_type( uint8( *t ) );
8696  }
8697  else
8698  Clear();
8699  }
8700 
8706  void Assign( const_c_string8 t, size_type i, size_type n )
8707  {
8708  size_type len = char8_traits::Length( t );
8709  if ( i < len )
8710  {
8711  n = pcl::Min( n, len-i );
8712  MaybeReallocate( n );
8713  t += i;
8714  for ( iterator i = m_data->string; i < m_data->end; ++i, ++t )
8715  *i = char_type( uint8( *t ) );
8716  }
8717  else
8718  Clear();
8719  }
8720 
8725  void Assign( const_char8_iterator p, const_char8_iterator q )
8726  {
8727  if ( p < q )
8728  {
8729  MaybeReallocate( q - p );
8730  for ( iterator i = m_data->string; i < m_data->end; ++i, ++p )
8731  *i = char_type( uint8( *p ) );
8732  }
8733  else
8734  Clear();
8735  }
8736 
8744  void Assign( std::initializer_list<char8_type> l )
8745  {
8746  Assign( l.begin(), l.end() );
8747  }
8748 
8752  void Assign( char8_type c, size_type n = 1 )
8753  {
8754  string_base::Assign( char_type( c ), n );
8755  }
8756 
8757  // -------------------------------------------------------------------------
8758 
8759  void Insert( size_type i, const String& s )
8760  {
8761  string_base::Insert( i, s );
8762  }
8763 
8764  void Insert( size_type i, const_iterator p, const_iterator q )
8765  {
8766  string_base::Insert( i, p, q );
8767  }
8768 
8769  void Insert( size_type i, const_iterator t )
8770  {
8771  string_base::Insert( i, t );
8772  }
8773 
8774  void Insert( size_type i, const_iterator t, size_type n )
8775  {
8776  string_base::Insert( i, t, n );
8777  }
8778 
8779  void Insert( size_type i, char_type c, size_type n = 1 )
8780  {
8781  string_base::Insert( i, c, n );
8782  }
8783 
8784  void Insert( size_type i, const char16_t* t )
8785  {
8786  string_base::Insert( i, reinterpret_cast<const_iterator>( t ) );
8787  }
8788 
8789  void Insert( size_type i, char16_t c, size_type n = 1 )
8790  {
8791  string_base::Insert( i, String( c, n ) );
8792  }
8793 
8794  void Insert( size_type i, const wchar_t* t )
8795  {
8796 #ifdef __PCL_WINDOWS
8797  string_base::Insert( i, reinterpret_cast<const_iterator>( t ) );
8798 #else
8799  string_base::Insert( i, String( t ) );
8800 #endif
8801  }
8802 
8803  void Insert( size_type i, wchar_t c, size_type n = 1 )
8804  {
8805  string_base::Insert( i, String( c, n ) );
8806  }
8807 
8808  void Insert( size_type i, const string8_base& s, size_type n )
8809  {
8810  n = pcl::Min( 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 string8_base& s )
8821  {
8822  size_type n = s.Length();
8823  if ( n > 0 )
8824  {
8825  UninitializedGrow( i, n ); // -> 0 <= i <= len
8826  const_char8_iterator t = s.Begin();
8827  for ( iterator p = m_data->string+i, q = p+n; p < q; ++p, ++t )
8828  *p = char_type( uint8( *t ) );
8829  }
8830  }
8831 
8832  void Insert( size_type i, const_c_string8 t )
8833  {
8834  size_type n = char8_traits::Length( t );
8835  if ( n > 0 )
8836  {
8837  UninitializedGrow( i, n ); // -> 0 <= i <= len
8838  for ( iterator p = m_data->string+i, q = p+n; p < q; ++p, ++t )
8839  *p = char_type( uint8( *t ) );
8840  }
8841  }
8842 
8843  void Insert( size_type i, const_c_string8 t, size_type n )
8844  {
8845  n = pcl::Min( n, char8_traits::Length( t ) );
8846  if ( n > 0 )
8847  {
8848  UninitializedGrow( i, n ); // -> 0 <= i <= len
8849  for ( iterator p = m_data->string+i, q = p+n; p < q; ++p, ++t )
8850  *p = char_type( uint8( *t ) );
8851  }
8852  }
8853 
8854  void Insert( size_type i, const_char8_iterator p, const_char8_iterator q )
8855  {
8856  if ( p < q )
8857  {
8858  size_type n = q - p;
8859  UninitializedGrow( i, n ); // -> 0 <= i <= len
8860  for ( iterator r = m_data->string+i, s = r+n; r < s; ++r, ++p )
8861  *r = char_type( uint8( *p ) );
8862  }
8863  }
8864 
8865  void Insert( size_type i, char8_type c, size_type n = 1 )
8866  {
8867  string_base::Insert( i, char_type( c ), n );
8868  }
8869 
8870  // -------------------------------------------------------------------------
8871 
8872  void Append( const String& s )
8873  {
8874  string_base::Append( s );
8875  }
8876 
8877  String& operator +=( const String& s )
8878  {
8879  Append( s );
8880  return *this;
8881  }
8882 
8883  void Append( const_iterator i, const_iterator j )
8884  {
8885  string_base::Append( i, j );
8886  }
8887 
8888  void Append( const_iterator t )
8889  {
8890  string_base::Append( t );
8891  }
8892 
8893  String& operator +=( const_iterator t )
8894  {
8895  Append( t );
8896  return *this;
8897  }
8898 
8899  void Append( const_iterator t, size_type n )
8900  {
8901  string_base::Append( t, n );
8902  }
8903 
8904  void Append( char_type c, size_type n = 1 )
8905  {
8906  string_base::Append( c, n );
8907  }
8908 
8909  String& operator +=( char_type c )
8910  {
8911  Append( c );
8912  return *this;
8913  }
8914 
8915  void Append( const char16_t* t )
8916  {
8917  string_base::Append( reinterpret_cast<const_iterator>( t ) );
8918  }
8919 
8920  String& operator +=( const char16_t* t )
8921  {
8922  Append( t );
8923  return *this;
8924  }
8925 
8926  void Append( char16_t c, size_type n = 1 )
8927  {
8928  string_base::Append( char_type( c ), n );
8929  }
8930 
8931  String& operator +=( char16_t c )
8932  {
8933  Append( c );
8934  return *this;
8935  }
8936 
8937  void Append( const wchar_t* t )
8938  {
8939 #ifdef __PCL_WINDOWS
8940  string_base::Append( reinterpret_cast<const_iterator>( t ) );
8941 #else
8942  string_base::Append( String( t ) );
8943 #endif
8944  }
8945 
8946  String& operator +=( const wchar_t* t )
8947  {
8948  Append( t );
8949  return *this;
8950  }
8951 
8952  void Append( wchar_t c, size_type n = 1 )
8953  {
8954  string_base::Append( char_type( c ), n );
8955  }
8956 
8957  String& operator +=( wchar_t c )
8958  {
8959  Append( c );
8960  return *this;
8961  }
8962 
8963  void Append( const string8_base& s )
8964  {
8965  Insert( maxPos, s );
8966  }
8967 
8968  String& operator +=( const string8_base& s )
8969  {
8970  Append( s );
8971  return *this;
8972  }
8973 
8974  void Append( const string8_base& s, size_type n )
8975  {
8976  Insert( maxPos, s, n );
8977  }
8978 
8979  void Append( const_c_string8 t )
8980  {
8981  Insert( maxPos, t );
8982  }
8983 
8984  String& operator +=( const_c_string8 t )
8985  {
8986  Append( t );
8987  return *this;
8988  }
8989 
8990  void Append( const_c_string8 t, size_type n )
8991  {
8992  Insert( maxPos, t, n );
8993  }
8994 
8995  void Append( const_char8_iterator p, const_char8_iterator q )
8996  {
8997  Insert( maxPos, p, q );
8998  }
8999 
9000  void Append( char8_type c, size_type n = 1 )
9001  {
9002  string_base::Append( char_type( c ), n );
9003  }
9004 
9005  String& operator +=( char8_type c )
9006  {
9007  Append( c );
9008  return *this;
9009  }
9010 
9011  void Add( const String& s )
9012  {
9013  Append( s );
9014  }
9015 
9016  void Add( const_iterator i, const_iterator j )
9017  {
9018  Append( i, j );
9019  }
9020 
9021  void Add( const_iterator t )
9022  {
9023  Append( t );
9024  }
9025 
9026  void Add( const_iterator t, size_type n )
9027  {
9028  Append( t, n );
9029  }
9030 
9031  void Add( char_type c, size_type n = 1 )
9032  {
9033  Append( c, n );
9034  }
9035 
9036  void Add( const char16_t* t )
9037  {
9038  Append( t );
9039  }
9040 
9041  void Add( char16_t c, size_type n = 1 )
9042  {
9043  Append( c, n );
9044  }
9045 
9046  void Add( const wchar_t* t )
9047  {
9048  Append( t );
9049  }
9050 
9051  void Add( wchar_t c, size_type n = 1 )
9052  {
9053  Append( c, n );
9054  }
9055 
9056  void Add( const string8_base& s )
9057  {
9058  Append( s );
9059  }
9060 
9061  void Add( const string8_base& s, size_type n )
9062  {
9063  Append( s, n );
9064  }
9065 
9066  void Add( const_c_string8 t )
9067  {
9068  Append( t );
9069  }
9070 
9071  void Add( const_c_string8 t, size_type n )
9072  {
9073  Append( t, n );
9074  }
9075 
9076  void Add( const_char8_iterator p, const_char8_iterator q )
9077  {
9078  Append( p, q );
9079  }
9080 
9081  void Add( char8_type c, size_type n = 1 )
9082  {
9083  Append( c, n );
9084  }
9085 
9086  // -------------------------------------------------------------------------
9087 
9088  void Prepend( const String& s )
9089  {
9090  string_base::Prepend( s );
9091  }
9092 
9093  String& operator -=( const String& s )
9094  {
9095  Prepend( s );
9096  return *this;
9097  }
9098 
9099  void Prepend( const_iterator i, const_iterator j )
9100  {
9101  string_base::Prepend( i, j );
9102  }
9103 
9104  void Prepend( const_iterator t )
9105  {
9106  string_base::Prepend( t );
9107  }
9108 
9109  String& operator -=( const_iterator t )
9110  {
9111  Prepend( t );
9112  return *this;
9113  }
9114 
9115  void Prepend( const_iterator t, size_type n )
9116  {
9117  string_base::Prepend( t, n );
9118  }
9119 
9120  void Prepend( char_type c, size_type n = 1 )
9121  {
9122  string_base::Prepend( c, n );
9123  }
9124 
9125  String& operator -=( char_type c )
9126  {
9127  Prepend( c );
9128  return *this;
9129  }
9130 
9131  void Prepend( const char16_t* t )
9132  {
9133  string_base::Prepend( reinterpret_cast<const_iterator>( t ) );
9134  }
9135 
9136  String& operator -=( const char16_t* t )
9137  {
9138  Prepend( t );
9139  return *this;
9140  }
9141 
9142  void Prepend( char16_t c, size_type n = 1 )
9143  {
9144  string_base::Prepend( char_type( c ), n );
9145  }
9146 
9147  String& operator -=( char16_t c )
9148  {
9149  Prepend( c );
9150  return *this;
9151  }
9152 
9153  void Prepend( const wchar_t* t )
9154  {
9155 #ifdef __PCL_WINDOWS
9156  string_base::Prepend( reinterpret_cast<const_iterator>( t ) );
9157 #else
9158  string_base::Prepend( String( t ) );
9159 #endif
9160  }
9161 
9162  String& operator -=( const wchar_t* t )
9163  {
9164  Prepend( t );
9165  return *this;
9166  }
9167 
9168  void Prepend( wchar_t c, size_type n = 1 )
9169  {
9170  string_base::Prepend( char_type( c ), n );
9171  }
9172 
9173  String& operator -=( wchar_t c )
9174  {
9175  Prepend( c );
9176  return *this;
9177  }
9178 
9179  void Prepend( const string8_base& s )
9180  {
9181  Insert( 0, s );
9182  }
9183 
9184  String& operator -=( const string8_base& s )
9185  {
9186  Prepend( s );
9187  return *this;
9188  }
9189 
9190  void Prepend( const string8_base& s, size_type n )
9191  {
9192  Insert( 0, s, n );
9193  }
9194 
9195  void Prepend( const_c_string8 t )
9196  {
9197  Insert( 0, t );
9198  }
9199 
9200  String& operator -=( const_c_string8 t )
9201  {
9202  Prepend( t );
9203  return *this;
9204  }
9205 
9206  void Prepend( const_c_string8 t, size_type n )
9207  {
9208  Insert( 0, t, n );
9209  }
9210 
9211  void Prepend( const_char8_iterator p, const_char8_iterator q )
9212  {
9213  Insert( 0, p, q );
9214  }
9215 
9216  void Prepend( char8_type c, size_type n = 1 )
9217  {
9218  string_base::Prepend( String( c, n ) );
9219  }
9220 
9221  String& operator -=( char8_type c )
9222  {
9223  Prepend( c );
9224  return *this;
9225  }
9226 
9227  // -------------------------------------------------------------------------
9228 
9229  void Replace( size_type i, size_type n, const String& s )
9230  {
9231  string_base::Replace( i, n, s );
9232  }
9233 
9234  void Replace( size_type i, size_type n, const_iterator t )
9235  {
9236  string_base::Replace( i, n, t );
9237  }
9238 
9239  void Replace( size_type i, size_type n, char_type c, size_type nc = 1 )
9240  {
9241  string_base::Replace( i, n, c, nc );
9242  }
9243 
9244  void Replace( size_type i, size_type n, const char16_t* t )
9245  {
9246  string_base::Replace( i, n, reinterpret_cast<const_iterator>( t ) );
9247  }
9248 
9249  void Replace( size_type i, size_type n, char16_t c, size_type nc = 1 )
9250  {
9251  string_base::Replace( i, n, char_type( c ), nc );
9252  }
9253 
9254  void Replace( size_type i, size_type n, const wchar_t* t )
9255  {
9256 #ifdef __PCL_WINDOWS
9257  string_base::Replace( i, n, reinterpret_cast<const_iterator>( t ) );
9258 #else
9259  string_base::Replace( i, n, String( t ) );
9260 #endif
9261  }
9262 
9263  void Replace( size_type i, size_type n, wchar_t c, size_type nc = 1 )
9264  {
9265  string_base::Replace( i, n, char_type( c ), nc );
9266  }
9267 
9268  void Replace( size_type i, size_type n, const_c_string8 t )
9269  {
9270  if ( n > 0 )
9271  {
9272  size_type len = Length();
9273  if ( i < len )
9274  {
9275  n = pcl::Min( n, len-i );
9276  if ( n == len )
9277  Assign( t );
9278  else
9279  {
9280  size_type nt = char8_traits::Length( t );
9281  if ( nt > 0 )
9282  {
9283  if ( n < nt )
9284  UninitializedGrow( i, nt-n );
9285  else if ( nt < n )
9286  Delete( i, n-nt );
9287  else
9288  EnsureUnique();
9289 
9290  for ( iterator p = m_data->string+i, q = p+nt; p < q; ++p, ++t )
9291  *p = char_type( *t );
9292  }
9293  else
9294  Delete( i, n );
9295  }
9296  }
9297  }
9298  }
9299 
9300  void Replace( size_type i, size_type n, char8_type c, size_type nc = 1 )
9301  {
9302  string_base::Replace( i, n, char_type( c ), nc );
9303  }
9304 
9305  // -------------------------------------------------------------------------
9306 
9307  void ReplaceChar( char_type c1, char_type c2, size_type i = 0, size_type n = maxPos )
9308  {
9309  string_base::ReplaceChar( c1, c2, i, n );
9310  }
9311 
9312  void ReplaceCharIC( char_type c1, char_type c2, size_type i = 0, size_type n = maxPos )
9313  {
9314  string_base::ReplaceCharIC( c1, c2, i, n );
9315  }
9316 
9317  void ReplaceChar( char16_t c1, char16_t c2, size_type i = 0, size_type n = maxPos )
9318  {
9319  string_base::ReplaceChar( char_type( c1 ), char_type( c2 ), i, n );
9320  }
9321 
9322  void ReplaceCharIC( char16_t c1, char16_t c2, size_type i = 0, size_type n = maxPos )
9323  {
9324  string_base::ReplaceCharIC( char_type( c1 ), char_type( c2 ), i, n );
9325  }
9326 
9327  void ReplaceChar( wchar_t c1, wchar_t c2, size_type i = 0, size_type n = maxPos )
9328  {
9329  string_base::ReplaceChar( char_type( c1 ), char_type( c2 ), i, n );
9330  }
9331 
9332  void ReplaceCharIC( wchar_t c1, wchar_t c2, size_type i = 0, size_type n = maxPos )
9333  {
9334  string_base::ReplaceCharIC( char_type( c1 ), char_type( c2 ), i, n );
9335  }
9336 
9337  void ReplaceChar( char8_type c1, char8_type c2, size_type i = 0, size_type n = maxPos )
9338  {
9339  string_base::ReplaceChar( char_type( c1 ), char_type( c2 ), i, n );
9340  }
9341 
9342  void ReplaceCharIC( char8_type c1, char8_type c2, size_type i = 0, size_type n = maxPos )
9343  {
9344  string_base::ReplaceCharIC( char_type( c1 ), char_type( c2 ), i, n );
9345  }
9346 
9347  // -------------------------------------------------------------------------
9348 
9349  void ReplaceString( const String& s1, const String& s2, size_type i = 0 )
9350  {
9351  string_base::ReplaceString( s1, s2, i );
9352  }
9353 
9354  void ReplaceStringIC( const String& s1, const String& s2, size_type i = 0 )
9355  {
9356  string_base::ReplaceStringIC( s1, s2, i );
9357  }
9358 
9359  void ReplaceString( const_iterator t1, const_iterator t2, size_type i = 0 )
9360  {
9361  string_base::ReplaceString( t1, t2, i );
9362  }
9363 
9364  void ReplaceStringIC( const_iterator t1, const_iterator t2, size_type i = 0 )
9365  {
9366  string_base::ReplaceStringIC( t1, t2, i );
9367  }
9368 
9369  void ReplaceString( const char16_t* t1, const char16_t* t2, size_type i = 0 )
9370  {
9371  string_base::ReplaceString( reinterpret_cast<const_iterator>( t1 ),
9372  reinterpret_cast<const_iterator>( t2 ), i );
9373  }
9374 
9375  void ReplaceStringIC( const char16_t* t1, const char16_t* t2, size_type i = 0 )
9376  {
9377  string_base::ReplaceStringIC( reinterpret_cast<const_iterator>( t1 ),
9378  reinterpret_cast<const_iterator>( t2 ), i );
9379  }
9380 
9381  void ReplaceString( const wchar_t* t1, const wchar_t* t2, size_type i = 0 )
9382  {
9383 #ifdef __PCL_WINDOWS
9384  string_base::ReplaceString( reinterpret_cast<const_iterator>( t1 ),
9385  reinterpret_cast<const_iterator>( t2 ), i );
9386 #else
9387  string_base::ReplaceString( String( t1 ), String( t2 ), i );
9388 #endif
9389  }
9390 
9391  void ReplaceStringIC( const wchar_t* t1, const wchar_t* t2, size_type i = 0 )
9392  {
9393 #ifdef __PCL_WINDOWS
9394  string_base::ReplaceStringIC( reinterpret_cast<const_iterator>( t1 ),
9395  reinterpret_cast<const_iterator>( t2 ), i );
9396 #else
9397  string_base::ReplaceStringIC( String( t1 ), String( t2 ), i );
9398 #endif
9399  }
9400 
9401  void ReplaceString( const_c_string8 t1, const_c_string8 t2, size_type i = 0 )
9402  {
9403  string_base::ReplaceString( String( t1 ), String( t2 ), i );
9404  }
9405 
9406  void ReplaceStringIC( const_c_string8 t1, const_c_string8 t2, size_type i = 0 )
9407  {
9408  string_base::ReplaceStringIC( String( t1 ), String( t2 ), i );
9409  }
9410 
9411  // -------------------------------------------------------------------------
9412 
9413  void DeleteChar( char_type c, size_type i = 0 )
9414  {
9415  string_base::DeleteChar( c, i );
9416  }
9417 
9418  void DeleteCharIC( char_type c, size_type i = 0 )
9419  {
9420  string_base::DeleteCharIC( c, i );
9421  }
9422 
9423  void DeleteChar( char16_t c, size_type i = 0 )
9424  {
9425  string_base::DeleteChar( char_type( c ), i );
9426  }
9427 
9428  void DeleteCharIC( char16_t c, size_type i = 0 )
9429  {
9430  string_base::DeleteCharIC( char_type( c ), i );
9431  }
9432 
9433  void DeleteChar( wchar_t c, size_type i = 0 )
9434  {
9435  string_base::DeleteChar( char_type( c ), i );
9436  }
9437 
9438  void DeleteCharIC( wchar_t c, size_type i = 0 )
9439  {
9440  string_base::DeleteCharIC( char_type( c ), i );
9441  }
9442 
9443  void DeleteChar( char8_type c, size_type i = 0 )
9444  {
9445  string_base::DeleteChar( char_type( c ), i );
9446  }
9447 
9448  void DeleteCharIC( char8_type c, size_type i = 0 )
9449  {
9450  string_base::DeleteCharIC( char_type( c ), i );
9451  }
9452 
9453  // -------------------------------------------------------------------------
9454 
9455  void DeleteString( const String& s, size_type i = 0 )
9456  {
9457  string_base::DeleteString( s, i );
9458  }
9459 
9460  void DeleteStringIC( const String& s, size_type i = 0 )
9461  {
9462  string_base::DeleteStringIC( s, i );
9463  }
9464 
9465  void DeleteString( const_iterator t, size_type i = 0 )
9466  {
9467  string_base::DeleteString( t, i );
9468  }
9469 
9470  void DeleteStringIC( const_iterator t, size_type i = 0 )
9471  {
9472  string_base::DeleteStringIC( t, i );
9473  }
9474 
9475  void DeleteString( const char16_t* t, size_type i = 0 )
9476  {
9477  string_base::DeleteString( reinterpret_cast<const_iterator>( t ), i );
9478  }
9479 
9480  void DeleteStringIC( const char16_t* t, size_type i = 0 )
9481  {
9482  string_base::DeleteStringIC( reinterpret_cast<const_iterator>( t ), i );
9483  }
9484 
9485  void DeleteString( const wchar_t* t, size_type i = 0 )
9486  {
9487 #ifdef __PCL_WINDOWS
9488  string_base::DeleteString( reinterpret_cast<const_iterator>( t ), i );
9489 #else
9490  string_base::DeleteString( String( t ), i );
9491 #endif
9492  }
9493 
9494  void DeleteStringIC( const wchar_t* t, size_type i = 0 )
9495  {
9496 #ifdef __PCL_WINDOWS
9497  string_base::DeleteStringIC( reinterpret_cast<const_iterator>( t ), i );
9498 #else
9499  string_base::DeleteStringIC( String( t ), i );
9500 #endif
9501  }
9502 
9503  void DeleteString( const_c_string8 t, size_type i = 0 )
9504  {
9505  string_base::DeleteString( String( t ), i );
9506  }
9507 
9508  void DeleteStringIC( const_c_string8 t, size_type i = 0 )
9509  {
9510  string_base::DeleteStringIC( String( t ), i );
9511  }
9512 
9513  // -------------------------------------------------------------------------
9514 
9515  bool StartsWith( const String& s ) const
9516  {
9517  return string_base::StartsWith( s );
9518  }
9519 
9520  bool StartsWith( const_iterator t ) const
9521  {
9522  return string_base::StartsWith( t );
9523  }
9524 
9525  bool StartsWith( char_type c ) const
9526  {
9527  return string_base::StartsWith( c );
9528  }
9529 
9530  bool StartsWithIC( const String& s ) const
9531  {
9532  return string_base::StartsWithIC( s );
9533  }
9534 
9535  bool StartsWithIC( const_iterator t ) const
9536  {
9537  return string_base::StartsWithIC( t );
9538  }
9539 
9540  bool StartsWithIC( char_type c ) const
9541  {
9542  return string_base::StartsWithIC( c );
9543  }
9544 
9545  bool StartsWith( const char16_t* t ) const
9546  {
9547  return string_base::StartsWith( reinterpret_cast<const_iterator>( t ) );
9548  }
9549 
9550  bool StartsWith( char16_t c ) const
9551  {
9552  return string_base::StartsWith( char_type( c ) );
9553  }
9554 
9555  bool StartsWithIC( const char16_t* t ) const
9556  {
9557  return string_base::StartsWithIC( reinterpret_cast<const_iterator>( t ) );
9558  }
9559 
9560  bool StartsWithIC( char16_t c ) const
9561  {
9562  return string_base::StartsWithIC( char_type( c ) );
9563  }
9564 
9565  bool StartsWith( const wchar_t* t ) const
9566  {
9567 #ifdef __PCL_WINDOWS
9568  return string_base::StartsWith( reinterpret_cast<const_iterator>( t ) );
9569 #else
9570  return string_base::StartsWith( String( t ) );
9571 #endif
9572  }
9573 
9574  bool StartsWith( wchar_t c ) const
9575  {
9576  return string_base::StartsWith( char_type( c ) );
9577  }
9578 
9579  bool StartsWithIC( const wchar_t* t ) const
9580  {
9581 #ifdef __PCL_WINDOWS
9582  return string_base::StartsWithIC( reinterpret_cast<const_iterator>( t ) );
9583 #else
9584  return string_base::StartsWithIC( String( t ) );
9585 #endif
9586  }
9587 
9588  bool StartsWithIC( wchar_t c ) const
9589  {
9590  return string_base::StartsWithIC( char_type( c ) );
9591  }
9592 
9593  bool StartsWith( const_c_string8 t ) const
9594  {
9595  size_type n = char8_traits::Length( t );
9596  if ( n == 0 || Length() < n )
9597  return false;
9598  for ( const_iterator p = m_data->string, q = p+n; p < q; ++p, ++t )
9599  if ( *p != char_type( *t ) )
9600  return false;
9601  return true;
9602  }
9603 
9604  bool StartsWith( char8_type c ) const
9605  {
9606  return string_base::StartsWith( char_type( c ) );
9607  }
9608 
9609  bool StartsWithIC( const_c_string8 t ) const
9610  {
9611  size_type n = char8_traits::Length( t );
9612  if ( n == 0 || Length() < n )
9613  return false;
9614  for ( const_iterator p = m_data->string, q = p+n; p < q; ++p, ++t )
9615  if ( char_traits::ToCaseFolded( *p ) != char_type( char8_traits::ToCaseFolded( *t ) ) )
9616  return false;
9617  return true;
9618  }
9619 
9620  bool StartsWithIC( char8_type c ) const
9621  {
9622  return string_base::StartsWithIC( char_type( c ) );
9623  }
9624 
9625  // -------------------------------------------------------------------------
9626 
9627  bool EndsWith( const String& s ) const
9628  {
9629  return string_base::EndsWith( s );
9630  }
9631 
9632  bool EndsWith( const_iterator t ) const
9633  {
9634  return string_base::EndsWith( t );
9635  }
9636 
9637  bool EndsWith( char_type c ) const
9638  {
9639  return string_base::EndsWith( c );
9640  }
9641 
9642  bool EndsWithIC( const String& s ) const
9643  {
9644  return string_base::EndsWithIC( s );
9645  }
9646 
9647  bool EndsWithIC( const_iterator t ) const
9648  {
9649  return string_base::EndsWithIC( t );
9650  }
9651 
9652  bool EndsWithIC( char_type c ) const
9653  {
9654  return string_base::EndsWithIC( c );
9655  }
9656 
9657  bool EndsWith( const char16_t* t ) const
9658  {
9659  return string_base::EndsWith( reinterpret_cast<const_iterator>( t ) );
9660  }
9661 
9662  bool EndsWith( char16_t c ) const
9663  {
9664  return string_base::EndsWith( char_type( c ) );
9665  }
9666 
9667  bool EndsWithIC( const char16_t* t ) const
9668  {
9669  return string_base::EndsWithIC( reinterpret_cast<const_iterator>( t ) );
9670  }
9671 
9672  bool EndsWithIC( char16_t c ) const
9673  {
9674  return string_base::EndsWithIC( char_type( c ) );
9675  }
9676 
9677  bool EndsWith( const wchar_t* t ) const
9678  {
9679 #ifdef __PCL_WINDOWS
9680  return string_base::EndsWith( reinterpret_cast<const_iterator>( t ) );
9681 #else
9682  return string_base::EndsWith( String( t ) );
9683 #endif
9684  }
9685 
9686  bool EndsWith( wchar_t c ) const
9687  {
9688  return string_base::EndsWith( char_type( c ) );
9689  }
9690 
9691  bool EndsWithIC( const wchar_t* t ) const
9692  {
9693 #ifdef __PCL_WINDOWS
9694  return string_base::EndsWithIC( reinterpret_cast<const_iterator>( t ) );
9695 #else
9696  return string_base::EndsWithIC( String( t ) );
9697 #endif
9698  }
9699 
9700  bool EndsWithIC( wchar_t c ) const
9701  {
9702  return string_base::EndsWithIC( char_type( c ) );
9703  }
9704 
9705  bool EndsWith( const_c_string8 t ) const
9706  {
9707  size_type n = char8_traits::Length( t );
9708  if ( n == 0 || Length() < n )
9709  return false;
9710  for ( const_iterator p = m_data->end-n; p < m_data->end; ++p, ++t )
9711  if ( *p != char_type( *t ) )
9712  return false;
9713  return true;
9714  }
9715 
9716  bool EndsWith( char8_type c ) const
9717  {
9718  return string_base::EndsWith( char_type( c ) );
9719  }
9720 
9721  bool EndsWithIC( const_c_string8 t ) const
9722  {
9723  size_type n = char8_traits::Length( t );
9724  if ( n == 0 || Length() < n )
9725  return false;
9726  for ( const_iterator p = m_data->end-n; p < m_data->end; ++p, ++t )
9727  if ( char_traits::ToCaseFolded( *p ) != char_type( char8_traits::ToCaseFolded( *t ) ) )
9728  return false;
9729  return true;
9730  }
9731 
9732  bool EndsWithIC( char8_type c ) const
9733  {
9734  return string_base::EndsWithIC( char_type( c ) );
9735  }
9736 
9737  // -------------------------------------------------------------------------
9738 
9739  size_type FindFirst( const String& s, size_type i = 0 ) const
9740  {
9741  return string_base::FindFirst( s, i );
9742  }
9743 
9744  size_type FindFirst( const_iterator t, size_type i = 0 ) const
9745  {
9746  return string_base::FindFirst( t, i );
9747  }
9748 
9749  size_type FindFirst( char_type c, size_type i = 0 ) const
9750  {
9751  return string_base::FindFirst( c, i );
9752  }
9753 
9754  size_type FindFirstIC( const String& s, size_type i = 0 ) const
9755  {
9756  return string_base::FindFirstIC( s, i );
9757  }
9758 
9759  size_type FindFirstIC( const_iterator t, size_type i = 0 ) const
9760  {
9761  return string_base::FindFirstIC( t, i );
9762  }
9763 
9764  size_type FindFirstIC( char_type c, size_type i = 0 ) const
9765  {
9766  return string_base::FindFirstIC( c, i );
9767  }
9768 
9769  size_type FindFirst( const char16_t* t, size_type i = 0 ) const
9770  {
9771  return string_base::FindFirst( reinterpret_cast<const_iterator>( t ), i );
9772  }
9773 
9774  size_type FindFirst( char16_t c, size_type i = 0 ) const
9775  {
9776  return string_base::FindFirst( char_type( c ), i );
9777  }
9778 
9779  size_type FindFirstIC( const char16_t* t, size_type i = 0 ) const
9780  {
9781  return string_base::FindFirstIC( reinterpret_cast<const_iterator>( t ), i );
9782  }
9783 
9784  size_type FindFirstIC( char16_t c, size_type i = 0 ) const
9785  {
9786  return string_base::FindFirstIC( char_type( c ), i );
9787  }
9788 
9789  size_type FindFirst( const wchar_t* t, size_type i = 0 ) const
9790  {
9791 #ifdef __PCL_WINDOWS
9792  return string_base::FindFirst( reinterpret_cast<const_iterator>( t ), i );
9793 #else
9794  return string_base::FindFirst( String( t ), i );
9795 #endif
9796  }
9797 
9798  size_type FindFirst( wchar_t c, size_type i = 0 ) const
9799  {
9800  return string_base::FindFirst( char_type( c ), i );
9801  }
9802 
9803  size_type FindFirstIC( const wchar_t* t, size_type i = 0 ) const
9804  {
9805 #ifdef __PCL_WINDOWS
9806  return string_base::FindFirstIC( reinterpret_cast<const_iterator>( t ), i );
9807 #else
9808  return string_base::FindFirstIC( String( t ), i );
9809 #endif
9810  }
9811 
9812  size_type FindFirstIC( wchar_t c, size_type i = 0 ) const
9813  {
9814  return string_base::FindFirstIC( char_type( c ), i );
9815  }
9816 
9817  size_type FindFirst( const_c_string8 t, size_type i = 0 ) const
9818  {
9819  return string_base::FindFirst( String( t ), i );
9820  }
9821 
9822  size_type FindFirst( char8_type c, size_type i = 0 ) const
9823  {
9824  return string_base::FindFirst( char_type( c ), i );
9825  }
9826 
9827  size_type FindFirstIC( const_c_string8 t, size_type i = 0 ) const
9828  {
9829  return string_base::FindFirstIC( String( t ), i );
9830  }
9831 
9832  size_type FindFirstIC( char8_type c, size_type i = 0 ) const
9833  {
9834  return string_base::FindFirstIC( char_type( c ), i );
9835  }
9836 
9837  //
9838 
9839  size_type Find( const String& s, size_type i = 0 ) const
9840  {
9841  return FindFirst( s, i );
9842  }
9843 
9844  size_type Find( const_iterator t, size_type i = 0 ) const
9845  {
9846  return FindFirst( t, i );
9847  }
9848 
9849  size_type Find( char_type c, size_type i = 0 ) const
9850  {
9851  return FindFirst( c, i );
9852  }
9853 
9854  size_type Find( const char16_t* t, size_type i = 0 ) const
9855  {
9856  return FindFirst( t, i );
9857  }
9858 
9859  size_type Find( char16_t c, size_type i = 0 ) const
9860  {
9861  return FindFirst( c, i );
9862  }
9863 
9864  size_type Find( const wchar_t* t, size_type i = 0 ) const
9865  {
9866  return FindFirst( t, i );
9867  }
9868 
9869  size_type Find( wchar_t c, size_type i = 0 ) const
9870  {
9871  return FindFirst( c, i );
9872  }
9873 
9874  size_type Find( const_c_string8 t, size_type i = 0 ) const
9875  {
9876  return FindFirst( t, i );
9877  }
9878 
9879  size_type Find( char8_type c, size_type i = 0 ) const
9880  {
9881  return FindFirst( c, i );
9882  }
9883 
9884  size_type FindIC( const String& s, size_type i = 0 ) const
9885  {
9886  return FindFirstIC( s, i );
9887  }
9888 
9889  size_type FindIC( const_iterator t, size_type i = 0 ) const
9890  {
9891  return FindFirstIC( t, i );
9892  }
9893 
9894  size_type FindIC( char_type c, size_type i = 0 ) const
9895  {
9896  return FindFirstIC( c, i );
9897  }
9898 
9899  size_type FindIC( const char16_t* t, size_type i = 0 ) const
9900  {
9901  return FindFirstIC( t, i );
9902  }
9903 
9904  size_type FindIC( char16_t c, size_type i = 0 ) const
9905  {
9906  return FindFirstIC( c, i );
9907  }
9908 
9909  size_type FindIC( const wchar_t* t, size_type i = 0 ) const
9910  {
9911  return FindFirstIC( t, i );
9912  }
9913 
9914  size_type FindIC( wchar_t c, size_type i = 0 ) const
9915  {
9916  return FindFirstIC( c, i );
9917  }
9918 
9919  size_type FindIC( const_c_string8 t, size_type i = 0 ) const
9920  {
9921  return FindFirstIC( t, i );
9922  }
9923 
9924  size_type FindIC( char8_type c, size_type i = 0 ) const
9925  {
9926  return FindFirstIC( c, i );
9927  }
9928 
9929  // -------------------------------------------------------------------------
9930 
9931  size_type FindLast( const String& s, size_type r = maxPos ) const
9932  {
9933  return string_base::FindLast( s, r );
9934  }
9935 
9936  size_type FindLast( const_iterator t, size_type r = maxPos ) const
9937  {
9938  return string_base::FindLast( t, r );
9939  }
9940 
9941  size_type FindLast( char_type c, size_type r = maxPos ) const
9942  {
9943  return string_base::FindLast( c, r );
9944  }
9945 
9946  size_type FindLastIC( const String& s, size_type r = maxPos ) const
9947  {
9948  return string_base::FindLastIC( s, r );
9949  }
9950 
9951  size_type FindLastIC( const_iterator t, size_type r = maxPos ) const
9952  {
9953  return string_base::FindLastIC( t, r );
9954  }
9955 
9956  size_type FindLastIC( char_type c, size_type r = maxPos ) const
9957  {
9958  return string_base::FindLastIC( c, r );
9959  }
9960 
9961  size_type FindLast( const char16_t* t, size_type r = maxPos ) const
9962  {
9963  return string_base::FindLast( reinterpret_cast<const_iterator>( t ), r );
9964  }
9965 
9966  size_type FindLast( char16_t c, size_type r = maxPos ) const
9967  {
9968  return string_base::FindLast( char_type( c ), r );
9969  }
9970 
9971  size_type FindLastIC( const char16_t* t, size_type r = maxPos ) const
9972  {
9973  return string_base::FindLastIC( reinterpret_cast<const_iterator>( t ), r );
9974  }
9975 
9976  size_type FindLastIC( char16_t c, size_type r = maxPos ) const
9977  {
9978  return string_base::FindLastIC( char_type( c ), r );
9979  }
9980 
9981  size_type FindLast( const wchar_t* t, size_type r = maxPos ) const
9982  {
9983 #ifdef __PCL_WINDOWS
9984  return string_base::FindLast( reinterpret_cast<const_iterator>( t ), r );
9985 #else
9986  return string_base::FindLast( String( t ), r );
9987 #endif
9988  }
9989 
9990  size_type FindLast( wchar_t c, size_type r = maxPos ) const
9991  {
9992  return string_base::FindLast( char_type( c ), r );
9993  }
9994 
9995  size_type FindLastIC( const wchar_t* t, size_type r = maxPos ) const
9996  {
9997 #ifdef __PCL_WINDOWS
9998  return string_base::FindLastIC( reinterpret_cast<const_iterator>( t ), r );
9999 #else
10000  return string_base::FindLastIC( String( t ), r );
10001 #endif
10002  }
10003 
10004  size_type FindLastIC( wchar_t c, size_type r = maxPos ) const
10005  {
10006  return string_base::FindLastIC( char_type( c ), r );
10007  }
10008 
10009  size_type FindLast( const_c_string8 t, size_type r = maxPos ) const
10010  {
10011  return string_base::FindLast( String( t ), r );
10012  }
10013 
10014  size_type FindLast( char8_type c, size_type r = maxPos ) const
10015  {
10016  return string_base::FindLast( char_type( c ), r );
10017  }
10018 
10019  size_type FindLastIC( const_c_string8 t, size_type r = maxPos ) const
10020  {
10021  return string_base::FindLastIC( String( t ), r );
10022  }
10023 
10024  size_type FindLastIC( char8_type c, size_type r = maxPos ) const
10025  {
10026  return string_base::FindLastIC( char_type( c ), r );
10027  }
10028 
10029  // -------------------------------------------------------------------------
10030 
10031  bool Contains( const String& s ) const
10032  {
10033  return string_base::Contains( s );
10034  }
10035 
10036  bool Contains( const_iterator t ) const
10037  {
10038  return string_base::Contains( t );
10039  }
10040 
10041  bool Contains( char_type c ) const
10042  {
10043  return string_base::Contains( c );
10044  }
10045 
10046  bool ContainsIC( const String& s ) const
10047  {
10048  return string_base::ContainsIC( s );
10049  }
10050 
10051  bool ContainsIC( const_iterator t ) const
10052  {
10053  return string_base::ContainsIC( t );
10054  }
10055 
10056  bool ContainsIC( char_type c ) const
10057  {
10058  return string_base::ContainsIC( c );
10059  }
10060 
10061  bool Contains( const char16_t* t ) const
10062  {
10063  return string_base::Contains( reinterpret_cast<const_iterator>( t ) );
10064  }
10065 
10066  bool Contains( char16_t c ) const
10067  {
10068  return string_base::Contains( char_type( c ) );
10069  }
10070 
10071  bool ContainsIC( const char16_t* t ) const
10072  {
10073  return string_base::ContainsIC( reinterpret_cast<const_iterator>( t ) );
10074  }
10075 
10076  bool ContainsIC( char16_t c ) const
10077  {
10078  return string_base::ContainsIC( char_type( c ) );
10079  }
10080 
10081  bool Contains( const wchar_t* t ) const
10082  {
10083 #ifdef __PCL_WINDOWS
10084  return string_base::Contains( reinterpret_cast<const_iterator>( t ) );
10085 #else
10086  return string_base::Contains( String( t ) );
10087 #endif
10088  }
10089 
10090  bool Contains( wchar_t c ) const
10091  {
10092  return string_base::Contains( char_type( c ) );
10093  }
10094 
10095  bool ContainsIC( const wchar_t* t ) const
10096  {
10097 #ifdef __PCL_WINDOWS
10098  return string_base::ContainsIC( reinterpret_cast<const_iterator>( t ) );
10099 #else
10100  return string_base::ContainsIC( String( t ) );
10101 #endif
10102  }
10103 
10104  bool ContainsIC( wchar_t c ) const
10105  {
10106  return string_base::ContainsIC( char_type( c ) );
10107  }
10108 
10109  bool Contains( const_c_string8 t ) const
10110  {
10111  return string_base::Contains( String( t ) );
10112  }
10113 
10114  bool Contains( char8_type c ) const
10115  {
10116  return string_base::Contains( char_type( c ) );
10117  }
10118 
10119  bool ContainsIC( const_c_string8 t ) const
10120  {
10121  return string_base::ContainsIC( String( t ) );
10122  }
10123 
10124  bool ContainsIC( char8_type c ) const
10125  {
10126  return string_base::ContainsIC( char_type( c ) );
10127  }
10128 
10129  // -------------------------------------------------------------------------
10130 
10131  int CompareCodePoints( const String& s, bool caseSensitive = true ) const
10132  {
10133  return string_base::CompareCodePoints( s, caseSensitive );
10134  }
10135 
10136  int CompareCodePoints( const_iterator t, bool caseSensitive = true ) const
10137  {
10138  return string_base::CompareCodePoints( t, caseSensitive );
10139  }
10140 
10141  int CompareCodePoints( char_type c, bool caseSensitive = true ) const
10142  {
10143  return string_base::CompareCodePoints( c, caseSensitive );
10144  }
10145 
10146  int CompareCodePoints( const char16_t* t, bool caseSensitive = true ) const
10147  {
10148  return string_base::CompareCodePoints( reinterpret_cast<const_iterator>( t ), caseSensitive );
10149  }
10150 
10151  int CompareCodePoints( char16_t c, bool caseSensitive = true ) const
10152  {
10153  return string_base::CompareCodePoints( char_type( c ), caseSensitive );
10154  }
10155 
10156  int CompareCodePoints( const wchar_t* t, bool caseSensitive = true ) const
10157  {
10158 #ifdef __PCL_WINDOWS
10159  return string_base::CompareCodePoints( reinterpret_cast<const_iterator>( t ), caseSensitive );
10160 #else
10161  return string_base::CompareCodePoints( String( t ), caseSensitive );
10162 #endif
10163  }
10164 
10165  int CompareCodePoints( wchar_t c, bool caseSensitive = true ) const
10166  {
10167  return string_base::CompareCodePoints( char_type( c ), caseSensitive );
10168  }
10169 
10170  int CompareCodePoints( const_c_string8 t, bool caseSensitive = true ) const
10171  {
10172  return string_base::CompareCodePoints( String( t ), caseSensitive );
10173  }
10174 
10175  int CompareCodePoints( char8_type c, bool caseSensitive = true ) const
10176  {
10177  return string_base::CompareCodePoints( char_type( c ), caseSensitive );
10178  }
10179 
10180  // -------------------------------------------------------------------------
10181 
10182  int Compare( const String& s, bool caseSensitive = true, bool localeAware = true ) const
10183  {
10184  return string_base::Compare( s, caseSensitive, localeAware );
10185  }
10186 
10187  int Compare( const_iterator t, bool caseSensitive = true, bool localeAware = true ) const
10188  {
10189  return string_base::Compare( t, caseSensitive, localeAware );
10190  }
10191 
10192  int Compare( char_type c, bool caseSensitive = true, bool localeAware = true ) const
10193  {
10194  return string_base::Compare( c, caseSensitive, localeAware );
10195  }
10196 
10197  int CompareIC( const String& s, bool localeAware = true ) const
10198  {
10199  return string_base::CompareIC( s, localeAware );
10200  }
10201 
10202  int CompareIC( const_iterator t, bool localeAware = true ) const
10203  {
10204  return string_base::CompareIC( t, localeAware );
10205  }
10206 
10207  int CompareIC( char_type c, bool localeAware = true ) const
10208  {
10209  return string_base::CompareIC( c, localeAware );
10210  }
10211 
10212  int Compare( const char16_t* t, bool caseSensitive = true, bool localeAware = true ) const
10213  {
10214  return string_base::Compare( reinterpret_cast<const_iterator>( t ), caseSensitive, localeAware );
10215  }
10216 
10217  int Compare( char16_t c, bool caseSensitive = true, bool localeAware = true ) const
10218  {
10219  return string_base::Compare( char_type( c ), caseSensitive, localeAware );
10220  }
10221 
10222  int CompareIC( const char16_t* t, bool localeAware = true ) const
10223  {
10224  return string_base::CompareIC( reinterpret_cast<const_iterator>( t ), localeAware );
10225  }
10226 
10227  int CompareIC( char16_t c, bool localeAware = true ) const
10228  {
10229  return string_base::CompareIC( char_type( c ), localeAware );
10230  }
10231 
10232  int Compare( const wchar_t* t, bool caseSensitive = true, bool localeAware = true ) const
10233  {
10234 #ifdef __PCL_WINDOWS
10235  return string_base::Compare( reinterpret_cast<const_iterator>( t ), caseSensitive, localeAware );
10236 #else
10237  return string_base::Compare( String( t ), caseSensitive, localeAware );
10238 #endif
10239  }
10240 
10241  int Compare( wchar_t c, bool caseSensitive = true, bool localeAware = true ) const
10242  {
10243  return string_base::Compare( char_type( c ), caseSensitive, localeAware );
10244  }
10245 
10246  int CompareIC( const wchar_t* t, bool localeAware = true ) const
10247  {
10248 #ifdef __PCL_WINDOWS
10249  return string_base::CompareIC( reinterpret_cast<const_iterator>( t ), localeAware );
10250 #else
10251  return string_base::CompareIC( String( t ), localeAware );
10252 #endif
10253  }
10254 
10255  int CompareIC( wchar_t c, bool localeAware = true ) const
10256  {
10257  return string_base::CompareIC( char_type( c ), localeAware );
10258  }
10259 
10260  int Compare( const_c_string8 t, bool caseSensitive = true, bool localeAware = true ) const
10261  {
10262  return string_base::Compare( String( t ), caseSensitive, localeAware );
10263  }
10264 
10265  int Compare( char8_type c, bool caseSensitive = true, bool localeAware = true ) const
10266  {
10267  return string_base::Compare( char_type( c ), caseSensitive, localeAware );
10268  }
10269 
10270  int CompareIC( const_c_string8 t, bool localeAware = true ) const
10271  {
10272  return string_base::CompareIC( String( t ), localeAware );
10273  }
10274 
10275  int CompareIC( char8_type c, bool localeAware = true ) const
10276  {
10277  return string_base::CompareIC( char_type( c ), localeAware );
10278  }
10279 
10280  // -------------------------------------------------------------------------
10281 
10282  bool WildMatch( const String& pattern, bool caseSensitive = true ) const
10283  {
10284  return string_base::WildMatch( pattern, caseSensitive );
10285  }
10286 
10287  bool WildMatchIC( const String& pattern ) const
10288  {
10289  return string_base::WildMatchIC( pattern );
10290  }
10291 
10292  bool WildMatch( const_iterator pattern, bool caseSensitive = true ) const
10293  {
10294  return string_base::WildMatch( pattern, caseSensitive );
10295  }
10296 
10297  bool WildMatchIC( const_iterator pattern ) const
10298  {
10299  return string_base::WildMatchIC( pattern );
10300  }
10301 
10302  bool WildMatch( const string8_base& pattern, bool caseSensitive = true ) const
10303  {
10304  return char_traits::WildMatch( m_data->string, Length(), pattern.Begin(), pattern.Length(), caseSensitive );
10305  }
10306 
10307  bool WildMatchIC( const string8_base& pattern ) const
10308  {
10309  return char_traits::WildMatch( m_data->string, Length(), pattern.Begin(), pattern.Length(), false/*caseSensitive*/ );
10310  }
10311 
10312  bool WildMatch( const_c_string8 pattern, bool caseSensitive = true ) const
10313  {
10314  return char_traits::WildMatch( m_data->string, Length(), pattern, char8_traits::Length( pattern ), caseSensitive );
10315  }
10316 
10317  bool WildMatchIC( const_c_string8 pattern ) const
10318  {
10319  return char_traits::WildMatch( m_data->string, Length(), pattern, char8_traits::Length( pattern ), false/*caseSensitive*/ );
10320  }
10321 
10322  // -------------------------------------------------------------------------
10323 
10324  String SetToLength( size_type n ) const
10325  {
10326  return string_base::SetToLength( n );
10327  }
10328 
10329  String ResizedToNullTerminated() const
10330  {
10331  return string_base::ResizedToNullTerminated();
10332  }
10333 
10334  String Squeezed() const
10335  {
10336  return string_base::Squeezed();
10337  }
10338 
10339  // -------------------------------------------------------------------------
10340 
10341  String Substring( size_type i, size_type n = maxPos ) const
10342  {
10343  return string_base::Substring( i, n );
10344  }
10345 
10346  String Left( size_type n ) const
10347  {
10348  return string_base::Left( n );
10349  }
10350 
10351  String Right( size_type n ) const
10352  {
10353  return string_base::Right( n );
10354  }
10355 
10356  String Suffix( size_type i ) const
10357  {
10358  return string_base::Suffix( i );
10359  }
10360 
10361  String Prefix( size_type i ) const
10362  {
10363  return string_base::Prefix( i );
10364  }
10365 
10366  // -------------------------------------------------------------------------
10367 
10368  template <class C>
10369  size_type Break( C& list, const String& s, bool trim = false, size_type i = 0 ) const
10370  {
10371  return string_base::Break( list, s, trim, i );
10372  }
10373 
10374  template <class C>
10375  size_type Break( C& list, const string8_base& s, bool trim = false, size_type i = 0 ) const
10376  {
10377  return string_base::Break( list, String( s ), trim, i );
10378  }
10379 
10380  template <class C>
10381  size_type Break( C& list, const_c_string8 s, bool trim = false, size_type i = 0 ) const
10382  {
10383  return string_base::Break( list, String( s ), trim, i );
10384  }
10385 
10386  template <class C>
10387  size_type Break( C& list, char_type c, bool trim = false, size_type i = 0 ) const
10388  {
10389  return string_base::Break( list, c, trim, i );
10390  }
10391 
10392  template <class C>
10393  size_type Break( C& list, char8_type c, bool trim = false, size_type i = 0 ) const
10394  {
10395  return string_base::Break( list, char_type( c ), trim, i );
10396  }
10397 
10398  template <class C, typename S>
10399  size_type Break( C& list, const Array<S>& ca, bool trim = false, size_type i = 0 ) const
10400  {
10401  return string_base::Break( list, ca, trim, i );
10402  }
10403 
10404  // -------------------------------------------------------------------------
10405 
10406  template <class C>
10407  size_type BreakIC( C& list, const String& s, bool trim = false, size_type i = 0 ) const
10408  {
10409  return string_base::BreakIC( list, s, trim, i );
10410  }
10411 
10412  template <class C>
10413  size_type BreakIC( C& list, const string8_base& s, bool trim = false, size_type i = 0 ) const
10414  {
10415  return string_base::BreakIC( list, String( s ), trim, i );
10416  }
10417 
10418  template <class C>
10419  size_type BreakIC( C& list, const_c_string8 s, bool trim = false, size_type i = 0 ) const
10420  {
10421  return string_base::BreakIC( list, String( s ), trim, i );
10422  }
10423 
10424  template <class C>
10425  size_type BreakIC( C& list, char_type c, bool trim = false, size_type i = 0 ) const
10426  {
10427  return string_base::BreakIC( list, c, trim, i );
10428  }
10429 
10430  template <class C>
10431  size_type BreakIC( C& list, char8_type c, bool trim = false, size_type i = 0 ) const
10432  {
10433  return string_base::BreakIC( list, char_type( c ), trim, i );
10434  }
10435 
10436  // -------------------------------------------------------------------------
10437 
10438  String Trimmed() const
10439  {
10440  return string_base::Trimmed();
10441  }
10442 
10443  String TrimmedLeft() const
10444  {
10445  return string_base::TrimmedLeft();
10446  }
10447 
10448  String TrimmedRight() const
10449  {
10450  return string_base::TrimmedRight();
10451  }
10452 
10453  // -------------------------------------------------------------------------
10454 
10455  String LeftJustified( size_type width, char_type fill = CharTraits::Blank() ) const
10456  {
10457  return string_base::LeftJustified( width, fill );
10458  }
10459 
10460  String RightJustified( size_type width, char_type fill = CharTraits::Blank() ) const
10461  {
10462  return string_base::RightJustified( width, fill );
10463  }
10464 
10465  String CenterJustified( size_type width, char_type fill = CharTraits::Blank() ) const
10466  {
10467  return string_base::CenterJustified( width, fill );
10468  }
10469 
10470  // -------------------------------------------------------------------------
10471 
10472  String Enclosed( char_type c ) const
10473  {
10474  return string_base::Enclosed( c );
10475  }
10476 
10477  String SingleQuoted() const
10478  {
10479  return string_base::SingleQuoted();
10480  }
10481 
10482  String DoubleQuoted() const
10483  {
10484  return string_base::DoubleQuoted();
10485  }
10486 
10487  String Unquoted() const
10488  {
10489  return string_base::Unquoted();
10490  }
10491 
10492  // -------------------------------------------------------------------------
10493 
10494  String CaseFolded() const
10495  {
10496  return string_base::CaseFolded();
10497  }
10498 
10499  String Lowercase() const
10500  {
10501  return string_base::Lowercase();
10502  }
10503 
10504  String Uppercase() const
10505  {
10506  return string_base::Uppercase();
10507  }
10508 
10509  // -------------------------------------------------------------------------
10510 
10511  String Reversed() const
10512  {
10513  return string_base::Reversed();
10514  }
10515 
10516  String Sorted() const
10517  {
10518  return string_base::Sorted();
10519  }
10520 
10521  template <class BP>
10522  String Sorted( BP p ) const
10523  {
10524  return string_base::Sorted( p );
10525  }
10526 
10527  // -------------------------------------------------------------------------
10528 
10538  template <class C>
10539  String& ToSeparated( const C& c, char_type separator )
10540  {
10541  Clear();
10542  return c.ToSeparated( *this, separator );
10543  }
10544 
10561  template <class C, class AF>
10562  String& ToSeparated( const C& c, char_type separator, AF append )
10563  {
10564  Clear();
10565  return c.ToSeparated( *this, separator, append );
10566  }
10567 
10577  template <class C>
10578  String& ToSeparated( const C& c, const String& separator )
10579  {
10580  Clear();
10581  return c.ToSeparated( *this, separator );
10582  }
10583 
10600  template <class C, class AF>
10601  String& ToSeparated( const C& c, const String& separator, AF append )
10602  {
10603  Clear();
10604  return c.ToSeparated( *this, separator, append );
10605  }
10606 
10616  template <class C>
10617  String& ToSeparated( const C& c, const_c_string separator )
10618  {
10619  return ToSeparated( c, String( separator ) );
10620  }
10621 
10638  template <class C, class AF>
10639  String& ToSeparated( const C& c, const_c_string separator, AF append )
10640  {
10641  return ToSeparated( c, String( separator ), append );
10642  }
10643 
10654  template <class C>
10655  String& ToSeparated( const C& c, const_c_string8 separator )
10656  {
10657  return ToSeparated( c, String( separator ) );
10658  }
10659 
10676  template <class C, class AF>
10677  String& ToSeparated( const C& c, const_c_string8 separator, AF append )
10678  {
10679  return ToSeparated( c, String( separator ), append );
10680  }
10681 
10691  template <class C>
10692  String& ToCommaSeparated( const C& c )
10693  {
10694  return ToSeparated( c, CharTraits::Comma() );
10695  }
10696 
10706  template <class C>
10707  String& ToColonSeparated( const C& c )
10708  {
10709  return ToSeparated( c, CharTraits::Colon() );
10710  }
10711 
10721  template <class C>
10722  String& ToSpaceSeparated( const C& c )
10723  {
10724  return ToSeparated( c, CharTraits::Blank() );
10725  }
10726 
10736  template <class C>
10737  String& ToTabSeparated( const C& c )
10738  {
10739  return ToSeparated( c, CharTraits::Tab() );
10740  }
10741 
10751  template <class C>
10753  {
10754  return ToSeparated( c, CharTraits::LF() );
10755  }
10756 
10766  template <class C>
10767  String& ToNullSeparated( const C& c )
10768  {
10769  return ToSeparated( c, CharTraits::Null() );
10770  }
10771 
10780  template <class C>
10781  String& ToHyphenated( const C& c )
10782  {
10783  return ToSeparated( c, CharTraits::Hyphen() );
10784  }
10785 
10786  // ------------------------------------------------------------