PCL
String.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.8.5
6 // ----------------------------------------------------------------------------
7 // pcl/String.h - Released 2024-12-28T16:53:48Z
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-2024 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 (https://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/Utility.h>
71 
72 #include <stdarg.h>
73 
74 #ifdef __PCL_ALIGNED_STRING_ALLOCATION
75 # include <pcl/AlignedAllocator.h>
76 # define PCL_STRING_ALLOCATOR AlignedAllocator
77 #else
78 # include <pcl/StandardAllocator.h>
79 # define PCL_STRING_ALLOCATOR StandardAllocator
80 #endif
81 
82 #ifndef __PCL_NO_STRING_COMPLEX
83 # include <pcl/Complex.h>
84 #endif
85 
86 #ifndef __PCL_NO_STRING_OSTREAM
87 # ifndef _MSC_VER
88 # define _GLIBCXX_USE_WCHAR_T 1
89 # endif
90 # include <ostream>
91 #endif
92 
93 #ifdef __PCL_QT_INTERFACE
94 # include <QtCore/QByteArray>
95 # include <QtCore/QDateTime>
96 # include <QtCore/QString>
97 # define PCL_GET_CHARPTR_FROM_QSTRING( qs ) (qs.toLatin1().data())
98 # define PCL_GET_CHAR16PTR_FROM_QSTRING( qs ) ((char16_type*)( qs.utf16() ))
99 # define PCL_GET_CHARPTR_FROM_QSTRINGVIEW( qv ) ((const char*)qv.data())
100 # define PCL_GET_CHAR16PTR_FROM_QSTRINGVIEW( qv ) ((const char16_type*)qv.data())
101 # define PCL_GET_QSTRING_FROM_CHAR16PTR( s ) (QString::fromUtf16( (const char16_t*)(s) ))
102 # define PCL_GET_CHARPTR_FROM_QBYTEARRAY( qb ) (qb.data())
103 # define PCL_QDATE_FMT_STR "yyyy/MM/dd"
104 # define PCL_QDATETIME_FMT_STR "yyyy/MM/dd hh:mm:ss"
105 #endif
106 
107 namespace pcl
108 {
109 
110 #ifndef __PCL_NO_STRING_VECTOR
111  template <typename T> class PCL_CLASS GenericVector;
112 #endif
113 
114 // ----------------------------------------------------------------------------
115 
132 namespace RandomizationOption
133 {
134  enum mask_type
135  {
136  Lowercase = 0x00000001, // Generate random lowercase alphabetic characters: a..z
137  Uppercase = 0x00000002, // Generate random uppercase alphabetic characters: A..Z
138  Alpha = Lowercase|Uppercase, // Generate random alphabetic characters: a..zA..Z
139  Digits = 0x00000004, // Generate random decimal digits: 0..9
140  Symbols = 0x00000008, // Generate random symbol characters: .#/[]() etc
141  HexDigits = 0x00000010, // Generate hexadecimal digits: 0..9a..f or 0..9A..F
142  BinDigits = 0x00000020, // Generate binary digits: 0 and 1
143  FullRange = 0x80000000, // Generate random characters in the whole range of code points except zero
144  Default = Alpha|Digits
145  };
146 };
147 
152 using RandomizationOptions = Flags<RandomizationOption::mask_type>;
153 
154 // ----------------------------------------------------------------------------
155 
170 {
177  unsigned items : 2;
178 
183  unsigned precision : 4;
184 
189  bool sign : 1;
190 
198  unsigned width : 4;
199 
204  char separator;
205 
211  char padding;
212 
216  constexpr SexagesimalConversionOptions( unsigned items_ = 3,
217  unsigned precision_ = 2,
218  bool sign_ = false,
219  unsigned width_ = 0,
220  char separator_ = ':',
221  char padding_ = ' ' )
222  : items( items_ )
223  , precision( precision_ )
224  , sign( sign_ )
225  , width( width_ )
226  , separator( separator_ )
227  , padding( padding_ )
228  {
229  }
230 
235 
240 };
241 
242 // ----------------------------------------------------------------------------
243 
257 {
265  constexpr AngleConversionOptions( unsigned precision = 2, unsigned width = 3, char padding = ' ' )
266  : SexagesimalConversionOptions( 3/*items*/, precision, false/*sign*/, width, ' '/*separator*/, padding )
267  {}
268 };
269 
270 // ----------------------------------------------------------------------------
271 
286 {
295  constexpr LongitudeConversionOptions( unsigned precision = 2, unsigned width = 4, char padding = ' ' )
296  : SexagesimalConversionOptions( 3/*items*/, precision, true/*sign*/, width, ' '/*separator*/, padding )
297  {}
298 };
299 
300 // ----------------------------------------------------------------------------
301 
317 {
325  constexpr RAConversionOptions( unsigned precision = 3, unsigned width = 2, char padding = ' ' )
326  : SexagesimalConversionOptions( 3/*items*/, precision, false/*sign*/, width, ' '/*separator*/, padding )
327  {}
328 };
329 
330 // ----------------------------------------------------------------------------
331 
346 {
355  constexpr LatitudeConversionOptions( unsigned precision = 2, unsigned width = 3, char padding = ' ' )
356  : SexagesimalConversionOptions( 3/*items*/, precision, true/*sign*/, width, ' '/*separator*/, padding )
357  {}
358 };
359 
360 // ----------------------------------------------------------------------------
361 
375 {
384  constexpr DecConversionOptions( unsigned precision = 2, unsigned width = 3, char padding = ' ' )
385  : LatitudeConversionOptions( precision, width, padding )
386  {}
387 };
388 
389 // ----------------------------------------------------------------------------
390 
398 struct PCL_CLASS ISO8601ConversionOptions
399 {
406  unsigned timeItems : 2;
407 
412  unsigned precision : 4;
413 
418  bool timeZone : 1;
419 
424  bool zuluTime : 1;
425 
429  constexpr ISO8601ConversionOptions( unsigned timeItems_ = 3,
430  unsigned precision_ = 3,
431  bool timeZone_ = true,
432  bool zuluTime_ = true )
433  : timeItems( timeItems_ )
434  , precision( precision_ )
435  , timeZone( timeZone_ )
436  , zuluTime( zuluTime_ )
437  {
438  }
439 
444 
448  ISO8601ConversionOptions& operator =( const ISO8601ConversionOptions& ) = default;
449 };
450 
459 {
463  constexpr ISO8601ConversionOptionsNoTimeZone( unsigned timeItems_ = 3,
464  unsigned precision_ = 3 )
465  : ISO8601ConversionOptions( timeItems_, precision_, false/*timeZone*/, false/*zuluTime*/ )
466  {
467  }
468 };
469 
470 // ----------------------------------------------------------------------------
471 
491 template <class T, class R, class A = PCL_STRING_ALLOCATOR>
492 class PCL_CLASS GenericString : public DirectContainer<T>
493 {
494 public:
495 
499 
503 
507 
511  using char_type = T;
512 
516  using char_traits = R;
517 
521  using block_allocator = A;
522 
527 
531  using c_string = T*;
532 
536  using const_c_string = const T*;
537 
541  using iterator = T*;
542 
546  using const_iterator = const T*;
547 
552 
557 
558  // -------------------------------------------------------------------------
559 
563  static const size_type notFound = ~size_type( 0 );
564 
568  static const size_type maxPos = ~size_type( 0 );
569 
570  // -------------------------------------------------------------------------
571 
576  {
577  m_data = Data::New();
578  }
579 
584  : m_data( s.m_data )
585  {
586  m_data->Attach();
587  }
588 
593  : m_data( s.m_data )
594  {
595  s.m_data = nullptr;
596  }
597 
603  {
604  size_type len = R::Length( t );
605  if ( len > 0 )
606  {
607  m_data = Data::New( len );
608  R::Copy( m_data->string, t, len );
609  }
610  else
611  m_data = Data::New();
612  }
613 
632  {
633  if ( i < j )
634  {
635  size_type len = j - i;
636  m_data = Data::New( len );
637  R::Copy( m_data->string, i, len );
638  }
639  else
640  m_data = Data::New();
641  }
642 
651  GenericString( std::initializer_list<char_type> l )
652  : GenericString( l.begin(), l.end() )
653  {
654  }
655 
661  {
662  size_type len = R::Length( t );
663  if ( i < len && (n = pcl::Min( n, len-i )) > 0 )
664  {
665  m_data = Data::New( n );
666  R::Copy( m_data->string, t+i, n );
667  }
668  else
669  m_data = Data::New();
670  }
671 
676  {
677  if ( n > 0 )
678  {
679  m_data = Data::New( n );
680  R::Fill( m_data->string, c, n );
681  }
682  else
683  m_data = Data::New();
684  }
685 
691  {
692  if ( m_data != nullptr )
693  {
694  DetachFromData();
695  m_data = nullptr;
696  }
697  }
698 
704  bool IsUnique() const noexcept
705  {
706  return m_data->IsUnique();
707  }
708 
716  bool IsAliasOf( const GenericString& s ) const noexcept
717  {
718  return m_data == s.m_data;
719  }
720 
731  {
732  if ( !IsUnique() )
733  {
734  size_type len = Length();
735  Data* newData = Data::New( len );
736  if ( len > 0 )
737  R::Copy( newData->string, m_data->string, len );
738  DetachFromData();
739  m_data = newData;
740  }
741  }
742 
750  static size_type BytesPerChar() noexcept
751  {
752  return R::BytesPerChar();
753  }
754 
761  size_type Size() const noexcept
762  {
763  return Length()*BytesPerChar();
764  }
765 
772  size_type Length() const noexcept
773  {
774  return m_data->end - m_data->string;
775  }
776 
785  size_type Capacity() const noexcept
786  {
787  return m_data->capacity - m_data->string;
788  }
789 
797  size_type Available() const noexcept
798  {
799  return m_data->capacity - m_data->end;
800  }
801 
818  bool IsValid() const noexcept
819  {
820  return m_data != nullptr;
821  }
822 
830  bool IsEmpty() const noexcept
831  {
832  return m_data->string == m_data->end;
833  }
834 
843  size_type LowerBound() const noexcept
844  {
845  return 0;
846  }
847 
856  size_type UpperBound() const noexcept
857  {
858  PCL_PRECONDITION( !IsEmpty() )
859  return Length()-1;
860  }
861 
867  const allocator& Allocator() const noexcept
868  {
869  return m_data->alloc;
870  }
871 
881  void SetAllocator( const allocator& a )
882  {
883  EnsureUnique();
884  m_data->alloc = a;
885  }
886 
900  {
901  PCL_PRECONDITION( i < Length() )
902  EnsureUnique();
903  return m_data->string + i;
904  }
905 
915  const_iterator At( size_type i ) const noexcept
916  {
917  PCL_PRECONDITION( i < Length() )
918  return m_data->string + i;
919  }
920 
933  char_type& operator []( size_type i )
934  {
935  return *At( i );
936  }
937 
947  char_type operator []( size_type i ) const noexcept
948  {
949  return *At( i );
950  }
951 
960  {
961  EnsureUnique();
962  return *m_data->string;
963  }
964 
972  char_type operator *() const noexcept
973  {
974  return *m_data->string;
975  }
976 
989  {
990  EnsureUnique();
991  return m_data->string;
992  }
993 
1002  const_iterator Begin() const noexcept
1003  {
1004  return m_data->string;
1005  }
1006 
1019  {
1020  EnsureUnique();
1021  return m_data->end;
1022  }
1023 
1032  const_iterator End() const noexcept
1033  {
1034  return m_data->end;
1035  }
1036 
1051  {
1052  EnsureUnique();
1053  return (m_data->string < m_data->end) ? m_data->end-1 : nullptr;
1054  }
1055 
1067  {
1068  return (m_data->string < m_data->end) ? m_data->end-1 : nullptr;
1069  }
1070 
1085  {
1086  EnsureUnique();
1087  return (m_data->string < m_data->end) ? m_data->string-1 : nullptr;
1088  }
1089 
1101  {
1102  return (m_data->string < m_data->end) ? m_data->string-1 : nullptr;
1103  }
1104 
1115  size_type IndexAt( const_iterator i ) const noexcept
1116  {
1117  PCL_PRECONDITION( i >= m_data->string )
1118  return i - m_data->string;
1119  }
1120 
1121 #ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
1126  {
1127  return Begin();
1128  }
1129 
1133  const_iterator begin() const noexcept
1134  {
1135  return Begin();
1136  }
1137 
1142  {
1143  return End();
1144  }
1145 
1149  const_iterator end() const noexcept
1150  {
1151  return End();
1152  }
1153 #endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
1154 
1162  const_c_string c_str() const noexcept
1163  {
1164  static const char_type theNullChar = char_traits::Null();
1165  return IsEmpty() ? &theNullChar : Begin();
1166  }
1167 
1173  GenericString& operator =( const GenericString& s )
1174  {
1175  Assign( s );
1176  return *this;
1177  }
1178 
1193  void Assign( const GenericString& s )
1194  {
1195  s.m_data->Attach();
1196  DetachFromData();
1197  m_data = s.m_data;
1198  }
1199 
1205  GenericString& operator =( GenericString&& s )
1206  {
1207  Transfer( s );
1208  return *this;
1209  }
1210 
1225  {
1226  if ( &s != this )
1227  {
1228  DetachFromData();
1229  m_data = s.m_data;
1230  s.m_data = nullptr;
1231  }
1232  }
1233 
1240  {
1241  if ( &s != this )
1242  {
1243  DetachFromData();
1244  m_data = s.m_data;
1245  s.m_data = nullptr;
1246  }
1247  }
1248 
1254  {
1255  Assign( t );
1256  return *this;
1257  }
1258 
1263  GenericString& operator =( char_type c )
1264  {
1265  Assign( c, 1 );
1266  return *this;
1267  }
1268 
1273  void Assign( const GenericString& s, size_type i, size_type n )
1274  {
1275  Transfer( s.Substring( i, n ) );
1276  }
1277 
1286  {
1287  size_type len = R::Length( t );
1288  if ( len > 0 )
1289  {
1290  MaybeReallocate( len );
1291  R::Copy( m_data->string, t, len );
1292  }
1293  else
1294  Clear();
1295  }
1296 
1318  {
1319  if ( i < j )
1320  {
1321  size_type len = j - i;
1322  MaybeReallocate( len );
1323  R::Copy( m_data->string, i, len );
1324  }
1325  else
1326  Clear();
1327  }
1328 
1335  void Assign( std::initializer_list<char_type> l )
1336  {
1337  Assign( l.begin(), l.end() );
1338  }
1339 
1354  {
1355  size_type len = R::Length( t );
1356  if ( i < len && (n = pcl::Min( n, len-i )) > 0 )
1357  {
1358  MaybeReallocate( n );
1359  R::Copy( m_data->string, t+i, n );
1360  }
1361  else
1362  Clear();
1363  }
1364 
1370  void Assign( char_type c, size_type n = 1 )
1371  {
1372  if ( !R::IsNull( c ) && n > 0 )
1373  {
1374  MaybeReallocate( n );
1375  R::Fill( m_data->string, c, n );
1376  }
1377  else
1378  Clear();
1379  }
1380 
1384  void Swap( GenericString& s ) noexcept
1385  {
1386  pcl::Swap( m_data, s.m_data );
1387  }
1388 
1398  void Fill( char_type c )
1399  {
1400  size_type len = Length();
1401  if ( len > 0 )
1402  {
1403  if ( !IsUnique() )
1404  {
1405  Data* newData = Data::New( len );
1406  DetachFromData();
1407  m_data = newData;
1408  }
1409  R::Fill( m_data->string, c, len );
1410  }
1411  }
1412 
1427  void Fill( char_type c, size_type i, size_type n = maxPos )
1428  {
1429  size_type len = Length();
1430  if ( i < len )
1431  {
1432  n = pcl::Min( n, len-i );
1433  if ( n < len )
1434  EnsureUnique();
1435  else if ( !IsUnique() )
1436  {
1437  Data* newData = Data::New( len );
1438  DetachFromData();
1439  m_data = newData;
1440  }
1441  R::Fill( m_data->string+i, c, n );
1442  }
1443  }
1444 
1466  void SecureFill( char c = '\0' ) noexcept
1467  {
1468  volatile char* s = reinterpret_cast<volatile char*>( m_data->string );
1469  for ( size_type n = Capacity()*sizeof( char_type ); n > 0; --n )
1470  *s++ = c;
1471  }
1472 
1480  void Reserve( size_type n )
1481  {
1482  if ( n > 0 )
1483  if ( IsUnique() )
1484  {
1485  if ( Capacity() < n+1 )
1486  {
1487  iterator old = m_data->string;
1488  size_type len = Length();
1489  m_data->Reserve( len, n );
1490  if ( old != nullptr )
1491  {
1492  if ( len > 0 )
1493  R::Copy( m_data->string, old, len );
1494  m_data->alloc.Deallocate( old );
1495  }
1496  }
1497  }
1498  else
1499  {
1500  size_type len = Length();
1501  Data* newData = Data::New(); // ### FIXME: unlikely, but this is a potential leak
1502  newData->Reserve( len, pcl::Max( len, n ) );
1503  if ( len > 0 )
1504  R::Copy( newData->string, m_data->string, len );
1505  DetachFromData();
1506  m_data = newData;
1507  }
1508  }
1509 
1524  {
1525  if ( n != Length() )
1526  {
1527  if ( n > 0 )
1528  {
1529  if ( !IsUnique() || m_data->ShouldReallocate( n ) )
1530  {
1531  Data* newData = Data::New( n );
1532  size_type m = Capacity();
1533  if ( m > 0 )
1534  R::Copy( newData->string, m_data->string, pcl::Min( n, m ) );
1535  DetachFromData();
1536  m_data = newData;
1537  }
1538  else
1539  m_data->SetLength( n );
1540  }
1541  else
1542  Clear();
1543  }
1544  else
1545  EnsureUnique();
1546  }
1547 
1554  {
1555  // NB: This can be done more efficiently if this string is unique.
1556  GenericString s( *this );
1557  s.SetLength( n );
1558  return s;
1559  }
1560 
1570  {
1571  SetLength( R::Length( m_data->string ) );
1572  }
1573 
1579  {
1580  GenericString s( *this );
1582  return s;
1583  }
1584 
1597  void Squeeze()
1598  {
1599  if ( Available() > 0 )
1600  {
1601  size_type len = Length();
1602  if ( len > 0 )
1603  {
1604  if ( IsUnique() )
1605  {
1606  iterator old = m_data->string;
1607  m_data->Allocate( len, 0 );
1608  R::Copy( m_data->string, old, len );
1609  m_data->alloc.Deallocate( old );
1610  }
1611  else
1612  {
1613  Data* newData = Data::New( len, 0 );
1614  R::Copy( newData->string, m_data->string, len );
1615  DetachFromData();
1616  m_data = newData;
1617  }
1618  }
1619  else
1620  Clear();
1621  }
1622  }
1623 
1629  {
1630  // NB: This can be done more efficiently if this string is unique.
1631  GenericString s( *this );
1632  s.Squeeze();
1633  return s;
1634  }
1635 
1649  {
1650  EnsureUnique();
1651  iterator string = m_data->string;
1652  m_data->Reset();
1653  return string;
1654  }
1655 
1672  void c_copy( iterator dst, size_type maxCharsToCopy, size_type i = 0 ) const noexcept
1673  {
1674  if ( dst != nullptr )
1675  if ( maxCharsToCopy > 0 )
1676  {
1677  if ( --maxCharsToCopy > 0 )
1678  {
1679  size_type len = Length();
1680  if ( i < len )
1681  {
1682  size_type n = pcl::Min( maxCharsToCopy, len-i );
1683  R::Copy( dst, m_data->string+i, n );
1684  dst += n;
1685  }
1686  }
1687 
1688  *dst = R::Null();
1689  }
1690  }
1691 
1695  template <class R1, class A1>
1697  {
1698  size_type n = s.Length();
1699  if ( n > 0 )
1700  {
1701  UninitializedGrow( i, n ); // -> 0 <= i <= len
1702  R::Copy( m_data->string+i, s.m_data->string, n );
1703  }
1704  }
1705 
1714  {
1715  if ( p < q )
1716  {
1717  size_type n = q - p;
1718  UninitializedGrow( i, n ); // -> 0 <= i <= len
1719  R::Copy( m_data->string+i, p, n );
1720  }
1721  }
1722 
1728  {
1729  size_type n = R::Length( t );
1730  if ( n > 0 )
1731  {
1732  UninitializedGrow( i, n ); // -> 0 <= i <= len
1733  R::Copy( m_data->string+i, t, n );
1734  }
1735  }
1736 
1742  {
1743  if ( (n = pcl::Min( n, R::Length( t ) )) > 0 )
1744  {
1745  UninitializedGrow( i, n ); // -> 0 <= i <= len
1746  R::Copy( m_data->string+i, t, n );
1747  }
1748  }
1749 
1753  void Insert( size_type i, char_type c, size_type n = 1 )
1754  {
1755  if ( n > 0 )
1756  {
1757  UninitializedGrow( i, n ); // -> 0 <= i <= len
1758  R::Fill( m_data->string+i, c, n );
1759  }
1760  }
1761 
1765  template <class R1, class A1>
1767  {
1768  Insert( maxPos, s );
1769  }
1770 
1775  template <class R1, class A1>
1776  GenericString& operator +=( const GenericString<T,R1,A1>& s )
1777  {
1778  Append( s );
1779  return *this;
1780  }
1781 
1790  {
1791  Insert( maxPos, i, j );
1792  }
1793 
1799  {
1800  Insert( maxPos, t, n );
1801  }
1802 
1807  {
1808  Insert( maxPos, t );
1809  }
1810 
1815  GenericString& operator +=( const_c_string t )
1816  {
1817  Append( t );
1818  return *this;
1819  }
1820 
1824  void Append( char_type c, size_type n = 1 )
1825  {
1826  Insert( maxPos, c, n );
1827  }
1828 
1833  template <class R1, class A1>
1834  void Add( const GenericString<T,R1,A1>& s )
1835  {
1836  Append( s );
1837  }
1838 
1844  {
1845  Append( i, j );
1846  }
1847 
1853  {
1854  Append( t, n );
1855  }
1856 
1862  {
1863  Append( t );
1864  }
1865 
1870  void Add( char_type c, size_type n = 1 )
1871  {
1872  Append( c, n );
1873  }
1874 
1879  GenericString& operator +=( char_type c )
1880  {
1881  Append( c );
1882  return *this;
1883  }
1884 
1889  template <class R1, class A1>
1891  {
1892  Insert( 0, s );
1893  }
1894 
1899  template <class R1, class A1>
1900  GenericString& operator -=( const GenericString<T,R1,A1>& s )
1901  {
1902  Prepend( s );
1903  return *this;
1904  }
1905 
1914  {
1915  Insert( 0, i, j );
1916  }
1917 
1923  {
1924  Insert( 0, t, n );
1925  }
1926 
1932  {
1933  Insert( 0, t );
1934  }
1935 
1940  GenericString& operator -=( const_c_string t )
1941  {
1942  Prepend( t );
1943  return *this;
1944  }
1945 
1949  void Prepend( char_type c, size_type n = 1 )
1950  {
1951  Insert( 0, c, n );
1952  }
1953 
1958  GenericString& operator -=( char_type c )
1959  {
1960  Prepend( c );
1961  return *this;
1962  }
1963 
1968  template <class R1, class A1>
1970  {
1971  if ( n > 0 )
1972  {
1973  size_type len = Length();
1974  if ( i < len )
1975  {
1976  n = pcl::Min( n, len-i );
1977  if ( n != len )
1978  {
1979  size_type ns = s.Length();
1980  if ( ns > 0 )
1981  {
1982  if ( n < ns )
1983  UninitializedGrow( i, ns-n );
1984  else if ( ns < n )
1985  Delete( i, n-ns );
1986  else
1987  EnsureUnique();
1988 
1989  R::Copy( m_data->string+i, s.m_data->string, ns );
1990  }
1991  else
1992  Delete( i, n );
1993  }
1994  else
1995  Assign( s );
1996  }
1997  }
1998  }
1999 
2009  {
2010  if ( n > 0 )
2011  {
2012  size_type len = Length();
2013  if ( i < len )
2014  {
2015  n = pcl::Min( n, len-i );
2016  if ( n != len )
2017  {
2018  size_type nt = R::Length( t );
2019  if ( nt > 0 )
2020  {
2021  if ( n < nt )
2022  UninitializedGrow( i, nt-n );
2023  else if ( nt < n )
2024  Delete( i, n-nt );
2025  else
2026  EnsureUnique();
2027 
2028  R::Copy( m_data->string+i, t, nt );
2029  }
2030  else
2031  Delete( i, n );
2032  }
2033  else
2034  Assign( t );
2035  }
2036  }
2037  }
2038 
2044  {
2045  if ( n > 0 )
2046  {
2047  size_type len = Length();
2048  if ( i < len )
2049  {
2050  n = pcl::Min( n, len-i );
2051  if ( n != len )
2052  {
2053  if ( nc > 0 )
2054  {
2055  if ( n < nc )
2056  UninitializedGrow( i, nc-n );
2057  else if ( nc < n )
2058  Delete( i, n-nc );
2059  else
2060  EnsureUnique();
2061 
2062  R::Fill( m_data->string+i, c, nc );
2063  }
2064  else
2065  Delete( i, n );
2066  }
2067  else
2068  Assign( c, nc );
2069  }
2070  }
2071  }
2072 
2078  void ReplaceChar( char_type c1, char_type c2, size_type i = 0, size_type n = maxPos )
2079  {
2080  ReplaceChar( c1, c2, i, n, true/*case*/ );
2081  }
2082 
2090  void ReplaceCharIC( char_type c1, char_type c2, size_type i = 0, size_type n = maxPos )
2091  {
2092  ReplaceChar( c1, c2, i, n, false/*case*/ );
2093  }
2094 
2100  template <class R1, class A1, class R2, class A2>
2102  const GenericString<T,R2,A2>& s2, size_type i = 0 )
2103  {
2104  ReplaceString( s1.m_data->string, s1.Length(), s2.m_data->string, s2.Length(), i, true/*case*/ );
2105  }
2106 
2113  {
2114  ReplaceString( t1, R::Length( t1 ), t2, R::Length( t2 ), i, true/*case*/ );
2115  }
2116 
2124  template <class R1, class A1, class R2, class A2>
2126  const GenericString<T,R2,A2>& s2, size_type i = 0 )
2127  {
2128  ReplaceString( s1.m_data->string, s1.Length(), s2.m_data->string, s2.Length(), i, false/*case*/ );
2129  }
2130 
2139  {
2140  ReplaceString( t1, R::Length( t1 ), t2, R::Length( t2 ), i, false/*case*/ );
2141  }
2142 
2147  void Delete( size_type i, size_type n = 1 )
2148  {
2149  if ( n > 0 )
2150  {
2151  size_type len = Length();
2152  if ( i < len )
2153  {
2154  n = pcl::Min( n, len-i );
2155  if ( n < len )
2156  {
2157  size_type newLen = len-n;
2158  if ( !IsUnique() || m_data->ShouldReallocate( newLen ) )
2159  {
2160  Data* newData = Data::New( newLen );
2161  if ( i > 0 )
2162  R::Copy( newData->string, m_data->string, i );
2163  if ( i < newLen )
2164  R::Copy( newData->string+i, m_data->string+i+n, newLen-i );
2165  DetachFromData();
2166  m_data = newData;
2167  }
2168  else
2169  {
2170  if ( i < newLen )
2171  R::CopyOverlapped( m_data->string+i, m_data->string+i+n, newLen-i );
2172  m_data->SetLength( newLen );
2173  }
2174  }
2175  else
2176  Clear();
2177  }
2178  }
2179  }
2180 
2186  {
2187  Delete( i, maxPos );
2188  }
2189 
2195  {
2196  Delete( 0, i );
2197  }
2198 
2204  void DeleteChar( char_type c, size_type i = 0 )
2205  {
2206  ReplaceString( &c, 1, nullptr, 0, i, true/*case*/ );
2207  }
2208 
2217  {
2218  ReplaceString( &c, 1, nullptr, 0, i, false/*case*/ );
2219  }
2220 
2226  template <class R1, class A1>
2228  {
2229  ReplaceString( s.m_data->string, s.Length(), nullptr, 0, i, true/*case*/ );
2230  }
2231 
2238  {
2239  ReplaceString( t, R::Length( t ), nullptr, 0, i, true/*case*/ );
2240  }
2241 
2249  template <class R1, class A1>
2251  {
2252  ReplaceString( s.m_data->string, s.Length(), nullptr, 0, i, false/*case*/ );
2253  }
2254 
2263  {
2264  ReplaceString( t, R::Length( t ), nullptr, 0, i, false/*case*/ );
2265  }
2266 
2276  void Clear()
2277  {
2278  if ( !IsEmpty() )
2279  if ( IsUnique() )
2280  m_data->Deallocate();
2281  else
2282  {
2283  Data* newData = Data::New();
2284  DetachFromData();
2285  m_data = newData;
2286  }
2287  }
2288 
2294  {
2295  size_type len = Length();
2296  if ( i < len )
2297  {
2298  n = pcl::Min( n, len-i );
2299  if ( n > 0 )
2300  {
2301  if ( n < len )
2302  {
2303  GenericString t;
2304  t.m_data->Allocate( n );
2305  R::Copy( t.m_data->string, m_data->string+i, n );
2306  return t;
2307  }
2308  return *this;
2309  }
2310  }
2311  return GenericString();
2312  }
2313 
2319  {
2320  size_type len = Length();
2321  n = pcl::Min( n, len );
2322  if ( n > 0 )
2323  {
2324  if ( n < len )
2325  {
2326  GenericString t;
2327  t.m_data->Allocate( n );
2328  R::Copy( t.m_data->string, m_data->string, n );
2329  return t;
2330  }
2331  return *this;
2332  }
2333  return GenericString();
2334  }
2335 
2341  {
2342  size_type len = Length();
2343  n = pcl::Min( n, len );
2344  if ( n > 0 )
2345  {
2346  if ( n < len )
2347  {
2348  GenericString t;
2349  t.m_data->Allocate( n );
2350  R::Copy( t.m_data->string, m_data->string+len-n, n );
2351  return t;
2352  }
2353  return *this;
2354  }
2355  return GenericString();
2356  }
2357 
2365  {
2366  return Substring( i );
2367  }
2368 
2376  {
2377  return Left( (i > 0) ? i-1 : 0 );
2378  }
2379 
2397  template <class C, class R1, class A1>
2398  size_type Break( C& list, const GenericString<T,R1,A1>& s, bool trim = false, size_type i = 0 ) const
2399  {
2400  size_type count = 0;
2401  size_type len = Length();
2402  if ( i < len )
2403  {
2404  size_type n = s.Length();
2405  if ( n > 0 )
2406  for ( SearchEngine S( s.m_data->string, n, true/*case*/ ); ; )
2407  {
2408  size_type j = S( m_data->string, i, len );
2409 
2410  GenericString t;
2411  if ( i < j )
2412  {
2413  const_iterator l = m_data->string + i;
2414  size_type m = j - i;
2415  if ( trim )
2416  {
2417  const_iterator r = l + m;
2418  l = R::SearchTrimLeft( l, r );
2419  m = R::SearchTrimRight( l, r ) - l;
2420  }
2421  if ( m > 0 )
2422  {
2423  t.m_data->Allocate( m );
2424  R::Copy( t.m_data->string, l, m );
2425  }
2426  }
2427  list.Add( t );
2428  ++count;
2429 
2430  if ( j == len )
2431  break;
2432 
2433  i = j + n;
2434  }
2435  }
2436  return count;
2437  }
2438 
2457  template <class C>
2458  size_type Break( C& list, const_c_string s, bool trim = false, size_type i = 0 ) const
2459  {
2460  size_type count = 0;
2461  size_type len = Length();
2462  if ( i < len )
2463  {
2464  size_type n = R::Length( s );
2465  if ( n > 0 )
2466  for ( SearchEngine S( s, n, true/*case*/ ); ; )
2467  {
2468  size_type j = S( m_data->string, i, len );
2469 
2470  GenericString t;
2471  if ( i < j )
2472  {
2473  const_iterator l = m_data->string + i;
2474  size_type m = j - i;
2475  if ( trim )
2476  {
2477  const_iterator r = l + m;
2478  l = R::SearchTrimLeft( l, r );
2479  m = R::SearchTrimRight( l, r ) - l;
2480  }
2481  if ( m > 0 )
2482  {
2483  t.m_data->Allocate( m );
2484  R::Copy( t.m_data->string, l, m );
2485  }
2486  }
2487  list.Add( t );
2488  ++count;
2489 
2490  if ( j == len )
2491  break;
2492 
2493  i = j + n;
2494  }
2495  }
2496  return count;
2497  }
2498 
2517  template <class C>
2518  size_type Break( C& list, char_type c, bool trim = false, size_type i = 0 ) const
2519  {
2520  size_type count = 0;
2521  size_type len = Length();
2522  if ( i < len )
2523  {
2524  for ( ;; )
2525  {
2526  size_type j = i;
2527  for ( const_iterator p = m_data->string + i; j < len; ++j, ++p )
2528  if ( *p == c )
2529  break;
2530 
2531  GenericString t;
2532  if ( i < j )
2533  {
2534  const_iterator l = m_data->string + i;
2535  size_type m = j - i;
2536  if ( trim )
2537  {
2538  const_iterator r = l + m;
2539  l = R::SearchTrimLeft( l, r );
2540  m = R::SearchTrimRight( l, r ) - l;
2541  }
2542  if ( m > 0 )
2543  {
2544  t.m_data->Allocate( m );
2545  R::Copy( t.m_data->string, l, m );
2546  }
2547  }
2548  list.Add( t );
2549  ++count;
2550 
2551  if ( j == len )
2552  break;
2553 
2554  i = j + 1;
2555  }
2556  }
2557  return count;
2558  }
2559 
2582  template <class C, typename S>
2583  size_type Break( C& list, const Array<S>& ca, bool trim = false, size_type i = 0 ) const
2584  {
2585  size_type count = 0;
2586  if ( !ca.IsEmpty() )
2587  {
2588  size_type len = Length();
2589  if ( i < len )
2590  {
2591  for ( ;; )
2592  {
2593  size_type j = i;
2594  for ( const_iterator p = m_data->string + i; j < len; ++j, ++p )
2595  for ( auto c : ca )
2596  if ( *p == char_type( c ) )
2597  goto __Break_1;
2598 __Break_1:
2599  GenericString t;
2600  if ( i < j )
2601  {
2602  const_iterator l = m_data->string + i;
2603  size_type m = j - i;
2604  if ( trim )
2605  {
2606  const_iterator r = l + m;
2607  l = R::SearchTrimLeft( l, r );
2608  m = R::SearchTrimRight( l, r ) - l;
2609  }
2610  if ( m > 0 )
2611  {
2612  t.m_data->Allocate( m );
2613  R::Copy( t.m_data->string, l, m );
2614  }
2615  }
2616  list.Add( t );
2617  ++count;
2618 
2619  if ( j == len )
2620  break;
2621 
2622  i = j + 1;
2623  }
2624  }
2625  }
2626  return count;
2627  }
2628 
2649  template <class C, class R1, class A1>
2650  size_type BreakIC( C& list, const GenericString<T,R1,A1>& s, bool trim = false, size_type i = 0 ) const
2651  {
2652  size_type count = 0;
2653  size_type len = Length();
2654  if ( i < len )
2655  {
2656  size_type n = s.Length();
2657  if ( n > 0 )
2658  {
2659  for ( SearchEngine S( s.m_data->string, n, false/*case*/ ); ; )
2660  {
2661  size_type j = S( m_data->string, i, len );
2662 
2663  GenericString t;
2664  if ( i < j )
2665  {
2666  const_iterator l = m_data->string + i;
2667  size_type m = j - i;
2668  if ( trim )
2669  {
2670  const_iterator r = l + m;
2671  l = R::SearchTrimLeft( l, r );
2672  m = R::SearchTrimRight( l, r ) - l;
2673  }
2674  if ( m > 0 )
2675  {
2676  t.m_data->Allocate( m );
2677  R::Copy( t.m_data->string, l, m );
2678  }
2679  }
2680  list.Add( t );
2681  ++count;
2682 
2683  if ( j == len )
2684  break;
2685 
2686  i = j + n;
2687  }
2688  }
2689  }
2690  return count;
2691  }
2692 
2715  template <class C>
2716  size_type BreakIC( C& list, const_c_string s, bool trim = false, size_type i = 0 ) const
2717  {
2718  size_type count = 0;
2719  size_type len = Length();
2720  if ( i < len )
2721  {
2722  size_type n = R::Length( s );
2723  if ( n > 0 )
2724  {
2725  for ( SearchEngine S( s, n, false/*case*/ ); ; )
2726  {
2727  size_type j = S( m_data->string, i, len );
2728 
2729  GenericString t;
2730  if ( i < j )
2731  {
2732  const_iterator l = m_data->string + i;
2733  size_type m = j - i;
2734  if ( trim )
2735  {
2736  const_iterator r = l + m;
2737  l = R::SearchTrimLeft( l, r );
2738  m = R::SearchTrimRight( l, r ) - l;
2739  }
2740  if ( m > 0 )
2741  {
2742  t.m_data->Allocate( m );
2743  R::Copy( t.m_data->string, l, m );
2744  }
2745  }
2746  list.Add( t );
2747  ++count;
2748 
2749  if ( j == len )
2750  break;
2751 
2752  i = j + n;
2753  }
2754  }
2755  }
2756  return count;
2757  }
2758 
2780  template <class C>
2781  size_type BreakIC( C& list, char_type c, bool trim = false, size_type i = 0 ) const
2782  {
2783  size_type count = 0;
2784  size_type len = Length();
2785  if ( i < len )
2786  {
2787  c = R::ToCaseFolded( c );
2788  for ( ;; )
2789  {
2790  size_type j = i;
2791  for ( const_iterator p = m_data->string + i; j < len; ++j, ++p )
2792  if ( R::ToCaseFolded( *p ) == c )
2793  break;
2794 
2795  GenericString t;
2796  if ( i < j )
2797  {
2798  const_iterator l = m_data->string + i;
2799  size_type m = j - i;
2800  if ( trim )
2801  {
2802  const_iterator r = l + m;
2803  l = R::SearchTrimLeft( l, r );
2804  m = R::SearchTrimRight( l, r ) - l;
2805  }
2806  if ( m > 0 )
2807  {
2808  t.m_data->Allocate( m );
2809  R::Copy( t.m_data->string, l, m );
2810  }
2811  }
2812  list.Add( t );
2813  ++count;
2814 
2815  if ( j == len )
2816  break;
2817 
2818  i = j + 1;
2819  }
2820  }
2821  return count;
2822  }
2823 
2828  char_type FirstChar() const noexcept
2829  {
2830  return (m_data->string != nullptr) ? *m_data->string : R::Null();
2831  }
2832 
2837  char_type LastChar() const noexcept
2838  {
2839  return (m_data->string < m_data->end) ? *(m_data->end-1) : R::Null();
2840  }
2841 
2845  template <class R1, class A1>
2846  bool StartsWith( const GenericString<T,R1,A1>& s ) const noexcept
2847  {
2848  if ( s.IsEmpty() || Length() < s.Length() )
2849  return false;
2850  for ( const_iterator p = m_data->string, q = s.m_data->string; q < s.m_data->end; ++p, ++q )
2851  if ( *p != *q )
2852  return false;
2853  return true;
2854  }
2855 
2860  bool StartsWith( const_c_string t ) const noexcept
2861  {
2862  size_type n = R::Length( t );
2863  if ( n == 0 || Length() < n )
2864  return false;
2865  for ( const_iterator p = m_data->string, e = p+n; p < e; ++p, ++t )
2866  if ( *p != *t )
2867  return false;
2868  return true;
2869  }
2870 
2874  bool StartsWith( char_type c ) const noexcept
2875  {
2876  return m_data->string < m_data->end && *m_data->string == c;
2877  }
2878 
2883  template <class R1, class A1>
2884  bool StartsWithIC( const GenericString<T,R1,A1>& s ) const noexcept
2885  {
2886  if ( s.IsEmpty() || Length() < s.Length() )
2887  return false;
2888  for ( const_iterator p = m_data->string, q = s.m_data->string; q < s.m_data->end; ++p, ++q )
2889  if ( R::ToCaseFolded( *p ) != R::ToCaseFolded( *q ) )
2890  return false;
2891  return true;
2892  }
2893 
2898  bool StartsWithIC( const_c_string t ) const noexcept
2899  {
2900  size_type n = R::Length( t );
2901  if ( n == 0 || Length() < n )
2902  return false;
2903  for ( const_iterator p = m_data->string, e = p+n; p < e; ++p, ++t )
2904  if ( R::ToCaseFolded( *p ) != R::ToCaseFolded( *t ) )
2905  return false;
2906  return true;
2907  }
2908 
2913  bool StartsWithIC( char_type c ) const noexcept
2914  {
2915  return m_data->string < m_data->end && R::ToCaseFolded( *m_data->string ) == R::ToCaseFolded( c );
2916  }
2917 
2921  template <class R1, class A1>
2922  bool EndsWith( const GenericString<T,R1,A1>& s ) const noexcept
2923  {
2924  size_type n = s.Length();
2925  if ( n == 0 || Length() < n )
2926  return false;
2927  for ( const_iterator p = m_data->end-n, q = s.m_data->string; p < m_data->end; ++p, ++q )
2928  if ( *p != *q )
2929  return false;
2930  return true;
2931  }
2932 
2937  bool EndsWith( const_c_string t ) const noexcept
2938  {
2939  size_type n = R::Length( t );
2940  if ( n == 0 || Length() < n )
2941  return false;
2942  for ( const_iterator p = m_data->end-n; p < m_data->end; ++p, ++t )
2943  if ( *p != *t )
2944  return false;
2945  return true;
2946  }
2947 
2951  bool EndsWith( char_type c ) const noexcept
2952  {
2953  return m_data->string < m_data->end && *(m_data->end-1) == c;
2954  }
2955 
2960  template <class R1, class A1>
2961  bool EndsWithIC( const GenericString<T,R1,A1>& s ) const noexcept
2962  {
2963  size_type n = s.Length();
2964  if ( n == 0 || Length() < n )
2965  return false;
2966  for ( const_iterator p = m_data->end-n, q = s.m_data->string; p < m_data->end; ++p, ++q )
2967  if ( R::ToCaseFolded( *p ) != R::ToCaseFolded( *q ) )
2968  return false;
2969  return true;
2970  }
2971 
2976  bool EndsWithIC( const_c_string t ) const noexcept
2977  {
2978  size_type n = R::Length( t );
2979  if ( n == 0 || Length() < n )
2980  return false;
2981  for ( const_iterator p = m_data->end-n; p < m_data->end; ++p, ++t )
2982  if ( R::ToCaseFolded( *p ) != R::ToCaseFolded( *t ) )
2983  return false;
2984  return true;
2985  }
2986 
2991  bool EndsWithIC( char_type c ) const noexcept
2992  {
2993  return m_data->string < m_data->end && R::ToCaseFolded( *(m_data->end-1) ) == R::ToCaseFolded( c );
2994  }
2995 
3001  template <class R1, class A1>
3002  size_type FindFirst( const GenericString<T,R1,A1>& s, size_type i = 0 ) const noexcept
3003  {
3004  size_type len = Length();
3005  i = SearchEngine( s.m_data->string, s.Length(), true/*case*/ )( m_data->string, i, len );
3006  return (i < len) ? i : notFound;
3007  }
3008 
3014  size_type FindFirst( const_c_string t, size_type i = 0 ) const noexcept
3015  {
3016  size_type len = Length();
3017  i = SearchEngine( t, R::Length( t ), true/*case*/ )( m_data->string, i, len );
3018  return (i < len) ? i : notFound;
3019  }
3020 
3026  size_type FindFirst( char_type c, size_type i = 0 ) const noexcept
3027  {
3028  for ( const_iterator p = m_data->string+i; p < m_data->end; ++p )
3029  if ( *p == c )
3030  return p - m_data->string;
3031  return notFound;
3032  }
3033 
3042  template <class R1, class A1>
3043  size_type FindFirstIC( const GenericString<T,R1,A1>& s, size_type i = 0 ) const noexcept
3044  {
3045  size_type len = Length();
3046  i = SearchEngine( s.m_data->string, s.Length(), false/*case*/ )( m_data->string, i, len );
3047  return (i < len) ? i : notFound;
3048  }
3049 
3058  size_type FindFirstIC( const_c_string t, size_type i = 0 ) const noexcept
3059  {
3060  size_type len = Length();
3061  i = SearchEngine( t, R::Length( t ), false/*case*/ )( m_data->string, i, len );
3062  return (i < len) ? i : notFound;
3063  }
3064 
3073  size_type FindFirstIC( char_type c, size_type i = 0 ) const noexcept
3074  {
3075  c = R::ToCaseFolded( c );
3076  for ( const_iterator p = m_data->string+i; p < m_data->end; ++p )
3077  if ( R::ToCaseFolded( *p ) == c )
3078  return p - m_data->string;
3079  return notFound;
3080  }
3081 
3085  template <class R1, class A1>
3086  size_type Find( const GenericString<T,R1,A1>& s, size_type i = 0 ) const noexcept
3087  {
3088  return FindFirst( s, i );
3089  }
3090 
3094  size_type Find( const_c_string t, size_type i = 0 ) const noexcept
3095  {
3096  return FindFirst( t, i );
3097  }
3098 
3102  size_type Find( char_type c, size_type i = 0 ) const noexcept
3103  {
3104  return FindFirst( c, i );
3105  }
3106 
3110  template <class R1, class A1>
3111  size_type FindIC( const GenericString<T,R1,A1>& s, size_type i = 0 ) const noexcept
3112  {
3113  return FindFirstIC( s, i );
3114  }
3115 
3119  size_type FindIC( const_c_string t, size_type i = 0 ) const noexcept
3120  {
3121  return FindFirstIC( t, i );
3122  }
3123 
3127  size_type FindIC( char_type c, size_type i = 0 ) const noexcept
3128  {
3129  return FindFirstIC( c, i );
3130  }
3131 
3141  template <class R1, class A1>
3142  size_type FindLast( const GenericString<T,R1,A1>& s, size_type r = maxPos ) const noexcept
3143  {
3144  r = pcl::Min( r, Length() );
3145  size_type i = SearchEngine( s.m_data->string, s.Length(), true/*case*/, true/*last*/ )( m_data->string, 0, r );
3146  return (i < r) ? i : notFound;
3147  }
3148 
3158  size_type FindLast( const_c_string t, size_type r = maxPos ) const noexcept
3159  {
3160  r = pcl::Min( r, Length() );
3161  size_type i = SearchEngine( t, R::Length( t ), true/*case*/, true/*last*/ )( m_data->string, 0, r );
3162  return (i < r) ? i : notFound;
3163  }
3164 
3170  size_type FindLast( char_type c, size_type r = maxPos ) const noexcept
3171  {
3172  r = pcl::Min( r, Length() );
3173  for ( const_iterator p = m_data->string+r; r > 0; --r )
3174  if ( *--p == c )
3175  return r - 1;
3176  return notFound;
3177  }
3178 
3191  template <class R1, class A1>
3192  size_type FindLastIC( const GenericString<T,R1,A1>& s, size_type r = maxPos ) const noexcept
3193  {
3194  r = pcl::Min( r, Length() );
3195  size_type i = SearchEngine( s.m_data->string, s.Length(), false/*case*/, true/*last*/ )( m_data->string, 0, r );
3196  return (i < r) ? i : notFound;
3197  }
3198 
3211  size_type FindLastIC( const_c_string t, size_type r = maxPos ) const noexcept
3212  {
3213  r = pcl::Min( r, Length() );
3214  size_type i = SearchEngine( t, R::Length( t ), false/*case*/, true/*last*/ )( m_data->string, 0, r );
3215  return (i < r) ? i : notFound;
3216  }
3217 
3226  size_type FindLastIC( char_type c, size_type r = maxPos ) const noexcept
3227  {
3228  c = R::ToCaseFolded( c );
3229  r = pcl::Min( r, Length() );
3230  for ( const_iterator p = m_data->string+r; r > 0; --r )
3231  if ( R::ToCaseFolded( *--p ) == c )
3232  return r - 1;
3233  return notFound;
3234  }
3235 
3239  template <class R1, class A1>
3240  bool Contains( const GenericString<T,R1,A1>& s ) const noexcept
3241  {
3242  return Find( s ) != notFound;
3243  }
3244 
3248  bool Contains( const_c_string t ) const noexcept
3249  {
3250  return Find( t ) != notFound;
3251  }
3252 
3256  bool Contains( char_type c ) const noexcept
3257  {
3258  return Find( c ) != notFound;
3259  }
3260 
3267  template <class R1, class A1>
3268  bool ContainsIC( const GenericString<T,R1,A1>& s ) const noexcept
3269  {
3270  return FindIC( s ) != notFound;
3271  }
3272 
3279  bool ContainsIC( const_c_string t ) const noexcept
3280  {
3281  return FindIC( t ) != notFound;
3282  }
3283 
3290  bool ContainsIC( char_type c ) const noexcept
3291  {
3292  return FindIC( c ) != notFound;
3293  }
3294 
3304  void Trim()
3305  {
3306  const_iterator l = R::SearchTrimLeft( m_data->string, m_data->end );
3307  const_iterator r = R::SearchTrimRight( l, m_data->end );
3308  if ( m_data->string < l || r < m_data->end )
3309  Trim( l, r - l );
3310  }
3311 
3321  void TrimLeft()
3322  {
3323  const_iterator l = R::SearchTrimLeft( m_data->string, m_data->end );
3324  if ( m_data->string < l )
3325  Trim( l, m_data->end - l );
3326  }
3327 
3337  void TrimRight()
3338  {
3339  const_iterator r = R::SearchTrimRight( m_data->string, m_data->end );
3340  if ( r < m_data->end )
3341  Trim( m_data->string, r - m_data->string );
3342  }
3343 
3350  {
3351  GenericString s( *this );
3352  s.Trim();
3353  return s;
3354  }
3355 
3362  {
3363  GenericString s( *this );
3364  s.TrimLeft();
3365  return s;
3366  }
3367 
3374  {
3375  GenericString s( *this );
3376  s.TrimRight();
3377  return s;
3378  }
3379 
3387  {
3388  int encloseLeft = 1;
3389  int encloseRight = 1;
3390  size_type len = Length();
3391  if ( len > 0 )
3392  {
3393  if ( *m_data->string == c )
3394  encloseLeft = 0;
3395  if ( *(m_data->end-1) == c )
3396  if ( len > 1 )
3397  encloseRight = 0;
3398  else
3399  encloseLeft = 0;
3400  }
3401  size_type n = len + encloseLeft + encloseRight;
3402  if ( n > len )
3403  {
3404  if ( !IsUnique() || m_data->ShouldReallocate( n ) )
3405  {
3406  Data* newData = Data::New( n );
3407  R::Copy( newData->string + encloseLeft, m_data->string, len );
3408  DetachFromData();
3409  m_data = newData;
3410  }
3411  else
3412  {
3413  m_data->SetLength( n );
3414  R::CopyOverlapped( m_data->string + encloseLeft, m_data->string, len );
3415  }
3416 
3417  if ( encloseLeft )
3418  *m_data->string = c;
3419  if ( encloseRight )
3420  *(m_data->end-1) = c;
3421  }
3422  }
3423 
3431  {
3432  GenericString s( *this );
3433  s.EnsureEnclosed( c );
3434  return s;
3435  }
3436 
3444  {
3445  EnsureEnclosed( R::SingleQuote() );
3446  }
3447 
3455  {
3456  GenericString s( *this );
3457  s.EnsureSingleQuoted();
3458  return s;
3459  }
3460 
3468  {
3469  EnsureEnclosed( R::DoubleQuote() );
3470  }
3471 
3479  {
3480  GenericString s( *this );
3481  s.EnsureDoubleQuoted();
3482  return s;
3483  }
3484 
3498  void Unquote()
3499  {
3500  size_type len = Length();
3501  if ( len > 1 )
3502  if ( *m_data->string == R::SingleQuote() && *(m_data->end-1) == R::SingleQuote() ||
3503  *m_data->string == R::DoubleQuote() && *(m_data->end-1) == R::DoubleQuote() )
3504  if ( IsUnique() )
3505  {
3506  R::CopyOverlapped( m_data->string, m_data->string+1, len-2 );
3507  m_data->SetLength( len-2 );
3508  }
3509  else
3510  {
3511  Data* newData = Data::New( len-2 );
3512  R::Copy( newData->string, m_data->string+1, len-2 );
3513  DetachFromData();
3514  m_data = newData;
3515  }
3516  }
3517 
3523  {
3524  GenericString s( *this );
3525  s.Unquote();
3526  return s;
3527  }
3528 
3540  void JustifyLeft( size_type width, char_type fill = R::Blank() )
3541  {
3542  size_type len = Length();
3543  if ( len < width )
3544  Append( fill, width-len );
3545  }
3546 
3558  void JustifyRight( size_type width, char_type fill = R::Blank() )
3559  {
3560  size_type len = Length();
3561  if ( len < width )
3562  Prepend( fill, width-len );
3563  }
3564 
3577  void JustifyCenter( size_type width, char_type fill = R::Blank() )
3578  {
3579  size_type len = Length();
3580  if ( len < width )
3581  {
3582  size_type n = width-len;
3583  size_type n2 = n >> 1;
3584  Prepend( fill, n2 );
3585  Append( fill, n-n2 );
3586  }
3587  }
3588 
3595  GenericString LeftJustified( size_type width, char_type fill = R::Blank() ) const
3596  {
3597  GenericString s( *this );
3598  s.JustifyLeft( width, fill );
3599  return s;
3600  }
3601 
3608  GenericString RightJustified( size_type width, char_type fill = R::Blank() ) const
3609  {
3610  GenericString s( *this );
3611  s.JustifyRight( width, fill );
3612  return s;
3613  }
3614 
3621  GenericString CenterJustified( size_type width, char_type fill = R::Blank() ) const
3622  {
3623  GenericString s( *this );
3624  s.JustifyCenter( width, fill );
3625  return s;
3626  }
3627 
3651  template <class R1, class A1>
3652  int CompareCodePoints( const GenericString<T,R1,A1>& s, bool caseSensitive = true ) const noexcept
3653  {
3654  return R::CompareCodePoints( m_data->string, Length(), s.m_data->string, s.Length(), caseSensitive );
3655  }
3656 
3681  int CompareCodePoints( const_c_string t, bool caseSensitive = true ) const noexcept
3682  {
3683  return R::CompareCodePoints( m_data->string, Length(), t, R::Length( t ), caseSensitive );
3684  }
3685 
3713  int CompareCodePoints( char_type c, bool caseSensitive = true ) const noexcept
3714  {
3715  return R::CompareCodePoints( m_data->string, Length(), &c, 1, caseSensitive );
3716  }
3717 
3744  template <class R1, class A1>
3746  bool caseSensitive = true, bool localeAware = true ) const noexcept
3747  {
3748  return R::Compare( m_data->string, Length(), s.m_data->string, s.Length(), caseSensitive, localeAware );
3749  }
3750 
3778  int Compare( const_c_string t, bool caseSensitive = true, bool localeAware = true ) const noexcept
3779  {
3780  return R::Compare( m_data->string, Length(), t, R::Length( t ), caseSensitive, localeAware );
3781  }
3782 
3812  int Compare( char_type c, bool caseSensitive = true, bool localeAware = true ) const noexcept
3813  {
3814  return R::Compare( m_data->string, Length(), &c, 1, caseSensitive, localeAware );
3815  }
3816 
3837  template <class R1, class A1>
3838  int CompareIC( const GenericString<T,R1,A1>& s, bool localeAware = true ) const noexcept
3839  {
3840  return R::Compare( m_data->string, Length(), s.m_data->string, s.Length(), false/*caseSensitive*/, localeAware );
3841  }
3842 
3864  int CompareIC( const_c_string t, bool localeAware = true ) const noexcept
3865  {
3866  return R::Compare( m_data->string, Length(), t, R::Length( t ), false/*caseSensitive*/, localeAware );
3867  }
3868 
3893  int CompareIC( char_type c, bool localeAware = true ) const noexcept
3894  {
3895  return R::Compare( m_data->string, Length(), &c, 1, false/*caseSensitive*/, localeAware );
3896  }
3897 
3913  template <class R1, class A1>
3914  bool WildMatch( const GenericString<T,R1,A1>& pattern, bool caseSensitive = true ) const noexcept
3915  {
3916  return R::WildMatch( m_data->string, Length(), pattern.m_data->string, pattern.Length(), caseSensitive );
3917  }
3918 
3932  template <class R1, class A1>
3933  bool WildMatchIC( const GenericString<T,R1,A1>& pattern ) const noexcept
3934  {
3935  return R::WildMatch( m_data->string, Length(), pattern.m_data->string, pattern.Length(), false/*caseSensitive*/ );
3936  }
3937 
3953  bool WildMatch( const_c_string pattern, bool caseSensitive = true ) const noexcept
3954  {
3955  return R::WildMatch( m_data->string, Length(), pattern, R::Length( pattern ), caseSensitive );
3956  }
3957 
3972  bool WildMatchIC( const_c_string pattern ) const noexcept
3973  {
3974  return R::WildMatch( m_data->string, Length(), pattern, R::Length( pattern ), false/*caseSensitive*/ );
3975  }
3976 
3981  bool HasWildcards() const noexcept
3982  {
3983  for ( iterator i = m_data->string; i < m_data->end; ++i )
3984  if ( R::IsWildcard( *i ) )
3985  return true;
3986  return false;
3987  }
3988 
3994  {
3995  size_type len = Length();
3996  if ( len > 0 )
3997  {
3998  EnsureUnique();
3999  R::ToCaseFolded( m_data->string, len );
4000  }
4001  }
4002 
4008  {
4009  size_type len = Length();
4010  if ( len > 0 )
4011  {
4012  EnsureUnique();
4013  R::ToLowercase( m_data->string, len );
4014  }
4015  }
4016 
4022  {
4023  size_type len = Length();
4024  if ( len > 0 )
4025  {
4026  EnsureUnique();
4027  R::ToUppercase( m_data->string, len );
4028  }
4029  }
4030 
4036  {
4037  GenericString s( *this );
4038  s.ToCaseFolded();
4039  return s;
4040  }
4041 
4047  {
4048  GenericString s( *this );
4049  s.ToLowercase();
4050  return s;
4051  }
4052 
4058  {
4059  GenericString s( *this );
4060  s.ToUppercase();
4061  return s;
4062  }
4063 
4069  void Reverse()
4070  {
4071  if ( !IsEmpty() )
4072  {
4073  EnsureUnique();
4074  for ( iterator i = m_data->string, j = m_data->end; i < --j; ++i )
4075  pcl::Swap( *i, *j );
4076  }
4077  }
4078 
4083  {
4084  GenericString s( *this );
4085  s.Reverse();
4086  return s;
4087  }
4088 
4092  void Sort()
4093  {
4094  if ( !IsEmpty() )
4095  {
4096  EnsureUnique();
4097  pcl::Sort( m_data->string, m_data->end );
4098  }
4099  }
4100 
4106  {
4107  GenericString s( *this );
4108  s.Sort();
4109  return s;
4110  }
4111 
4117  template <class BP>
4118  void Sort( BP p )
4119  {
4120  if ( !IsEmpty() )
4121  {
4122  EnsureUnique();
4123  pcl::Sort( m_data->string, m_data->end, p );
4124  }
4125  }
4126 
4131  template <class BP>
4132  GenericString Sorted( BP p ) const
4133  {
4134  GenericString s( *this );
4135  s.Sort( p );
4136  return s;
4137  }
4138 
4153  bool IsNumeral() const noexcept
4154  {
4155  if ( IsEmpty() )
4156  return false;
4157  char_type c = *R::SearchTrimLeft( m_data->string, m_data->end );
4158  return R::IsDigit( c ) || R::IsSign( c ) || R::IsDecimalSeparator( c );
4159  }
4160 
4175  bool IsSymbol() const noexcept
4176  {
4177  if ( IsEmpty() )
4178  return false;
4179  char_type c = *R::SearchTrimLeft( m_data->string, m_data->end );
4180  return R::IsSymbolDigit( c );
4181  }
4182 
4198  bool IsValidIdentifier( distance_type& pos ) const noexcept
4199  {
4200  if ( IsEmpty() )
4201  {
4202  pos = 0;
4203  return false;
4204  }
4205  const_iterator i = m_data->string;
4206  if ( R::IsStartingSymbolDigit( *i ) )
4207  for ( ;; )
4208  {
4209  if ( ++i == m_data->end )
4210  return true;
4211  if ( !R::IsSymbolDigit( *i ) )
4212  break;
4213  }
4214  pos = i - m_data->string;
4215  return false;
4216  }
4217 
4229  bool IsValidIdentifier() const noexcept
4230  {
4231  if ( !IsEmpty() )
4232  if ( R::IsStartingSymbolDigit( *m_data->string ) )
4233  {
4234  for ( const_iterator i = m_data->string; ++i < m_data->end; )
4235  if ( !R::IsSymbolDigit( *i ) )
4236  return false;
4237  return true;
4238  }
4239  return false;
4240  }
4241 
4250  uint64 Hash64( uint64 seed = 0 ) const noexcept
4251  {
4252  return pcl::Hash64( m_data->string, Size(), seed );
4253  }
4254 
4263  uint32 Hash32( uint32 seed = 0 ) const noexcept
4264  {
4265  return pcl::Hash32( m_data->string, Size(), seed );
4266  }
4267 
4272  uint64 Hash( uint64 seed = 0 ) const noexcept
4273  {
4274  return Hash64( seed );
4275  }
4276 
4285  {
4286  return Data::DeleteFreeList();
4287  }
4288 
4289  // -------------------------------------------------------------------------
4290 
4291 protected:
4292 
4297  void DetachFromData()
4298  {
4299  if ( !m_data->Detach() )
4300  Data::Dispose( m_data );
4301  }
4302 
4314  void MaybeReallocate( size_type len )
4315  {
4316  if ( IsUnique() )
4317  {
4318  if ( m_data->ShouldReallocate( len ) )
4319  {
4320  m_data->Deallocate();
4321  m_data->Allocate( len );
4322  }
4323  else
4324  m_data->SetLength( len );
4325  }
4326  else
4327  {
4328  Data* newData = Data::New( len );
4329  DetachFromData();
4330  m_data = newData;
4331  }
4332  }
4333 
4342  void UninitializedGrow( size_type& i, size_type n )
4343  {
4344  size_type len = Length();
4345  size_type newLen = len+n;
4346  if ( newLen > len )
4347  {
4348  if ( i > len )
4349  i = len;
4350  if ( IsUnique() )
4351  {
4352  if ( size_type( m_data->capacity - m_data->string ) < newLen+1 )
4353  {
4354  iterator old = m_data->string;
4355  m_data->Allocate( newLen );
4356  if ( old != nullptr )
4357  {
4358  if ( i > 0 )
4359  R::Copy( m_data->string, old, i );
4360  if ( i < len )
4361  R::Copy( m_data->string+i+n, old+i, len-i );
4362  m_data->alloc.Deallocate( old );
4363  }
4364  }
4365  else
4366  {
4367  if ( i < len )
4368  R::CopyOverlapped( m_data->string+i+n, m_data->string+i, len-i );
4369  m_data->SetLength( newLen );
4370  }
4371  }
4372  else
4373  {
4374  Data* newData = Data::New( newLen );
4375  if ( i > 0 )
4376  R::Copy( newData->string, m_data->string, i );
4377  if ( i < len )
4378  R::Copy( newData->string+i+n, m_data->string+i, len-i );
4379  DetachFromData();
4380  m_data = newData;
4381  }
4382  }
4383  }
4384 
4389  void Trim( const_iterator left, size_type len )
4390  {
4391  if ( len > 0 )
4392  {
4393  if ( IsUnique() )
4394  {
4395  if ( m_data->ShouldReallocate( len ) )
4396  {
4397  iterator old = m_data->string;
4398  m_data->Allocate( len );
4399  R::Copy( m_data->string, left, len );
4400  if ( old != nullptr )
4401  m_data->alloc.Deallocate( old );
4402  }
4403  else
4404  {
4405  if ( left != m_data->string ) // trim left
4406  R::CopyOverlapped( m_data->string, left, len );
4407  m_data->SetLength( len ); // trim right
4408  }
4409  }
4410  else
4411  {
4412  Data* newData = Data::New( len );
4413  R::Copy( newData->string, left, len );
4414  DetachFromData();
4415  m_data = newData;
4416  }
4417  }
4418  else
4419  Clear();
4420  }
4421 
4426  void ReplaceChar( char_type c1, char_type c2, size_type i, size_type n, bool caseSensitive )
4427  {
4428  if ( n > 0 )
4429  {
4430  size_type len = Length();
4431  if ( i < len )
4432  {
4433  n = pcl::Min( n, len-i );
4434  if ( caseSensitive )
4435  {
4436  for ( iterator p = m_data->string + i, p1 = p + n; p < p1; ++p )
4437  if ( *p == c1 )
4438  {
4439  distance_type d = p - m_data->string;
4440  EnsureUnique();
4441  p = m_data->string + d;
4442  *p = c2;
4443  for ( iterator p1 = m_data->string + i + n; ++p < p1; )
4444  if ( *p == c1 )
4445  *p = c2;
4446  break;
4447  }
4448  }
4449  else
4450  {
4451  c1 = R::ToCaseFolded( c1 );
4452  for ( iterator p = m_data->string + i, p1 = p + n; p < p1; ++p )
4453  if ( R::ToCaseFolded( *p ) == c1 )
4454  {
4455  distance_type d = p - m_data->string;
4456  EnsureUnique();
4457  p = m_data->string + d;
4458  *p = c2;
4459  for ( iterator p1 = m_data->string + i + n; ++p < p1; )
4460  if ( R::ToCaseFolded( *p ) == c1 )
4461  *p = c2;
4462  break;
4463  }
4464  }
4465  }
4466  }
4467  }
4468 
4473  void ReplaceString( const_iterator t1, size_type n1, const_iterator t2, size_type n2, size_type i, bool caseSensitive )
4474  {
4475  if ( n1 > 0 )
4476  {
4477  size_type len = Length();
4478  if ( i < len )
4479  {
4480  SearchEngine S( t1, n1, caseSensitive );
4481  if ( n1 == n2 )
4482  {
4483  EnsureUnique();
4484  for ( size_type p = i; (p = S( m_data->string, p, len )) < len; p += n1 )
4485  R::Copy( m_data->string + p, t2, n2 );
4486  }
4487  else
4488  {
4489  Array<size_type> P;
4490  for ( size_type p = i; (p = S( m_data->string, p, len )) < len; p += n1 )
4491  P.Add( p );
4492  if ( !P.IsEmpty() )
4493  {
4494  size_type newLen = len;
4495  if ( n1 < n2 )
4496  newLen += P.Length()*(n2 - n1);
4497  else
4498  newLen -= P.Length()*(n1 - n2);
4499 
4500  if ( newLen > 0 )
4501  {
4502  Data* newData = Data::New( newLen );
4503  size_type targetIndex = 0;
4504  size_type sourceIndex = 0;
4505  for ( size_type p : P )
4506  {
4507  size_type n = p - sourceIndex;
4508  if ( n > 0 )
4509  R::Copy( newData->string+targetIndex, m_data->string+sourceIndex, n );
4510  R::Copy( newData->string+targetIndex+n, t2, n2 );
4511  targetIndex += n + n2;
4512  sourceIndex = p + n1;
4513  }
4514  if ( sourceIndex < len )
4515  R::Copy( newData->string+targetIndex, m_data->string+sourceIndex, len-sourceIndex );
4516  DetachFromData();
4517  m_data = newData;
4518  }
4519  else
4520  Clear();
4521  }
4522  }
4523  }
4524  }
4525  }
4526 
4544  class PCL_CLASS SearchEngine
4545  {
4546  public:
4547 
4558  SearchEngine( const_iterator pattern, size_type patternLength,
4559  bool caseSensitive = true, bool searchLast = false, bool useBoyerMoore = true )
4560  : m_pattern( pattern )
4561  , m_patternLength( int( patternLength ) )
4562  , m_caseSensitive( caseSensitive )
4563  , m_searchLast( searchLast )
4564  , m_useBoyerMoore( useBoyerMoore && m_patternLength > 3 )
4565  {
4566  if ( m_useBoyerMoore )
4567  InitSkipList();
4568  }
4569 
4582  size_type operator()( const_iterator text, size_type startIndex, size_type endIndex ) const noexcept
4583  {
4584  if ( endIndex <= startIndex
4585  || m_patternLength <= 0
4586  || endIndex-startIndex < size_type( m_patternLength )
4587  || text == nullptr
4588  || m_pattern == nullptr )
4589  return endIndex;
4590 
4591  if ( m_caseSensitive )
4592  {
4593  if ( m_useBoyerMoore )
4594  {
4595  if ( m_searchLast )
4596  {
4597  for ( size_type i = startIndex, r = endIndex-m_patternLength; i <= r; )
4598  {
4599  int skip = 0;
4600  const_iterator t = text + r - i;
4601  const_iterator p = m_pattern;
4602  for ( int j = m_patternLength; --j >= 0; )
4603  {
4604  char_type c = *t++;
4605  if ( c != *p++ )
4606  {
4607  skip = j - m_skipList[uint8( c )];
4608  if ( skip < 1 )
4609  skip = 1;
4610  break;
4611  }
4612  }
4613  if ( skip == 0 )
4614  return r - i;
4615  i += skip;
4616  }
4617  }
4618  else
4619  {
4620  for ( size_type i = startIndex, r = endIndex-m_patternLength; i <= r; )
4621  {
4622  int skip = 0;
4623  const_iterator t = text + i + m_patternLength;
4624  const_iterator p = m_pattern + m_patternLength;
4625  for ( int j = m_patternLength; --j >= 0; )
4626  {
4627  char_type c = *--t;
4628  if ( c != *--p )
4629  {
4630  // ### N.B.: Could do better with a precomputed pattern mismatch table.
4631  skip = j - m_skipList[uint8( c )];
4632  if ( skip < 1 )
4633  skip = 1;
4634  break;
4635  }
4636  }
4637  if ( skip == 0 )
4638  return i;
4639  i += skip;
4640  }
4641  }
4642  }
4643  else
4644  {
4645  // Use a brute force search for very small patterns.
4646  if ( m_searchLast )
4647  {
4648  for ( size_type i = endIndex-m_patternLength; ; --i )
4649  {
4650  const_iterator t = text + i;
4651  const_iterator p = m_pattern;
4652  for ( int j = m_patternLength; ; ++t, ++p )
4653  {
4654  if ( *t != *p )
4655  break;
4656  if ( --j == 0 )
4657  return i;
4658  }
4659  if ( i == startIndex )
4660  break;
4661  }
4662  }
4663  else
4664  {
4665  for ( size_type i = startIndex, r = endIndex-m_patternLength; ; ++i )
4666  {
4667  const_iterator t = text + i;
4668  const_iterator p = m_pattern;
4669  for ( int j = m_patternLength; ; ++t, ++p )
4670  {
4671  if ( *t != *p )
4672  break;
4673  if ( --j == 0 )
4674  return i;
4675  }
4676  if ( i == r )
4677  break;
4678  }
4679  }
4680  }
4681  }
4682  else
4683  {
4684  if ( m_useBoyerMoore )
4685  {
4686  if ( m_searchLast )
4687  {
4688  for ( size_type i = startIndex, r = endIndex-m_patternLength; i <= r; )
4689  {
4690  int skip = 0;
4691  const_iterator t = text + r - i;
4692  const_iterator p = m_pattern;
4693  for ( int j = m_patternLength; --j >= 0; )
4694  {
4695  char_type c = R::ToCaseFolded( *t++ );
4696  if ( c != R::ToCaseFolded( *p++ ) )
4697  {
4698  skip = j - m_skipList[uint8( c )];
4699  if ( skip < 1 )
4700  skip = 1;
4701  break;
4702  }
4703  }
4704  if ( skip == 0 )
4705  return r - i;
4706  i += skip;
4707  }
4708  }
4709  else
4710  {
4711  for ( size_type i = startIndex, r = endIndex-m_patternLength; i <= r; )
4712  {
4713  int skip = 0;
4714  const_iterator t = text + i + m_patternLength;
4715  const_iterator p = m_pattern + m_patternLength;
4716  for ( int j = m_patternLength; --j >= 0; )
4717  {
4718  char_type c = R::ToCaseFolded( *--t );
4719  if ( c != R::ToCaseFolded( *--p ) )
4720  {
4721  // ### N.B.: Could do better with a precomputed pattern mismatch table.
4722  skip = j - m_skipList[uint8( c )];
4723  if ( skip < 1 )
4724  skip = 1;
4725  break;
4726  }
4727  }
4728  if ( skip == 0 )
4729  return i;
4730  i += skip;
4731  }
4732  }
4733  }
4734  else
4735  {
4736  // Use a brute force search for very small patterns.
4737  if ( m_searchLast )
4738  {
4739  for ( size_type i = endIndex-m_patternLength; ; --i )
4740  {
4741  const_iterator t = text + i;
4742  const_iterator p = m_pattern;
4743  for ( int j = m_patternLength; ; ++t, ++p )
4744  {
4745  if ( R::ToCaseFolded( *t ) != R::ToCaseFolded( *p ) )
4746  break;
4747  if ( --j == 0 )
4748  return i;
4749  }
4750  if ( i == startIndex )
4751  break;
4752  }
4753  }
4754  else
4755  {
4756  for ( size_type i = startIndex, r = endIndex-m_patternLength; ; ++i )
4757  {
4758  const_iterator t = text + i;
4759  const_iterator p = m_pattern;
4760  for ( int j = m_patternLength; ; ++t, ++p )
4761  {
4762  if ( R::ToCaseFolded( *t ) != R::ToCaseFolded( *p ) )
4763  break;
4764  if ( --j == 0 )
4765  return i;
4766  }
4767  if ( i == r )
4768  break;
4769  }
4770  }
4771  }
4772  }
4773  return endIndex;
4774  }
4775 
4776  private:
4777 
4778  int m_skipList[ 256 ];
4779  const_iterator m_pattern;
4780  int m_patternLength;
4781  bool m_caseSensitive : 1;
4782  bool m_searchLast : 1;
4783  bool m_useBoyerMoore : 1;
4784 
4785  void InitSkipList() noexcept
4786  {
4787  ::memset( m_skipList, 0xff, sizeof( m_skipList ) ); // fill with -1
4788  if ( m_searchLast )
4789  {
4790  const_iterator p = m_pattern + m_patternLength;
4791  if ( m_caseSensitive )
4792  for ( int i = 0; i < m_patternLength; ++i )
4793  m_skipList[uint8( *--p )] = i;
4794  else
4795  for ( int i = 0; i < m_patternLength; ++i )
4796  m_skipList[uint8( R::ToCaseFolded( *--p ) )] = i;
4797  }
4798  else
4799  {
4800  const_iterator p = m_pattern;
4801  if ( m_caseSensitive )
4802  for ( int i = 0; i < m_patternLength; ++i )
4803  m_skipList[uint8( *p++ )] = i;
4804  else
4805  for ( int i = 0; i < m_patternLength; ++i )
4806  m_skipList[uint8( R::ToCaseFolded( *p++ ) )] = i;
4807  }
4808  }
4809  };
4810 
4811  // -------------------------------------------------------------------------
4812 
4818  class PCL_CLASS Data : public ReferenceCounter
4819  {
4820  private:
4821 
4822 #ifndef __PCL_NO_STRING_FREE_LIST
4823  static Data* freeList;
4824  static AtomicInt freeLock;
4825 #endif
4826 
4827  public:
4828 
4829  iterator string = nullptr;
4830  iterator end = nullptr;
4831  iterator capacity = nullptr;
4832  allocator alloc;
4833 
4837  Data() = default;
4838 
4842  Data( size_type len )
4843  {
4844  Allocate( len );
4845  }
4846 
4851  Data( size_type len, size_type total )
4852  {
4853  Allocate( len, total );
4854  }
4855 
4859  ~Data()
4860  {
4861  Deallocate();
4862  }
4863 
4874  void Allocate( size_type len, size_type total )
4875  {
4876  total = (len <= total) ? alloc.PagedLength( total+1 ) : len+1; // +1 is room for a null terminating character
4877  string = alloc.Allocate( total );
4878  capacity = string + total;
4879  SetLength( len );
4880  }
4881 
4886  void Allocate( size_type len )
4887  {
4888  Allocate( len, len );
4889  }
4890 
4899  void Reserve( size_type len, size_type total )
4900  {
4901  PCL_PRECONDITION( len <= total )
4902  string = alloc.Allocate( total+1 );
4903  capacity = string + total+1;
4904  SetLength( pcl::Min( len, total ) );
4905  }
4906 
4910  void Deallocate()
4911  {
4912  PCL_CHECK( (string == nullptr) ? end == nullptr : string < end )
4913  if ( string != nullptr )
4914  {
4915  alloc.Deallocate( string );
4916  Reset();
4917  }
4918  }
4919 
4924  bool ShouldReallocate( size_type len ) const noexcept
4925  {
4926  size_type m = capacity - string;
4927  return m <= len || alloc.ReallocatedLength( m, len+1 ) < (m >> 1);
4928  }
4929 
4934  void SetLength( size_type len ) noexcept
4935  {
4936  *(end = (string + len)) = R::Null();
4937  }
4938 
4942  void Reset() noexcept
4943  {
4944  string = end = capacity = nullptr;
4945  }
4946 
4953 #ifndef __PCL_NO_STRING_FREE_LIST
4954  static Data* NextFree() noexcept
4955  {
4956  if ( freeLock.TestAndSet( 0, 1 ) )
4957  {
4958  Data* data = freeList;
4959  if ( data != nullptr )
4960  freeList = reinterpret_cast<Data*>( data->string );
4961  freeLock.Store( 0 );
4962  return data;
4963  }
4964  return nullptr;
4965  }
4966 #endif // !__PCL_NO_STRING_FREE_LIST
4967 
4975  static Data* New()
4976  {
4977 #ifndef __PCL_NO_STRING_FREE_LIST
4978  Data* data = NextFree();
4979  if ( data != nullptr )
4980  {
4981  data->string = nullptr;
4982  return data;
4983  }
4984 #endif // !__PCL_NO_STRING_FREE_LIST
4985  return new Data;
4986  }
4987 
4995  static Data* New( size_type len )
4996  {
4997 #ifndef __PCL_NO_STRING_FREE_LIST
4998  Data* data = NextFree();
4999  if ( data != nullptr )
5000  {
5001  data->Allocate( len ); // ### FIXME: If allocation fails, data is a leak.
5002  return data;
5003  }
5004 #endif // !__PCL_NO_STRING_FREE_LIST
5005  return new Data( len );
5006  }
5007 
5015  static Data* New( size_type len, size_type total )
5016  {
5017 #ifndef __PCL_NO_STRING_FREE_LIST
5018  Data* data = NextFree();
5019  if ( data != nullptr )
5020  {
5021  data->Allocate( len, total ); // ### FIXME: If allocation fails, data is a leak.
5022  return data;
5023  }
5024 #endif // !__PCL_NO_STRING_FREE_LIST
5025  return new Data( len, total );
5026  }
5027 
5035  static void Dispose( Data* data )
5036  {
5037  PCL_PRECONDITION( data != nullptr )
5038  PCL_CHECK( data->RefCount() == 0 )
5039 #ifndef __PCL_NO_STRING_FREE_LIST
5040  if ( freeLock.TestAndSet( 0, 1 ) )
5041  {
5042  data->Attach();
5043  data->Deallocate();
5044  data->string = reinterpret_cast<iterator>( freeList );
5045  freeList = data;
5046  freeLock.Store( 0 );
5047  }
5048  else
5049 #endif // !__PCL_NO_STRING_FREE_LIST
5050  delete data;
5051  }
5052 
5060  static size_type DeleteFreeList()
5061  {
5062  size_type count = 0;
5063 #ifndef __PCL_NO_STRING_FREE_LIST
5064  while ( freeList != nullptr )
5065  {
5066  Data* data = freeList;
5067  freeList = reinterpret_cast<Data*>( data->string );
5068  data->string = nullptr;
5069  delete data;
5070  ++count;
5071  }
5072 #endif // !__PCL_NO_STRING_FREE_LIST
5073  return count;
5074  }
5075  };
5076 
5077  /*
5078  * The reference-counted string data.
5079  */
5080  Data* m_data = nullptr;
5081 };
5082 
5083 #ifndef __PCL_NO_STRING_FREE_LIST
5084 
5085 template <class T, class R, class A>
5086 typename GenericString<T,R,A>::Data* GenericString<T,R,A>::Data::freeList = nullptr;
5087 
5088 template <class T, class R, class A>
5089 AtomicInt GenericString<T,R,A>::Data::freeLock;
5090 
5091 #endif // !__PCL_NO_STRING_FREE_LIST
5092 
5096 template <class T, class R, class A> inline
5098 {
5099  s1.Swap( s2 );
5100 }
5101 
5102 // ----------------------------------------------------------------------------
5103 
5108 // ----------------------------------------------------------------------------
5109 
5114 template <class T, class R1, class A1, class R2, class A2> inline
5115 bool operator ==( const GenericString<T,R1,A1>& s1, const GenericString<T,R2,A2>& s2 ) noexcept
5116 {
5117  return s1.CompareCodePoints( s2 ) == 0;
5118 }
5119 
5127 template <class T, class R1, class A1, class R2, class A2> inline
5128 bool operator <( const GenericString<T,R1,A1>& s1, const GenericString<T,R2,A2>& s2 ) noexcept
5129 {
5130  return s1.CompareCodePoints( s2 ) < 0;
5131 }
5132 
5140 template <class T, class R1, class A1, class R2, class A2> inline
5141 bool operator <=( const GenericString<T,R1,A1>& s1, const GenericString<T,R2,A2>& s2 ) noexcept
5142 {
5143  return s1.CompareCodePoints( s2 ) <= 0;
5144 }
5145 
5153 template <class T, class R1, class A1, class R2, class A2> inline
5154 bool operator >( const GenericString<T,R1,A1>& s1, const GenericString<T,R2,A2>& s2 ) noexcept
5155 {
5156  return s1.CompareCodePoints( s2 ) > 0;
5157 }
5158 
5166 template <class T, class R1, class A1, class R2, class A2> inline
5167 bool operator >=( const GenericString<T,R1,A1>& s1, const GenericString<T,R2,A2>& s2 ) noexcept
5168 {
5169  return s1.CompareCodePoints( s2 ) >= 0;
5170 }
5171 
5172 // ----------------------------------------------------------------------------
5173 
5178 template <class T, class R, class A> inline
5180 {
5181  return s1.CompareCodePoints( t2 ) == 0;
5182 }
5183 
5191 template <class T, class R, class A> inline
5193 {
5194  return s1.CompareCodePoints( t2 ) < 0;
5195 }
5196 
5204 template <class T, class R, class A> inline
5206 {
5207  return s1.CompareCodePoints( t2 ) <= 0;
5208 }
5209 
5217 template <class T, class R, class A> inline
5219 {
5220  return s1.CompareCodePoints( t2 ) > 0;
5221 }
5222 
5230 template <class T, class R, class A> inline
5232 {
5233  return s1.CompareCodePoints( t2 ) >= 0;
5234 }
5235 
5236 // ----------------------------------------------------------------------------
5237 
5242 template <class T, class R, class A> inline
5244 {
5245  return s2.CompareCodePoints( t1 ) == 0;
5246 }
5247 
5255 template <class T, class R, class A> inline
5257 {
5258  return s2.CompareCodePoints( t1 ) > 0;
5259 }
5260 
5268 template <class T, class R, class A> inline
5270 {
5271  return s2.CompareCodePoints( t1 ) >= 0;
5272 }
5273 
5281 template <class T, class R, class A> inline
5283 {
5284  return s2.CompareCodePoints( t1 ) < 0;
5285 }
5286 
5294 template <class T, class R, class A> inline
5296 {
5297  return s2.CompareCodePoints( t1 ) <= 0;
5298 }
5299 
5300 // ----------------------------------------------------------------------------
5301 
5306 template <class T, class R, class A> inline
5308 {
5309  return s1.CompareCodePoints( c2 ) == 0;
5310 }
5311 
5319 template <class T, class R, class A> inline
5320 bool operator <( const GenericString<T,R,A>& s1, typename GenericString<T,R,A>::char_type c2 ) noexcept
5321 {
5322  return s1.CompareCodePoints( c2 ) < 0;
5323 }
5324 
5332 template <class T, class R, class A> inline
5334 {
5335  return s1.CompareCodePoints( c2 ) <= 0;
5336 }
5337 
5345 template <class T, class R, class A> inline
5346 bool operator >( const GenericString<T,R,A>& s1, typename GenericString<T,R,A>::char_type c2 ) noexcept
5347 {
5348  return s1.CompareCodePoints( c2 ) > 0;
5349 }
5350 
5358 template <class T, class R, class A> inline
5360 {
5361  return s1.CompareCodePoints( c2 ) >= 0;
5362 }
5363 
5364 // ----------------------------------------------------------------------------
5365 
5370 template <class T, class R, class A> inline
5372 {
5373  return s2.CompareCodePoints( c1 ) == 0;
5374 }
5375 
5383 template <class T, class R, class A> inline
5384 bool operator <( typename GenericString<T,R,A>::char_type c1, const GenericString<T,R,A>& s2 ) noexcept
5385 {
5386  return s2.CompareCodePoints( c1 ) > 0;
5387 }
5388 
5396 template <class T, class R, class A> inline
5398 {
5399  return s2.CompareCodePoints( c1 ) >= 0;
5400 }
5401 
5409 template <class T, class R, class A> inline
5410 bool operator >( typename GenericString<T,R,A>::char_type c1, const GenericString<T,R,A>& s2 ) noexcept
5411 {
5412  return s2.CompareCodePoints( c1 ) < 0;
5413 }
5414 
5422 template <class T, class R, class A> inline
5424 {
5425  return s2.CompareCodePoints( c1 ) <= 0;
5426 }
5427 
5428 // ----------------------------------------------------------------------------
5429 
5442 class PCL_CLASS IsoString : public GenericString<char, IsoCharTraits, PCL_STRING_ALLOCATOR>
5443 {
5444 public:
5445 
5450 
5455 
5460 
5465 
5470 
5475 
5480 
5485 
5490 
5495 
5500 
5505 
5510 
5515 
5522 
5527 
5532 
5537 
5541  using const_c_ustring = ustring_base::const_c_string;
5542 
5547 
5552 
5553  // -------------------------------------------------------------------------
5554 
5558  IsoString() = default;
5559 
5565  : string_base( s )
5566  {
5567  }
5568 
5572  IsoString( const IsoString& ) = default;
5573 
5579  : string_base( std::move( s ) )
5580  {
5581  }
5582 
5586  IsoString( IsoString&& ) = default;
5587 
5595  explicit
5597  {
5598  (void)operator =( s );
5599  }
5600 
5605  : string_base( t )
5606  {
5607  }
5608 
5614  : string_base( t, i, n )
5615  {
5616  }
5617 
5622  : string_base( c, n )
5623  {
5624  }
5625 
5631  : string_base( i, j )
5632  {
5633  }
5634 
5643  IsoString( std::initializer_list<char_type> l )
5644  : IsoString( l.begin(), l.end() )
5645  {
5646  }
5647 
5657  explicit
5659  {
5660  (void)operator =( t );
5661  }
5662 
5673  IsoString( const_c_ustring t, size_type i, size_type n );
5674 
5682  explicit
5683  IsoString( const ByteArray& B )
5684  : IsoString( const_iterator( B.Begin() ), const_iterator( B.End() ) )
5685  {
5686  }
5687 
5691  explicit
5692  IsoString( bool x )
5693  : string_base( x ? "true" : "false" )
5694  {
5695  }
5696 
5701  explicit
5702  IsoString( short x )
5703  {
5704  (void)Format( "%hd", x );
5705  }
5706 
5711  explicit
5712  IsoString( unsigned short x )
5713  {
5714  (void)Format( "%hu", x );
5715  }
5716 
5721  explicit
5722  IsoString( int x )
5723  {
5724  (void)Format( "%i", x );
5725  }
5726 
5731  explicit
5732  IsoString( unsigned int x )
5733  {
5734  (void)Format( "%u", x );
5735  }
5736 
5741  explicit
5742  IsoString( long x )
5743  {
5744  (void)Format( "%ld", x );
5745  }
5746 
5751  explicit
5752  IsoString( unsigned long x )
5753  {
5754  (void)Format( "%lu", x );
5755  }
5756 
5761  explicit
5762  IsoString( long long x )
5763  {
5764  (void)Format( "%lli", x );
5765  }
5766 
5771  explicit
5772  IsoString( unsigned long long x )
5773  {
5774  (void)Format( "%llu", x );
5775  }
5776 
5781  explicit
5782  IsoString( float x )
5783  {
5784  (void)Format( "%.7g", x );
5785  }
5786 
5791  explicit
5792  IsoString( double x )
5793  {
5794  (void)Format( "%.16g", x );
5795  }
5796 
5801  explicit
5802  IsoString( long double x )
5803  {
5804 #ifdef _MSC_VER
5805  (void)Format( "%.16Lg", x );
5806 #else
5807  (void)Format( "%.18Lg", x );
5808 #endif
5809  }
5810 
5811 #ifndef __PCL_NO_STRING_COMPLEX
5812 
5817  explicit
5819  {
5820  (void)Format( "{%.7g,%.7g}", x.Real(), x.Imag() );
5821  }
5822 
5827  explicit
5829  {
5830  (void)Format( "{%.16g,%.16g}", x.Real(), x.Imag() );
5831  }
5832 
5837  explicit
5839  {
5840 #ifdef _MSC_VER
5841  (void)Format( "{%.16Lg,%.16Lg}", x.Real(), x.Imag() );
5842 #else
5843  (void)Format( "{%.18Lg,%.18Lg}", x.Real(), x.Imag() );
5844 #endif
5845  }
5846 
5847 #endif // !__PCL_NO_STRING_COMPLEX
5848 
5849 #ifdef __PCL_QT_INTERFACE
5850 
5851  explicit
5852  IsoString( const QString& qs )
5853  : string_base( qs.isEmpty() ? iterator( nullptr ) : iterator( PCL_GET_CHARPTR_FROM_QSTRING( qs ) ) )
5854  {
5855  }
5856 
5857  explicit
5858  IsoString( const QAnyStringView& qv )
5859  : string_base( qv.isEmpty() ? iterator( nullptr ) : iterator( PCL_GET_CHARPTR_FROM_QSTRINGVIEW( qv ) ) )
5860  {
5861  }
5862 
5863  explicit
5864  IsoString( const QByteArray& qb )
5865  : string_base( qb.isEmpty() ? iterator( nullptr ) : iterator( PCL_GET_CHARPTR_FROM_QBYTEARRAY( qb ) ) )
5866  {
5867  }
5868 
5869  explicit
5870  IsoString( const QDate& qd )
5871  : string_base( iterator( PCL_GET_CHARPTR_FROM_QSTRING( qd.toString( PCL_QDATE_FMT_STR ) ) ) )
5872  {
5873  }
5874 
5875  explicit
5876  IsoString( const QDateTime& qdt )
5877  : string_base( iterator( PCL_GET_CHARPTR_FROM_QSTRING( qdt.toString( PCL_QDATETIME_FMT_STR ) ) ) )
5878  {
5879  }
5880 
5881 #endif
5882 
5883  // -------------------------------------------------------------------------
5884 
5888  IsoString& operator =( const IsoString& s )
5889  {
5890  Assign( s );
5891  return *this;
5892  }
5893 
5897  IsoString& operator =( IsoString&& s )
5898  {
5899  Transfer( s );
5900  return *this;
5901  }
5902 
5907  IsoString& operator =( const string_base& s )
5908  {
5909  Assign( s );
5910  return *this;
5911  }
5912 
5917  IsoString& operator =( string_base&& s )
5918  {
5919  Transfer( s );
5920  return *this;
5921  }
5922 
5933  IsoString& operator =( const ustring_base& s )
5934  {
5935  return operator =( s.Begin() );
5936  }
5937 
5942  IsoString& operator =( const_c_string t )
5943  {
5944  Assign( t );
5945  return *this;
5946  }
5947 
5952  IsoString& operator =( char_type c )
5953  {
5954  Assign( c, 1 );
5955  return *this;
5956  }
5957 
5968  IsoString& operator =( const_c_ustring t );
5969 
5970 #ifdef __PCL_QT_INTERFACE
5971 
5972  IsoString& operator =( const QString& qs )
5973  {
5974  if ( qs.isEmpty() )
5975  Clear();
5976  else
5977  Assign( PCL_GET_CHARPTR_FROM_QSTRING( qs ) );
5978  return *this;
5979  }
5980 
5981  IsoString& operator =( const QByteArray& qb )
5982  {
5983  if ( qb.isEmpty() )
5984  Clear();
5985  else
5986  Assign( PCL_GET_CHARPTR_FROM_QBYTEARRAY( qb ) );
5987  return *this;
5988  }
5989 
5990  IsoString& operator =( const QDate& qd )
5991  {
5992  Assign( PCL_GET_CHARPTR_FROM_QSTRING( qd.toString( PCL_QDATE_FMT_STR ) ) );
5993  return *this;
5994  }
5995 
5996  IsoString& operator =( const QDateTime& qdt )
5997  {
5998  Assign( PCL_GET_CHARPTR_FROM_QSTRING( qdt.toString( PCL_QDATETIME_FMT_STR ) ) );
5999  return *this;
6000  }
6001 
6002 #endif
6003 
6004  // -------------------------------------------------------------------------
6005 
6006  IsoString SetToLength( size_type n ) const
6007  {
6008  return string_base::SetToLength( n );
6009  }
6010 
6011  IsoString ResizedToNullTerminated() const
6012  {
6013  return string_base::ResizedToNullTerminated();
6014  }
6015 
6016  IsoString Squeezed() const
6017  {
6018  return string_base::Squeezed();
6019  }
6020 
6021  // -------------------------------------------------------------------------
6022 
6023  IsoString Substring( size_type i, size_type n = maxPos ) const
6024  {
6025  return string_base::Substring( i, n );
6026  }
6027 
6028  IsoString Left( size_type n ) const
6029  {
6030  return string_base::Left( n );
6031  }
6032 
6033  IsoString Right( size_type n ) const
6034  {
6035  return string_base::Right( n );
6036  }
6037 
6038  IsoString Suffix( size_type i ) const
6039  {
6040  return string_base::Suffix( i );
6041  }
6042 
6043  IsoString Prefix( size_type i ) const
6044  {
6045  return string_base::Prefix( i );
6046  }
6047 
6048  // -------------------------------------------------------------------------
6049 
6050  IsoString Trimmed() const
6051  {
6052  return string_base::Trimmed();
6053  }
6054 
6055  IsoString TrimmedLeft() const
6056  {
6057  return string_base::TrimmedLeft();
6058  }
6059 
6060  IsoString TrimmedRight() const
6061  {
6062  return string_base::TrimmedRight();
6063  }
6064 
6065  // -------------------------------------------------------------------------
6066 
6067  IsoString LeftJustified( size_type width, char_type fill = IsoCharTraits::Blank() ) const
6068  {
6069  return string_base::LeftJustified( width, fill );
6070  }
6071 
6072  IsoString RightJustified( size_type width, char_type fill = IsoCharTraits::Blank() ) const
6073  {
6074  return string_base::RightJustified( width, fill );
6075  }
6076 
6077  IsoString CenterJustified( size_type width, char_type fill = IsoCharTraits::Blank() ) const
6078  {
6079  return string_base::CenterJustified( width, fill );
6080  }
6081 
6082  // -------------------------------------------------------------------------
6083 
6084  IsoString Enclosed( char_type c ) const
6085  {
6086  return string_base::Enclosed( c );
6087  }
6088 
6089  IsoString SingleQuoted() const
6090  {
6091  return string_base::SingleQuoted();
6092  }
6093 
6094  IsoString DoubleQuoted() const
6095  {
6096  return string_base::DoubleQuoted();
6097  }
6098 
6099  IsoString Unquoted() const
6100  {
6101  return string_base::Unquoted();
6102  }
6103 
6104  // -------------------------------------------------------------------------
6105 
6106  IsoString CaseFolded() const
6107  {
6108  return string_base::CaseFolded();
6109  }
6110 
6111  IsoString Lowercase() const
6112  {
6113  return string_base::Lowercase();
6114  }
6115 
6116  IsoString Uppercase() const
6117  {
6118  return string_base::Uppercase();
6119  }
6120 
6121  // -------------------------------------------------------------------------
6122 
6123  IsoString Reversed() const
6124  {
6125  return string_base::Reversed();
6126  }
6127 
6128  IsoString Sorted() const
6129  {
6130  return string_base::Sorted();
6131  }
6132 
6133  template <class BP>
6134  IsoString Sorted( BP p ) const
6135  {
6136  return string_base::Sorted( p );
6137  }
6138 
6139  // -------------------------------------------------------------------------
6140 
6150  template <class C>
6151  IsoString& ToSeparated( const C& c, char_type separator )
6152  {
6153  Clear();
6154  return c.ToSeparated( *this, separator );
6155  }
6156 
6173  template <class C, class AF>
6174  IsoString& ToSeparated( const C& c, char_type separator, AF append )
6175  {
6176  Clear();
6177  return c.ToSeparated( *this, separator, append );
6178  }
6179 
6189  template <class C>
6190  IsoString& ToSeparated( const C& c, const IsoString& separator )
6191  {
6192  Clear();
6193  return c.ToSeparated( *this, separator );
6194  }
6195 
6212  template <class C, class AF>
6213  IsoString& ToSeparated( const C& c, const IsoString& separator, AF append )
6214  {
6215  Clear();
6216  return c.ToSeparated( *this, separator, append );
6217  }
6218 
6228  template <class C>
6229  IsoString& ToSeparated( const C& c, const_c_string separator )
6230  {
6231  return ToSeparated( c, IsoString( separator ) );
6232  }
6233 
6250  template <class C, class AF>
6251  IsoString& ToSeparated( const C& c, const_c_string separator, AF append )
6252  {
6253  return ToSeparated( c, IsoString( separator ), append );
6254  }
6255 
6265  template <class C>
6267  {
6268  return ToSeparated( c, IsoCharTraits::Comma() );
6269  }
6270 
6280  template <class C>
6282  {
6283  return ToSeparated( c, IsoCharTraits::Colon() );
6284  }
6285 
6295  template <class C>
6297  {
6298  return ToSeparated( c, IsoCharTraits::Blank() );
6299  }
6300 
6310  template <class C>
6311  IsoString& ToTabSeparated( const C& c )
6312  {
6313  return ToSeparated( c, IsoCharTraits::Tab() );
6314  }
6315 
6325  template <class C>
6327  {
6328  return ToSeparated( c, IsoCharTraits::LF() );
6329  }
6330 
6340  template <class C>
6342  {
6343  return ToSeparated( c, IsoCharTraits::Null() );
6344  }
6345 
6354  template <class C>
6355  IsoString& ToHyphenated( const C& c )
6356  {
6357  return ToSeparated( c, IsoCharTraits::Hyphen() );
6358  }
6359 
6360  // -------------------------------------------------------------------------
6361 
6377 
6385  {
6386  return IsoString( *this ).ToEncodedHTMLSpecialChars();
6387  }
6388 
6406 
6415  {
6416  return IsoString( *this ).ToDecodedHTMLSpecialChars();
6417  }
6418 
6430  static IsoString ToURLEncoded( const void* data, size_type length );
6431 
6444  template <class C>
6445  static IsoString ToURLEncoded( const C& c )
6446  {
6447  return ToURLEncoded( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
6448  }
6449 
6460 
6468  {
6469  return IsoString( *this ).ToURLEncoded();
6470  }
6471 
6483  static ByteArray FromURLEncoded( const void* data, size_type length );
6484 
6492  template <class C>
6493  static ByteArray FromURLEncoded( const C& c )
6494  {
6495  return FromURLEncoded( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
6496  }
6497 
6510  {
6511  return FromURLEncoded( Begin(), Length() );
6512  }
6513 
6525  static IsoString ToURLDecoded( const void* data, size_type length );
6526 
6533  template <class C>
6534  static IsoString ToURLDecoded( const C& c )
6535  {
6536  return ToURLDecoded( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
6537  }
6538 
6549 
6557  {
6558  return IsoString( *this ).ToURLDecoded();
6559  }
6560 
6561  // -------------------------------------------------------------------------
6562 
6563 #ifdef __PCL_QT_INTERFACE
6564 
6565  operator QString() const
6566  {
6567  return QString( c_str() );
6568  }
6569 
6570  operator QAnyStringView() const
6571  {
6572  return QAnyStringView( c_str() );
6573  }
6574 
6575  operator QByteArray() const
6576  {
6577  return QByteArray( c_str() );
6578  }
6579 
6580  operator QDate() const
6581  {
6582  return QDate::fromString( c_str(), PCL_QDATE_FMT_STR );
6583  }
6584 
6585  operator QDateTime() const
6586  {
6587  return QDateTime::fromString( c_str(), PCL_QDATETIME_FMT_STR );
6588  }
6589 
6590 #endif
6591 
6604  {
6605  va_list paramList;
6606  va_start( paramList, fmt );
6607 
6608  (void)VFormat( fmt, paramList );
6609 
6610  va_end( paramList );
6611  return *this;
6612  }
6613 
6626  {
6627  va_list paramList;
6628  va_start( paramList, fmt );
6629 
6630  (void)AppendVFormat( fmt, paramList );
6631 
6632  va_end( paramList );
6633  return *this;
6634  }
6635 
6648  int VFormat( const_c_string fmt, va_list paramList );
6649 
6662  int AppendVFormat( const_c_string fmt, va_list paramList );
6663 
6664  // -------------------------------------------------------------------------
6665 
6676  {
6677  ustring_base s;
6678  s.SetLength( Length() );
6679  uchar_iterator p = s.Begin();
6680  for ( const_iterator i = m_data->string; i < m_data->end; ++p, ++i )
6681  *p = uchar_type( *i );
6682  return s;
6683  }
6684 
6692  ustring_base UTF8ToUTF16( size_type i = 0, size_type n = maxPos ) const; // implemented inline after String
6693 
6710 
6711 #ifdef __PCL_QT_INTERFACE
6712 
6713  QString ToQString() const
6714  {
6715  return operator QString();
6716  }
6717 
6718  QByteArray ToQByteArray() const
6719  {
6720  return operator QByteArray();
6721  }
6722 
6723  QDate ToQDate() const
6724  {
6725  return operator QDate();
6726  }
6727 
6728  QDateTime ToQDateTime() const
6729  {
6730  return operator QDateTime();
6731  }
6732 
6733 #endif
6734 
6745  bool ToBool() const;
6746 
6761  bool TryToBool( bool& value ) const noexcept;
6762 
6776  float ToFloat() const;
6777 
6792  bool TryToFloat( float& value ) const noexcept;
6793 
6817  double ToDouble() const;
6818 
6833  bool TryToDouble( double& value ) const noexcept;
6834 
6852  long ToInt() const
6853  {
6854  return ToInt( 0 );
6855  }
6856 
6880  bool TryToInt( int& value ) const noexcept
6881  {
6882  return TryToInt( value, 0 );
6883  }
6884 
6911  long ToInt( int base ) const;
6912 
6930  bool TryToInt( int& value, int base ) const noexcept;
6931 
6949  unsigned long ToUInt() const
6950  {
6951  return ToUInt( 0 );
6952  }
6953 
6977  bool TryToUInt( unsigned& value ) const noexcept
6978  {
6979  return TryToUInt( value, 0 );
6980  }
6981 
6998  unsigned long ToUInt( int base ) const;
6999 
7017  bool TryToUInt( unsigned& value, int base ) const noexcept;
7018 
7033  long long ToInt64() const
7034  {
7035  return ToInt64( 0 );
7036  }
7037 
7062  bool TryToInt64( long long& value ) const noexcept
7063  {
7064  return TryToInt64( value, 0 );
7065  }
7066 
7081  long long ToInt64( int base ) const;
7082 
7100  bool TryToInt64( long long& value, int base ) const noexcept;
7101 
7116  unsigned long long ToUInt64() const
7117  {
7118  return ToUInt64( 0 );
7119  }
7120 
7145  bool TryToUInt64( unsigned long long& value ) const noexcept
7146  {
7147  return TryToUInt64( value, 0 );
7148  }
7149 
7164  unsigned long long ToUInt64( int base ) const;
7165 
7183  bool TryToUInt64( unsigned long long& value, int base ) const noexcept;
7184 
7216  Array<float> ParseListOfFloat( char separator = ',', size_type maxCount = ~size_type( 0 ) ) const;
7217 
7249  Array<double> ParseListOfDouble( char separator = ',', size_type maxCount = ~size_type( 0 ) ) const;
7250 
7251 #ifndef __PCL_NO_STRING_VECTOR
7252 
7260  GenericVector<float> ParseListOfFloatAsVector( char separator = ',', int maxCount = int_max ) const;
7261 
7269  GenericVector<double> ParseListOfDoubleAsVector( char separator = ',', int maxCount = int_max ) const;
7270 
7271 #endif // !__PCL_NO_STRING_VECTOR
7272 
7300  double SexagesimalToDouble( const IsoString& separator = ':' ) const
7301  {
7302  int sign, s1, s2; double s3;
7303  ParseSexagesimal( sign, s1, s2, s3, separator );
7304  return sign*(s1 + (s2 + s3/60)/60);
7305  }
7306 
7307  double SexagesimalToDouble( char separator ) const
7308  {
7309  return SexagesimalToDouble( IsoString( separator ) );
7310  }
7311 
7312  double SexagesimalToDouble( const ustring_base& separator ) const
7313  {
7314  return SexagesimalToDouble( IsoString( separator ) );
7315  }
7316 
7330  double SexagesimalToDouble( const Array<char_type>& separators ) const
7331  {
7332  int sign, s1, s2; double s3;
7333  ParseSexagesimal( sign, s1, s2, s3, separators );
7334  return sign*(s1 + (s2 + s3/60)/60);
7335  }
7336 
7354  bool TrySexagesimalToDouble( double& value, const IsoString& separator = ':' ) const noexcept
7355  {
7356  int sign, s1, s2; double s3;
7357  if ( TryParseSexagesimal( sign, s1, s2, s3, separator ) )
7358  {
7359  value = sign*(s1 + (s2 + s3/60)/60);
7360  return true;
7361  }
7362  return false;
7363  }
7364 
7365  bool TrySexagesimalToDouble( double& value, char separator ) const noexcept
7366  {
7367  return TrySexagesimalToDouble( value, IsoString( separator ) );
7368  }
7369 
7370  bool TrySexagesimalToDouble( double& value, const ustring_base& separator ) const noexcept
7371  {
7372  return TrySexagesimalToDouble( value, IsoString( separator ) );
7373  }
7374 
7387  bool TrySexagesimalToDouble( double& value, const Array<char_type>& separators ) const noexcept
7388  {
7389  int sign, s1, s2; double s3;
7390  if ( TryParseSexagesimal( sign, s1, s2, s3, separators ) )
7391  {
7392  value = sign*(s1 + (s2 + s3/60)/60);
7393  return true;
7394  }
7395  return false;
7396  }
7397 
7424  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const IsoString& separator = ':' ) const;
7425 
7426  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, char separator ) const
7427  {
7428  ParseSexagesimal( sign, s1, s2, s3, IsoString( separator ) );
7429  }
7430 
7431  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const ustring_base& separator ) const
7432  {
7433  ParseSexagesimal( sign, s1, s2, s3, IsoString( separator ) );
7434  }
7435 
7450  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const Array<char_type>& separators ) const;
7451 
7466  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const IsoString& separator = ':' ) const noexcept;
7467 
7468  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, char separator ) const noexcept
7469  {
7470  return TryParseSexagesimal( sign, s1, s2, s3, IsoString( separator ) );
7471  }
7472 
7473  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const ustring_base& separator ) const noexcept
7474  {
7475  return TryParseSexagesimal( sign, s1, s2, s3, IsoString( separator ) );
7476  }
7477 
7491  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const Array<char_type>& separators ) const noexcept;
7492 
7517  static IsoString ToSexagesimal( int sign, double s1, double s2, double s3,
7519 
7531  {
7532  return ToSexagesimal( (d < 0) ? -1 : +1, Abs( d ), 0, 0, options );
7533  }
7534 
7558  void ParseISO8601DateTime( int& year, int& month, int& day, double& dayf, double& tz ) const;
7559 
7573  bool TryParseISO8601DateTime( int& year, int& month, int& day, double& dayf, double& tz ) const noexcept;
7574 
7598  static IsoString ToISO8601DateTime( int year, int month, int day, double dayf, double tz = 0,
7600 
7612 
7624 
7632  static IsoString ToHex( const void* data, size_type length );
7633 
7646  template <class C>
7647  static IsoString ToHex( const C& c )
7648  {
7649  return ToHex( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
7650  }
7651 
7663  static IsoString ToBase64( const void* data, size_type length );
7664 
7678  template <class C>
7679  static IsoString ToBase64( const C& c )
7680  {
7681  return ToBase64( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
7682  }
7683 
7698  static IsoString ToBase64URL( const void* data, size_type length )
7699  {
7700  IsoString b64 = ToBase64( data, length );
7701  b64.DeleteChar( '=' );
7702  for ( char_type& c : b64 )
7703  if ( c == '+' )
7704  c = '-';
7705  else if ( c == '/' )
7706  c = '_';
7707  return b64;
7708  }
7709 
7721  template <class C>
7722  static IsoString ToBase64URL( const C& c )
7723  {
7724  return ToBase64URL( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
7725  }
7726 
7735  {
7736  return ByteArray( Begin(), End() );
7737  }
7738 
7752 
7766 
7777  {
7778  IsoString b64 = *this;
7779  for ( char_type& c : b64 )
7780  if ( c == '-' )
7781  c = '+';
7782  else if ( c == '_' )
7783  c = '/';
7784  return b64.FromBase64();
7785  }
7786 
7793  static IsoString Random( size_type n, RandomizationOptions options = RandomizationOption::Default );
7794 
7806  static IsoString UUID();
7807 };
7808 
7809 // ----------------------------------------------------------------------------
7810 
7820 {
7821  IsoString s( s1 );
7822  s.Append( s2 );
7823  return s;
7824 }
7825 
7832 {
7833  s1.Append( s2 );
7834  return IsoString( std::move( s1 ) );
7835 }
7836 
7843 {
7844  s1.Append( s2 );
7845  return std::move( s1 );
7846 }
7847 
7854 {
7855  s2.Prepend( s1 );
7856  return IsoString( std::move( s2 ) );
7857 }
7858 
7865 {
7866  s2.Prepend( s1 );
7867  return std::move( s2 );
7868 }
7869 
7876 {
7877  s1.Append( s2 );
7878  return IsoString( std::move( s1 ) );
7879 }
7880 
7887 {
7888  s1.Append( s2 );
7889  return std::move( s1 );
7890 }
7891 
7898 {
7899  s1.Append( s2 );
7900  return IsoString( std::move( s1 ) );
7901 }
7902 
7909 {
7910  s1.Append( s2 );
7911  return std::move( s1 );
7912 }
7913 
7914 // ----------------------------------------------------------------------------
7915 
7922 {
7923  IsoString s = s1;
7924  s.Append( t2 );
7925  return s;
7926 }
7927 
7934 {
7935  s1.Append( t2 );
7936  return IsoString( std::move( s1 ) );
7937 }
7938 
7945 {
7946  s1.Append( t2 );
7947  return std::move( s1 );
7948 }
7949 
7956 {
7957  IsoString s = s2;
7958  s.Prepend( t1 );
7959  return s;
7960 }
7961 
7968 {
7969  s2.Prepend( t1 );
7970  return IsoString( std::move( s2 ) );
7971 }
7972 
7979 {
7980  s2.Prepend( t1 );
7981  return std::move( s2 );
7982 }
7983 
7984 // ----------------------------------------------------------------------------
7985 
7992 {
7993  IsoString s = s1;
7994  s.Append( c2 );
7995  return s;
7996 }
7997 
8004 {
8005  s1.Append( c2 );
8006  return IsoString( std::move( s1 ) );
8007 }
8008 
8015 {
8016  s1.Append( c2 );
8017  return std::move( s1 );
8018 }
8019 
8026 {
8027  IsoString s = s2;
8028  s.Prepend( c1 );
8029  return s;
8030 }
8031 
8038 {
8039  s2.Prepend( c1 );
8040  return IsoString( std::move( s2 ) );
8041 }
8042 
8049 {
8050  s2.Prepend( c1 );
8051  return std::move( s2 );
8052 }
8053 
8054 // ----------------------------------------------------------------------------
8055 
8062 {
8063  s1.Append( s2 );
8064  return s1;
8065 }
8066 
8073 {
8074  s1.Append( s2 );
8075  return s1;
8076 }
8077 
8084 {
8085  s1.Append( t2 );
8086  return s1;
8087 }
8088 
8095 {
8096  s1.Append( t2 );
8097  return s1;
8098 }
8099 
8106 {
8107  s1.Append( c2 );
8108  return s1;
8109 }
8110 
8117 {
8118  s1.Append( c2 );
8119  return s1;
8120 }
8121 
8122 // ----------------------------------------------------------------------------
8123 
8124 #ifndef __PCL_NO_STRING_OSTREAM
8125 
8126 inline std::ostream& operator <<( std::ostream& o, const IsoString& s )
8127 {
8128  return o << s.c_str();
8129 }
8130 
8131 #endif
8132 
8133 // ----------------------------------------------------------------------------
8134 
8145 class PCL_CLASS String : public GenericString<char16_type, CharTraits, PCL_STRING_ALLOCATOR>
8146 {
8147 public:
8148 
8153 
8158 
8163 
8168 
8173 
8178 
8183 
8188 
8193 
8198 
8199  /*
8200  * Null-terminated UTF-16 string - C++11 compatibility.
8201  */
8202  using c16_string = char16_t*;
8203 
8204  /*
8205  * Immutable null-terminated UTF-16 string - C++11 compatibility.
8206  */
8207  using const_c16_string = const char16_t*;
8208 
8213 
8218 
8223 
8228 
8237 
8242 
8247 
8252 
8257 
8262 
8267 
8268  // -------------------------------------------------------------------------
8269 
8273  String() = default;
8274 
8279  String( const string_base& s )
8280  : string_base( s )
8281  {
8282  }
8283 
8287  String( const String& ) = default;
8288 
8294  : string_base( std::move( s ) )
8295  {
8296  }
8297 
8301  String( String&& ) = default;
8302 
8307  String( const string8_base& s )
8308  {
8309  Assign( s );
8310  }
8311 
8316  : string_base( t )
8317  {
8318  }
8319 
8325  : string_base( t, i, n )
8326  {
8327  }
8328 
8333  : string_base( c, n )
8334  {
8335  }
8336 
8342  : string_base( i, j )
8343  {
8344  }
8345 
8354  String( std::initializer_list<char_type> l )
8355  : String( l.begin(), l.end() )
8356  {
8357  }
8358 
8363  String( const char16_t* t )
8364  : string_base( reinterpret_cast<const_iterator>( t ) )
8365  {
8366  }
8367 
8373  String( const char16_t* t, size_type i, size_type n )
8374  : string_base( reinterpret_cast<const_iterator>( t ), i, n )
8375  {
8376  }
8377 
8381  String( char16_t c, size_type n )
8382  : string_base( char_type( c ), n )
8383  {
8384  }
8385 
8390  String( const wchar_t* t )
8391  {
8392  Assign( t );
8393  }
8394 
8400  String( const wchar_t* t, size_type i, size_type n )
8401  {
8402  Assign( t, i, n );
8403  }
8404 
8408  String( wchar_t c, size_type n )
8409  : string_base( char_type( c ), n )
8410  {
8411  }
8412 
8418  {
8419  Assign( t );
8420  }
8421 
8428  {
8429  Assign( t, i, n );
8430  }
8431 
8437  {
8438  Assign( i, j );
8439  }
8440 
8449  String( std::initializer_list<char8_type> l )
8450  : String( l.begin(), l.end() )
8451  {
8452  }
8453 
8459  : string_base( char_type( c ), n )
8460  {
8461  }
8462 
8466  explicit
8467  String( bool x )
8468  {
8469  Assign( x ? "true" : "false" );
8470  }
8471 
8476  explicit
8477  String( short x )
8478  {
8479  (void)Format( L"%hd", x );
8480  }
8481 
8486  explicit
8487  String( unsigned short x )
8488  {
8489  (void)Format( L"%hu", x );
8490  }
8491 
8496  explicit
8497  String( int x )
8498  {
8499  (void)Format( L"%i", x );
8500  }
8501 
8506  explicit
8507  String( unsigned int x )
8508  {
8509  (void)Format( L"%u", x );
8510  }
8511 
8516  explicit
8517  String( long x )
8518  {
8519  (void)Format( L"%ld", x );
8520  }
8521 
8526  explicit
8527  String( unsigned long x )
8528  {
8529  (void)Format( L"%lu", x );
8530  }
8531 
8536  explicit
8537  String( long long x )
8538  {
8539  (void)Format( L"%lli", x );
8540  }
8541 
8546  explicit
8547  String( unsigned long long x )
8548  {
8549  (void)Format( L"%llu", x );
8550  }
8551 
8556  explicit
8557  String( float x )
8558  {
8559  (void)Format( L"%.7g", x );
8560  }
8561 
8566  explicit
8567  String( double x )
8568  {
8569  (void)Format( L"%.16g", x );
8570  }
8571 
8576  explicit
8577  String( long double x )
8578  {
8579 #ifdef _MSC_VER
8580  (void)Format( L"%.16Lg", x );
8581 #else
8582  (void)Format( L"%.18Lg", x );
8583 #endif
8584  }
8585 
8586 #ifndef __PCL_NO_STRING_COMPLEX
8587 
8591  explicit
8593  {
8594  (void)Format( L"{%.7g,%.7g}", x.Real(), x.Imag() );
8595  }
8596 
8600  explicit
8602  {
8603  (void)Format( L"{%.16g,%.16g}", x.Real(), x.Imag() );
8604  }
8605 
8609  explicit
8611  {
8612 #ifdef _MSC_VER
8613  (void)Format( L"{%.16Lg,%.16Lg}", x.Real(), x.Imag() );
8614 #else
8615  (void)Format( L"{%.18Lg,%.18Lg}", x.Real(), x.Imag() );
8616 #endif
8617  }
8618 
8619 #endif // !__PCL_NO_STRING_COMPLEX
8620 
8621 #ifdef __PCL_QT_INTERFACE
8622 
8623  explicit
8624  String( const QString& qs )
8625  : string_base( qs.isEmpty() ? iterator( nullptr ) : iterator( PCL_GET_CHAR16PTR_FROM_QSTRING( qs ) ) )
8626  {
8627  }
8628 
8629  explicit
8630  String( const QDate& qd )
8631  : string_base( iterator( PCL_GET_CHAR16PTR_FROM_QSTRING( qd.toString( PCL_QDATE_FMT_STR ) ) ) )
8632  {
8633  }
8634 
8635  explicit
8636  String( const QDateTime& qdt )
8637  : string_base( iterator( PCL_GET_CHAR16PTR_FROM_QSTRING( qdt.toString( PCL_QDATETIME_FMT_STR ) ) ) )
8638  {
8639  }
8640 
8641 #endif
8642 
8643  // -------------------------------------------------------------------------
8644 
8648  String& operator =( const String& s )
8649  {
8650  string_base::Assign( s );
8651  return *this;
8652  }
8653 
8657  String& operator =( String&& s )
8658  {
8659  string_base::Transfer( s );
8660  return *this;
8661  }
8662 
8667  String& operator =( const string_base& s )
8668  {
8669  string_base::Assign( s );
8670  return *this;
8671  }
8672 
8677  String& operator =( string_base&& s )
8678  {
8679  string_base::Transfer( s );
8680  return *this;
8681  }
8682 
8687  String& operator =( const string8_base& s )
8688  {
8689  Assign( s );
8690  return *this;
8691  }
8692 
8697  String& operator =( const_iterator t )
8698  {
8699  string_base::Assign( t );
8700  return *this;
8701  }
8702 
8707  String& operator =( char_type c )
8708  {
8709  string_base::Assign( c );
8710  return *this;
8711  }
8712 
8717  String& operator =( const char16_t* t )
8718  {
8719  string_base::Assign( reinterpret_cast<const_iterator>( t ) );
8720  return *this;
8721  }
8722 
8727  String& operator =( char16_t c )
8728  {
8729  string_base::Assign( char_type( c ) );
8730  return *this;
8731  }
8732 
8737  String& operator =( const wchar_t* t )
8738  {
8739  Assign( t );
8740  return *this;
8741  }
8742 
8747  String& operator =( wchar_t c )
8748  {
8749  Assign( c );
8750  return *this;
8751  }
8752 
8757  String& operator =( const_c_string8 t )
8758  {
8759  Assign( t );
8760  return *this;
8761  }
8762 
8767  String& operator =( char8_type c )
8768  {
8769  Assign( c );
8770  return *this;
8771  }
8772 
8773 #ifdef __PCL_QT_INTERFACE
8774 
8775  String& operator =( const QString& qs )
8776  {
8777  if ( qs.isEmpty() )
8778  Clear();
8779  else
8780  string_base::Assign( PCL_GET_CHAR16PTR_FROM_QSTRING( qs ) );
8781  return *this;
8782  }
8783 
8784  String& operator =( const QDate& qd )
8785  {
8786  string_base::Assign( PCL_GET_CHAR16PTR_FROM_QSTRING( qd.toString( PCL_QDATE_FMT_STR ) ) );
8787  return *this;
8788  }
8789 
8790  String& operator =( const QDateTime& qdt )
8791  {
8792  string_base::Assign( PCL_GET_CHAR16PTR_FROM_QSTRING( qdt.toString( PCL_QDATETIME_FMT_STR ) ) );
8793  return *this;
8794  }
8795 
8796 #endif
8797 
8798  // -------------------------------------------------------------------------
8799 
8803  void Assign( const String& s )
8804  {
8805  string_base::Assign( s );
8806  }
8807 
8812  void Assign( const String& s, size_type i, size_type n )
8813  {
8814  string_base::Assign( s, i, n );
8815  }
8816 
8821  {
8822  string_base::Assign( t );
8823  }
8824 
8830  {
8831  string_base::Assign( i, j );
8832  }
8833 
8840  void Assign( std::initializer_list<char_type> l )
8841  {
8842  Assign( l.begin(), l.end() );
8843  }
8844 
8851  {
8852  string_base::Assign( t, i, n );
8853  }
8854 
8858  void Assign( char_type c, size_type n = 1 )
8859  {
8860  string_base::Assign( c, n );
8861  }
8862 
8866  void Assign( const char16_t* t )
8867  {
8868  string_base::Assign( reinterpret_cast<const_iterator>( t ) );
8869  }
8870 
8876  void Assign( const char16_t* t, size_type i, size_type n )
8877  {
8878  string_base::Assign( reinterpret_cast<const_iterator>( t ), i, n );
8879  }
8880 
8884  void Assign( char16_t c, size_type n = 1 )
8885  {
8886  string_base::Assign( char_type( c ), n );
8887  }
8888 
8892  void Assign( const wchar_t* t );
8893 
8899  void Assign( const wchar_t* t, size_type i, size_type n );
8900 
8904  void Assign( wchar_t c, size_type n = 1 )
8905  {
8906  string_base::Assign( char_type( c ), n );
8907  }
8908 
8912  void Assign( const string8_base& s )
8913  {
8914  size_type n = s.Length();
8915  if ( n > 0 )
8916  {
8917  MaybeReallocate( n );
8918  const_char8_iterator t = s.Begin();
8919  PCL_IVDEP
8920  for ( iterator i = m_data->string; i < m_data->end; ++i, ++t )
8921  *i = char_type( uint8( *t ) );
8922  }
8923  else
8924  Clear();
8925  }
8926 
8932  {
8933  size_type n = char8_traits::Length( t );
8934  if ( n > 0 )
8935  {
8936  MaybeReallocate( n );
8937  PCL_IVDEP
8938  for ( iterator i = m_data->string; i < m_data->end; ++i, ++t )
8939  *i = char_type( uint8( *t ) );
8940  }
8941  else
8942  Clear();
8943  }
8944 
8951  {
8952  size_type len = char8_traits::Length( t );
8953  if ( i < len )
8954  {
8955  n = pcl::Min( n, len-i );
8956  MaybeReallocate( n );
8957  t += i;
8958  PCL_IVDEP
8959  for ( iterator i = m_data->string; i < m_data->end; ++i, ++t )
8960  *i = char_type( uint8( *t ) );
8961  }
8962  else
8963  Clear();
8964  }
8965 
8971  {
8972  if ( p < q )
8973  {
8974  MaybeReallocate( q - p );
8975  PCL_IVDEP
8976  for ( iterator i = m_data->string; i < m_data->end; ++i, ++p )
8977  *i = char_type( uint8( *p ) );
8978  }
8979  else
8980  Clear();
8981  }
8982 
8990  void Assign( std::initializer_list<char8_type> l )
8991  {
8992  Assign( l.begin(), l.end() );
8993  }
8994 
8998  void Assign( char8_type c, size_type n = 1 )
8999  {
9000  string_base::Assign( char_type( c ), n );
9001  }
9002 
9003  // -------------------------------------------------------------------------
9004 
9005  void Insert( size_type i, const String& s )
9006  {
9007  string_base::Insert( i, s );
9008  }
9009 
9010  void Insert( size_type i, const_iterator p, const_iterator q )
9011  {
9012  string_base::Insert( i, p, q );
9013  }
9014 
9015  void Insert( size_type i, const_iterator t )
9016  {
9017  string_base::Insert( i, t );
9018  }
9019 
9020  void Insert( size_type i, const_iterator t, size_type n )
9021  {
9022  string_base::Insert( i, t, n );
9023  }
9024 
9025  void Insert( size_type i, char_type c, size_type n = 1 )
9026  {
9027  string_base::Insert( i, c, n );
9028  }
9029 
9030  void Insert( size_type i, const char16_t* t )
9031  {
9032  string_base::Insert( i, reinterpret_cast<const_iterator>( t ) );
9033  }
9034 
9035  void Insert( size_type i, char16_t c, size_type n = 1 )
9036  {
9037  string_base::Insert( i, String( c, n ) );
9038  }
9039 
9040  void Insert( size_type i, const wchar_t* t )
9041  {
9042 #ifdef __PCL_WINDOWS
9043  string_base::Insert( i, reinterpret_cast<const_iterator>( t ) );
9044 #else
9045  string_base::Insert( i, String( t ) );
9046 #endif
9047  }
9048 
9049  void Insert( size_type i, wchar_t c, size_type n = 1 )
9050  {
9051  string_base::Insert( i, String( c, n ) );
9052  }
9053 
9054  void Insert( size_type i, const string8_base& s, size_type n )
9055  {
9056  n = pcl::Min( n, s.Length() );
9057  if ( n > 0 )
9058  {
9059  UninitializedGrow( i, n ); // -> 0 <= i <= len
9060  const_char8_iterator t = s.Begin();
9061  PCL_IVDEP
9062  for ( iterator p = m_data->string+i, q = p+n; p < q; ++p, ++t )
9063  *p = char_type( uint8( *t ) );
9064  }
9065  }
9066 
9067  void Insert( size_type i, const string8_base& s )
9068  {
9069  size_type n = s.Length();
9070  if ( n > 0 )
9071  {
9072  UninitializedGrow( i, n ); // -> 0 <= i <= len
9073  const_char8_iterator t = s.Begin();
9074  PCL_IVDEP
9075  for ( iterator p = m_data->string+i, q = p+n; p < q; ++p, ++t )
9076  *p = char_type( uint8( *t ) );
9077  }
9078  }
9079 
9080  void Insert( size_type i, const_c_string8 t )
9081  {
9082  size_type n = char8_traits::Length( t );
9083  if ( n > 0 )
9084  {
9085  UninitializedGrow( i, n ); // -> 0 <= i <= len
9086  PCL_IVDEP
9087  for ( iterator p = m_data->string+i, q = p+n; p < q; ++p, ++t )
9088  *p = char_type( uint8( *t ) );
9089  }
9090  }
9091 
9092  void Insert( size_type i, const_c_string8 t, size_type n )
9093  {
9094  n = pcl::Min( n, char8_traits::Length( t ) );
9095  if ( n > 0 )
9096  {
9097  UninitializedGrow( i, n ); // -> 0 <= i <= len
9098  PCL_IVDEP
9099  for ( iterator p = m_data->string+i, q = p+n; p < q; ++p, ++t )
9100  *p = char_type( uint8( *t ) );
9101  }
9102  }
9103 
9104  void Insert( size_type i, const_char8_iterator p, const_char8_iterator q )
9105  {
9106  if ( p < q )
9107  {
9108  size_type n = q - p;
9109  UninitializedGrow( i, n ); // -> 0 <= i <= len
9110  PCL_IVDEP
9111  for ( iterator r = m_data->string+i, s = r+n; r < s; ++r, ++p )
9112  *r = char_type( uint8( *p ) );
9113  }
9114  }
9115 
9116  void Insert( size_type i, char8_type c, size_type n = 1 )
9117  {
9118  string_base::Insert( i, char_type( c ), n );
9119  }
9120 
9121  // -------------------------------------------------------------------------
9122 
9123  void Append( const String& s )
9124  {
9125  string_base::Append( s );
9126  }
9127 
9128  String& operator +=( const String& s )
9129  {
9130  Append( s );
9131  return *this;
9132  }
9133 
9134  void Append( const_iterator i, const_iterator j )
9135  {
9136  string_base::Append( i, j );
9137  }
9138 
9139  void Append( const_iterator t )
9140  {
9141  string_base::Append( t );
9142  }
9143 
9144  String& operator +=( const_iterator t )
9145  {
9146  Append( t );
9147  return *this;
9148  }
9149 
9150  void Append( const_iterator t, size_type n )
9151  {
9152  string_base::Append( t, n );
9153  }
9154 
9155  void Append( char_type c, size_type n = 1 )
9156  {
9157  string_base::Append( c, n );
9158  }
9159 
9160  String& operator +=( char_type c )
9161  {
9162  Append( c );
9163  return *this;
9164  }
9165 
9166  void Append( const char16_t* t )
9167  {
9168  string_base::Append( reinterpret_cast<const_iterator>( t ) );
9169  }
9170 
9171  String& operator +=( const char16_t* t )
9172  {
9173  Append( t );
9174  return *this;
9175  }
9176 
9177  void Append( char16_t c, size_type n = 1 )
9178  {
9179  string_base::Append( char_type( c ), n );
9180  }
9181 
9182  String& operator +=( char16_t c )
9183  {
9184  Append( c );
9185  return *this;
9186  }
9187 
9188  void Append( const wchar_t* t )
9189  {
9190 #ifdef __PCL_WINDOWS
9191  string_base::Append( reinterpret_cast<const_iterator>( t ) );
9192 #else
9193  string_base::Append( String( t ) );
9194 #endif
9195  }
9196 
9197  String& operator +=( const wchar_t* t )
9198  {
9199  Append( t );
9200  return *this;
9201  }
9202 
9203  void Append( wchar_t c, size_type n = 1 )
9204  {
9205  string_base::Append( char_type( c ), n );
9206  }
9207 
9208  String& operator +=( wchar_t c )
9209  {
9210  Append( c );
9211  return *this;
9212  }
9213 
9214  void Append( const string8_base& s )
9215  {
9216  Insert( maxPos, s );
9217  }
9218 
9219  String& operator +=( const string8_base& s )
9220  {
9221  Append( s );
9222  return *this;
9223  }
9224 
9225  void Append( const string8_base& s, size_type n )
9226  {
9227  Insert( maxPos, s, n );
9228  }
9229 
9230  void Append( const_c_string8 t )
9231  {
9232  Insert( maxPos, t );
9233  }
9234 
9235  String& operator +=( const_c_string8 t )
9236  {
9237  Append( t );
9238  return *this;
9239  }
9240 
9241  void Append( const_c_string8 t, size_type n )
9242  {
9243  Insert( maxPos, t, n );
9244  }
9245 
9246  void Append( const_char8_iterator p, const_char8_iterator q )
9247  {
9248  Insert( maxPos, p, q );
9249  }
9250 
9251  void Append( char8_type c, size_type n = 1 )
9252  {
9253  string_base::Append( char_type( c ), n );
9254  }
9255 
9256  String& operator +=( char8_type c )
9257  {
9258  Append( c );
9259  return *this;
9260  }
9261 
9262  void Add( const String& s )
9263  {
9264  Append( s );
9265  }
9266 
9267  void Add( const_iterator i, const_iterator j )
9268  {
9269  Append( i, j );
9270  }
9271 
9272  void Add( const_iterator t )
9273  {
9274  Append( t );
9275  }
9276 
9277  void Add( const_iterator t, size_type n )
9278  {
9279  Append( t, n );
9280  }
9281 
9282  void Add( char_type c, size_type n = 1 )
9283  {
9284  Append( c, n );
9285  }
9286 
9287  void Add( const char16_t* t )
9288  {
9289  Append( t );
9290  }
9291 
9292  void Add( char16_t c, size_type n = 1 )
9293  {
9294  Append( c, n );
9295  }
9296 
9297  void Add( const wchar_t* t )
9298  {
9299  Append( t );
9300  }
9301 
9302  void Add( wchar_t c, size_type n = 1 )
9303  {
9304  Append( c, n );
9305  }
9306 
9307  void Add( const string8_base& s )
9308  {
9309  Append( s );
9310  }
9311 
9312  void Add( const string8_base& s, size_type n )
9313  {
9314  Append( s, n );
9315  }
9316 
9317  void Add( const_c_string8 t )
9318  {
9319  Append( t );
9320  }
9321 
9322  void Add( const_c_string8 t, size_type n )
9323  {
9324  Append( t, n );
9325  }
9326 
9327  void Add( const_char8_iterator p, const_char8_iterator q )
9328  {
9329  Append( p, q );
9330  }
9331 
9332  void Add( char8_type c, size_type n = 1 )
9333  {
9334  Append( c, n );
9335  }
9336 
9337  // -------------------------------------------------------------------------
9338 
9339  void Prepend( const String& s )
9340  {
9341  string_base::Prepend( s );
9342  }
9343 
9344  String& operator -=( const String& s )
9345  {
9346  Prepend( s );
9347  return *this;
9348  }
9349 
9350  void Prepend( const_iterator i, const_iterator j )
9351  {
9352  string_base::Prepend( i, j );
9353  }
9354 
9355  void Prepend( const_iterator t )
9356  {
9357  string_base::Prepend( t );
9358  }
9359 
9360  String& operator -=( const_iterator t )
9361  {
9362  Prepend( t );
9363  return *this;
9364  }
9365 
9366  void Prepend( const_iterator t, size_type n )
9367  {
9368  string_base::Prepend( t, n );
9369  }
9370 
9371  void Prepend( char_type c, size_type n = 1 )
9372  {
9373  string_base::Prepend( c, n );
9374  }
9375 
9376  String& operator -=( char_type c )
9377  {
9378  Prepend( c );
9379  return *this;
9380  }
9381 
9382  void Prepend( const char16_t* t )
9383  {
9384  string_base::Prepend( reinterpret_cast<const_iterator>( t ) );
9385  }
9386 
9387  String& operator -=( const char16_t* t )
9388  {
9389  Prepend( t );
9390  return *this;
9391  }
9392 
9393  void Prepend( char16_t c, size_type n = 1 )
9394  {
9395  string_base::Prepend( char_type( c ), n );
9396  }
9397 
9398  String& operator -=( char16_t c )
9399  {
9400  Prepend( c );
9401  return *this;
9402  }
9403 
9404  void Prepend( const wchar_t* t )
9405  {
9406 #ifdef __PCL_WINDOWS
9407  string_base::Prepend( reinterpret_cast<const_iterator>( t ) );
9408 #else
9409  string_base::Prepend( String( t ) );
9410 #endif
9411  }
9412 
9413  String& operator -=( const wchar_t* t )
9414  {
9415  Prepend( t );
9416  return *this;
9417  }
9418 
9419  void Prepend( wchar_t c, size_type n = 1 )
9420  {
9421  string_base::Prepend( char_type( c ), n );
9422  }
9423 
9424  String& operator -=( wchar_t c )
9425  {
9426  Prepend( c );
9427  return *this;
9428  }
9429 
9430  void Prepend( const string8_base& s )
9431  {
9432  Insert( 0, s );
9433  }
9434 
9435  String& operator -=( const string8_base& s )
9436  {
9437  Prepend( s );
9438  return *this;
9439  }
9440 
9441  void Prepend( const string8_base& s, size_type n )
9442  {
9443  Insert( 0, s, n );
9444  }
9445 
9446  void Prepend( const_c_string8 t )
9447  {
9448  Insert( 0, t );
9449  }
9450 
9451  String& operator -=( const_c_string8 t )
9452  {
9453  Prepend( t );
9454  return *this;
9455  }
9456 
9457  void Prepend( const_c_string8 t, size_type n )
9458  {
9459  Insert( 0, t, n );
9460  }
9461 
9462  void Prepend( const_char8_iterator p, const_char8_iterator q )
9463  {
9464  Insert( 0, p, q );
9465  }
9466 
9467  void Prepend( char8_type c, size_type n = 1 )
9468  {
9469  string_base::Prepend( String( c, n ) );
9470  }
9471 
9472  String& operator -=( char8_type c )
9473  {
9474  Prepend( c );
9475  return *this;
9476  }
9477 
9478  // -------------------------------------------------------------------------
9479 
9480  void Replace( size_type i, size_type n, const String& s )
9481  {
9482  string_base::Replace( i, n, s );
9483  }
9484 
9485  void Replace( size_type i, size_type n, const_iterator t )
9486  {
9487  string_base::Replace( i, n, t );
9488  }
9489 
9490  void Replace( size_type i, size_type n, char_type c, size_type nc = 1 )
9491  {
9492  string_base::Replace( i, n, c, nc );
9493  }
9494 
9495  void Replace( size_type i, size_type n, const char16_t* t )
9496  {
9497  string_base::Replace( i, n, reinterpret_cast<const_iterator>( t ) );
9498  }
9499 
9500  void Replace( size_type i, size_type n, char16_t c, size_type nc = 1 )
9501  {
9502  string_base::Replace( i, n, char_type( c ), nc );
9503  }
9504 
9505  void Replace( size_type i, size_type n, const wchar_t* t )
9506  {
9507 #ifdef __PCL_WINDOWS
9508  string_base::Replace( i, n, reinterpret_cast<const_iterator>( t ) );
9509 #else
9510  string_base::Replace( i, n, String( t ) );
9511 #endif
9512  }
9513 
9514  void Replace( size_type i, size_type n, wchar_t c, size_type nc = 1 )
9515  {
9516  string_base::Replace( i, n, char_type( c ), nc );
9517  }
9518 
9519  void Replace( size_type i, size_type n, const_c_string8 t )
9520  {
9521  if ( n > 0 )
9522  {
9523  size_type len = Length();
9524  if ( i < len )
9525  {
9526  n = pcl::Min( n, len-i );
9527  if ( n == len )
9528  Assign( t );
9529  else
9530  {
9531  size_type nt = char8_traits::Length( t );
9532  if ( nt > 0 )
9533  {
9534  if ( n < nt )
9535  UninitializedGrow( i, nt-n );
9536  else if ( nt < n )
9537  Delete( i, n-nt );
9538  else
9539  EnsureUnique();
9540 
9541  PCL_IVDEP
9542  for ( iterator p = m_data->string+i, q = p+nt; p < q; ++p, ++t )
9543  *p = char_type( *t );
9544  }
9545  else
9546  Delete( i, n );
9547  }
9548  }
9549  }
9550  }
9551 
9552  void Replace( size_type i, size_type n, char8_type c, size_type nc = 1 )
9553  {
9554  string_base::Replace( i, n, char_type( c ), nc );
9555  }
9556 
9557  // -------------------------------------------------------------------------
9558 
9559  void ReplaceChar( char_type c1, char_type c2, size_type i = 0, size_type n = maxPos )
9560  {
9561  string_base::ReplaceChar( c1, c2, i, n );
9562  }
9563 
9564  void ReplaceCharIC( char_type c1, char_type c2, size_type i = 0, size_type n = maxPos )
9565  {
9566  string_base::ReplaceCharIC( c1, c2, i, n );
9567  }
9568 
9569  void ReplaceChar( char16_t c1, char16_t c2, size_type i = 0, size_type n = maxPos )
9570  {
9571  string_base::ReplaceChar( char_type( c1 ), char_type( c2 ), i, n );
9572  }
9573 
9574  void ReplaceCharIC( char16_t c1, char16_t c2, size_type i = 0, size_type n = maxPos )
9575  {
9576  string_base::ReplaceCharIC( char_type( c1 ), char_type( c2 ), i, n );
9577  }
9578 
9579  void ReplaceChar( wchar_t c1, wchar_t c2, size_type i = 0, size_type n = maxPos )
9580  {
9581  string_base::ReplaceChar( char_type( c1 ), char_type( c2 ), i, n );
9582  }
9583 
9584  void ReplaceCharIC( wchar_t c1, wchar_t c2, size_type i = 0, size_type n = maxPos )
9585  {
9586  string_base::ReplaceCharIC( char_type( c1 ), char_type( c2 ), i, n );
9587  }
9588 
9589  void ReplaceChar( char8_type c1, char8_type c2, size_type i = 0, size_type n = maxPos )
9590  {
9591  string_base::ReplaceChar( char_type( c1 ), char_type( c2 ), i, n );
9592  }
9593 
9594  void ReplaceCharIC( char8_type c1, char8_type c2, size_type i = 0, size_type n = maxPos )
9595  {
9596  string_base::ReplaceCharIC( char_type( c1 ), char_type( c2 ), i, n );
9597  }
9598 
9599  // -------------------------------------------------------------------------
9600 
9601  void ReplaceString( const String& s1, const String& s2, size_type i = 0 )
9602  {
9603  string_base::ReplaceString( s1, s2, i );
9604  }
9605 
9606  void ReplaceStringIC( const String& s1, const String& s2, size_type i = 0 )
9607  {
9608  string_base::ReplaceStringIC( s1, s2, i );
9609  }
9610 
9611  void ReplaceString( const_iterator t1, const_iterator t2, size_type i = 0 )
9612  {
9613  string_base::ReplaceString( t1, t2, i );
9614  }
9615 
9616  void ReplaceStringIC( const_iterator t1, const_iterator t2, size_type i = 0 )
9617  {
9618  string_base::ReplaceStringIC( t1, t2, i );
9619  }
9620 
9621  void ReplaceString( const char16_t* t1, const char16_t* t2, size_type i = 0 )
9622  {
9623  string_base::ReplaceString( reinterpret_cast<const_iterator>( t1 ),
9624  reinterpret_cast<const_iterator>( t2 ), i );
9625  }
9626 
9627  void ReplaceStringIC( const char16_t* t1, const char16_t* t2, size_type i = 0 )
9628  {
9629  string_base::ReplaceStringIC( reinterpret_cast<const_iterator>( t1 ),
9630  reinterpret_cast<const_iterator>( t2 ), i );
9631  }
9632 
9633  void ReplaceString( const wchar_t* t1, const wchar_t* t2, size_type i = 0 )
9634  {
9635 #ifdef __PCL_WINDOWS
9636  string_base::ReplaceString( reinterpret_cast<const_iterator>( t1 ),
9637  reinterpret_cast<const_iterator>( t2 ), i );
9638 #else
9639  string_base::ReplaceString( String( t1 ), String( t2 ), i );
9640 #endif
9641  }
9642 
9643  void ReplaceStringIC( const wchar_t* t1, const wchar_t* t2, size_type i = 0 )
9644  {
9645 #ifdef __PCL_WINDOWS
9646  string_base::ReplaceStringIC( reinterpret_cast<const_iterator>( t1 ),
9647  reinterpret_cast<const_iterator>( t2 ), i );
9648 #else
9649  string_base::ReplaceStringIC( String( t1 ), String( t2 ), i );
9650 #endif
9651  }
9652 
9653  void ReplaceString( const_c_string8 t1, const_c_string8 t2, size_type i = 0 )
9654  {
9655  string_base::ReplaceString( String( t1 ), String( t2 ), i );
9656  }
9657 
9658  void ReplaceStringIC( const_c_string8 t1, const_c_string8 t2, size_type i = 0 )
9659  {
9660  string_base::ReplaceStringIC( String( t1 ), String( t2 ), i );
9661  }
9662 
9663  // -------------------------------------------------------------------------
9664 
9665  void DeleteChar( char_type c, size_type i = 0 )
9666  {
9667  string_base::DeleteChar( c, i );
9668  }
9669 
9670  void DeleteCharIC( char_type c, size_type i = 0 )
9671  {
9672  string_base::DeleteCharIC( c, i );
9673  }
9674 
9675  void DeleteChar( char16_t c, size_type i = 0 )
9676  {
9677  string_base::DeleteChar( char_type( c ), i );
9678  }
9679 
9680  void DeleteCharIC( char16_t c, size_type i = 0 )
9681  {
9682  string_base::DeleteCharIC( char_type( c ), i );
9683  }
9684 
9685  void DeleteChar( wchar_t c, size_type i = 0 )
9686  {
9687  string_base::DeleteChar( char_type( c ), i );
9688  }
9689 
9690  void DeleteCharIC( wchar_t c, size_type i = 0 )
9691  {
9692  string_base::DeleteCharIC( char_type( c ), i );
9693  }
9694 
9695  void DeleteChar( char8_type c, size_type i = 0 )
9696  {
9697  string_base::DeleteChar( char_type( c ), i );
9698  }
9699 
9700  void DeleteCharIC( char8_type c, size_type i = 0 )
9701  {
9702  string_base::DeleteCharIC( char_type( c ), i );
9703  }
9704 
9705  // -------------------------------------------------------------------------
9706 
9707  void DeleteString( const String& s, size_type i = 0 )
9708  {
9709  string_base::DeleteString( s, i );
9710  }
9711 
9712  void DeleteStringIC( const String& s, size_type i = 0 )
9713  {
9714  string_base::DeleteStringIC( s, i );
9715  }
9716 
9717  void DeleteString( const_iterator t, size_type i = 0 )
9718  {
9719  string_base::DeleteString( t, i );
9720  }
9721 
9722  void DeleteStringIC( const_iterator t, size_type i = 0 )
9723  {
9724  string_base::DeleteStringIC( t, i );
9725  }
9726 
9727  void DeleteString( const char16_t* t, size_type i = 0 )
9728  {
9729  string_base::DeleteString( reinterpret_cast<const_iterator>( t ), i );
9730  }
9731 
9732  void DeleteStringIC( const char16_t* t, size_type i = 0 )
9733  {
9734  string_base::DeleteStringIC( reinterpret_cast<const_iterator>( t ), i );
9735  }
9736 
9737  void DeleteString( const wchar_t* t, size_type i = 0 )
9738  {
9739 #ifdef __PCL_WINDOWS
9740  string_base::DeleteString( reinterpret_cast<const_iterator>( t ), i );
9741 #else
9742  string_base::DeleteString( String( t ), i );
9743 #endif
9744  }
9745 
9746  void DeleteStringIC( const wchar_t* t, size_type i = 0 )
9747  {
9748 #ifdef __PCL_WINDOWS
9749  string_base::DeleteStringIC( reinterpret_cast<const_iterator>( t ), i );
9750 #else
9751  string_base::DeleteStringIC( String( t ), i );
9752 #endif
9753  }
9754 
9755  void DeleteString( const_c_string8 t, size_type i = 0 )
9756  {
9757  string_base::DeleteString( String( t ), i );
9758  }
9759 
9760  void DeleteStringIC( const_c_string8 t, size_type i = 0 )
9761  {
9762  string_base::DeleteStringIC( String( t ), i );
9763  }
9764 
9765  // -------------------------------------------------------------------------
9766 
9767  bool StartsWith( const String& s ) const noexcept
9768  {
9769  return string_base::StartsWith( s );
9770  }
9771 
9772  bool StartsWith( const_iterator t ) const noexcept
9773  {
9774  return string_base::StartsWith( t );
9775  }
9776 
9777  bool StartsWith( char_type c ) const noexcept
9778  {
9779  return string_base::StartsWith( c );
9780  }
9781 
9782  bool StartsWithIC( const String& s ) const noexcept
9783  {
9784  return string_base::StartsWithIC( s );
9785  }
9786 
9787  bool StartsWithIC( const_iterator t ) const noexcept
9788  {
9789  return string_base::StartsWithIC( t );
9790  }
9791 
9792  bool StartsWithIC( char_type c ) const noexcept
9793  {
9794  return string_base::StartsWithIC( c );
9795  }
9796 
9797  bool StartsWith( const char16_t* t ) const noexcept
9798  {
9799  return string_base::StartsWith( reinterpret_cast<const_iterator>( t ) );
9800  }
9801 
9802  bool StartsWith( char16_t c ) const noexcept
9803  {
9804  return string_base::StartsWith( char_type( c ) );
9805  }
9806 
9807  bool StartsWithIC( const char16_t* t ) const noexcept
9808  {
9809  return string_base::StartsWithIC( reinterpret_cast<const_iterator>( t ) );
9810  }
9811 
9812  bool StartsWithIC( char16_t c ) const noexcept
9813  {
9814  return string_base::StartsWithIC( char_type( c ) );
9815  }
9816 
9817  bool StartsWith( const wchar_t* t ) const noexcept
9818  {
9819 #ifdef __PCL_WINDOWS
9820  return string_base::StartsWith( reinterpret_cast<const_iterator>( t ) );
9821 #else
9822  return string_base::StartsWith( String( t ) );
9823 #endif
9824  }
9825 
9826  bool StartsWith( wchar_t c ) const noexcept
9827  {
9828  return string_base::StartsWith( char_type( c ) );
9829  }
9830 
9831  bool StartsWithIC( const wchar_t* t ) const noexcept
9832  {
9833 #ifdef __PCL_WINDOWS
9834  return string_base::StartsWithIC( reinterpret_cast<const_iterator>( t ) );
9835 #else
9836  return string_base::StartsWithIC( String( t ) );
9837 #endif
9838  }
9839 
9840  bool StartsWithIC( wchar_t c ) const noexcept
9841  {
9842  return string_base::StartsWithIC( char_type( c ) );
9843  }
9844 
9845  bool StartsWith( const_c_string8 t ) const noexcept
9846  {
9847  size_type n = char8_traits::Length( t );
9848  if ( n == 0 || Length() < n )
9849  return false;
9850  for ( const_iterator p = m_data->string, q = p+n; p < q; ++p, ++t )
9851  if ( *p != char_type( *t ) )
9852  return false;
9853  return true;
9854  }
9855 
9856  bool StartsWith( char8_type c ) const noexcept
9857  {
9858  return string_base::StartsWith( char_type( c ) );
9859  }
9860 
9861  bool StartsWithIC( const_c_string8 t ) const noexcept
9862  {
9863  size_type n = char8_traits::Length( t );
9864  if ( n == 0 || Length() < n )
9865  return false;
9866  for ( const_iterator p = m_data->string, q = p+n; p < q; ++p, ++t )
9867  if ( char_traits::ToCaseFolded( *p ) != char_type( char8_traits::ToCaseFolded( *t ) ) )
9868  return false;
9869  return true;
9870  }
9871 
9872  bool StartsWithIC( char8_type c ) const noexcept
9873  {
9874  return string_base::StartsWithIC( char_type( c ) );
9875  }
9876 
9877  // -------------------------------------------------------------------------
9878 
9879  bool EndsWith( const String& s ) const noexcept
9880  {
9881  return string_base::EndsWith( s );
9882  }
9883 
9884  bool EndsWith( const_iterator t ) const noexcept
9885  {
9886  return string_base::EndsWith( t );
9887  }
9888 
9889  bool EndsWith( char_type c ) const noexcept
9890  {
9891  return string_base::EndsWith( c );
9892  }
9893 
9894  bool EndsWithIC( const String& s ) const noexcept
9895  {
9896  return string_base::EndsWithIC( s );
9897  }
9898 
9899  bool EndsWithIC( const_iterator t ) const noexcept
9900  {
9901  return string_base::EndsWithIC( t );
9902  }
9903 
9904  bool EndsWithIC( char_type c ) const noexcept
9905  {
9906  return string_base::EndsWithIC( c );
9907  }
9908 
9909  bool EndsWith( const char16_t* t ) const noexcept
9910  {
9911  return string_base::EndsWith( reinterpret_cast<const_iterator>( t ) );
9912  }
9913 
9914  bool EndsWith( char16_t c ) const noexcept
9915  {
9916  return string_base::EndsWith( char_type( c ) );
9917  }
9918 
9919  bool EndsWithIC( const char16_t* t ) const noexcept
9920  {
9921  return string_base::EndsWithIC( reinterpret_cast<const_iterator>( t ) );
9922  }
9923 
9924  bool EndsWithIC( char16_t c ) const noexcept
9925  {
9926  return string_base::EndsWithIC( char_type( c ) );
9927  }
9928 
9929  bool EndsWith( const wchar_t* t ) const noexcept
9930  {
9931 #ifdef __PCL_WINDOWS
9932  return string_base::EndsWith( reinterpret_cast<const_iterator>( t ) );
9933 #else
9934  return string_base::EndsWith( String( t ) );
9935 #endif
9936  }
9937 
9938  bool EndsWith( wchar_t c ) const noexcept
9939  {
9940  return string_base::EndsWith( char_type( c ) );
9941  }
9942 
9943  bool EndsWithIC( const wchar_t* t ) const noexcept
9944  {
9945 #ifdef __PCL_WINDOWS
9946  return string_base::EndsWithIC( reinterpret_cast<const_iterator>( t ) );
9947 #else
9948  return string_base::EndsWithIC( String( t ) );
9949 #endif
9950  }
9951 
9952  bool EndsWithIC( wchar_t c ) const noexcept
9953  {
9954  return string_base::EndsWithIC( char_type( c ) );
9955  }
9956 
9957  bool EndsWith( const_c_string8 t ) const noexcept
9958  {
9959  size_type n = char8_traits::Length( t );
9960  if ( n == 0 || Length() < n )
9961  return false;
9962  for ( const_iterator p = m_data->end-n; p < m_data->end; ++p, ++t )
9963  if ( *p != char_type( *t ) )
9964  return false;
9965  return true;
9966  }
9967 
9968  bool EndsWith( char8_type c ) const noexcept
9969  {
9970  return string_base::EndsWith( char_type( c ) );
9971  }
9972 
9973  bool EndsWithIC( const_c_string8 t ) const noexcept
9974  {
9975  size_type n = char8_traits::Length( t );
9976  if ( n == 0 || Length() < n )
9977  return false;
9978  for ( const_iterator p = m_data->end-n; p < m_data->end; ++p, ++t )
9979  if ( char_traits::ToCaseFolded( *p ) != char_type( char8_traits::ToCaseFolded( *t ) ) )
9980  return false;
9981  return true;
9982  }
9983 
9984  bool EndsWithIC( char8_type c ) const noexcept
9985  {
9986  return string_base::EndsWithIC( char_type( c ) );
9987  }
9988 
9989  // -------------------------------------------------------------------------
9990 
9991  size_type FindFirst( const String& s, size_type i = 0 ) const noexcept
9992  {
9993  return string_base::FindFirst( s, i );
9994  }
9995 
9996  size_type FindFirst( const_iterator t, size_type i = 0 ) const noexcept
9997  {
9998  return string_base::FindFirst( t, i );
9999  }
10000 
10001  size_type FindFirst( char_type c, size_type i = 0 ) const noexcept
10002  {
10003  return string_base::FindFirst( c, i );
10004  }
10005 
10006  size_type FindFirstIC( const String& s, size_type i = 0 ) const noexcept
10007  {
10008  return string_base::FindFirstIC( s, i );
10009  }
10010 
10011  size_type FindFirstIC( const_iterator t, size_type i = 0 ) const noexcept
10012  {
10013  return string_base::FindFirstIC( t, i );
10014  }
10015 
10016  size_type FindFirstIC( char_type c, size_type i = 0 ) const noexcept
10017  {
10018  return string_base::FindFirstIC( c, i );
10019  }
10020 
10021  size_type FindFirst( const char16_t* t, size_type i = 0 ) const noexcept
10022  {
10023  return string_base::FindFirst( reinterpret_cast<const_iterator>( t ), i );
10024  }
10025 
10026  size_type FindFirst( char16_t c, size_type i = 0 ) const noexcept
10027  {
10028  return string_base::FindFirst( char_type( c ), i );
10029  }
10030 
10031  size_type FindFirstIC( const char16_t* t, size_type i = 0 ) const noexcept
10032  {
10033  return string_base::FindFirstIC( reinterpret_cast<const_iterator>( t ), i );
10034  }
10035 
10036  size_type FindFirstIC( char16_t c, size_type i = 0 ) const noexcept
10037  {
10038  return string_base::FindFirstIC( char_type( c ), i );
10039  }
10040 
10041  size_type FindFirst( const wchar_t* t, size_type i = 0 ) const noexcept
10042  {
10043 #ifdef __PCL_WINDOWS
10044  return string_base::FindFirst( reinterpret_cast<const_iterator>( t ), i );
10045 #else
10046  return string_base::FindFirst( String( t ), i );
10047 #endif
10048  }
10049 
10050  size_type FindFirst( wchar_t c, size_type i = 0 ) const noexcept
10051  {
10052  return string_base::FindFirst( char_type( c ), i );
10053  }
10054 
10055  size_type FindFirstIC( const wchar_t* t, size_type i = 0 ) const noexcept
10056  {
10057 #ifdef __PCL_WINDOWS
10058  return string_base::FindFirstIC( reinterpret_cast<const_iterator>( t ), i );
10059 #else
10060  return string_base::FindFirstIC( String( t ), i );
10061 #endif
10062  }
10063 
10064  size_type FindFirstIC( wchar_t c, size_type i = 0 ) const noexcept
10065  {
10066  return string_base::FindFirstIC( char_type( c ), i );
10067  }
10068 
10069  size_type FindFirst( const_c_string8 t, size_type i = 0 ) const noexcept
10070  {
10071  return string_base::FindFirst( String( t ), i );
10072  }
10073 
10074  size_type FindFirst( char8_type c, size_type i = 0 ) const noexcept
10075  {
10076  return string_base::FindFirst( char_type( c ), i );
10077  }
10078 
10079  size_type FindFirstIC( const_c_string8 t, size_type i = 0 ) const noexcept
10080  {
10081  return string_base::FindFirstIC( String( t ), i );
10082  }
10083 
10084  size_type FindFirstIC( char8_type c, size_type i = 0 ) const noexcept
10085  {
10086  return string_base::FindFirstIC( char_type( c ), i );
10087  }
10088 
10089  //
10090 
10091  size_type Find( const String& s, size_type i = 0 ) const noexcept
10092  {
10093  return FindFirst( s, i );
10094  }
10095 
10096  size_type Find( const_iterator t, size_type i = 0 ) const noexcept
10097  {
10098  return FindFirst( t, i );
10099  }
10100 
10101  size_type Find( char_type c, size_type i = 0 ) const noexcept
10102  {
10103  return FindFirst( c, i );
10104  }
10105 
10106  size_type Find( const char16_t* t, size_type i = 0 ) const noexcept
10107  {
10108  return FindFirst( t, i );
10109  }
10110 
10111  size_type Find( char16_t c, size_type i = 0 ) const noexcept
10112  {
10113  return FindFirst( c, i );
10114  }
10115 
10116  size_type Find( const wchar_t* t, size_type i = 0 ) const noexcept
10117  {
10118  return FindFirst( t, i );
10119  }
10120 
10121  size_type Find( wchar_t c, size_type i = 0 ) const noexcept
10122  {
10123  return FindFirst( c, i );
10124  }
10125 
10126  size_type Find( const_c_string8 t, size_type i = 0 ) const noexcept
10127  {
10128  return FindFirst( t, i );
10129  }
10130 
10131  size_type Find( char8_type c, size_type i = 0 ) const noexcept
10132  {
10133  return FindFirst( c, i );
10134  }
10135 
10136  size_type FindIC( const String& s, size_type i = 0 ) const noexcept
10137  {
10138  return FindFirstIC( s, i );
10139  }
10140 
10141  size_type FindIC( const_iterator t, size_type i = 0 ) const noexcept
10142  {
10143  return FindFirstIC( t, i );
10144  }
10145 
10146  size_type FindIC( char_type c, size_type i = 0 ) const noexcept
10147  {
10148  return FindFirstIC( c, i );
10149  }
10150 
10151  size_type FindIC( const char16_t* t, size_type i = 0 ) const noexcept
10152  {
10153  return FindFirstIC( t, i );
10154  }
10155 
10156  size_type FindIC( char16_t c, size_type i = 0 ) const noexcept
10157  {
10158  return FindFirstIC( c, i );
10159  }
10160 
10161  size_type FindIC( const wchar_t* t, size_type i = 0 ) const noexcept
10162  {
10163  return FindFirstIC( t, i );
10164  }
10165 
10166  size_type FindIC( wchar_t c, size_type i = 0 ) const noexcept
10167  {
10168  return FindFirstIC( c, i );
10169  }
10170 
10171  size_type FindIC( const_c_string8 t, size_type i = 0 ) const noexcept
10172  {
10173  return FindFirstIC( t, i );
10174  }
10175 
10176  size_type FindIC( char8_type c, size_type i = 0 ) const noexcept
10177  {
10178  return FindFirstIC( c, i );
10179  }
10180 
10181  // -------------------------------------------------------------------------
10182 
10183  size_type FindLast( const String& s, size_type r = maxPos ) const noexcept
10184  {
10185  return string_base::FindLast( s, r );
10186  }
10187 
10188  size_type FindLast( const_iterator t, size_type r = maxPos ) const noexcept
10189  {
10190  return string_base::FindLast( t, r );
10191  }
10192 
10193  size_type FindLast( char_type c, size_type r = maxPos ) const noexcept
10194  {
10195  return string_base::FindLast( c, r );
10196  }
10197 
10198  size_type FindLastIC( const String& s, size_type r = maxPos ) const noexcept
10199  {
10200  return string_base::FindLastIC( s, r );
10201  }
10202 
10203  size_type FindLastIC( const_iterator t, size_type r = maxPos ) const noexcept
10204  {
10205  return string_base::FindLastIC( t, r );
10206  }
10207 
10208  size_type FindLastIC( char_type c, size_type r = maxPos ) const noexcept
10209  {
10210  return string_base::FindLastIC( c, r );
10211  }
10212 
10213  size_type FindLast( const char16_t* t, size_type r = maxPos ) const noexcept
10214  {
10215  return string_base::FindLast( reinterpret_cast<const_iterator>( t ), r );
10216  }
10217 
10218  size_type FindLast( char16_t c, size_type r = maxPos ) const noexcept
10219  {
10220  return string_base::FindLast( char_type( c ), r );
10221  }
10222 
10223  size_type FindLastIC( const char16_t* t, size_type r = maxPos ) const noexcept
10224  {
10225  return string_base::FindLastIC( reinterpret_cast<const_iterator>( t ), r );
10226  }
10227 
10228  size_type FindLastIC( char16_t c, size_type r = maxPos ) const noexcept
10229  {
10230  return string_base::FindLastIC( char_type( c ), r );
10231  }
10232 
10233  size_type FindLast( const wchar_t* t, size_type r = maxPos ) const noexcept
10234  {
10235 #ifdef __PCL_WINDOWS
10236  return string_base::FindLast( reinterpret_cast<const_iterator>( t ), r );
10237 #else
10238  return string_base::FindLast( String( t ), r );
10239 #endif
10240  }
10241 
10242  size_type FindLast( wchar_t c, size_type r = maxPos ) const noexcept
10243  {
10244  return string_base::FindLast( char_type( c ), r );
10245  }
10246 
10247  size_type FindLastIC( const wchar_t* t, size_type r = maxPos ) const noexcept
10248  {
10249 #ifdef __PCL_WINDOWS
10250  return string_base::FindLastIC( reinterpret_cast<const_iterator>( t ), r );
10251 #else
10252  return string_base::FindLastIC( String( t ), r );
10253 #endif
10254  }
10255 
10256  size_type FindLastIC( wchar_t c, size_type r = maxPos ) const noexcept
10257  {
10258  return string_base::FindLastIC( char_type( c ), r );
10259  }
10260 
10261  size_type FindLast( const_c_string8 t, size_type r = maxPos ) const noexcept
10262  {
10263  return string_base::FindLast( String( t ), r );
10264  }
10265 
10266  size_type FindLast( char8_type c, size_type r = maxPos ) const noexcept
10267  {
10268  return string_base::FindLast( char_type( c ), r );
10269  }
10270 
10271  size_type FindLastIC( const_c_string8 t, size_type r = maxPos ) const noexcept
10272  {
10273  return string_base::FindLastIC( String( t ), r );
10274  }
10275 
10276  size_type FindLastIC( char8_type c, size_type r = maxPos ) const noexcept
10277  {
10278  return string_base::FindLastIC( char_type( c ), r );
10279  }
10280 
10281  // -------------------------------------------------------------------------
10282 
10283  bool Contains( const String& s ) const noexcept
10284  {
10285  return string_base::Contains( s );
10286  }
10287 
10288  bool Contains( const_iterator t ) const noexcept
10289  {
10290  return string_base::Contains( t );
10291  }
10292 
10293  bool Contains( char_type c ) const noexcept
10294  {
10295  return string_base::Contains( c );
10296  }
10297 
10298  bool ContainsIC( const String& s ) const noexcept
10299  {
10300  return string_base::ContainsIC( s );
10301  }
10302 
10303  bool ContainsIC( const_iterator t ) const noexcept
10304  {
10305  return string_base::ContainsIC( t );
10306  }
10307 
10308  bool ContainsIC( char_type c ) const noexcept
10309  {
10310  return string_base::ContainsIC( c );
10311  }
10312 
10313  bool Contains( const char16_t* t ) const noexcept
10314  {
10315  return string_base::Contains( reinterpret_cast<const_iterator>( t ) );
10316  }
10317 
10318  bool Contains( char16_t c ) const noexcept
10319  {
10320  return string_base::Contains( char_type( c ) );
10321  }
10322 
10323  bool ContainsIC( const char16_t* t ) const noexcept
10324  {
10325  return string_base::ContainsIC( reinterpret_cast<const_iterator>( t ) );
10326  }
10327 
10328  bool ContainsIC( char16_t c ) const noexcept
10329  {
10330  return string_base::ContainsIC( char_type( c ) );
10331  }
10332 
10333  bool Contains( const wchar_t* t ) const noexcept
10334  {
10335 #ifdef __PCL_WINDOWS
10336  return string_base::Contains( reinterpret_cast<const_iterator>( t ) );
10337 #else
10338  return string_base::Contains( String( t ) );
10339 #endif
10340  }
10341 
10342  bool Contains( wchar_t c ) const noexcept
10343  {
10344  return string_base::Contains( char_type( c ) );
10345  }
10346 
10347  bool ContainsIC( const wchar_t* t ) const noexcept
10348  {
10349 #ifdef __PCL_WINDOWS
10350  return string_base::ContainsIC( reinterpret_cast<const_iterator>( t ) );
10351 #else
10352  return string_base::ContainsIC( String( t ) );
10353 #endif
10354  }
10355 
10356  bool ContainsIC( wchar_t c ) const noexcept
10357  {
10358  return string_base::ContainsIC( char_type( c ) );
10359  }
10360 
10361  bool Contains( const_c_string8 t ) const noexcept
10362  {
10363  return string_base::Contains( String( t ) );
10364  }
10365 
10366  bool Contains( char8_type c ) const noexcept
10367  {
10368  return string_base::Contains( char_type( c ) );
10369  }
10370 
10371  bool ContainsIC( const_c_string8 t ) const noexcept
10372  {
10373  return string_base::ContainsIC( String( t ) );
10374  }
10375 
10376  bool ContainsIC( char8_type c ) const noexcept
10377  {
10378  return string_base::ContainsIC( char_type( c ) );
10379  }
10380 
10381  // -------------------------------------------------------------------------
10382 
10383  int CompareCodePoints( const String& s, bool caseSensitive = true ) const noexcept
10384  {
10385  return string_base::CompareCodePoints( s, caseSensitive );
10386  }
10387 
10388  int CompareCodePoints( const_iterator t, bool caseSensitive = true ) const noexcept
10389  {
10390  return string_base::CompareCodePoints( t, caseSensitive );
10391  }
10392 
10393  int CompareCodePoints( char_type c, bool caseSensitive = true ) const noexcept
10394  {
10395  return string_base::CompareCodePoints( c, caseSensitive );
10396  }
10397 
10398  int CompareCodePoints( const char16_t* t, bool caseSensitive = true ) const noexcept
10399  {
10400  return string_base::CompareCodePoints( reinterpret_cast<const_iterator>( t ), caseSensitive );
10401  }
10402 
10403  int CompareCodePoints( char16_t c, bool caseSensitive = true ) const noexcept
10404  {
10405  return string_base::CompareCodePoints( char_type( c ), caseSensitive );
10406  }
10407 
10408  int CompareCodePoints( const wchar_t* t, bool caseSensitive = true ) const noexcept
10409  {
10410 #ifdef __PCL_WINDOWS
10411  return string_base::CompareCodePoints( reinterpret_cast<const_iterator>( t ), caseSensitive );
10412 #else
10413  return string_base::CompareCodePoints( String( t ), caseSensitive );
10414 #endif
10415  }
10416 
10417  int CompareCodePoints( wchar_t c, bool caseSensitive = true ) const noexcept
10418  {
10419  return string_base::CompareCodePoints( char_type( c ), caseSensitive );
10420  }
10421 
10422  int CompareCodePoints( const_c_string8 t, bool caseSensitive = true ) const noexcept
10423  {
10424  return string_base::CompareCodePoints( String( t ), caseSensitive );
10425  }
10426 
10427  int CompareCodePoints( char8_type c, bool caseSensitive = true ) const noexcept
10428  {
10429  return string_base::CompareCodePoints( char_type( c ), caseSensitive );
10430  }
10431 
10432  // -------------------------------------------------------------------------
10433 
10434  int Compare( const String& s, bool caseSensitive = true, bool localeAware = true ) const noexcept
10435  {
10436  return string_base::Compare( s, caseSensitive, localeAware );
10437  }
10438 
10439  int Compare( const_iterator t, bool caseSensitive = true, bool localeAware = true ) const noexcept
10440  {
10441  return string_base::Compare( t, caseSensitive, localeAware );
10442  }
10443 
10444  int Compare( char_type c, bool caseSensitive = true, bool localeAware = true ) const noexcept
10445  {
10446  return string_base::Compare( c, caseSensitive, localeAware );
10447  }
10448 
10449  int CompareIC( const String& s, bool localeAware = true ) const noexcept
10450  {
10451  return string_base::CompareIC( s, localeAware );
10452  }
10453 
10454  int CompareIC( const_iterator t, bool localeAware = true ) const noexcept
10455  {
10456  return string_base::CompareIC( t, localeAware );
10457  }
10458 
10459  int CompareIC( char_type c, bool localeAware = true ) const noexcept
10460  {
10461  return string_base::CompareIC( c, localeAware );
10462  }
10463 
10464  int Compare( const char16_t* t, bool caseSensitive = true, bool localeAware = true ) const noexcept
10465  {
10466  return string_base::Compare( reinterpret_cast<const_iterator>( t ), caseSensitive, localeAware );
10467  }
10468 
10469  int Compare( char16_t c, bool caseSensitive = true, bool localeAware = true ) const noexcept
10470  {
10471  return string_base::Compare( char_type( c ), caseSensitive, localeAware );
10472  }
10473 
10474  int CompareIC( const char16_t* t, bool localeAware = true ) const noexcept
10475  {
10476  return string_base::CompareIC( reinterpret_cast<const_iterator>( t ), localeAware );
10477  }
10478 
10479  int CompareIC( char16_t c, bool localeAware = true ) const noexcept
10480  {
10481  return string_base::CompareIC( char_type( c ), localeAware );
10482  }
10483 
10484  int Compare( const wchar_t* t, bool caseSensitive = true, bool localeAware = true ) const noexcept
10485  {
10486 #ifdef __PCL_WINDOWS
10487  return string_base::Compare( reinterpret_cast<const_iterator>( t ), caseSensitive, localeAware );
10488 #else
10489  return string_base::Compare( String( t ), caseSensitive, localeAware );
10490 #endif
10491  }
10492 
10493  int Compare( wchar_t c, bool caseSensitive = true, bool localeAware = true ) const noexcept
10494  {
10495  return string_base::Compare( char_type( c ), caseSensitive, localeAware );
10496  }
10497 
10498  int CompareIC( const wchar_t* t, bool localeAware = true ) const noexcept
10499  {
10500 #ifdef __PCL_WINDOWS
10501  return string_base::CompareIC( reinterpret_cast<const_iterator>( t ), localeAware );
10502 #else
10503  return string_base::CompareIC( String( t ), localeAware );
10504 #endif
10505  }
10506 
10507  int CompareIC( wchar_t c, bool localeAware = true ) const noexcept
10508  {
10509  return string_base::CompareIC( char_type( c ), localeAware );
10510  }
10511 
10512  int Compare( const_c_string8 t, bool caseSensitive = true, bool localeAware = true ) const noexcept
10513  {
10514  return string_base::Compare( String( t ), caseSensitive, localeAware );
10515  }
10516 
10517  int Compare( char8_type c, bool caseSensitive = true, bool localeAware = true ) const noexcept
10518  {
10519  return string_base::Compare( char_type( c ), caseSensitive, localeAware );
10520  }
10521 
10522  int CompareIC( const_c_string8 t, bool localeAware = true ) const noexcept
10523  {
10524  return string_base::CompareIC( String( t ), localeAware );
10525  }
10526 
10527  int CompareIC( char8_type c, bool localeAware = true ) const noexcept
10528  {
10529  return string_base::CompareIC( char_type( c ), localeAware );
10530  }
10531 
10532  // -------------------------------------------------------------------------
10533 
10534  bool WildMatch( const String& pattern, bool caseSensitive = true ) const noexcept
10535  {
10536  return string_base::WildMatch( pattern, caseSensitive );
10537  }
10538 
10539  bool WildMatchIC( const String& pattern ) const noexcept
10540  {
10541  return string_base::WildMatchIC( pattern );
10542  }
10543 
10544  bool WildMatch( const_iterator pattern, bool caseSensitive = true ) const noexcept
10545  {
10546  return string_base::WildMatch( pattern, caseSensitive );
10547  }
10548 
10549  bool WildMatchIC( const_iterator pattern ) const noexcept
10550  {
10551  return string_base::WildMatchIC( pattern );
10552  }
10553 
10554  bool WildMatch( const string8_base& pattern, bool caseSensitive = true ) const noexcept
10555  {
10556  return char_traits::WildMatch( m_data->string, Length(), pattern.Begin(), pattern.Length(), caseSensitive );
10557  }
10558 
10559  bool WildMatchIC( const string8_base& pattern ) const noexcept
10560  {
10561  return char_traits::WildMatch( m_data->string, Length(), pattern.Begin(), pattern.Length(), false/*caseSensitive*/ );
10562  }
10563 
10564  bool WildMatch( const_c_string8 pattern, bool caseSensitive = true ) const noexcept
10565  {
10566  return char_traits::WildMatch( m_data->string, Length(), pattern, char8_traits::Length( pattern ), caseSensitive );
10567  }
10568 
10569  bool WildMatchIC( const_c_string8 pattern ) const noexcept
10570  {
10571  return char_traits::WildMatch( m_data->string, Length(), pattern, char8_traits::Length( pattern ), false/*caseSensitive*/ );
10572  }
10573 
10574  // -------------------------------------------------------------------------
10575 
10576  String SetToLength( size_type n ) const
10577  {
10578  return string_base::SetToLength( n );
10579  }
10580 
10581  String ResizedToNullTerminated() const
10582  {
10583  return string_base::ResizedToNullTerminated();
10584  }
10585 
10586  String Squeezed() const
10587  {
10588  return string_base::Squeezed();
10589  }
10590 
10591  // -------------------------------------------------------------------------
10592 
10593  String Substring( size_type i, size_type n = maxPos ) const
10594  {
10595  return string_base::Substring( i, n );
10596  }
10597 
10598  String Left( size_type n ) const
10599  {
10600  return string_base::Left( n );
10601  }
10602 
10603  String Right( size_type n ) const
10604  {
10605  return string_base::Right( n );
10606  }
10607 
10608  String Suffix( size_type i ) const
10609  {
10610  return string_base::Suffix( i );
10611  }
10612 
10613  String Prefix( size_type i ) const
10614  {
10615  return string_base::Prefix( i );
10616  }
10617 
10618  // -------------------------------------------------------------------------
10619 
10620  template <class C>
10621  size_type Break( C& list, const String& s, bool trim = false, size_type i = 0 ) const
10622  {
10623  return string_base::Break( list, s, trim, i );
10624  }
10625 
10626  template <class C>
10627  size_type Break( C& list, const string8_base& s, bool trim = false, size_type i = 0 ) const
10628  {
10629  return string_base::Break( list, String( s ), trim, i );
10630  }
10631 
10632  template <class C>
10633  size_type Break( C& list, const_c_string8 s, bool trim = false, size_type i = 0 ) const
10634  {
10635  return string_base::Break( list, String( s ), trim, i );
10636  }
10637 
10638  template <class C>
10639  size_type Break( C& list, char_type c, bool trim = false, size_type i = 0 ) const
10640  {
10641  return string_base::Break( list, c, trim, i );
10642  }
10643 
10644  template <class C>
10645  size_type Break( C& list, char8_type c, bool trim = false, size_type i = 0 ) const
10646  {
10647  return string_base::Break( list, char_type( c ), trim, i );
10648  }
10649 
10650  template <class C, typename S>
10651  size_type Break( C& list, const Array<S>& ca, bool trim = false, size_type i = 0 ) const
10652  {
10653  return string_base::Break( list, ca, trim, i );
10654  }
10655 
10656  // -------------------------------------------------------------------------
10657 
10658  template <class C>
10659  size_type BreakIC( C& list, const String& s, bool trim = false, size_type i = 0 ) const
10660  {
10661  return string_base::BreakIC( list, s, trim, i );
10662  }
10663 
10664  template <class C>
10665  size_type BreakIC( C& list, const string8_base& s, bool trim = false, size_type i = 0 ) const
10666  {
10667  return string_base::BreakIC( list, String( s ), trim, i );
10668  }
10669 
10670  template <class C>
10671  size_type BreakIC( C& list, const_c_string8 s, bool trim = false, size_type i = 0 ) const
10672  {
10673  return string_base::BreakIC( list, String( s ), trim, i );
10674  }
10675 
10676  template <class C>
10677  size_type BreakIC( C& list, char_type c, bool trim = false, size_type i = 0 ) const
10678  {
10679  return string_base::BreakIC( list, c, trim, i );
10680  }
10681 
10682  template <class C>
10683  size_type BreakIC( C& list, char8_type c, bool trim = false, size_type i = 0 ) const
10684  {
10685  return string_base::BreakIC( list, char_type( c ), trim, i );
10686  }
10687 
10688  // -------------------------------------------------------------------------
10689 
10690  String Trimmed() const
10691  {
10692  return string_base::Trimmed();
10693  }
10694 
10695  String TrimmedLeft() const
10696  {
10697  return string_base::TrimmedLeft();
10698  }
10699 
10700  String TrimmedRight() const
10701  {
10702  return string_base::TrimmedRight();
10703  }
10704 
10705  // -------------------------------------------------------------------------
10706 
10707  String LeftJustified( size_type width, char_type fill = CharTraits::Blank() ) const
10708  {
10709  return string_base::LeftJustified( width, fill );
10710  }
10711 
10712  String RightJustified( size_type width, char_type fill = CharTraits::Blank() ) const
10713  {
10714  return string_base::RightJustified( width, fill );
10715  }
10716 
10717  String CenterJustified( size_type width, char_type fill = CharTraits::Blank() ) const
10718  {
10719  return string_base::CenterJustified( width, fill );
10720  }
10721 
10722  // -------------------------------------------------------------------------
10723 
10724  String Enclosed( char_type c ) const
10725  {
10726  return string_base::Enclosed( c );
10727  }
10728 
10729  String SingleQuoted() const
10730  {
10731  return string_base::SingleQuoted();
10732  }
10733 
10734  String DoubleQuoted() const
10735  {
10736  return string_base::DoubleQuoted();
10737  }
10738 
10739  String Unquoted() const
10740  {
10741  return string_base::Unquoted();
10742  }
10743 
10744  // -------------------------------------------------------------------------
10745 
10746  String CaseFolded() const
10747  {
10748  return string_base::CaseFolded();
10749  }
10750 
10751  String Lowercase() const
10752  {
10753  return string_base::Lowercase();
10754  }
10755 
10756  String Uppercase() const
10757  {
10758  return string_base::Uppercase();
10759  }
10760 
10761  // -------------------------------------------------------------------------
10762 
10763  String Reversed() const
10764  {
10765  return string_base::Reversed();
10766  }
10767 
10768  String Sorted() const
10769  {
10770  return string_base::Sorted();
10771  }
10772 
10773  template <class BP>
10774  String Sorted( BP p ) const
10775  {
10776  return string_base::Sorted( p );
10777  }
10778 
10779  // -------------------------------------------------------------------------
10780 
10790  template <class C>
10791  String& ToSeparated( const C& c, char_type separator )
10792  {
10793  Clear();
10794  return c.ToSeparated( *this, separator );
10795  }
10796 
10813  template <class C, class AF>
10814  String& ToSeparated( const C& c, char_type separator, AF append )
10815  {
10816  Clear();
10817  return c.ToSeparated( *this, separator, append );
10818  }
10819 
10829  template <class C>
10830  String& ToSeparated( const C& c, const String& separator )
10831  {
10832  Clear();
10833  return c.ToSeparated( *this, separator );
10834  }
10835 
10852  template <class C, class AF>
10853  String& ToSeparated( const C& c, const String& separator, AF append )
10854  {
10855  Clear();
10856  return c.ToSeparated( *this, separator, append );
10857  }
10858 
10868  template <class C>
10869  String& ToSeparated( const C& c, const_c_string separator )
10870  {
10871  return ToSeparated( c, String( separator ) );
10872  }
10873 
10890  template <class C, class AF>
10891  String& ToSeparated( const C& c, const_c_string separator, AF append )
10892  {
10893  return ToSeparated( c, String( separator ), append );
10894  }
10895 
10906  template <class C>
10907  String& ToSeparated( const C& c, const_c_string8 separator )
10908  {
10909  return ToSeparated( c, String( separator ) );
10910  }
10911 
10928  template <class C, class AF>
10929  String& ToSeparated( const C& c, const_c_string8 separator, AF append )
10930  {
10931  return ToSeparated( c, String( separator ), append );
10932  }
10933 
10943  template <class C>
10944  String& ToCommaSeparated( const C& c )
10945  {
10946  return ToSeparated( c, CharTraits::Comma() );
10947  }
10948 
10958  template <class C>
10959  String& ToColonSeparated( const C& c )
10960  {
10961  return ToSeparated( c, CharTraits::Colon() );
10962  }
10963 
10973  template <class C>
10974  String& ToSpaceSeparated( const C& c )
10975  {
10976  return ToSeparated( c, CharTraits::Blank() );
10977  }
10978 
10988  template <class C>
10989  String& ToTabSeparated( const C& c )
10990  {
10991  return ToSeparated( c, CharTraits::Tab() );
10992  }
10993 
11003  template <class C>
11005  {
11006  return ToSeparated( c, CharTraits::LF() );
11007  }
11008 
11018  template <class C>
11019  String& ToNullSeparated( const C& c )
11020  {
11021  return ToSeparated( c, CharTraits::Null() );
11022  }
11023 
11032  template <class C>
11033  String& ToHyphenated( const C& c )
11034  {
11035  return ToSeparated( c, CharTraits::Hyphen() );
11036  }
11037 
11038  // -------------------------------------------------------------------------
11039 
11055 
11063  {
11064  return String( *this ).ToEncodedHTMLSpecialChars();
11065  }
11066 
11084 
11093  {
11094  return String( *this ).ToDecodedHTMLSpecialChars();
11095  }
11096 
11097  // -------------------------------------------------------------------------
11098 
11099 #ifdef __PCL_QT_INTERFACE
11100 
11101  operator QString() const
11102  {
11103  return PCL_GET_QSTRING_FROM_CHAR16PTR( c_str() );
11104  }
11105 
11106  operator QDate() const
11107  {
11108  return QDate::fromString( operator QString(), PCL_QDATE_FMT_STR );
11109  }
11110 
11111  operator QDateTime() const
11112  {
11113  return QDateTime::fromString( operator QString(), PCL_QDATETIME_FMT_STR );
11114  }
11115 
11116 #endif
11117 
11130  {
11131  va_list paramList;
11132  va_start( paramList, fmt );
11133 
11134  (void)VFormat( fmt, paramList );
11135 
11136  va_end( paramList );
11137  return *this;
11138  }
11139 
11152  {
11153  va_list paramList;
11154  va_start( paramList, fmt );
11155 
11156  (void)AppendVFormat( fmt, paramList );
11157 
11158  va_end( paramList );
11159  return *this;
11160  }
11161 
11174  int VFormat( const_c_string8 fmt, va_list paramList )
11175  {
11176  IsoString s;
11177  int count = s.VFormat( fmt, paramList );
11178  Assign( s );
11179  return count;
11180  }
11181 
11194  int AppendVFormat( const_c_string8 fmt, va_list paramList )
11195  {
11196  IsoString s;
11197  int count = s.VFormat( fmt, paramList );
11198  Append( s );
11199  return count;
11200  }
11201 
11214  String& Format( const wchar_t* fmt, ... )
11215  {
11216  va_list paramList;
11217  va_start( paramList, fmt );
11218 
11219  (void)VFormat( fmt, paramList );
11220 
11221  va_end( paramList );
11222  return *this;
11223  }
11224 
11237  String& AppendFormat( const wchar_t* fmt, ... )
11238  {
11239  va_list paramList;
11240  va_start( paramList, fmt );
11241 
11242  (void)AppendVFormat( fmt, paramList );
11243 
11244  va_end( paramList );
11245  return *this;
11246  }
11247 
11261  int VFormat( const wchar_t* fmt, va_list paramList );
11262 
11276  int AppendVFormat( const wchar_t* fmt, va_list paramList );
11277 
11278  // -------------------------------------------------------------------------
11279 
11289  static String UTF8ToUTF16( const_c_string8 string, size_type i = 0, size_type n = maxPos );
11290 
11300  static IsoString UTF16ToUTF8( const_c_string string, size_type i = 0, size_type n = maxPos );
11301 
11311  static Array<uint32> UTF16ToUTF32( const_c_string string, size_type i = 0, size_type n = maxPos );
11312 
11322  static String UTF32ToUTF16( const uint32* string, size_type i = 0, size_type n = maxPos );
11323 
11324  // -------------------------------------------------------------------------
11325 
11336 
11347 
11355  IsoString ToUTF8( size_type i = 0, size_type n = maxPos ) const
11356  {
11357  return UTF16ToUTF8( Begin(), i, n );
11358  }
11359 
11375  IsoString ToMBS() const;
11376 
11386  {
11387 #ifdef __PCL_WINDOWS
11388  return ToMBS();
11389 #else
11390  return ToUTF8();
11391 #endif
11392  }
11393 
11414  Array<wchar_t> ToWCharArray( size_type i = 0, size_type n = maxPos ) const
11415  {
11416  if ( n > 0 )
11417  {
11418  size_type len = Length();
11419  if ( i < len )
11420  {
11421  n = pcl::Min( n, len-i );
11422  Array<wchar_t> a( n+1, wchar_t( 0 ) );
11423 #ifdef __PCL_WINDOWS
11424  char_traits::Copy( reinterpret_cast<iterator>( a.Begin() ), m_data->string+i, n );
11425 #else
11426  Array<wchar_t>::iterator w = a.Begin();
11427  for ( const_iterator s = m_data->string+i, e = s+n; s < e; ++w, ++s )
11428  *w = wchar_t( *s );
11429 #endif // __PCL_WINDOWS
11430  return a;
11431  }
11432  }
11433 
11434  return Array<wchar_t>( size_type( 1 ), wchar_t( 0 ) );
11435  }
11436 
11445  Array<uint32> ToUTF32( size_type i = 0, size_type n = maxPos ) const
11446  {
11447  return UTF16ToUTF32( Begin(), i, n );
11448  }
11449 
11450 #ifdef __PCL_QT_INTERFACE
11451 
11452  QString ToQString() const
11453  {
11454  return operator QString();
11455  }
11456 
11457  QDate ToQDate() const
11458  {
11459  return operator QDate();
11460  }
11461 
11462  QDateTime ToQDateTime() const
11463  {
11464  return operator QDateTime();
11465  }
11466 
11467 #endif
11468 
11479  bool ToBool() const;
11480 
11495  bool TryToBool( bool& value ) const noexcept;
11496 
11510  float ToFloat() const;
11511 
11526  bool TryToFloat( float& value ) const noexcept;
11527 
11551  double ToDouble() const;
11552 
11567  bool TryToDouble( double& value ) const noexcept;
11568 
11585  long ToInt() const
11586  {
11587  return ToInt( 0 );
11588  }
11589 
11613  bool TryToInt( int& value ) const noexcept
11614  {
11615  return TryToInt( value, 0 );
11616  }
11617 
11644  long ToInt( int base ) const;
11645 
11663  bool TryToInt( int& value, int base ) const noexcept;
11664 
11682  unsigned long ToUInt() const
11683  {
11684  return ToUInt( 0 );
11685  }
11686 
11710  bool TryToUInt( unsigned& value ) const noexcept
11711  {
11712  return TryToUInt( value, 0 );
11713  }
11714 
11731  unsigned long ToUInt( int base ) const;
11732 
11750  bool TryToUInt( unsigned& value, int base ) const noexcept;
11751 
11766  long long ToInt64() const
11767  {
11768  return ToInt64( 0 );
11769  }
11770 
11795  bool TryToInt64( long long& value ) const noexcept
11796  {
11797  return TryToInt64( value, 0 );
11798  }
11799 
11814  long long ToInt64( int base ) const;
11815 
11833  bool TryToInt64( long long& value, int base ) const noexcept;
11834 
11849  unsigned long long ToUInt64() const
11850  {
11851  return ToUInt64( 0 );
11852  }
11853 
11878  bool TryToUInt64( unsigned long long& value ) const noexcept
11879  {
11880  return TryToUInt64( value, 0 );
11881  }
11882 
11897  unsigned long long ToUInt64( int base ) const;
11898 
11916  bool TryToUInt64( unsigned long long& value, int base ) const noexcept;
11917 
11949  Array<float> ParseListOfFloat( char separator = ',', size_type maxCount = ~size_type( 0 ) ) const;
11950 
11982  Array<double> ParseListOfDouble( char separator = ',', size_type maxCount = ~size_type( 0 ) ) const;
11983 
11984 #ifndef __PCL_NO_STRING_VECTOR
11985 
11993  GenericVector<float> ParseListOfFloatAsVector( char separator = ',', int maxCount = int_max ) const;
11994 
12002  GenericVector<double> ParseListOfDoubleAsVector( char separator = ',', int maxCount = int_max ) const;
12003 
12004 #endif // !__PCL_NO_STRING_VECTOR
12005 
12033  double SexagesimalToDouble( const String& separator = ':' ) const
12034  {
12035  int sign, s1, s2; double s3;
12036  ParseSexagesimal( sign, s1, s2, s3, separator );
12037  return sign*(s1 + (s2 + s3/60)/60);
12038  }
12039 
12053  double SexagesimalToDouble( const Array<char_type>& separators ) const
12054  {
12055  int sign, s1, s2; double s3;
12056  ParseSexagesimal( sign, s1, s2, s3, separators );
12057  return sign*(s1 + (s2 + s3/60)/60);
12058  }
12059 
12077  bool TrySexagesimalToDouble( double& value, const String& separator = ':' ) const noexcept
12078  {
12079  int sign, s1, s2; double s3;
12080  if ( TryParseSexagesimal( sign, s1, s2, s3, separator ) )
12081  {
12082  value = sign*(s1 + (s2 + s3/60)/60);
12083  return true;
12084  }
12085  return false;
12086  }
12087 
12100  bool TrySexagesimalToDouble( double& value, const Array<char_type>& separators ) const noexcept
12101  {
12102  int sign, s1, s2; double s3;
12103  if ( TryParseSexagesimal( sign, s1, s2, s3, separators ) )
12104  {
12105  value = sign*(s1 + (s2 + s3/60)/60);
12106  return true;
12107  }
12108  return false;
12109  }
12110 
12137  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const String& separator = ':' ) const;
12138 
12153  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const Array<char_type>& separators ) const;
12154 
12169  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const String& separator = ':' ) const noexcept;
12170 
12184  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const Array<char_type>& separators ) const noexcept;
12185 
12210  static String ToSexagesimal( int sign, double s1, double s2, double s3,
12212 
12223  static String ToSexagesimal( double d, const SexagesimalConversionOptions& options = SexagesimalConversionOptions() )
12224  {
12225  return ToSexagesimal( (d < 0) ? -1 : +1, Abs( d ), 0, 0, options );
12226  }
12227 
12251  void ParseISO8601DateTime( int& year, int& month, int& day, double& dayf, double& tz ) const;
12252 
12266  bool TryParseISO8601DateTime( int& year, int& month, int& day, double& dayf, double& tz ) const noexcept;
12267 
12291  static String ToISO8601DateTime( int year, int month, int day, double dayf, double tz = 0,
12293 
12305 
12317 
12324  static String Random( size_type n, RandomizationOptions options = RandomizationOption::Default );
12325 
12337  static String UUID();
12338 };
12339 
12340 // ----------------------------------------------------------------------------
12341 // ----------------------------------------------------------------------------
12342 
12344 {
12345  size_type len = uchar_traits::Length( t );
12346  if ( p < len )
12347  {
12348  m_data->Allocate( n = pcl::Min( n, len-p ) );
12349  t += p;
12350  for ( iterator i = m_data->string; i < m_data->end; ++i, ++t )
12351  *i = char_type( uint8( *t ) );
12352  }
12353 }
12354 
12356 {
12357  size_type len = uchar_traits::Length( t );
12358  if ( len > 0 )
12359  {
12360  MaybeReallocate( len );
12361  for ( iterator i = m_data->string; i < m_data->end; ++i, ++t )
12362  *i = char_type( uint8( *t ) );
12363  }
12364  else
12365  Clear();
12366 
12367  return *this;
12368 }
12369 
12371 {
12372  return String::UTF8ToUTF16( Begin(), i, n );
12373 }
12374 
12375 // ----------------------------------------------------------------------------
12376 
12386 inline String operator +( const String::string_base& s1, const String::string_base& s2 )
12387 {
12388  String s = s1;
12389  s.Append( s2 );
12390  return s;
12391 }
12392 
12398 inline String operator +( String::string_base&& s1, const String::string_base& s2 )
12399 {
12400  s1.Append( s2 );
12401  return String( std::move( s1 ) );
12402 }
12403 
12409 inline String operator +( String&& s1, const String::string_base& s2 )
12410 {
12411  s1.Append( s2 );
12412  return std::move( s1 );
12413 }
12414 
12420 inline String operator +( const String::string_base& s1, String::string_base&& s2 )
12421 {
12422  s2.Prepend( s1 );
12423  return String( std::move( s2 ) );
12424 }
12425 
12431 inline String operator +( const String::string_base& s1, String&& s2 )
12432 {
12433  s2.Prepend( s1 );
12434  return std::move( s2 );
12435 }
12436 
12442 inline String operator +( String::string_base&& s1, String::string_base&& s2 )
12443 {
12444  s1.Append( s2 );
12445  return String( std::move( s1 ) );
12446 }
12447 
12454 {
12455  s1.Append( s2 );
12456  return std::move( s1 );
12457 }
12458 
12465 {
12466  s1.Append( s2 );
12467  return String( std::move( s1 ) );
12468 }
12469 
12475 inline String operator +( String&& s1, String&& s2 )
12476 {
12477  s1.Append( s2 );
12478  return std::move( s1 );
12479 }
12480 
12481 // ----------------------------------------------------------------------------
12482 
12489 {
12490  String s = s1;
12491  s.Append( t2 );
12492  return s;
12493 }
12494 
12501 {
12502  s1.Append( t2 );
12503  return String( std::move( s1 ) );
12504 }
12505 
12512 {
12513  s1.Append( t2 );
12514  return std::move( s1 );
12515 }
12516 
12523 {
12524  String s = s2;
12525  s.Prepend( t1 );
12526  return s;
12527 }
12528 
12535 {
12536  s2.Prepend( t1 );
12537  return String( std::move( s2 ) );
12538 }
12539 
12546 {
12547  s2.Prepend( t1 );
12548  return std::move( s2 );
12549 }
12550 
12551 // ----------------------------------------------------------------------------
12552 
12558 inline String operator +( const String::string_base& s1, String::char_type c2 )
12559 {
12560  String s = s1;
12561  s.Append( c2 );
12562  return s;
12563 }
12564 
12570 inline String operator +( String::string_base&& s1, String::char_type c2 )
12571 {
12572  s1.Append( c2 );
12573  return String( std::move( s1 ) );
12574 }
12575 
12582 {
12583  s1.Append( c2 );
12584  return std::move( s1 );
12585 }
12586 
12592 inline String operator +( String::char_type c1, const String::string_base& s2 )
12593 {
12594  String s = s2;
12595  s.Prepend( c1 );
12596  return s;
12597 }
12598 
12604 inline String operator +( String::char_type c1, String::string_base&& s2 )
12605 {
12606  s2.Prepend( c1 );
12607  return String( std::move( s2 ) );
12608 }
12609 
12616 {
12617  s2.Prepend( c1 );
12618  return std::move( s2 );
12619 }
12620 
12621 // ----------------------------------------------------------------------------
12622 
12628 inline String operator +( const String::string_base& s1, const char16_t* t2 )
12629 {
12630  String s = s1;
12631  s.Append( t2 );
12632  return s;
12633 }
12634 
12640 inline String operator +( String::string_base&& s1, const char16_t* t2 )
12641 {
12642  String s = std::move( s1 );
12643  s.Append( t2 );
12644  return s;
12645 }
12646 
12652 inline String operator +( String&& s1, const char16_t* t2 )
12653 {
12654  s1.Append( t2 );
12655  return std::move( s1 );
12656 }
12657 
12663 inline String operator +( const char16_t* t1, const String::string_base& s2 )
12664 {
12665  String s = s2;
12666  s.Prepend( t1 );
12667  return s;
12668 }
12669 
12675 inline String operator +( const char16_t* t1, String::string_base&& s2 )
12676 {
12677  String s = std::move( s2 );
12678  s.Prepend( t1 );
12679  return s;
12680 }
12681 
12687 inline String operator +( const char16_t* t1, String&& s2 )
12688 {
12689  s2.Prepend( t1 );
12690  return std::move( s2 );
12691 }
12692 
12693 // ----------------------------------------------------------------------------
12694 
12700 inline String operator +( const String::string_base& s1, char16_t c2 )
12701 {
12702  String s = s1;
12703  s.Append( c2 );
12704  return s;
12705 }
12706 
12712 inline String operator +( String::string_base&& s1, char16_t c2 )
12713 {
12714  String s = std::move( s1 );
12715  s.Append( c2 );
12716  return s;
12717 }
12718 
12724 inline String operator +( String&& s1, char16_t c2 )
12725 {
12726  s1.Append( c2 );
12727  return std::move( s1 );
12728 }
12729 
12735 inline String operator +( char16_t c1, const String::string_base& s2 )
12736 {
12737  String s = s2;
12738  s.Prepend( c1 );
12739  return s;
12740 }
12741 
12747 inline String operator +( char16_t c1, String::string_base&& s2 )
12748 {
12749  String s = std::move( s2 );
12750  s.Prepend( c1 );
12751  return s;
12752 }
12753 
12759 inline String operator +( char16_t c1, String&& s2 )
12760 {
12761  s2.Prepend( c1 );
12762  return std::move( s2 );
12763 }
12764 
12765 // ----------------------------------------------------------------------------
12766 
12772 inline String operator +( const String::string_base& s1, const wchar_t* t2 )
12773 {
12774  String s = s1;
12775  s.Append( t2 );
12776  return s;
12777 }
12778 
12784 inline String operator +( String::string_base&& s1, const wchar_t* t2 )
12785 {
12786  String s = std::move( s1 );
12787  s.Append( t2 );
12788  return s;
12789 }
12790 
12796 inline String operator +( String&& s1, const wchar_t* t2 )
12797 {
12798  s1.Append( t2 );
12799  return std::move( s1 );
12800 }
12801 
12807 inline String operator +( const wchar_t* t1, const String::string_base& s2 )
12808 {
12809  String s = s2;
12810  s.Prepend( t1 );
12811  return s;
12812 }
12813 
12819 inline String operator +( const wchar_t* t1, String::string_base&& s2 )
12820 {
12821  String s = std::move( s2 );
12822  s.Prepend( t1 );
12823  return s;
12824 }
12825 
12831 inline String operator +( const wchar_t* t1, String&& s2 )
12832 {
12833  s2.Prepend( t1 );
12834  return std::move( s2 );
12835 }
12836 
12837 // ----------------------------------------------------------------------------
12838 
12844 inline String operator +( const String::string_base& s1, wchar_t c2 )
12845 {
12846  String s = s1;
12847  s.Append( c2 );
12848  return s;
12849 }
12850 
12856 inline String operator +( String::string_base&& s1, wchar_t c2 )
12857 {
12858  String s = std::move( s1 );
12859  s.Append( c2 );
12860  return s;
12861 }
12862 
12868 inline String operator +( String&& s1, wchar_t c2 )
12869 {
12870  s1.Append( c2 );
12871  return std::move( s1 );
12872 }
12873 
12879 inline String operator +( wchar_t c1, const String::string_base& s2 )
12880 {
12881  String s = s2;
12882  s.Prepend( c1 );
12883  return s;
12884 }
12885 
12891 inline String operator +( wchar_t c1, String::string_base&& s2 )
12892 {
12893  String s = std::move( s2 );
12894  s.Prepend( c1 );
12895  return s;
12896 }
12897 
12903 inline String operator +( wchar_t c1, String&& s2 )
12904 {
12905  s2.Prepend( c1 );
12906  return std::move( s2 );
12907 }
12908 
12909 // ----------------------------------------------------------------------------
12910 
12917 {
12918  String s = s1;
12919  s.Append( s2 );
12920  return s;
12921 }
12922 
12929 {
12930  String s = std::move( s1 );
12931  s.Append( s2 );
12932  return s;
12933 }
12934 
12941 {
12942  s1.Append( s2 );
12943  return std::move( s1 );
12944 }
12945 
12952 {
12953  String s = s2;
12954  s.Prepend( s1 );
12955  return s;
12956 }
12957 
12964 {
12965  String s = std::move( s2 );
12966  s.Prepend( s1 );
12967  return s;
12968 }
12969 
12976 {
12977  s2.Prepend( s1 );
12978  return std::move( s2 );
12979 }
12980 
12981 // ----------------------------------------------------------------------------
12982 
12989 {
12990  String s = s1;
12991  s.Append( t2 );
12992  return s;
12993 }
12994 
13001 {
13002  String s = std::move( s1 );
13003  s.Append( t2 );
13004  return s;
13005 }
13006 
13013 {
13014  s1.Append( t2 );
13015  return std::move( s1 );
13016 }
13017 
13024 {
13025  String s = s2;
13026  s.Prepend( t1 );
13027  return s;
13028 }
13029 
13036 {
13037  String s = std::move( s2 );
13038  s.Prepend( t1 );
13039  return s;
13040 }
13041 
13048 {
13049  s2.Prepend( t1 );
13050  return std::move( s2 );
13051 }
13052 
13053 // ----------------------------------------------------------------------------
13054 
13061 {
13062  String s = s1;
13063  s.Append( c2 );
13064  return s;
13065 }
13066 
13073 {
13074  s1.Append( String::char_type( c2 ) );
13075  return String( std::move( s1 ) );
13076 }
13077 
13084 {
13085  s1.Append( c2 );
13086  return std::move( s1 );
13087 }
13088 
13095 {
13096  String s = s2;
13097  s.Prepend( c1 );
13098  return s;
13099 }
13100 
13107 {
13108  s2.Prepend( String::char_type( c1 ) );
13109  return String( std::move( s2 ) );
13110 }
13111 
13118 {
13119  s2.Prepend( c1 );
13120  return std::move( s2 );
13121 }
13122 
13123 // ----------------------------------------------------------------------------
13124 
13131 {
13132  s1.Append( s2 );
13133  return s1;
13134 }
13135 
13141 inline String& operator <<( String&& s1, const String::string_base& s2 )
13142 {
13143  s1.Append( s2 );
13144  return s1;
13145 }
13146 
13153 {
13154  s1.Append( t2 );
13155  return s1;
13156 }
13157 
13164 {
13165  s1.Append( t2 );
13166  return s1;
13167 }
13168 
13175 {
13176  s1.Append( c2 );
13177  return s1;
13178 }
13179 
13186 {
13187  s1.Append( c2 );
13188  return s1;
13189 }
13190 
13196 inline String& operator <<( String& s1, const char16_t* t2 )
13197 {
13198  s1.Append( t2 );
13199  return s1;
13200 }
13201 
13207 inline String& operator <<( String&& s1, const char16_t* t2 )
13208 {
13209  s1.Append( t2 );
13210  return s1;
13211 }
13212 
13218 inline String& operator <<( String& s1, char16_t c2 )
13219 {
13220  s1.Append( c2 );
13221  return s1;
13222 }
13223 
13229 inline String& operator <<( String&& s1, char16_t c2 )
13230 {
13231  s1.Append( c2 );
13232  return s1;
13233 }
13234 
13240 inline String& operator <<( String& s1, const wchar_t* t2 )
13241 {
13242  s1.Append( t2 );
13243  return s1;
13244 }
13245 
13251 inline String& operator <<( String&& s1, const wchar_t* t2 )
13252 {
13253  s1.Append( t2 );
13254  return s1;
13255 }
13256 
13262 inline String& operator <<( String& s1, wchar_t c2 )
13263 {
13264  s1.Append( c2 );
13265  return s1;
13266 }
13267 
13273 inline String& operator <<( String&& s1, wchar_t c2 )
13274 {
13275  s1.Append( c2 );
13276  return s1;
13277 }
13278 
13285 {
13286  s1.Append( s2 );
13287  return s1;
13288 }
13289 
13295 inline String& operator <<( String&& s1, const String::string8_base& s2 )
13296 {
13297  s1.Append( s2 );
13298  return s1;
13299 }
13300 
13307 {
13308  s1.Append( t2 );
13309  return s1;
13310 }
13311 
13318 {
13319  s1.Append( t2 );
13320  return s1;
13321 }
13322 
13329 {
13330  s1.Append( c2 );
13331  return s1;
13332 }
13333 
13340 {
13341  s1.Append( c2 );
13342  return s1;
13343 }
13344 
13345 // ----------------------------------------------------------------------------
13346 
13355 inline bool operator ==( const String& s1, const char16_t* t2 ) noexcept
13356 {
13357  return s1.CompareCodePoints( t2 ) == 0;
13358 }
13359 
13366 inline bool operator <( const String& s1, const char16_t* t2 ) noexcept
13367 {
13368  return s1.CompareCodePoints( t2 ) < 0;
13369 }
13370 
13377 inline bool operator <=( const String& s1, const char16_t* t2 ) noexcept
13378 {
13379  return s1.CompareCodePoints( t2 ) <= 0;
13380 }
13381 
13388 inline bool operator >( const String& s1, const char16_t* t2 ) noexcept
13389 {
13390  return s1.CompareCodePoints( t2 ) > 0;
13391 }
13392 
13399 inline bool operator >=( const String& s1, const char16_t* t2 ) noexcept
13400 {
13401  return s1.CompareCodePoints( t2 ) >= 0;
13402 }
13403 
13404 // ----------------------------------------------------------------------------
13405 
13410 inline bool operator ==( const char16_t* t1, const String& s2 ) noexcept
13411 {
13412  return s2.CompareCodePoints( t1 ) == 0;
13413 }
13414 
13421 inline bool operator <( const char16_t* t1, const String& s2 ) noexcept
13422 {
13423  return s2.CompareCodePoints( t1 ) > 0;
13424 }
13425 
13432 inline bool operator <=( const char16_t* t1, const String& s2 ) noexcept
13433 {
13434  return s2.CompareCodePoints( t1 ) >= 0;
13435 }
13436 
13443 inline bool operator >( const char16_t* t1, const String& s2 ) noexcept
13444 {
13445  return s2.CompareCodePoints( t1 ) < 0;
13446 }
13447 
13454 inline bool operator >=( const char16_t* t1, const String& s2 ) noexcept
13455 {
13456  return s2.CompareCodePoints( t1 ) <= 0;
13457 }
13458 
13459 // ----------------------------------------------------------------------------
13460 
13465 inline bool operator ==( const String& s1, char16_t c2 ) noexcept
13466 {
13467  return s1.CompareCodePoints( c2 ) == 0;
13468 }
13469 
13476 inline bool operator <( const String& s1, char16_t c2 ) noexcept
13477 {
13478  return s1.CompareCodePoints( c2 ) < 0;
13479 }
13480 
13487 inline bool operator <=( const String& s1, char16_t c2 ) noexcept
13488 {
13489  return s1.CompareCodePoints( c2 ) <= 0;
13490 }
13491 
13498 inline bool operator >( const String& s1, char16_t c2 ) noexcept
13499 {
13500  return s1.CompareCodePoints( c2 ) > 0;
13501 }
13502 
13509 inline bool operator >=( const String& s1, char16_t c2 ) noexcept
13510 {
13511  return s1.CompareCodePoints( c2 ) >= 0;
13512 }
13513 
13514 // ----------------------------------------------------------------------------
13515 
13520 inline bool operator ==( char16_t c1, const String& s2 ) noexcept
13521 {
13522  return s2.CompareCodePoints( c1 ) == 0;
13523 }
13524 
13531 inline bool operator <( char16_t c1, const String& s2 ) noexcept
13532 {
13533  return s2.CompareCodePoints( c1 ) > 0;
13534 }
13535 
13542 inline bool operator <=( char16_t c1, const String& s2 ) noexcept
13543 {
13544  return s2.CompareCodePoints( c1 ) >= 0;
13545 }
13546 
13553 inline bool operator >( char16_t c1, const String& s2 ) noexcept
13554 {
13555  return s2.CompareCodePoints( c1 ) < 0;
13556 }
13557 
13564 inline bool operator >=( char16_t c1, const String& s2 ) noexcept
13565 {
13566  return s2.CompareCodePoints( c1 ) <= 0;
13567 }
13568 
13569 // ----------------------------------------------------------------------------
13570 
13575 inline bool operator ==( const String& s1, const wchar_t* t2 ) noexcept
13576 {
13577  return s1.CompareCodePoints( t2 ) == 0;
13578 }
13579 
13586 inline bool operator <( const String& s1, const wchar_t* t2 ) noexcept
13587 {
13588  return s1.CompareCodePoints( t2 ) < 0;
13589 }
13590 
13597 inline bool operator <=( const String& s1, const wchar_t* t2 ) noexcept
13598 {
13599  return s1.CompareCodePoints( t2 ) <= 0;
13600 }
13601 
13608 inline bool operator >( const String& s1, const wchar_t* t2 ) noexcept
13609 {
13610  return s1.CompareCodePoints( t2 ) > 0;
13611 }
13612 
13619 inline bool operator >=( const String& s1, const wchar_t* t2 ) noexcept
13620 {
13621  return s1.CompareCodePoints( t2 ) >= 0;
13622 }
13623 
13624 // ----------------------------------------------------------------------------
13625 
13630 inline bool operator ==( const wchar_t* t1, const String& s2 ) noexcept
13631 {
13632  return s2.CompareCodePoints( t1 ) == 0;
13633 }
13634 
13641 inline bool operator <( const wchar_t* t1, const String& s2 ) noexcept
13642 {
13643  return s2.CompareCodePoints( t1 ) > 0;
13644 }
13645 
13652 inline bool operator <=( const wchar_t* t1, const String& s2 ) noexcept
13653 {
13654  return s2.CompareCodePoints( t1 ) >= 0;
13655 }
13656 
13663 inline bool operator >( const wchar_t* t1, const String& s2 ) noexcept
13664 {
13665  return s2.CompareCodePoints( t1 ) < 0;
13666 }
13667 
13674 inline bool operator >=( const wchar_t* t1, const String& s2 ) noexcept
13675 {
13676  return s2.CompareCodePoints( t1 ) <= 0;
13677 }
13678 
13679 // ----------------------------------------------------------------------------
13680 
13685 inline bool operator ==( const String& s1, wchar_t c2 ) noexcept
13686 {
13687  return s1.CompareCodePoints( c2 ) == 0;
13688 }
13689 
13696 inline bool operator <( const String& s1, wchar_t c2 ) noexcept
13697 {
13698  return s1.CompareCodePoints( c2 ) < 0;
13699 }
13700 
13707 inline bool operator <=( const String& s1, wchar_t c2 ) noexcept
13708 {
13709  return s1.CompareCodePoints( c2 ) <= 0;
13710 }
13711 
13718 inline bool operator >( const String& s1, wchar_t c2 ) noexcept
13719 {
13720  return s1.CompareCodePoints( c2 ) > 0;
13721 }
13722 
13729 inline bool operator >=( const String& s1, wchar_t c2 ) noexcept
13730 {
13731  return s1.CompareCodePoints( c2 ) >= 0;
13732 }
13733 
13734 // ----------------------------------------------------------------------------
13735 
13740 inline bool operator ==( wchar_t c1, const String& s2 ) noexcept
13741 {
13742  return s2.CompareCodePoints( c1 ) == 0;
13743 }
13744 
13751 inline bool operator <( wchar_t c1, const String& s2 ) noexcept
13752 {
13753  return s2.CompareCodePoints( c1 ) > 0;
13754 }
13755 
13762 inline bool operator <=( wchar_t c1, const String& s2 ) noexcept
13763 {
13764  return s2.CompareCodePoints( c1 ) >= 0;
13765 }
13766 
13773 inline bool operator >( wchar_t c1, const String& s2 ) noexcept
13774 {
13775  return s2.CompareCodePoints( c1 ) < 0;
13776 }
13777 
13784 inline bool operator >=( wchar_t c1, const String& s2 ) noexcept
13785 {
13786  return s2.CompareCodePoints( c1 ) <= 0;
13787 }
13788 
13789 // ----------------------------------------------------------------------------
13790 
13795 inline bool operator ==( const String& s1, String::const_c_string8 t2 ) noexcept
13796 {
13797  return s1.CompareCodePoints( t2 ) == 0;
13798 }
13799 
13806 inline bool operator <( const String& s1, String::const_c_string8 t2 ) noexcept
13807 {
13808  return s1.CompareCodePoints( t2 ) < 0;
13809 }
13810 
13817 inline bool operator <=( const String& s1, String::const_c_string8 t2 ) noexcept
13818 {
13819  return s1.CompareCodePoints( t2 ) <= 0;
13820 }
13821 
13828 inline bool operator >( const String& s1, String::const_c_string8 t2 ) noexcept
13829 {
13830  return s1.CompareCodePoints( t2 ) > 0;
13831 }
13832 
13839 inline bool operator >=( const String& s1, String::const_c_string8 t2 ) noexcept
13840 {
13841  return s1.CompareCodePoints( t2 ) >= 0;
13842 }
13843 
13844 // ----------------------------------------------------------------------------
13845 
13850 inline bool operator ==( String::const_c_string8 t1, const String& s2 ) noexcept
13851 {
13852  return s2.CompareCodePoints( t1 ) == 0;
13853 }
13854 
13861 inline bool operator <( String::const_c_string8 t1, const String& s2 ) noexcept
13862 {
13863  return s2.CompareCodePoints( t1 ) > 0;
13864 }
13865 
13872 inline bool operator <=( String::const_c_string8 t1, const String& s2 ) noexcept
13873 {
13874  return s2.CompareCodePoints( t1 ) >= 0;
13875 }
13876 
13883 inline bool operator >( String::const_c_string8 t1, const String& s2 ) noexcept
13884 {
13885  return s2.CompareCodePoints( t1 ) < 0;
13886 }
13887 
13894 inline bool operator >=( String::const_c_string8 t1, const String& s2 ) noexcept
13895 {
13896  return s2.CompareCodePoints( t1 ) <= 0;
13897 }
13898 
13899 // ----------------------------------------------------------------------------
13900 
13905 inline bool operator ==( const String& s1, String::char8_type c2 ) noexcept
13906 {
13907  return s1.CompareCodePoints( c2 ) == 0;
13908 }
13909 
13916 inline bool operator <( const String& s1, String::char8_type c2 ) noexcept
13917 {
13918  return s1.CompareCodePoints( c2 ) < 0;
13919 }
13920 
13927 inline bool operator <=( const String& s1, String::char8_type c2 ) noexcept
13928 {
13929  return s1.CompareCodePoints( c2 ) <= 0;
13930 }
13931 
13938 inline bool operator >( const String& s1, String::char8_type c2 ) noexcept
13939 {
13940  return s1.CompareCodePoints( c2 ) > 0;
13941 }
13942 
13949 inline bool operator >=( const String& s1, String::char8_type c2 ) noexcept
13950 {
13951  return s1.CompareCodePoints( c2 ) >= 0;
13952 }
13953 
13954 // ----------------------------------------------------------------------------
13955 
13960 inline bool operator ==( String::char8_type c1, const String& s2 ) noexcept
13961 {
13962  return s2.CompareCodePoints( c1 ) == 0;
13963 }
13964 
13971 inline bool operator <( String::char8_type c1, const String& s2 ) noexcept
13972 {
13973  return s2.CompareCodePoints( c1 ) > 0;
13974 }
13975 
13982 inline bool operator <=( String::char8_type c1, const String& s2 ) noexcept
13983 {
13984  return s2.CompareCodePoints( c1 ) >= 0;
13985 }
13986 
13993 inline bool operator >( String::char8_type c1, const String& s2 ) noexcept
13994 {
13995  return s2.CompareCodePoints( c1 ) < 0;
13996 }
13997 
14004 inline bool operator >=( String::char8_type c1, const String& s2 ) noexcept
14005 {
14006  return s2.CompareCodePoints( c1 ) <= 0;
14007 }
14008 
14009 // ----------------------------------------------------------------------------
14010 
14011 #ifndef __PCL_NO_STRING_OSTREAM
14012 
14013 inline std::wostream& operator <<( std::wostream& o, const String& s )
14014 {
14015 #ifdef __PCL_WINDOWS
14016  return o << reinterpret_cast<const wchar_t*>( s.c_str() );
14017 #else
14018  Array<wchar_t> w = s.ToWCharArray();
14019  return o << w.Begin();
14020 #endif
14021 }
14022 
14023 inline std::ostream& operator <<( std::ostream& o, const String& s )
14024 {
14025  return o << s.ToUTF8();
14026 }
14027 
14028 #endif // __PCL_NO_STRING_OSTREAM
14029 
14030 // ----------------------------------------------------------------------------
14031 
14032 } // pcl
14033 
14034 #endif // __PCL_String_h
14035 
14036 // ----------------------------------------------------------------------------
14037 // EOF pcl/String.h - Released 2024-12-28T16:53:48Z
Provides memory allocation for PCL containers.
Definition: Allocator.h:132
Generic dynamic array.
Definition: Array.h:100
bool IsEmpty() const noexcept
Definition: Array.h:324
T * iterator
Definition: Array.h:125
A template instantiation of GenericCharTraits for char16_type.
Definition: CharTraits.h:1119
static size_type Length(const char_type *__restrict__ s) noexcept
Definition: CharTraits.h:1139
Generic complex number.
Definition: Complex.h:84
constexpr T Imag() const noexcept
Definition: Complex.h:136
constexpr T Real() const noexcept
Definition: Complex.h:120
Root base class of all PCL containers of objects.
Definition: Container.h:78
const T const_item_type
Definition: Container.h:89
A type-safe collection of enumerated flags.
Definition: Flags.h:85
static constexpr char_type LF() noexcept
Definition: CharTraits.h:599
static constexpr char_type Colon() noexcept
Definition: CharTraits.h:615
static constexpr char_type Null() noexcept
Definition: CharTraits.h:567
static constexpr char_type Hyphen() noexcept
Definition: CharTraits.h:631
static constexpr char_type Blank() noexcept
Definition: CharTraits.h:575
static constexpr char_type Comma() noexcept
Definition: CharTraits.h:607
static constexpr char_type Tab() noexcept
Definition: CharTraits.h:583
Generic character string.
Definition: String.h:493
size_type FindFirstIC(const_c_string t, size_type i=0) const noexcept
Definition: String.h:3058
iterator begin()
Definition: String.h:1125
void Append(const_c_string t)
Definition: String.h:1806
int CompareIC(const_c_string t, bool localeAware=true) const noexcept
Definition: String.h:3864
void JustifyCenter(size_type width, char_type fill=R::Blank())
Definition: String.h:3577
int CompareCodePoints(const GenericString< T, R1, A1 > &s, bool caseSensitive=true) const noexcept
Definition: String.h:3652
static size_type DeleteFreeList()
Definition: String.h:4284
iterator end()
Definition: String.h:1141
void Transfer(GenericString &s)
Definition: String.h:1224
bool WildMatch(const GenericString< T, R1, A1 > &pattern, bool caseSensitive=true) const noexcept
Definition: String.h:3914
bool ContainsIC(const_c_string t) const noexcept
Definition: String.h:3279
void ToUppercase()
Definition: String.h:4021
size_type FindFirst(const_c_string t, size_type i=0) const noexcept
Definition: String.h:3014
reverse_iterator ReverseBegin()
Definition: String.h:1050
const_iterator begin() const noexcept
Definition: String.h:1133
size_type Find(const GenericString< T, R1, A1 > &s, size_type i=0) const noexcept
Definition: String.h:3086
void ReplaceString(const GenericString< T, R1, A1 > &s1, const GenericString< T, R2, A2 > &s2, size_type i=0)
Definition: String.h:2101
bool StartsWith(const_c_string t) const noexcept
Definition: String.h:2860
void Insert(size_type i, const_c_string t, size_type n)
Definition: String.h:1741
const T * const_c_string
Definition: String.h:536
void JustifyRight(size_type width, char_type fill=R::Blank())
Definition: String.h:3558
void Fill(char_type c)
Definition: String.h:1398
void ReplaceChar(char_type c1, char_type c2, size_type i=0, size_type n=maxPos)
Definition: String.h:2078
bool StartsWithIC(char_type c) const noexcept
Definition: String.h:2913
void Add(const_c_string t, size_type n)
Definition: String.h:1852
void Swap(GenericString &s) noexcept
Definition: String.h:1384
void Insert(size_type i, char_type c, size_type n=1)
Definition: String.h:1753
GenericString ResizedToNullTerminated() const
Definition: String.h:1578
size_type BreakIC(C &list, char_type c, bool trim=false, size_type i=0) const
Definition: String.h:2781
GenericString SetToLength(size_type n) const
Definition: String.h:1553
void TrimRight()
Definition: String.h:3337
iterator At(size_type i)
Definition: String.h:899
void DeleteLeft(size_type i)
Definition: String.h:2194
void EnsureDoubleQuoted()
Definition: String.h:3467
bool EndsWithIC(char_type c) const noexcept
Definition: String.h:2991
void c_copy(iterator dst, size_type maxCharsToCopy, size_type i=0) const noexcept
Definition: String.h:1672
GenericString Left(size_type n) const
Definition: String.h:2318
void Prepend(const GenericString< T, R1, A1 > &s)
Definition: String.h:1890
size_type FindIC(const_c_string t, size_type i=0) const noexcept
Definition: String.h:3119
GenericString(char_type c, size_type n=1)
Definition: String.h:675
void Assign(const_iterator i, const_iterator j)
Definition: String.h:1317
char_type LastChar() const noexcept
Definition: String.h:2837
size_type FindLast(const_c_string t, size_type r=maxPos) const noexcept
Definition: String.h:3158
size_type FindIC(const GenericString< T, R1, A1 > &s, size_type i=0) const noexcept
Definition: String.h:3111
void Assign(const_c_string t, size_type i, size_type n)
Definition: String.h:1353
GenericString(const_iterator i, const_iterator j)
Definition: String.h:631
void Assign(const GenericString &s, size_type i, size_type n)
Definition: String.h:1273
void EnsureUnique()
Definition: String.h:730
GenericString Enclosed(char_type c) const
Definition: String.h:3430
GenericString Suffix(size_type i) const
Definition: String.h:2364
void Insert(size_type i, const_iterator p, const_iterator q)
Definition: String.h:1713
void EnsureEnclosed(char_type c)
Definition: String.h:3386
reverse_iterator ReverseEnd()
Definition: String.h:1084
void ToCaseFolded()
Definition: String.h:3993
size_type FindLast(const GenericString< T, R1, A1 > &s, size_type r=maxPos) const noexcept
Definition: String.h:3142
const_iterator end() const noexcept
Definition: String.h:1149
GenericString Lowercase() const
Definition: String.h:4046
bool Contains(const GenericString< T, R1, A1 > &s) const noexcept
Definition: String.h:3240
size_type FindFirst(char_type c, size_type i=0) const noexcept
Definition: String.h:3026
GenericString(std::initializer_list< char_type > l)
Definition: String.h:651
void Assign(std::initializer_list< char_type > l)
Definition: String.h:1335
void Insert(size_type i, const_c_string t)
Definition: String.h:1727
void Add(char_type c, size_type n=1)
Definition: String.h:1870
GenericString TrimmedRight() const
Definition: String.h:3373
void Reserve(size_type n)
Definition: String.h:1480
GenericString Unquoted() const
Definition: String.h:3522
bool StartsWith(char_type c) const noexcept
Definition: String.h:2874
uint64 Hash64(uint64 seed=0) const noexcept
Definition: String.h:4250
void Assign(const GenericString &s)
Definition: String.h:1193
void ReplaceStringIC(const GenericString< T, R1, A1 > &s1, const GenericString< T, R2, A2 > &s2, size_type i=0)
Definition: String.h:2125
bool StartsWithIC(const GenericString< T, R1, A1 > &s) const noexcept
Definition: String.h:2884
GenericString Uppercase() const
Definition: String.h:4057
bool ContainsIC(const GenericString< T, R1, A1 > &s) const noexcept
Definition: String.h:3268
size_type FindLast(char_type c, size_type r=maxPos) const noexcept
Definition: String.h:3170
GenericString SingleQuoted() const
Definition: String.h:3454
char_type FirstChar() const noexcept
Definition: String.h:2828
void Append(const_c_string t, size_type n)
Definition: String.h:1798
void Assign(const_c_string t)
Definition: String.h:1285
GenericString Trimmed() const
Definition: String.h:3349
void Prepend(const_c_string t)
Definition: String.h:1931
GenericString Sorted() const
Definition: String.h:4105
size_type IndexAt(const_iterator i) const noexcept
Definition: String.h:1115
GenericString LeftJustified(size_type width, char_type fill=R::Blank()) const
Definition: String.h:3595
size_type FindIC(char_type c, size_type i=0) const noexcept
Definition: String.h:3127
static size_type BytesPerChar() noexcept
Definition: String.h:750
void Replace(size_type i, size_type n, const GenericString< T, R1, A1 > &s)
Definition: String.h:1969
void DeleteCharIC(char_type c, size_type i=0)
Definition: String.h:2216
GenericString Right(size_type n) const
Definition: String.h:2340
bool IsValid() const noexcept
Definition: String.h:818
GenericString RightJustified(size_type width, char_type fill=R::Blank()) const
Definition: String.h:3608
bool WildMatch(const_c_string pattern, bool caseSensitive=true) const noexcept
Definition: String.h:3953
size_type Break(C &list, char_type c, bool trim=false, size_type i=0) const
Definition: String.h:2518
int Compare(const GenericString< T, R1, A1 > &s, bool caseSensitive=true, bool localeAware=true) const noexcept
Definition: String.h:3745
void ToLowercase()
Definition: String.h:4007
bool StartsWith(const GenericString< T, R1, A1 > &s) const noexcept
Definition: String.h:2846
size_type UpperBound() const noexcept
Definition: String.h:856
GenericString Prefix(size_type i) const
Definition: String.h:2375
const_reverse_iterator ReverseBegin() const noexcept
Definition: String.h:1066
int CompareCodePoints(const_c_string t, bool caseSensitive=true) const noexcept
Definition: String.h:3681
int CompareIC(char_type c, bool localeAware=true) const noexcept
Definition: String.h:3893
GenericString(const GenericString &s)
Definition: String.h:583
typename container_type::const_item_type const_item_type
Definition: String.h:506
bool EndsWithIC(const GenericString< T, R1, A1 > &s) const noexcept
Definition: String.h:2961
bool IsEmpty() const noexcept
Definition: String.h:830
bool HasWildcards() const noexcept
Definition: String.h:3981
bool IsValidIdentifier() const noexcept
Definition: String.h:4229
const allocator & Allocator() const noexcept
Definition: String.h:867
void DeleteRight(size_type i)
Definition: String.h:2185
bool StartsWithIC(const_c_string t) const noexcept
Definition: String.h:2898
int CompareCodePoints(char_type c, bool caseSensitive=true) const noexcept
Definition: String.h:3713
GenericString CenterJustified(size_type width, char_type fill=R::Blank()) const
Definition: String.h:3621
void Add(const_c_string t)
Definition: String.h:1861
void Append(const_iterator i, const_iterator j)
Definition: String.h:1789
void DeleteString(const GenericString< T, R1, A1 > &s, size_type i=0)
Definition: String.h:2227
void Fill(char_type c, size_type i, size_type n=maxPos)
Definition: String.h:1427
void Replace(size_type i, size_type n, const_c_string t)
Definition: String.h:2008
iterator Begin()
Definition: String.h:988
void SetLength(size_type n)
Definition: String.h:1523
bool WildMatchIC(const GenericString< T, R1, A1 > &pattern) const noexcept
Definition: String.h:3933
size_type FindFirstIC(char_type c, size_type i=0) const noexcept
Definition: String.h:3073
GenericString(const_c_string t, size_type i, size_type n)
Definition: String.h:660
bool IsAliasOf(const GenericString &s) const noexcept
Definition: String.h:716
bool IsNumeral() const noexcept
Definition: String.h:4153
void Prepend(const_iterator i, const_iterator j)
Definition: String.h:1913
GenericString Sorted(BP p) const
Definition: String.h:4132
void DeleteStringIC(const_c_string t, size_type i=0)
Definition: String.h:2262
void Prepend(char_type c, size_type n=1)
Definition: String.h:1949
bool IsSymbol() const noexcept
Definition: String.h:4175
bool EndsWith(char_type c) const noexcept
Definition: String.h:2951
void SecureFill(char c='\0') noexcept
Definition: String.h:1466
size_type Break(C &list, const Array< S > &ca, bool trim=false, size_type i=0) const
Definition: String.h:2583
bool Contains(char_type c) const noexcept
Definition: String.h:3256
GenericString Reversed() const
Definition: String.h:4082
void DeleteString(const_c_string t, size_type i=0)
Definition: String.h:2237
bool WildMatchIC(const_c_string pattern) const noexcept
Definition: String.h:3972
uint32 Hash32(uint32 seed=0) const noexcept
Definition: String.h:4263
uint64 Hash(uint64 seed=0) const noexcept
Definition: String.h:4272
size_type FindLastIC(char_type c, size_type r=maxPos) const noexcept
Definition: String.h:3226
void Delete(size_type i, size_type n=1)
Definition: String.h:2147
size_type FindFirstIC(const GenericString< T, R1, A1 > &s, size_type i=0) const noexcept
Definition: String.h:3043
size_type Size() const noexcept
Definition: String.h:761
void DeleteChar(char_type c, size_type i=0)
Definition: String.h:2204
void DeleteStringIC(const GenericString< T, R1, A1 > &s, size_type i=0)
Definition: String.h:2250
int CompareIC(const GenericString< T, R1, A1 > &s, bool localeAware=true) const noexcept
Definition: String.h:3838
GenericString(const_c_string t)
Definition: String.h:602
int Compare(const_c_string t, bool caseSensitive=true, bool localeAware=true) const noexcept
Definition: String.h:3778
const_iterator End() const noexcept
Definition: String.h:1032
size_type Break(C &list, const GenericString< T, R1, A1 > &s, bool trim=false, size_type i=0) const
Definition: String.h:2398
void JustifyLeft(size_type width, char_type fill=R::Blank())
Definition: String.h:3540
void ResizeToNullTerminated()
Definition: String.h:1569
void Add(const GenericString< T, R1, A1 > &s)
Definition: String.h:1834
size_type Find(const_c_string t, size_type i=0) const noexcept
Definition: String.h:3094
size_type LowerBound() const noexcept
Definition: String.h:843
void Append(const GenericString< T, R1, A1 > &s)
Definition: String.h:1766
void Replace(size_type i, size_type n, char_type c, size_type nc=1)
Definition: String.h:2043
bool Contains(const_c_string t) const noexcept
Definition: String.h:3248
void ReplaceString(const_c_string t1, const_c_string t2, size_type i=0)
Definition: String.h:2112
void ReplaceStringIC(const_c_string t1, const_c_string t2, size_type i=0)
Definition: String.h:2138
void SetAllocator(const allocator &a)
Definition: String.h:881
size_type FindFirst(const GenericString< T, R1, A1 > &s, size_type i=0) const noexcept
Definition: String.h:3002
size_type Capacity() const noexcept
Definition: String.h:785
iterator End()
Definition: String.h:1018
const T * const_iterator
Definition: String.h:546
size_type Available() const noexcept
Definition: String.h:797
void Prepend(const_c_string t, size_type n)
Definition: String.h:1922
void Sort(BP p)
Definition: String.h:4118
void ReplaceCharIC(char_type c1, char_type c2, size_type i=0, size_type n=maxPos)
Definition: String.h:2090
void EnsureSingleQuoted()
Definition: String.h:3443
bool ContainsIC(char_type c) const noexcept
Definition: String.h:3290
size_type BreakIC(C &list, const GenericString< T, R1, A1 > &s, bool trim=false, size_type i=0) const
Definition: String.h:2650
bool EndsWithIC(const_c_string t) const noexcept
Definition: String.h:2976
size_type Find(char_type c, size_type i=0) const noexcept
Definition: String.h:3102
size_type Break(C &list, const_c_string s, bool trim=false, size_type i=0) const
Definition: String.h:2458
void Transfer(GenericString &&s)
Definition: String.h:1239
GenericString DoubleQuoted() const
Definition: String.h:3478
size_type FindLastIC(const GenericString< T, R1, A1 > &s, size_type r=maxPos) const noexcept
Definition: String.h:3192
void Append(char_type c, size_type n=1)
Definition: String.h:1824
void Add(const_iterator i, const_iterator j)
Definition: String.h:1843
const_iterator Begin() const noexcept
Definition: String.h:1002
bool EndsWith(const_c_string t) const noexcept
Definition: String.h:2937
bool IsUnique() const noexcept
Definition: String.h:704
void Insert(size_type i, const GenericString< T, R1, A1 > &s)
Definition: String.h:1696
const_iterator At(size_type i) const noexcept
Definition: String.h:915
void Assign(char_type c, size_type n=1)
Definition: String.h:1370
GenericString CaseFolded() const
Definition: String.h:4035
c_string Release()
Definition: String.h:1648
GenericString Squeezed() const
Definition: String.h:1628
int Compare(char_type c, bool caseSensitive=true, bool localeAware=true) const noexcept
Definition: String.h:3812
const_c_string c_str() const noexcept
Definition: String.h:1162
GenericString Substring(size_type i, size_type n=maxPos) const
Definition: String.h:2293
const_reverse_iterator ReverseEnd() const noexcept
Definition: String.h:1100
GenericString TrimmedLeft() const
Definition: String.h:3361
size_type FindLastIC(const_c_string t, size_type r=maxPos) const noexcept
Definition: String.h:3211
size_type Length() const noexcept
Definition: String.h:772
bool IsValidIdentifier(distance_type &pos) const noexcept
Definition: String.h:4198
bool EndsWith(const GenericString< T, R1, A1 > &s) const noexcept
Definition: String.h:2922
GenericString(GenericString &&s)
Definition: String.h:592
size_type BreakIC(C &list, const_c_string s, bool trim=false, size_type i=0) const
Definition: String.h:2716
Generic vector of arbitrary length.
Definition: Vector.h:107
A template instantiation of GenericCharTraits for the char type.
Definition: CharTraits.h:859
Eight-bit string (ISO/IEC-8859-1 or UTF-8 string)
Definition: String.h:5443
IsoString(const ustring_base &s)
Definition: String.h:5596
IsoString(Complex< float > &x)
Definition: String.h:5818
IsoString EncodedHTMLSpecialChars() const
Definition: String.h:6384
IsoString()=default
IsoString(std::initializer_list< char_type > l)
Definition: String.h:5643
string_base::const_iterator const_iterator
Definition: String.h:5504
GenericVector< double > ParseListOfDoubleAsVector(char separator=',', int maxCount=int_max) const
IsoString(const ByteArray &B)
Definition: String.h:5683
bool TryToInt(int &value, int base) const noexcept
string_base::item_type item_type
Definition: String.h:5459
IsoString & ToSeparated(const C &c, char_type separator)
Definition: String.h:6151
static IsoString ToURLEncoded(const void *data, size_type length)
ustring_base::char_type uchar_type
Definition: String.h:5526
double ToDouble() const
IsoString & ToURLDecoded()
IsoString & ToCommaSeparated(const C &c)
Definition: String.h:6266
IsoString & ToHyphenated(const C &c)
Definition: String.h:6355
int AppendVFormat(const_c_string fmt, va_list paramList)
bool TryToUInt(unsigned &value) const noexcept
Definition: String.h:6977
IsoString & ToSeparated(const C &c, const_c_string separator)
Definition: String.h:6229
IsoString(short x)
Definition: String.h:5702
IsoString & ToSeparated(const C &c, char_type separator, AF append)
Definition: String.h:6174
IsoString URLDecoded() const
Definition: String.h:6556
string_base::iterator iterator
Definition: String.h:5499
bool TryToInt64(long long &value, int base) const noexcept
ByteArray FromBase64() const
IsoString(unsigned long x)
Definition: String.h:5752
IsoString(const string_base &s)
Definition: String.h:5564
static IsoString ToBase64URL(const void *data, size_type length)
Definition: String.h:7698
ByteArray FromHex() const
bool TryToInt64(long long &value) const noexcept
Definition: String.h:7062
IsoString(unsigned long long x)
Definition: String.h:5772
IsoString(long long x)
Definition: String.h:5762
static ByteArray FromURLEncoded(const C &c)
Definition: String.h:6493
string_base::const_item_type const_item_type
Definition: String.h:5464
IsoString(const IsoString &)=default
unsigned long long ToUInt64(int base) const
bool TryToDouble(double &value) const noexcept
IsoString(bool x)
Definition: String.h:5692
ustring_base::const_c_string const_c_ustring
Definition: String.h:5541
IsoString & ToEncodedHTMLSpecialChars()
void ParseISO8601DateTime(int &year, int &month, int &day, double &dayf, double &tz) const
IsoString(IsoString &&)=default
IsoString & ToColonSeparated(const C &c)
Definition: String.h:6281
bool TryToInt(int &value) const noexcept
Definition: String.h:6880
unsigned long long ToUInt64() const
Definition: String.h:7116
IsoString & ToSpaceSeparated(const C &c)
Definition: String.h:6296
IsoString(long double x)
Definition: String.h:5802
IsoString DecodedHTMLSpecialChars() const
Definition: String.h:6414
static IsoString ToURLDecoded(const C &c)
Definition: String.h:6534
IsoString & ToNewLineSeparated(const C &c)
Definition: String.h:6326
long ToInt(int base) const
IsoString(int x)
Definition: String.h:5722
static IsoString ToURLEncoded(const C &c)
Definition: String.h:6445
IsoString & ToSeparated(const C &c, const_c_string separator, AF append)
Definition: String.h:6251
IsoString(Complex< long double > &x)
Definition: String.h:5838
long long ToInt64() const
Definition: String.h:7033
static IsoString ToBase64(const void *data, size_type length)
IsoString & ToTabSeparated(const C &c)
Definition: String.h:6311
IsoString(unsigned int x)
Definition: String.h:5732
bool TryToUInt64(unsigned long long &value) const noexcept
Definition: String.h:7145
IsoString(Complex< double > &x)
Definition: String.h:5828
IsoString(string_base &&s)
Definition: String.h:5578
unsigned long ToUInt(int base) const
IsoString & ToDecodedHTMLSpecialChars()
IsoString(char_type c, size_type n=1)
Definition: String.h:5621
ByteArray ToByteArray() const
Definition: String.h:7734
static IsoString ToHex(const C &c)
Definition: String.h:7647
ByteArray FromBase64URL() const
Definition: String.h:7776
IsoString(const_c_ustring t)
Definition: String.h:5658
long ToInt() const
Definition: String.h:6852
IsoString & AppendFormat(const_c_string fmt,...)
Definition: String.h:6625
ustring_base::c_string c_ustring
Definition: String.h:5536
static IsoString ToHex(const void *data, size_type length)
GenericVector< float > ParseListOfFloatAsVector(char separator=',', int maxCount=int_max) const
IsoString(long x)
Definition: String.h:5742
static IsoString UUID()
IsoString & ToSeparated(const C &c, const IsoString &separator)
Definition: String.h:6190
static IsoString ToBase64URL(const C &c)
Definition: String.h:7722
IsoString & ToSeparated(const C &c, const IsoString &separator, AF append)
Definition: String.h:6213
static IsoString Random(size_type n, RandomizationOptions options=RandomizationOption::Default)
IsoString & Format(const_c_string fmt,...)
Definition: String.h:6603
ustring_base MBSToWCS() const
static ByteArray FromURLEncoded(const void *data, size_type length)
bool ToBool() const
Array< double > ParseListOfDouble(char separator=',', size_type maxCount=~size_type(0)) const
string_base::block_allocator block_allocator
Definition: String.h:5479
IsoString(const_iterator i, const_iterator j)
Definition: String.h:5630
string_base::char_type char_type
Definition: String.h:5469
static IsoString CurrentLocalISO8601DateTime(const ISO8601ConversionOptions &options=ISO8601ConversionOptions())
string_base::const_c_string const_c_string
Definition: String.h:5494
IsoString & ToURLEncoded()
IsoString(unsigned short x)
Definition: String.h:5712
static IsoString CurrentUTCISO8601DateTime(const ISO8601ConversionOptions &options=ISO8601ConversionOptions())
bool TryParseISO8601DateTime(int &year, int &month, int &day, double &dayf, double &tz) const noexcept
ustring_base UTF8ToUTF16(size_type i=0, size_type n=maxPos) const
Definition: String.h:12370
IsoString(const_c_string t)
Definition: String.h:5604
string_base::c_string c_string
Definition: String.h:5489
IsoString(double x)
Definition: String.h:5792
IsoString & ToNullSeparated(const C &c)
Definition: String.h:6341
IsoString & operator=(const IsoString &s)
Definition: String.h:5888
static IsoString ToURLDecoded(const void *data, size_type length)
static IsoString ToISO8601DateTime(int year, int month, int day, double dayf, double tz=0, const ISO8601ConversionOptions &options=ISO8601ConversionOptions())
unsigned long ToUInt() const
Definition: String.h:6949
IsoString URLEncoded() const
Definition: String.h:6467
ustring_base::const_iterator const_uchar_iterator
Definition: String.h:5551
ByteArray FromURLEncoded() const
Definition: String.h:6509
int VFormat(const_c_string fmt, va_list paramList)
Array< float > ParseListOfFloat(char separator=',', size_type maxCount=~size_type(0)) const
ustring_base::iterator uchar_iterator
Definition: String.h:5546
bool TryToBool(bool &value) const noexcept
bool TryToFloat(float &value) const noexcept
bool TryToUInt64(unsigned long long &value, int base) const noexcept
float ToFloat() const
long long ToInt64(int base) const
static IsoString ToBase64(const C &c)
Definition: String.h:7679
IsoString(const_c_string t, size_type i, size_type n)
Definition: String.h:5613
IsoString(float x)
Definition: String.h:5782
ustring_base ToString() const
Definition: String.h:6675
bool TryToUInt(unsigned &value, int base) const noexcept
A collection of string randomization options.
Definition: String.h:146
Reverse random access iterator.
Definition: Iterator.h:420
Unicode (UTF-16) string.
Definition: String.h:8146
String & ToNewLineSeparated(const C &c)
Definition: String.h:11004
String & ToSeparated(const C &c, const String &separator)
Definition: String.h:10830
String(float x)
Definition: String.h:8557
String(const_char8_iterator i, const_char8_iterator j)
Definition: String.h:8436
String(Complex< long double > &x)
Definition: String.h:8610
static IsoString UTF16ToUTF8(const_c_string string, size_type i=0, size_type n=maxPos)
static String CurrentUTCISO8601DateTime(const ISO8601ConversionOptions &options=ISO8601ConversionOptions())
bool TryToInt64(long long &value, int base) const noexcept
GenericVector< double > ParseListOfDoubleAsVector(char separator=',', int maxCount=int_max) const
static String CurrentLocalISO8601DateTime(const ISO8601ConversionOptions &options=ISO8601ConversionOptions())
bool TryToInt(int &value, int base) const noexcept
void Assign(const String &s, size_type i, size_type n)
Definition: String.h:8812
String(long x)
Definition: String.h:8517
void Assign(std::initializer_list< char_type > l)
Definition: String.h:8840
IsoString ToMBS() const
void Assign(const_iterator i, const_iterator j)
Definition: String.h:8829
IsoString ToLocal8Bit() const
Definition: String.h:11385
String(const wchar_t *t)
Definition: String.h:8390
string_base::char_type char_type
Definition: String.h:8172
String & ToSeparated(const C &c, char_type separator)
Definition: String.h:10791
long ToInt() const
Definition: String.h:11585
String(unsigned short x)
Definition: String.h:8487
int AppendVFormat(const_c_string8 fmt, va_list paramList)
Definition: String.h:11194
static String UTF32ToUTF16(const uint32 *string, size_type i=0, size_type n=maxPos)
String & ToSeparated(const C &c, char_type separator, AF append)
Definition: String.h:10814
Array< uint32 > ToUTF32(size_type i=0, size_type n=maxPos) const
Definition: String.h:11445
void ParseISO8601DateTime(int &year, int &month, int &day, double &dayf, double &tz) const
string8_base::const_c_string const_c_string8
Definition: String.h:8256
string_base::block_allocator block_allocator
Definition: String.h:8182
String & AppendFormat(const wchar_t *fmt,...)
Definition: String.h:11237
Array< wchar_t > ToWCharArray(size_type i=0, size_type n=maxPos) const
Definition: String.h:11414
String & ToSpaceSeparated(const C &c)
Definition: String.h:10974
string_base::iterator iterator
Definition: String.h:8212
String DecodedHTMLSpecialChars() const
Definition: String.h:11092
String(const wchar_t *t, size_type i, size_type n)
Definition: String.h:8400
long long ToInt64() const
Definition: String.h:11766
String & Format(const wchar_t *fmt,...)
Definition: String.h:11214
String(std::initializer_list< char_type > l)
Definition: String.h:8354
string_base::item_type item_type
Definition: String.h:8162
String(const_c_string8 t, size_type i, size_type n)
Definition: String.h:8427
String(String &&)=default
String & ToSeparated(const C &c, const_c_string8 separator)
Definition: String.h:10907
String(std::initializer_list< char8_type > l)
Definition: String.h:8449
bool ToBool() const
void Assign(const_char8_iterator p, const_char8_iterator q)
Definition: String.h:8970
GenericVector< float > ParseListOfFloatAsVector(char separator=',', int maxCount=int_max) const
bool TryToUInt64(unsigned long long &value) const noexcept
Definition: String.h:11878
float ToFloat() const
String(Complex< double > &x)
Definition: String.h:8601
String(double x)
Definition: String.h:8567
string8_base::c_string c_string8
Definition: String.h:8251
String(const_c_string8 t)
Definition: String.h:8417
void Assign(std::initializer_list< char8_type > l)
Definition: String.h:8990
void Assign(const wchar_t *t, size_type i, size_type n)
bool TryToFloat(float &value) const noexcept
void Assign(const string8_base &s)
Definition: String.h:8912
String & ToSeparated(const C &c, const String &separator, AF append)
Definition: String.h:10853
String(char_type c, size_type n)
Definition: String.h:8332
String(const string_base &s)
Definition: String.h:8279
void Assign(const_c_string8 t, size_type i, size_type n)
Definition: String.h:8950
String(bool x)
Definition: String.h:8467
String & ToSeparated(const C &c, const_c_string separator)
Definition: String.h:10869
String(char8_type c, size_type n=1)
Definition: String.h:8458
void Assign(const_iterator t, size_type i, size_type n)
Definition: String.h:8850
String(const String &)=default
string8_base::const_iterator const_char8_iterator
Definition: String.h:8266
string_base::const_iterator const_iterator
Definition: String.h:8217
IsoString ToIsoString() const
String(string_base &&s)
Definition: String.h:8293
String(int x)
Definition: String.h:8497
void Assign(const char16_t *t, size_type i, size_type n)
Definition: String.h:8876
String & AppendFormat(const_c_string8 fmt,...)
Definition: String.h:11151
void Assign(char_type c, size_type n=1)
Definition: String.h:8858
String()=default
bool TryParseISO8601DateTime(int &year, int &month, int &day, double &dayf, double &tz) const noexcept
bool TryToUInt(unsigned &value, int base) const noexcept
static Array< uint32 > UTF16ToUTF32(const_c_string string, size_type i=0, size_type n=maxPos)
String & Format(const_c_string8 fmt,...)
Definition: String.h:11129
String(const_iterator t)
Definition: String.h:8315
String(long double x)
Definition: String.h:8577
String & ToNullSeparated(const C &c)
Definition: String.h:11019
String(Complex< float > &x)
Definition: String.h:8592
String(const string8_base &s)
Definition: String.h:8307
Array< float > ParseListOfFloat(char separator=',', size_type maxCount=~size_type(0)) const
void Assign(char16_t c, size_type n=1)
Definition: String.h:8884
bool TryToInt64(long long &value) const noexcept
Definition: String.h:11795
long ToInt(int base) const
bool TryToUInt(unsigned &value) const noexcept
Definition: String.h:11710
bool TryToInt(int &value) const noexcept
Definition: String.h:11613
void Assign(const_iterator t)
Definition: String.h:8820
void Assign(char8_type c, size_type n=1)
Definition: String.h:8998
unsigned long ToUInt() const
Definition: String.h:11682
String & ToSeparated(const C &c, const_c_string separator, AF append)
Definition: String.h:10891
string8_base::char_type char8_type
Definition: String.h:8241
void Assign(const char16_t *t)
Definition: String.h:8866
String(const_iterator i, const_iterator j)
Definition: String.h:8341
String & ToHyphenated(const C &c)
Definition: String.h:11033
void Assign(wchar_t c, size_type n=1)
Definition: String.h:8904
string8_base::iterator char8_iterator
Definition: String.h:8261
long long ToInt64(int base) const
string_base::const_item_type const_item_type
Definition: String.h:8167
static String Random(size_type n, RandomizationOptions options=RandomizationOption::Default)
void Assign(const wchar_t *t)
String(const char16_t *t, size_type i, size_type n)
Definition: String.h:8373
int VFormat(const wchar_t *fmt, va_list paramList)
String & ToCommaSeparated(const C &c)
Definition: String.h:10944
int VFormat(const_c_string8 fmt, va_list paramList)
Definition: String.h:11174
static String ToISO8601DateTime(int year, int month, int day, double dayf, double tz=0, const ISO8601ConversionOptions &options=ISO8601ConversionOptions())
String(unsigned long long x)
Definition: String.h:8547
String & ToColonSeparated(const C &c)
Definition: String.h:10959
String(const char16_t *t)
Definition: String.h:8363
void Assign(const_c_string8 t)
Definition: String.h:8931
string_base::c_string c_string
Definition: String.h:8192
string_base::const_c_string const_c_string
Definition: String.h:8197
String(char16_t c, size_type n)
Definition: String.h:8381
void Assign(const String &s)
Definition: String.h:8803
bool TryToUInt64(unsigned long long &value, int base) const noexcept
GenericString< char16_type, CharTraits, PCL_STRING_ALLOCATOR > string_base
Definition: String.h:8152
bool TryToDouble(double &value) const noexcept
String EncodedHTMLSpecialChars() const
Definition: String.h:11062
unsigned long long ToUInt64(int base) const
String(const_iterator t, size_type i, size_type n)
Definition: String.h:8324
String(unsigned int x)
Definition: String.h:8507
String(wchar_t c, size_type n)
Definition: String.h:8408
String & ToSeparated(const C &c, const_c_string8 separator, AF append)
Definition: String.h:10929
int AppendVFormat(const wchar_t *fmt, va_list paramList)
String & ToEncodedHTMLSpecialChars()
String & ToTabSeparated(const C &c)
Definition: String.h:10989
String & ToDecodedHTMLSpecialChars()
String(unsigned long x)
Definition: String.h:8527
String(short x)
Definition: String.h:8477
IsoString ToUTF8(size_type i=0, size_type n=maxPos) const
Definition: String.h:11355
unsigned long long ToUInt64() const
Definition: String.h:11849
static String UTF8ToUTF16(const_c_string8 string, size_type i=0, size_type n=maxPos)
Array< double > ParseListOfDouble(char separator=',', size_type maxCount=~size_type(0)) const
double ToDouble() const
bool TryToBool(bool &value) const noexcept
static String UUID()
String(long long x)
Definition: String.h:8537
unsigned long ToUInt(int base) const
IsoString To7BitASCII() const
Array< T, A > & operator<<(Array< T, A > &x, const V &v)
Definition: Array.h:2313
bool operator==(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
Definition: Array.h:2285
bool operator<(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
Definition: Array.h:2296
Complex< T1 > operator*(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Definition: Complex.h:562
Complex< T1 > operator+(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Definition: Complex.h:478
T Abs(const Complex< T > &c) noexcept
Definition: Complex.h:443
constexpr bool operator<=(const T1 &a, const T2 &b)
Definition: Relational.h:96
constexpr bool operator>(const T1 &a, const T2 &b)
Definition: Relational.h:106
constexpr bool operator>=(const T1 &a, const T2 &b)
Definition: Relational.h:117
uint64 Hash64(const void *data, size_type size, uint64 seed=0) noexcept
Definition: Math.h:4830
uint32 Hash32(const void *data, size_type size, uint32 seed=0) noexcept
Definition: Math.h:4984
void Swap(GenericPoint< T > &p1, GenericPoint< T > &p2) noexcept
Definition: Point.h:1459
unsigned long long uint64
Definition: Defs.h:682
unsigned char uint8
Definition: Defs.h:642
unsigned int uint32
Definition: Defs.h:666
double SexagesimalToDouble(const IsoString &separator=':') const
Definition: String.h:7300
bool TryParseSexagesimal(int &sign, int &s1, int &s2, double &s3, const String &separator=':') const noexcept
bool TrySexagesimalToDouble(double &value, const Array< char_type > &separators) const noexcept
Definition: String.h:7387
static IsoString ToSexagesimal(double d, const SexagesimalConversionOptions &options=SexagesimalConversionOptions())
Definition: String.h:7530
void ParseSexagesimal(int &sign, int &s1, int &s2, double &s3, const Array< char_type > &separators) const
double SexagesimalToDouble(const Array< char_type > &separators) const
Definition: String.h:7330
bool TryParseSexagesimal(int &sign, int &s1, int &s2, double &s3, const IsoString &separator=':') const noexcept
double SexagesimalToDouble(const String &separator=':') const
Definition: String.h:12033
void ParseSexagesimal(int &sign, int &s1, int &s2, double &s3, const Array< char_type > &separators) const
bool TrySexagesimalToDouble(double &value, const Array< char_type > &separators) const noexcept
Definition: String.h:12100
bool TryParseSexagesimal(int &sign, int &s1, int &s2, double &s3, const Array< char_type > &separators) const noexcept
static IsoString ToSexagesimal(int sign, double s1, double s2, double s3, const SexagesimalConversionOptions &options=SexagesimalConversionOptions())
double SexagesimalToDouble(const Array< char_type > &separators) const
Definition: String.h:12053
bool TrySexagesimalToDouble(double &value, const String &separator=':') const noexcept
Definition: String.h:12077
void ParseSexagesimal(int &sign, int &s1, int &s2, double &s3, const String &separator=':') const
bool TrySexagesimalToDouble(double &value, const IsoString &separator=':') const noexcept
Definition: String.h:7354
void ParseSexagesimal(int &sign, int &s1, int &s2, double &s3, const IsoString &separator=':') const
ptrdiff_t distance_type
Definition: Defs.h:615
size_t size_type
Definition: Defs.h:609
void Sort(BI i, BI j)
Definition: Sort.h:520
constexpr const T & Min(const T &a, const T &b) noexcept
Definition: Utility.h:90
int Compare(FI1 i1, FI1 j1, FI2 i2, FI2 j2) noexcept
Definition: Utility.h:639
constexpr const T & Max(const T &a, const T &b) noexcept
Definition: Utility.h:119
PCL root namespace.
Definition: AbstractImage.h:77
A set of options specific for string representations of angles.
Definition: String.h:257
constexpr AngleConversionOptions(unsigned precision=2, unsigned width=3, char padding=' ')
Definition: String.h:265
A set of options specific for string representations of declination angles.
Definition: String.h:375
constexpr DecConversionOptions(unsigned precision=2, unsigned width=3, char padding=' ')
Definition: String.h:384
Formatting options for string representations of dates and times in ISO 8601 format....
Definition: String.h:459
constexpr ISO8601ConversionOptionsNoTimeZone(unsigned timeItems_=3, unsigned precision_=3)
Definition: String.h:463
Formatting options for string representations of dates and times in ISO 8601 format.
Definition: String.h:399
ISO8601ConversionOptions(const ISO8601ConversionOptions &)=default
constexpr ISO8601ConversionOptions(unsigned timeItems_=3, unsigned precision_=3, bool timeZone_=true, bool zuluTime_=true)
Definition: String.h:429
A set of options specific for string representations of latitude angles.
Definition: String.h:346
constexpr LatitudeConversionOptions(unsigned precision=2, unsigned width=3, char padding=' ')
Definition: String.h:355
A set of options specific for string representations of longitude angles.
Definition: String.h:286
constexpr LongitudeConversionOptions(unsigned precision=2, unsigned width=4, char padding=' ')
Definition: String.h:295
A set of options specific for string representations of right ascensions.
Definition: String.h:317
constexpr RAConversionOptions(unsigned precision=3, unsigned width=2, char padding=' ')
Definition: String.h:325
Formatting options for string sexagesimal representations.
Definition: String.h:170
constexpr SexagesimalConversionOptions(unsigned items_=3, unsigned precision_=2, bool sign_=false, unsigned width_=0, char separator_=':', char padding_=' ')
Definition: String.h:216
SexagesimalConversionOptions(const SexagesimalConversionOptions &)=default