PCL
String.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.7.0
6 // ----------------------------------------------------------------------------
7 // pcl/String.h - Released 2024-06-18T15:48:54Z
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  using char_type = T;
500 
504  using char_traits = R;
505 
509  using block_allocator = A;
510 
515 
519  using c_string = T*;
520 
524  using const_c_string = const T*;
525 
529  using iterator = T*;
530 
534  using const_iterator = const T*;
535 
540 
545 
546  // -------------------------------------------------------------------------
547 
551  static const size_type notFound = ~size_type( 0 );
552 
556  static const size_type maxPos = ~size_type( 0 );
557 
558  // -------------------------------------------------------------------------
559 
564  {
565  m_data = Data::New();
566  }
567 
572  : m_data( s.m_data )
573  {
574  m_data->Attach();
575  }
576 
581  : m_data( s.m_data )
582  {
583  s.m_data = nullptr;
584  }
585 
591  {
592  size_type len = R::Length( t );
593  if ( len > 0 )
594  {
595  m_data = Data::New( len );
596  R::Copy( m_data->string, t, len );
597  }
598  else
599  m_data = Data::New();
600  }
601 
620  {
621  if ( i < j )
622  {
623  size_type len = j - i;
624  m_data = Data::New( len );
625  R::Copy( m_data->string, i, len );
626  }
627  else
628  m_data = Data::New();
629  }
630 
639  GenericString( std::initializer_list<char_type> l )
640  : GenericString( l.begin(), l.end() )
641  {
642  }
643 
649  {
650  size_type len = R::Length( t );
651  if ( i < len && (n = pcl::Min( n, len-i )) > 0 )
652  {
653  m_data = Data::New( n );
654  R::Copy( m_data->string, t+i, n );
655  }
656  else
657  m_data = Data::New();
658  }
659 
664  {
665  if ( n > 0 )
666  {
667  m_data = Data::New( n );
668  R::Fill( m_data->string, c, n );
669  }
670  else
671  m_data = Data::New();
672  }
673 
679  {
680  if ( m_data != nullptr )
681  {
682  DetachFromData();
683  m_data = nullptr;
684  }
685  }
686 
692  bool IsUnique() const noexcept
693  {
694  return m_data->IsUnique();
695  }
696 
704  bool IsAliasOf( const GenericString& s ) const noexcept
705  {
706  return m_data == s.m_data;
707  }
708 
719  {
720  if ( !IsUnique() )
721  {
722  size_type len = Length();
723  Data* newData = Data::New( len );
724  if ( len > 0 )
725  R::Copy( newData->string, m_data->string, len );
726  DetachFromData();
727  m_data = newData;
728  }
729  }
730 
738  static size_type BytesPerChar() noexcept
739  {
740  return R::BytesPerChar();
741  }
742 
749  size_type Size() const noexcept
750  {
751  return Length()*BytesPerChar();
752  }
753 
760  size_type Length() const noexcept
761  {
762  return m_data->end - m_data->string;
763  }
764 
773  size_type Capacity() const noexcept
774  {
775  return m_data->capacity - m_data->string;
776  }
777 
785  size_type Available() const noexcept
786  {
787  return m_data->capacity - m_data->end;
788  }
789 
806  bool IsValid() const noexcept
807  {
808  return m_data != nullptr;
809  }
810 
818  bool IsEmpty() const noexcept
819  {
820  return m_data->string == m_data->end;
821  }
822 
831  size_type LowerBound() const noexcept
832  {
833  return 0;
834  }
835 
844  size_type UpperBound() const noexcept
845  {
846  PCL_PRECONDITION( !IsEmpty() )
847  return Length()-1;
848  }
849 
855  const allocator& Allocator() const noexcept
856  {
857  return m_data->alloc;
858  }
859 
869  void SetAllocator( const allocator& a )
870  {
871  EnsureUnique();
872  m_data->alloc = a;
873  }
874 
888  {
889  PCL_PRECONDITION( i < Length() )
890  EnsureUnique();
891  return m_data->string + i;
892  }
893 
903  const_iterator At( size_type i ) const noexcept
904  {
905  PCL_PRECONDITION( i < Length() )
906  return m_data->string + i;
907  }
908 
921  char_type& operator []( size_type i )
922  {
923  return *At( i );
924  }
925 
935  char_type operator []( size_type i ) const noexcept
936  {
937  return *At( i );
938  }
939 
948  {
949  EnsureUnique();
950  return *m_data->string;
951  }
952 
960  char_type operator *() const noexcept
961  {
962  return *m_data->string;
963  }
964 
977  {
978  EnsureUnique();
979  return m_data->string;
980  }
981 
990  const_iterator Begin() const noexcept
991  {
992  return m_data->string;
993  }
994 
1007  {
1008  EnsureUnique();
1009  return m_data->end;
1010  }
1011 
1020  const_iterator End() const noexcept
1021  {
1022  return m_data->end;
1023  }
1024 
1039  {
1040  EnsureUnique();
1041  return (m_data->string < m_data->end) ? m_data->end-1 : nullptr;
1042  }
1043 
1055  {
1056  return (m_data->string < m_data->end) ? m_data->end-1 : nullptr;
1057  }
1058 
1073  {
1074  EnsureUnique();
1075  return (m_data->string < m_data->end) ? m_data->string-1 : nullptr;
1076  }
1077 
1089  {
1090  return (m_data->string < m_data->end) ? m_data->string-1 : nullptr;
1091  }
1092 
1103  size_type IndexAt( const_iterator i ) const noexcept
1104  {
1105  PCL_PRECONDITION( i >= m_data->string )
1106  return i - m_data->string;
1107  }
1108 
1109 #ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
1114  {
1115  return Begin();
1116  }
1117 
1121  const_iterator begin() const noexcept
1122  {
1123  return Begin();
1124  }
1125 
1130  {
1131  return End();
1132  }
1133 
1137  const_iterator end() const noexcept
1138  {
1139  return End();
1140  }
1141 #endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
1142 
1150  const_c_string c_str() const noexcept
1151  {
1152  static const char_type theNullChar = char_traits::Null();
1153  return IsEmpty() ? &theNullChar : Begin();
1154  }
1155 
1161  GenericString& operator =( const GenericString& s )
1162  {
1163  Assign( s );
1164  return *this;
1165  }
1166 
1181  void Assign( const GenericString& s )
1182  {
1183  s.m_data->Attach();
1184  DetachFromData();
1185  m_data = s.m_data;
1186  }
1187 
1193  GenericString& operator =( GenericString&& s )
1194  {
1195  Transfer( s );
1196  return *this;
1197  }
1198 
1213  {
1214  DetachFromData();
1215  m_data = s.m_data;
1216  s.m_data = nullptr;
1217  }
1218 
1225  {
1226  DetachFromData();
1227  m_data = s.m_data;
1228  s.m_data = nullptr;
1229  }
1230 
1236  {
1237  Assign( t );
1238  return *this;
1239  }
1240 
1245  GenericString& operator =( char_type c )
1246  {
1247  Assign( c, 1 );
1248  return *this;
1249  }
1250 
1255  void Assign( const GenericString& s, size_type i, size_type n )
1256  {
1257  Transfer( s.Substring( i, n ) );
1258  }
1259 
1268  {
1269  size_type len = R::Length( t );
1270  if ( len > 0 )
1271  {
1272  MaybeReallocate( len );
1273  R::Copy( m_data->string, t, len );
1274  }
1275  else
1276  Clear();
1277  }
1278 
1300  {
1301  if ( i < j )
1302  {
1303  size_type len = j - i;
1304  MaybeReallocate( len );
1305  R::Copy( m_data->string, i, len );
1306  }
1307  else
1308  Clear();
1309  }
1310 
1317  void Assign( std::initializer_list<char_type> l )
1318  {
1319  Assign( l.begin(), l.end() );
1320  }
1321 
1336  {
1337  size_type len = R::Length( t );
1338  if ( i < len && (n = pcl::Min( n, len-i )) > 0 )
1339  {
1340  MaybeReallocate( n );
1341  R::Copy( m_data->string, t+i, n );
1342  }
1343  else
1344  Clear();
1345  }
1346 
1352  void Assign( char_type c, size_type n = 1 )
1353  {
1354  if ( !R::IsNull( c ) && n > 0 )
1355  {
1356  MaybeReallocate( n );
1357  R::Fill( m_data->string, c, n );
1358  }
1359  else
1360  Clear();
1361  }
1362 
1366  void Swap( GenericString& s ) noexcept
1367  {
1368  pcl::Swap( m_data, s.m_data );
1369  }
1370 
1380  void Fill( char_type c )
1381  {
1382  size_type len = Length();
1383  if ( len > 0 )
1384  {
1385  if ( !IsUnique() )
1386  {
1387  Data* newData = Data::New( len );
1388  DetachFromData();
1389  m_data = newData;
1390  }
1391  R::Fill( m_data->string, c, len );
1392  }
1393  }
1394 
1409  void Fill( char_type c, size_type i, size_type n = maxPos )
1410  {
1411  size_type len = Length();
1412  if ( i < len )
1413  {
1414  n = pcl::Min( n, len-i );
1415  if ( n < len )
1416  EnsureUnique();
1417  else if ( !IsUnique() )
1418  {
1419  Data* newData = Data::New( len );
1420  DetachFromData();
1421  m_data = newData;
1422  }
1423  R::Fill( m_data->string+i, c, n );
1424  }
1425  }
1426 
1448  void SecureFill( char c = '\0' ) noexcept
1449  {
1450  volatile char* s = reinterpret_cast<volatile char*>( m_data->string );
1451  for ( size_type n = Capacity()*sizeof( char_type ); n > 0; --n )
1452  *s++ = c;
1453  }
1454 
1462  void Reserve( size_type n )
1463  {
1464  if ( n > 0 )
1465  if ( IsUnique() )
1466  {
1467  if ( Capacity() < n+1 )
1468  {
1469  iterator old = m_data->string;
1470  size_type len = Length();
1471  m_data->Reserve( len, n );
1472  if ( old != nullptr )
1473  {
1474  if ( len > 0 )
1475  R::Copy( m_data->string, old, len );
1476  m_data->alloc.Deallocate( old );
1477  }
1478  }
1479  }
1480  else
1481  {
1482  size_type len = Length();
1483  Data* newData = Data::New(); // ### FIXME: unlikely, but this is a potential leak
1484  newData->Reserve( len, pcl::Max( len, n ) );
1485  if ( len > 0 )
1486  R::Copy( newData->string, m_data->string, len );
1487  DetachFromData();
1488  m_data = newData;
1489  }
1490  }
1491 
1506  {
1507  if ( n != Length() )
1508  {
1509  if ( n > 0 )
1510  {
1511  if ( !IsUnique() || m_data->ShouldReallocate( n ) )
1512  {
1513  Data* newData = Data::New( n );
1514  size_type m = Capacity();
1515  if ( m > 0 )
1516  R::Copy( newData->string, m_data->string, pcl::Min( n, m ) );
1517  DetachFromData();
1518  m_data = newData;
1519  }
1520  else
1521  m_data->SetLength( n );
1522  }
1523  else
1524  Clear();
1525  }
1526  else
1527  EnsureUnique();
1528  }
1529 
1536  {
1537  // NB: This can be done more efficiently if this string is unique.
1538  GenericString s( *this );
1539  s.SetLength( n );
1540  return s;
1541  }
1542 
1552  {
1553  SetLength( R::Length( m_data->string ) );
1554  }
1555 
1561  {
1562  GenericString s( *this );
1564  return s;
1565  }
1566 
1579  void Squeeze()
1580  {
1581  if ( Available() > 0 )
1582  {
1583  size_type len = Length();
1584  if ( len > 0 )
1585  {
1586  if ( IsUnique() )
1587  {
1588  iterator old = m_data->string;
1589  m_data->Allocate( len, 0 );
1590  R::Copy( m_data->string, old, len );
1591  m_data->alloc.Deallocate( old );
1592  }
1593  else
1594  {
1595  Data* newData = Data::New( len, 0 );
1596  R::Copy( newData->string, m_data->string, len );
1597  DetachFromData();
1598  m_data = newData;
1599  }
1600  }
1601  else
1602  Clear();
1603  }
1604  }
1605 
1611  {
1612  // NB: This can be done more efficiently if this string is unique.
1613  GenericString s( *this );
1614  s.Squeeze();
1615  return s;
1616  }
1617 
1631  {
1632  EnsureUnique();
1633  iterator string = m_data->string;
1634  m_data->Reset();
1635  return string;
1636  }
1637 
1654  void c_copy( iterator dst, size_type maxCharsToCopy, size_type i = 0 ) const noexcept
1655  {
1656  if ( dst != nullptr )
1657  if ( maxCharsToCopy > 0 )
1658  {
1659  if ( --maxCharsToCopy > 0 )
1660  {
1661  size_type len = Length();
1662  if ( i < len )
1663  {
1664  size_type n = pcl::Min( maxCharsToCopy, len-i );
1665  R::Copy( dst, m_data->string+i, n );
1666  dst += n;
1667  }
1668  }
1669 
1670  *dst = R::Null();
1671  }
1672  }
1673 
1677  template <class R1, class A1>
1679  {
1680  size_type n = s.Length();
1681  if ( n > 0 )
1682  {
1683  UninitializedGrow( i, n ); // -> 0 <= i <= len
1684  R::Copy( m_data->string+i, s.m_data->string, n );
1685  }
1686  }
1687 
1696  {
1697  if ( p < q )
1698  {
1699  size_type n = q - p;
1700  UninitializedGrow( i, n ); // -> 0 <= i <= len
1701  R::Copy( m_data->string+i, p, n );
1702  }
1703  }
1704 
1710  {
1711  size_type n = R::Length( t );
1712  if ( n > 0 )
1713  {
1714  UninitializedGrow( i, n ); // -> 0 <= i <= len
1715  R::Copy( m_data->string+i, t, n );
1716  }
1717  }
1718 
1724  {
1725  if ( (n = pcl::Min( n, R::Length( t ) )) > 0 )
1726  {
1727  UninitializedGrow( i, n ); // -> 0 <= i <= len
1728  R::Copy( m_data->string+i, t, n );
1729  }
1730  }
1731 
1735  void Insert( size_type i, char_type c, size_type n = 1 )
1736  {
1737  if ( n > 0 )
1738  {
1739  UninitializedGrow( i, n ); // -> 0 <= i <= len
1740  R::Fill( m_data->string+i, c, n );
1741  }
1742  }
1743 
1747  template <class R1, class A1>
1749  {
1750  Insert( maxPos, s );
1751  }
1752 
1757  template <class R1, class A1>
1758  GenericString& operator +=( const GenericString<T,R1,A1>& s )
1759  {
1760  Append( s );
1761  return *this;
1762  }
1763 
1772  {
1773  Insert( maxPos, i, j );
1774  }
1775 
1781  {
1782  Insert( maxPos, t, n );
1783  }
1784 
1789  {
1790  Insert( maxPos, t );
1791  }
1792 
1797  GenericString& operator +=( const_c_string t )
1798  {
1799  Append( t );
1800  return *this;
1801  }
1802 
1806  void Append( char_type c, size_type n = 1 )
1807  {
1808  Insert( maxPos, c, n );
1809  }
1810 
1815  template <class R1, class A1>
1816  void Add( const GenericString<T,R1,A1>& s )
1817  {
1818  Append( s );
1819  }
1820 
1826  {
1827  Append( i, j );
1828  }
1829 
1835  {
1836  Append( t, n );
1837  }
1838 
1844  {
1845  Append( t );
1846  }
1847 
1852  void Add( char_type c, size_type n = 1 )
1853  {
1854  Append( c, n );
1855  }
1856 
1861  GenericString& operator +=( char_type c )
1862  {
1863  Append( c );
1864  return *this;
1865  }
1866 
1871  template <class R1, class A1>
1873  {
1874  Insert( 0, s );
1875  }
1876 
1881  template <class R1, class A1>
1882  GenericString& operator -=( const GenericString<T,R1,A1>& s )
1883  {
1884  Prepend( s );
1885  return *this;
1886  }
1887 
1896  {
1897  Insert( 0, i, j );
1898  }
1899 
1905  {
1906  Insert( 0, t, n );
1907  }
1908 
1914  {
1915  Insert( 0, t );
1916  }
1917 
1922  GenericString& operator -=( const_c_string t )
1923  {
1924  Prepend( t );
1925  return *this;
1926  }
1927 
1931  void Prepend( char_type c, size_type n = 1 )
1932  {
1933  Insert( 0, c, n );
1934  }
1935 
1940  GenericString& operator -=( char_type c )
1941  {
1942  Prepend( c );
1943  return *this;
1944  }
1945 
1950  template <class R1, class A1>
1952  {
1953  if ( n > 0 )
1954  {
1955  size_type len = Length();
1956  if ( i < len )
1957  {
1958  n = pcl::Min( n, len-i );
1959  if ( n != len )
1960  {
1961  size_type ns = s.Length();
1962  if ( ns > 0 )
1963  {
1964  if ( n < ns )
1965  UninitializedGrow( i, ns-n );
1966  else if ( ns < n )
1967  Delete( i, n-ns );
1968  else
1969  EnsureUnique();
1970 
1971  R::Copy( m_data->string+i, s.m_data->string, ns );
1972  }
1973  else
1974  Delete( i, n );
1975  }
1976  else
1977  Assign( s );
1978  }
1979  }
1980  }
1981 
1991  {
1992  if ( n > 0 )
1993  {
1994  size_type len = Length();
1995  if ( i < len )
1996  {
1997  n = pcl::Min( n, len-i );
1998  if ( n != len )
1999  {
2000  size_type nt = R::Length( t );
2001  if ( nt > 0 )
2002  {
2003  if ( n < nt )
2004  UninitializedGrow( i, nt-n );
2005  else if ( nt < n )
2006  Delete( i, n-nt );
2007  else
2008  EnsureUnique();
2009 
2010  R::Copy( m_data->string+i, t, nt );
2011  }
2012  else
2013  Delete( i, n );
2014  }
2015  else
2016  Assign( t );
2017  }
2018  }
2019  }
2020 
2026  {
2027  if ( n > 0 )
2028  {
2029  size_type len = Length();
2030  if ( i < len )
2031  {
2032  n = pcl::Min( n, len-i );
2033  if ( n != len )
2034  {
2035  if ( nc > 0 )
2036  {
2037  if ( n < nc )
2038  UninitializedGrow( i, nc-n );
2039  else if ( nc < n )
2040  Delete( i, n-nc );
2041  else
2042  EnsureUnique();
2043 
2044  R::Fill( m_data->string+i, c, nc );
2045  }
2046  else
2047  Delete( i, n );
2048  }
2049  else
2050  Assign( c, nc );
2051  }
2052  }
2053  }
2054 
2060  void ReplaceChar( char_type c1, char_type c2, size_type i = 0, size_type n = maxPos )
2061  {
2062  ReplaceChar( c1, c2, i, n, true/*case*/ );
2063  }
2064 
2072  void ReplaceCharIC( char_type c1, char_type c2, size_type i = 0, size_type n = maxPos )
2073  {
2074  ReplaceChar( c1, c2, i, n, false/*case*/ );
2075  }
2076 
2082  template <class R1, class A1, class R2, class A2>
2084  const GenericString<T,R2,A2>& s2, size_type i = 0 )
2085  {
2086  ReplaceString( s1.m_data->string, s1.Length(), s2.m_data->string, s2.Length(), i, true/*case*/ );
2087  }
2088 
2095  {
2096  ReplaceString( t1, R::Length( t1 ), t2, R::Length( t2 ), i, true/*case*/ );
2097  }
2098 
2106  template <class R1, class A1, class R2, class A2>
2108  const GenericString<T,R2,A2>& s2, size_type i = 0 )
2109  {
2110  ReplaceString( s1.m_data->string, s1.Length(), s2.m_data->string, s2.Length(), i, false/*case*/ );
2111  }
2112 
2121  {
2122  ReplaceString( t1, R::Length( t1 ), t2, R::Length( t2 ), i, false/*case*/ );
2123  }
2124 
2129  void Delete( size_type i, size_type n = 1 )
2130  {
2131  if ( n > 0 )
2132  {
2133  size_type len = Length();
2134  if ( i < len )
2135  {
2136  n = pcl::Min( n, len-i );
2137  if ( n < len )
2138  {
2139  size_type newLen = len-n;
2140  if ( !IsUnique() || m_data->ShouldReallocate( newLen ) )
2141  {
2142  Data* newData = Data::New( newLen );
2143  if ( i > 0 )
2144  R::Copy( newData->string, m_data->string, i );
2145  if ( i < newLen )
2146  R::Copy( newData->string+i, m_data->string+i+n, newLen-i );
2147  DetachFromData();
2148  m_data = newData;
2149  }
2150  else
2151  {
2152  if ( i < newLen )
2153  R::CopyOverlapped( m_data->string+i, m_data->string+i+n, newLen-i );
2154  m_data->SetLength( newLen );
2155  }
2156  }
2157  else
2158  Clear();
2159  }
2160  }
2161  }
2162 
2168  {
2169  Delete( i, maxPos );
2170  }
2171 
2177  {
2178  Delete( 0, i );
2179  }
2180 
2186  void DeleteChar( char_type c, size_type i = 0 )
2187  {
2188  ReplaceString( &c, 1, nullptr, 0, i, true/*case*/ );
2189  }
2190 
2199  {
2200  ReplaceString( &c, 1, nullptr, 0, i, false/*case*/ );
2201  }
2202 
2208  template <class R1, class A1>
2210  {
2211  ReplaceString( s.m_data->string, s.Length(), nullptr, 0, i, true/*case*/ );
2212  }
2213 
2220  {
2221  ReplaceString( t, R::Length( t ), nullptr, 0, i, true/*case*/ );
2222  }
2223 
2231  template <class R1, class A1>
2233  {
2234  ReplaceString( s.m_data->string, s.Length(), nullptr, 0, i, false/*case*/ );
2235  }
2236 
2245  {
2246  ReplaceString( t, R::Length( t ), nullptr, 0, i, false/*case*/ );
2247  }
2248 
2258  void Clear()
2259  {
2260  if ( !IsEmpty() )
2261  if ( IsUnique() )
2262  m_data->Deallocate();
2263  else
2264  {
2265  Data* newData = Data::New();
2266  DetachFromData();
2267  m_data = newData;
2268  }
2269  }
2270 
2276  {
2277  size_type len = Length();
2278  if ( i < len )
2279  {
2280  n = pcl::Min( n, len-i );
2281  if ( n > 0 )
2282  {
2283  if ( n < len )
2284  {
2285  GenericString t;
2286  t.m_data->Allocate( n );
2287  R::Copy( t.m_data->string, m_data->string+i, n );
2288  return t;
2289  }
2290  return *this;
2291  }
2292  }
2293  return GenericString();
2294  }
2295 
2301  {
2302  size_type len = Length();
2303  n = pcl::Min( n, len );
2304  if ( n > 0 )
2305  {
2306  if ( n < len )
2307  {
2308  GenericString t;
2309  t.m_data->Allocate( n );
2310  R::Copy( t.m_data->string, m_data->string, n );
2311  return t;
2312  }
2313  return *this;
2314  }
2315  return GenericString();
2316  }
2317 
2323  {
2324  size_type len = Length();
2325  n = pcl::Min( n, len );
2326  if ( n > 0 )
2327  {
2328  if ( n < len )
2329  {
2330  GenericString t;
2331  t.m_data->Allocate( n );
2332  R::Copy( t.m_data->string, m_data->string+len-n, n );
2333  return t;
2334  }
2335  return *this;
2336  }
2337  return GenericString();
2338  }
2339 
2347  {
2348  return Substring( i );
2349  }
2350 
2358  {
2359  return Left( (i > 0) ? i-1 : 0 );
2360  }
2361 
2379  template <class C, class R1, class A1>
2380  size_type Break( C& list, const GenericString<T,R1,A1>& s, bool trim = false, size_type i = 0 ) const
2381  {
2382  size_type count = 0;
2383  size_type len = Length();
2384  if ( i < len )
2385  {
2386  size_type n = s.Length();
2387  if ( n > 0 )
2388  for ( SearchEngine S( s.m_data->string, n, true/*case*/ ); ; )
2389  {
2390  size_type j = S( m_data->string, i, len );
2391 
2392  GenericString t;
2393  if ( i < j )
2394  {
2395  const_iterator l = m_data->string + i;
2396  size_type m = j - i;
2397  if ( trim )
2398  {
2399  const_iterator r = l + m;
2400  l = R::SearchTrimLeft( l, r );
2401  m = R::SearchTrimRight( l, r ) - l;
2402  }
2403  if ( m > 0 )
2404  {
2405  t.m_data->Allocate( m );
2406  R::Copy( t.m_data->string, l, m );
2407  }
2408  }
2409  list.Add( t );
2410  ++count;
2411 
2412  if ( j == len )
2413  break;
2414 
2415  i = j + n;
2416  }
2417  }
2418  return count;
2419  }
2420 
2439  template <class C>
2440  size_type Break( C& list, const_c_string s, bool trim = false, size_type i = 0 ) const
2441  {
2442  size_type count = 0;
2443  size_type len = Length();
2444  if ( i < len )
2445  {
2446  size_type n = R::Length( s );
2447  if ( n > 0 )
2448  for ( SearchEngine S( s, n, true/*case*/ ); ; )
2449  {
2450  size_type j = S( m_data->string, i, len );
2451 
2452  GenericString t;
2453  if ( i < j )
2454  {
2455  const_iterator l = m_data->string + i;
2456  size_type m = j - i;
2457  if ( trim )
2458  {
2459  const_iterator r = l + m;
2460  l = R::SearchTrimLeft( l, r );
2461  m = R::SearchTrimRight( l, r ) - l;
2462  }
2463  if ( m > 0 )
2464  {
2465  t.m_data->Allocate( m );
2466  R::Copy( t.m_data->string, l, m );
2467  }
2468  }
2469  list.Add( t );
2470  ++count;
2471 
2472  if ( j == len )
2473  break;
2474 
2475  i = j + n;
2476  }
2477  }
2478  return count;
2479  }
2480 
2499  template <class C>
2500  size_type Break( C& list, char_type c, bool trim = false, size_type i = 0 ) const
2501  {
2502  size_type count = 0;
2503  size_type len = Length();
2504  if ( i < len )
2505  {
2506  for ( ;; )
2507  {
2508  size_type j = i;
2509  for ( const_iterator p = m_data->string + i; j < len; ++j, ++p )
2510  if ( *p == c )
2511  break;
2512 
2513  GenericString t;
2514  if ( i < j )
2515  {
2516  const_iterator l = m_data->string + i;
2517  size_type m = j - i;
2518  if ( trim )
2519  {
2520  const_iterator r = l + m;
2521  l = R::SearchTrimLeft( l, r );
2522  m = R::SearchTrimRight( l, r ) - l;
2523  }
2524  if ( m > 0 )
2525  {
2526  t.m_data->Allocate( m );
2527  R::Copy( t.m_data->string, l, m );
2528  }
2529  }
2530  list.Add( t );
2531  ++count;
2532 
2533  if ( j == len )
2534  break;
2535 
2536  i = j + 1;
2537  }
2538  }
2539  return count;
2540  }
2541 
2564  template <class C, typename S>
2565  size_type Break( C& list, const Array<S>& ca, bool trim = false, size_type i = 0 ) const
2566  {
2567  size_type count = 0;
2568  if ( !ca.IsEmpty() )
2569  {
2570  size_type len = Length();
2571  if ( i < len )
2572  {
2573  for ( ;; )
2574  {
2575  size_type j = i;
2576  for ( const_iterator p = m_data->string + i; j < len; ++j, ++p )
2577  for ( auto c : ca )
2578  if ( *p == char_type( c ) )
2579  goto __Break_1;
2580 __Break_1:
2581  GenericString t;
2582  if ( i < j )
2583  {
2584  const_iterator l = m_data->string + i;
2585  size_type m = j - i;
2586  if ( trim )
2587  {
2588  const_iterator r = l + m;
2589  l = R::SearchTrimLeft( l, r );
2590  m = R::SearchTrimRight( l, r ) - l;
2591  }
2592  if ( m > 0 )
2593  {
2594  t.m_data->Allocate( m );
2595  R::Copy( t.m_data->string, l, m );
2596  }
2597  }
2598  list.Add( t );
2599  ++count;
2600 
2601  if ( j == len )
2602  break;
2603 
2604  i = j + 1;
2605  }
2606  }
2607  }
2608  return count;
2609  }
2610 
2631  template <class C, class R1, class A1>
2632  size_type BreakIC( C& list, const GenericString<T,R1,A1>& s, bool trim = false, size_type i = 0 ) const
2633  {
2634  size_type count = 0;
2635  size_type len = Length();
2636  if ( i < len )
2637  {
2638  size_type n = s.Length();
2639  if ( n > 0 )
2640  {
2641  for ( SearchEngine S( s.m_data->string, n, false/*case*/ ); ; )
2642  {
2643  size_type j = S( m_data->string, i, len );
2644 
2645  GenericString t;
2646  if ( i < j )
2647  {
2648  const_iterator l = m_data->string + i;
2649  size_type m = j - i;
2650  if ( trim )
2651  {
2652  const_iterator r = l + m;
2653  l = R::SearchTrimLeft( l, r );
2654  m = R::SearchTrimRight( l, r ) - l;
2655  }
2656  if ( m > 0 )
2657  {
2658  t.m_data->Allocate( m );
2659  R::Copy( t.m_data->string, l, m );
2660  }
2661  }
2662  list.Add( t );
2663  ++count;
2664 
2665  if ( j == len )
2666  break;
2667 
2668  i = j + n;
2669  }
2670  }
2671  }
2672  return count;
2673  }
2674 
2697  template <class C>
2698  size_type BreakIC( C& list, const_c_string s, bool trim = false, size_type i = 0 ) const
2699  {
2700  size_type count = 0;
2701  size_type len = Length();
2702  if ( i < len )
2703  {
2704  size_type n = R::Length( s );
2705  if ( n > 0 )
2706  {
2707  for ( SearchEngine S( s, n, false/*case*/ ); ; )
2708  {
2709  size_type j = S( m_data->string, i, len );
2710 
2711  GenericString t;
2712  if ( i < j )
2713  {
2714  const_iterator l = m_data->string + i;
2715  size_type m = j - i;
2716  if ( trim )
2717  {
2718  const_iterator r = l + m;
2719  l = R::SearchTrimLeft( l, r );
2720  m = R::SearchTrimRight( l, r ) - l;
2721  }
2722  if ( m > 0 )
2723  {
2724  t.m_data->Allocate( m );
2725  R::Copy( t.m_data->string, l, m );
2726  }
2727  }
2728  list.Add( t );
2729  ++count;
2730 
2731  if ( j == len )
2732  break;
2733 
2734  i = j + n;
2735  }
2736  }
2737  }
2738  return count;
2739  }
2740 
2762  template <class C>
2763  size_type BreakIC( C& list, char_type c, bool trim = false, size_type i = 0 ) const
2764  {
2765  size_type count = 0;
2766  size_type len = Length();
2767  if ( i < len )
2768  {
2769  c = R::ToCaseFolded( c );
2770  for ( ;; )
2771  {
2772  size_type j = i;
2773  for ( const_iterator p = m_data->string + i; j < len; ++j, ++p )
2774  if ( R::ToCaseFolded( *p ) == c )
2775  break;
2776 
2777  GenericString t;
2778  if ( i < j )
2779  {
2780  const_iterator l = m_data->string + i;
2781  size_type m = j - i;
2782  if ( trim )
2783  {
2784  const_iterator r = l + m;
2785  l = R::SearchTrimLeft( l, r );
2786  m = R::SearchTrimRight( l, r ) - l;
2787  }
2788  if ( m > 0 )
2789  {
2790  t.m_data->Allocate( m );
2791  R::Copy( t.m_data->string, l, m );
2792  }
2793  }
2794  list.Add( t );
2795  ++count;
2796 
2797  if ( j == len )
2798  break;
2799 
2800  i = j + 1;
2801  }
2802  }
2803  return count;
2804  }
2805 
2810  char_type FirstChar() const noexcept
2811  {
2812  return (m_data->string != nullptr) ? *m_data->string : R::Null();
2813  }
2814 
2819  char_type LastChar() const noexcept
2820  {
2821  return (m_data->string < m_data->end) ? *(m_data->end-1) : R::Null();
2822  }
2823 
2827  template <class R1, class A1>
2828  bool StartsWith( const GenericString<T,R1,A1>& s ) const noexcept
2829  {
2830  if ( s.IsEmpty() || Length() < s.Length() )
2831  return false;
2832  for ( const_iterator p = m_data->string, q = s.m_data->string; q < s.m_data->end; ++p, ++q )
2833  if ( *p != *q )
2834  return false;
2835  return true;
2836  }
2837 
2842  bool StartsWith( const_c_string t ) const noexcept
2843  {
2844  size_type n = R::Length( t );
2845  if ( n == 0 || Length() < n )
2846  return false;
2847  for ( const_iterator p = m_data->string, e = p+n; p < e; ++p, ++t )
2848  if ( *p != *t )
2849  return false;
2850  return true;
2851  }
2852 
2856  bool StartsWith( char_type c ) const noexcept
2857  {
2858  return m_data->string < m_data->end && *m_data->string == c;
2859  }
2860 
2865  template <class R1, class A1>
2866  bool StartsWithIC( const GenericString<T,R1,A1>& s ) const noexcept
2867  {
2868  if ( s.IsEmpty() || Length() < s.Length() )
2869  return false;
2870  for ( const_iterator p = m_data->string, q = s.m_data->string; q < s.m_data->end; ++p, ++q )
2871  if ( R::ToCaseFolded( *p ) != R::ToCaseFolded( *q ) )
2872  return false;
2873  return true;
2874  }
2875 
2880  bool StartsWithIC( const_c_string t ) const noexcept
2881  {
2882  size_type n = R::Length( t );
2883  if ( n == 0 || Length() < n )
2884  return false;
2885  for ( const_iterator p = m_data->string, e = p+n; p < e; ++p, ++t )
2886  if ( R::ToCaseFolded( *p ) != R::ToCaseFolded( *t ) )
2887  return false;
2888  return true;
2889  }
2890 
2895  bool StartsWithIC( char_type c ) const noexcept
2896  {
2897  return m_data->string < m_data->end && R::ToCaseFolded( *m_data->string ) == R::ToCaseFolded( c );
2898  }
2899 
2903  template <class R1, class A1>
2904  bool EndsWith( const GenericString<T,R1,A1>& s ) const noexcept
2905  {
2906  size_type n = s.Length();
2907  if ( n == 0 || Length() < n )
2908  return false;
2909  for ( const_iterator p = m_data->end-n, q = s.m_data->string; p < m_data->end; ++p, ++q )
2910  if ( *p != *q )
2911  return false;
2912  return true;
2913  }
2914 
2919  bool EndsWith( const_c_string t ) const noexcept
2920  {
2921  size_type n = R::Length( t );
2922  if ( n == 0 || Length() < n )
2923  return false;
2924  for ( const_iterator p = m_data->end-n; p < m_data->end; ++p, ++t )
2925  if ( *p != *t )
2926  return false;
2927  return true;
2928  }
2929 
2933  bool EndsWith( char_type c ) const noexcept
2934  {
2935  return m_data->string < m_data->end && *(m_data->end-1) == c;
2936  }
2937 
2942  template <class R1, class A1>
2943  bool EndsWithIC( const GenericString<T,R1,A1>& s ) const noexcept
2944  {
2945  size_type n = s.Length();
2946  if ( n == 0 || Length() < n )
2947  return false;
2948  for ( const_iterator p = m_data->end-n, q = s.m_data->string; p < m_data->end; ++p, ++q )
2949  if ( R::ToCaseFolded( *p ) != R::ToCaseFolded( *q ) )
2950  return false;
2951  return true;
2952  }
2953 
2958  bool EndsWithIC( const_c_string t ) const noexcept
2959  {
2960  size_type n = R::Length( t );
2961  if ( n == 0 || Length() < n )
2962  return false;
2963  for ( const_iterator p = m_data->end-n; p < m_data->end; ++p, ++t )
2964  if ( R::ToCaseFolded( *p ) != R::ToCaseFolded( *t ) )
2965  return false;
2966  return true;
2967  }
2968 
2973  bool EndsWithIC( char_type c ) const noexcept
2974  {
2975  return m_data->string < m_data->end && R::ToCaseFolded( *(m_data->end-1) ) == R::ToCaseFolded( c );
2976  }
2977 
2983  template <class R1, class A1>
2984  size_type FindFirst( const GenericString<T,R1,A1>& s, size_type i = 0 ) const noexcept
2985  {
2986  size_type len = Length();
2987  i = SearchEngine( s.m_data->string, s.Length(), true/*case*/ )( m_data->string, i, len );
2988  return (i < len) ? i : notFound;
2989  }
2990 
2996  size_type FindFirst( const_c_string t, size_type i = 0 ) const noexcept
2997  {
2998  size_type len = Length();
2999  i = SearchEngine( t, R::Length( t ), true/*case*/ )( m_data->string, i, len );
3000  return (i < len) ? i : notFound;
3001  }
3002 
3008  size_type FindFirst( char_type c, size_type i = 0 ) const noexcept
3009  {
3010  for ( const_iterator p = m_data->string+i; p < m_data->end; ++p )
3011  if ( *p == c )
3012  return p - m_data->string;
3013  return notFound;
3014  }
3015 
3024  template <class R1, class A1>
3025  size_type FindFirstIC( const GenericString<T,R1,A1>& s, size_type i = 0 ) const noexcept
3026  {
3027  size_type len = Length();
3028  i = SearchEngine( s.m_data->string, s.Length(), false/*case*/ )( m_data->string, i, len );
3029  return (i < len) ? i : notFound;
3030  }
3031 
3040  size_type FindFirstIC( const_c_string t, size_type i = 0 ) const noexcept
3041  {
3042  size_type len = Length();
3043  i = SearchEngine( t, R::Length( t ), false/*case*/ )( m_data->string, i, len );
3044  return (i < len) ? i : notFound;
3045  }
3046 
3055  size_type FindFirstIC( char_type c, size_type i = 0 ) const noexcept
3056  {
3057  c = R::ToCaseFolded( c );
3058  for ( const_iterator p = m_data->string+i; p < m_data->end; ++p )
3059  if ( R::ToCaseFolded( *p ) == c )
3060  return p - m_data->string;
3061  return notFound;
3062  }
3063 
3067  template <class R1, class A1>
3068  size_type Find( const GenericString<T,R1,A1>& s, size_type i = 0 ) const noexcept
3069  {
3070  return FindFirst( s, i );
3071  }
3072 
3076  size_type Find( const_c_string t, size_type i = 0 ) const noexcept
3077  {
3078  return FindFirst( t, i );
3079  }
3080 
3084  size_type Find( char_type c, size_type i = 0 ) const noexcept
3085  {
3086  return FindFirst( c, i );
3087  }
3088 
3092  template <class R1, class A1>
3093  size_type FindIC( const GenericString<T,R1,A1>& s, size_type i = 0 ) const noexcept
3094  {
3095  return FindFirstIC( s, i );
3096  }
3097 
3101  size_type FindIC( const_c_string t, size_type i = 0 ) const noexcept
3102  {
3103  return FindFirstIC( t, i );
3104  }
3105 
3109  size_type FindIC( char_type c, size_type i = 0 ) const noexcept
3110  {
3111  return FindFirstIC( c, i );
3112  }
3113 
3123  template <class R1, class A1>
3124  size_type FindLast( const GenericString<T,R1,A1>& s, size_type r = maxPos ) const noexcept
3125  {
3126  r = pcl::Min( r, Length() );
3127  size_type i = SearchEngine( s.m_data->string, s.Length(), true/*case*/, true/*last*/ )( m_data->string, 0, r );
3128  return (i < r) ? i : notFound;
3129  }
3130 
3140  size_type FindLast( const_c_string t, size_type r = maxPos ) const noexcept
3141  {
3142  r = pcl::Min( r, Length() );
3143  size_type i = SearchEngine( t, R::Length( t ), true/*case*/, true/*last*/ )( m_data->string, 0, r );
3144  return (i < r) ? i : notFound;
3145  }
3146 
3152  size_type FindLast( char_type c, size_type r = maxPos ) const noexcept
3153  {
3154  r = pcl::Min( r, Length() );
3155  for ( const_iterator p = m_data->string+r; r > 0; --r )
3156  if ( *--p == c )
3157  return r - 1;
3158  return notFound;
3159  }
3160 
3173  template <class R1, class A1>
3174  size_type FindLastIC( const GenericString<T,R1,A1>& s, size_type r = maxPos ) const noexcept
3175  {
3176  r = pcl::Min( r, Length() );
3177  size_type i = SearchEngine( s.m_data->string, s.Length(), false/*case*/, true/*last*/ )( m_data->string, 0, r );
3178  return (i < r) ? i : notFound;
3179  }
3180 
3193  size_type FindLastIC( const_c_string t, size_type r = maxPos ) const noexcept
3194  {
3195  r = pcl::Min( r, Length() );
3196  size_type i = SearchEngine( t, R::Length( t ), false/*case*/, true/*last*/ )( m_data->string, 0, r );
3197  return (i < r) ? i : notFound;
3198  }
3199 
3208  size_type FindLastIC( char_type c, size_type r = maxPos ) const noexcept
3209  {
3210  c = R::ToCaseFolded( c );
3211  r = pcl::Min( r, Length() );
3212  for ( const_iterator p = m_data->string+r; r > 0; --r )
3213  if ( R::ToCaseFolded( *--p ) == c )
3214  return r - 1;
3215  return notFound;
3216  }
3217 
3221  template <class R1, class A1>
3222  bool Contains( const GenericString<T,R1,A1>& s ) const noexcept
3223  {
3224  return Find( s ) != notFound;
3225  }
3226 
3230  bool Contains( const_c_string t ) const noexcept
3231  {
3232  return Find( t ) != notFound;
3233  }
3234 
3238  bool Contains( char_type c ) const noexcept
3239  {
3240  return Find( c ) != notFound;
3241  }
3242 
3249  template <class R1, class A1>
3250  bool ContainsIC( const GenericString<T,R1,A1>& s ) const noexcept
3251  {
3252  return FindIC( s ) != notFound;
3253  }
3254 
3261  bool ContainsIC( const_c_string t ) const noexcept
3262  {
3263  return FindIC( t ) != notFound;
3264  }
3265 
3272  bool ContainsIC( char_type c ) const noexcept
3273  {
3274  return FindIC( c ) != notFound;
3275  }
3276 
3286  void Trim()
3287  {
3288  const_iterator l = R::SearchTrimLeft( m_data->string, m_data->end );
3289  const_iterator r = R::SearchTrimRight( l, m_data->end );
3290  if ( m_data->string < l || r < m_data->end )
3291  Trim( l, r - l );
3292  }
3293 
3303  void TrimLeft()
3304  {
3305  const_iterator l = R::SearchTrimLeft( m_data->string, m_data->end );
3306  if ( m_data->string < l )
3307  Trim( l, m_data->end - l );
3308  }
3309 
3319  void TrimRight()
3320  {
3321  const_iterator r = R::SearchTrimRight( m_data->string, m_data->end );
3322  if ( r < m_data->end )
3323  Trim( m_data->string, r - m_data->string );
3324  }
3325 
3332  {
3333  GenericString s( *this );
3334  s.Trim();
3335  return s;
3336  }
3337 
3344  {
3345  GenericString s( *this );
3346  s.TrimLeft();
3347  return s;
3348  }
3349 
3356  {
3357  GenericString s( *this );
3358  s.TrimRight();
3359  return s;
3360  }
3361 
3369  {
3370  int encloseLeft = 1;
3371  int encloseRight = 1;
3372  size_type len = Length();
3373  if ( len > 0 )
3374  {
3375  if ( *m_data->string == c )
3376  encloseLeft = 0;
3377  if ( *(m_data->end-1) == c )
3378  if ( len > 1 )
3379  encloseRight = 0;
3380  else
3381  encloseLeft = 0;
3382  }
3383  size_type n = len + encloseLeft + encloseRight;
3384  if ( n > len )
3385  {
3386  if ( !IsUnique() || m_data->ShouldReallocate( n ) )
3387  {
3388  Data* newData = Data::New( n );
3389  R::Copy( newData->string + encloseLeft, m_data->string, len );
3390  DetachFromData();
3391  m_data = newData;
3392  }
3393  else
3394  {
3395  m_data->SetLength( n );
3396  R::CopyOverlapped( m_data->string + encloseLeft, m_data->string, len );
3397  }
3398 
3399  if ( encloseLeft )
3400  *m_data->string = c;
3401  if ( encloseRight )
3402  *(m_data->end-1) = c;
3403  }
3404  }
3405 
3413  {
3414  GenericString s( *this );
3415  s.EnsureEnclosed( c );
3416  return s;
3417  }
3418 
3426  {
3427  EnsureEnclosed( R::SingleQuote() );
3428  }
3429 
3437  {
3438  GenericString s( *this );
3439  s.EnsureSingleQuoted();
3440  return s;
3441  }
3442 
3450  {
3451  EnsureEnclosed( R::DoubleQuote() );
3452  }
3453 
3461  {
3462  GenericString s( *this );
3463  s.EnsureDoubleQuoted();
3464  return s;
3465  }
3466 
3480  void Unquote()
3481  {
3482  size_type len = Length();
3483  if ( len > 1 )
3484  if ( *m_data->string == R::SingleQuote() && *(m_data->end-1) == R::SingleQuote() ||
3485  *m_data->string == R::DoubleQuote() && *(m_data->end-1) == R::DoubleQuote() )
3486  if ( IsUnique() )
3487  {
3488  R::CopyOverlapped( m_data->string, m_data->string+1, len-2 );
3489  m_data->SetLength( len-2 );
3490  }
3491  else
3492  {
3493  Data* newData = Data::New( len-2 );
3494  R::Copy( newData->string, m_data->string+1, len-2 );
3495  DetachFromData();
3496  m_data = newData;
3497  }
3498  }
3499 
3505  {
3506  GenericString s( *this );
3507  s.Unquote();
3508  return s;
3509  }
3510 
3522  void JustifyLeft( size_type width, char_type fill = R::Blank() )
3523  {
3524  size_type len = Length();
3525  if ( len < width )
3526  Append( fill, width-len );
3527  }
3528 
3540  void JustifyRight( size_type width, char_type fill = R::Blank() )
3541  {
3542  size_type len = Length();
3543  if ( len < width )
3544  Prepend( fill, width-len );
3545  }
3546 
3559  void JustifyCenter( size_type width, char_type fill = R::Blank() )
3560  {
3561  size_type len = Length();
3562  if ( len < width )
3563  {
3564  size_type n = width-len;
3565  size_type n2 = n >> 1;
3566  Prepend( fill, n2 );
3567  Append( fill, n-n2 );
3568  }
3569  }
3570 
3577  GenericString LeftJustified( size_type width, char_type fill = R::Blank() ) const
3578  {
3579  GenericString s( *this );
3580  s.JustifyLeft( width, fill );
3581  return s;
3582  }
3583 
3590  GenericString RightJustified( size_type width, char_type fill = R::Blank() ) const
3591  {
3592  GenericString s( *this );
3593  s.JustifyRight( width, fill );
3594  return s;
3595  }
3596 
3603  GenericString CenterJustified( size_type width, char_type fill = R::Blank() ) const
3604  {
3605  GenericString s( *this );
3606  s.JustifyCenter( width, fill );
3607  return s;
3608  }
3609 
3633  template <class R1, class A1>
3634  int CompareCodePoints( const GenericString<T,R1,A1>& s, bool caseSensitive = true ) const noexcept
3635  {
3636  return R::CompareCodePoints( m_data->string, Length(), s.m_data->string, s.Length(), caseSensitive );
3637  }
3638 
3663  int CompareCodePoints( const_c_string t, bool caseSensitive = true ) const noexcept
3664  {
3665  return R::CompareCodePoints( m_data->string, Length(), t, R::Length( t ), caseSensitive );
3666  }
3667 
3695  int CompareCodePoints( char_type c, bool caseSensitive = true ) const noexcept
3696  {
3697  return R::CompareCodePoints( m_data->string, Length(), &c, 1, caseSensitive );
3698  }
3699 
3726  template <class R1, class A1>
3728  bool caseSensitive = true, bool localeAware = true ) const noexcept
3729  {
3730  return R::Compare( m_data->string, Length(), s.m_data->string, s.Length(), caseSensitive, localeAware );
3731  }
3732 
3760  int Compare( const_c_string t, bool caseSensitive = true, bool localeAware = true ) const noexcept
3761  {
3762  return R::Compare( m_data->string, Length(), t, R::Length( t ), caseSensitive, localeAware );
3763  }
3764 
3794  int Compare( char_type c, bool caseSensitive = true, bool localeAware = true ) const noexcept
3795  {
3796  return R::Compare( m_data->string, Length(), &c, 1, caseSensitive, localeAware );
3797  }
3798 
3819  template <class R1, class A1>
3820  int CompareIC( const GenericString<T,R1,A1>& s, bool localeAware = true ) const noexcept
3821  {
3822  return R::Compare( m_data->string, Length(), s.m_data->string, s.Length(), false/*caseSensitive*/, localeAware );
3823  }
3824 
3846  int CompareIC( const_c_string t, bool localeAware = true ) const noexcept
3847  {
3848  return R::Compare( m_data->string, Length(), t, R::Length( t ), false/*caseSensitive*/, localeAware );
3849  }
3850 
3875  int CompareIC( char_type c, bool localeAware = true ) const noexcept
3876  {
3877  return R::Compare( m_data->string, Length(), &c, 1, false/*caseSensitive*/, localeAware );
3878  }
3879 
3895  template <class R1, class A1>
3896  bool WildMatch( const GenericString<T,R1,A1>& pattern, bool caseSensitive = true ) const noexcept
3897  {
3898  return R::WildMatch( m_data->string, Length(), pattern.m_data->string, pattern.Length(), caseSensitive );
3899  }
3900 
3914  template <class R1, class A1>
3915  bool WildMatchIC( const GenericString<T,R1,A1>& pattern ) const noexcept
3916  {
3917  return R::WildMatch( m_data->string, Length(), pattern.m_data->string, pattern.Length(), false/*caseSensitive*/ );
3918  }
3919 
3935  bool WildMatch( const_c_string pattern, bool caseSensitive = true ) const noexcept
3936  {
3937  return R::WildMatch( m_data->string, Length(), pattern, R::Length( pattern ), caseSensitive );
3938  }
3939 
3954  bool WildMatchIC( const_c_string pattern ) const noexcept
3955  {
3956  return R::WildMatch( m_data->string, Length(), pattern, R::Length( pattern ), false/*caseSensitive*/ );
3957  }
3958 
3963  bool HasWildcards() const noexcept
3964  {
3965  for ( iterator i = m_data->string; i < m_data->end; ++i )
3966  if ( R::IsWildcard( *i ) )
3967  return true;
3968  return false;
3969  }
3970 
3976  {
3977  size_type len = Length();
3978  if ( len > 0 )
3979  {
3980  EnsureUnique();
3981  R::ToCaseFolded( m_data->string, len );
3982  }
3983  }
3984 
3990  {
3991  size_type len = Length();
3992  if ( len > 0 )
3993  {
3994  EnsureUnique();
3995  R::ToLowercase( m_data->string, len );
3996  }
3997  }
3998 
4004  {
4005  size_type len = Length();
4006  if ( len > 0 )
4007  {
4008  EnsureUnique();
4009  R::ToUppercase( m_data->string, len );
4010  }
4011  }
4012 
4018  {
4019  GenericString s( *this );
4020  s.ToCaseFolded();
4021  return s;
4022  }
4023 
4029  {
4030  GenericString s( *this );
4031  s.ToLowercase();
4032  return s;
4033  }
4034 
4040  {
4041  GenericString s( *this );
4042  s.ToUppercase();
4043  return s;
4044  }
4045 
4051  void Reverse()
4052  {
4053  if ( !IsEmpty() )
4054  {
4055  EnsureUnique();
4056  for ( iterator i = m_data->string, j = m_data->end; i < --j; ++i )
4057  pcl::Swap( *i, *j );
4058  }
4059  }
4060 
4065  {
4066  GenericString s( *this );
4067  s.Reverse();
4068  return s;
4069  }
4070 
4074  void Sort()
4075  {
4076  if ( !IsEmpty() )
4077  {
4078  EnsureUnique();
4079  pcl::Sort( m_data->string, m_data->end );
4080  }
4081  }
4082 
4088  {
4089  GenericString s( *this );
4090  s.Sort();
4091  return s;
4092  }
4093 
4099  template <class BP>
4100  void Sort( BP p )
4101  {
4102  if ( !IsEmpty() )
4103  {
4104  EnsureUnique();
4105  pcl::Sort( m_data->string, m_data->end, p );
4106  }
4107  }
4108 
4113  template <class BP>
4114  GenericString Sorted( BP p ) const
4115  {
4116  GenericString s( *this );
4117  s.Sort( p );
4118  return s;
4119  }
4120 
4135  bool IsNumeral() const noexcept
4136  {
4137  if ( IsEmpty() )
4138  return false;
4139  char_type c = *R::SearchTrimLeft( m_data->string, m_data->end );
4140  return R::IsDigit( c ) || R::IsSign( c ) || R::IsDecimalSeparator( c );
4141  }
4142 
4157  bool IsSymbol() const noexcept
4158  {
4159  if ( IsEmpty() )
4160  return false;
4161  char_type c = *R::SearchTrimLeft( m_data->string, m_data->end );
4162  return R::IsSymbolDigit( c );
4163  }
4164 
4180  bool IsValidIdentifier( distance_type& pos ) const noexcept
4181  {
4182  if ( IsEmpty() )
4183  {
4184  pos = 0;
4185  return false;
4186  }
4187  const_iterator i = m_data->string;
4188  if ( R::IsStartingSymbolDigit( *i ) )
4189  for ( ;; )
4190  {
4191  if ( ++i == m_data->end )
4192  return true;
4193  if ( !R::IsSymbolDigit( *i ) )
4194  break;
4195  }
4196  pos = i - m_data->string;
4197  return false;
4198  }
4199 
4211  bool IsValidIdentifier() const noexcept
4212  {
4213  if ( !IsEmpty() )
4214  if ( R::IsStartingSymbolDigit( *m_data->string ) )
4215  {
4216  for ( const_iterator i = m_data->string; ++i < m_data->end; )
4217  if ( !R::IsSymbolDigit( *i ) )
4218  return false;
4219  return true;
4220  }
4221  return false;
4222  }
4223 
4232  uint64 Hash64( uint64 seed = 0 ) const noexcept
4233  {
4234  return pcl::Hash64( m_data->string, Size(), seed );
4235  }
4236 
4245  uint32 Hash32( uint32 seed = 0 ) const noexcept
4246  {
4247  return pcl::Hash32( m_data->string, Size(), seed );
4248  }
4249 
4254  uint64 Hash( uint64 seed = 0 ) const noexcept
4255  {
4256  return Hash64( seed );
4257  }
4258 
4267  {
4268  return Data::DeleteFreeList();
4269  }
4270 
4271  // -------------------------------------------------------------------------
4272 
4273 protected:
4274 
4279  void DetachFromData()
4280  {
4281  if ( !m_data->Detach() )
4282  Data::Dispose( m_data );
4283  }
4284 
4296  void MaybeReallocate( size_type len )
4297  {
4298  if ( IsUnique() )
4299  {
4300  if ( m_data->ShouldReallocate( len ) )
4301  {
4302  m_data->Deallocate();
4303  m_data->Allocate( len );
4304  }
4305  else
4306  m_data->SetLength( len );
4307  }
4308  else
4309  {
4310  Data* newData = Data::New( len );
4311  DetachFromData();
4312  m_data = newData;
4313  }
4314  }
4315 
4324  void UninitializedGrow( size_type& i, size_type n )
4325  {
4326  size_type len = Length();
4327  size_type newLen = len+n;
4328  if ( newLen > len )
4329  {
4330  if ( i > len )
4331  i = len;
4332  if ( IsUnique() )
4333  {
4334  if ( size_type( m_data->capacity - m_data->string ) < newLen+1 )
4335  {
4336  iterator old = m_data->string;
4337  m_data->Allocate( newLen );
4338  if ( old != nullptr )
4339  {
4340  if ( i > 0 )
4341  R::Copy( m_data->string, old, i );
4342  if ( i < len )
4343  R::Copy( m_data->string+i+n, old+i, len-i );
4344  m_data->alloc.Deallocate( old );
4345  }
4346  }
4347  else
4348  {
4349  if ( i < len )
4350  R::CopyOverlapped( m_data->string+i+n, m_data->string+i, len-i );
4351  m_data->SetLength( newLen );
4352  }
4353  }
4354  else
4355  {
4356  Data* newData = Data::New( newLen );
4357  if ( i > 0 )
4358  R::Copy( newData->string, m_data->string, i );
4359  if ( i < len )
4360  R::Copy( newData->string+i+n, m_data->string+i, len-i );
4361  DetachFromData();
4362  m_data = newData;
4363  }
4364  }
4365  }
4366 
4371  void Trim( const_iterator left, size_type len )
4372  {
4373  if ( len > 0 )
4374  {
4375  if ( IsUnique() )
4376  {
4377  if ( m_data->ShouldReallocate( len ) )
4378  {
4379  iterator old = m_data->string;
4380  m_data->Allocate( len );
4381  R::Copy( m_data->string, left, len );
4382  if ( old != nullptr )
4383  m_data->alloc.Deallocate( old );
4384  }
4385  else
4386  {
4387  if ( left != m_data->string ) // trim left
4388  R::CopyOverlapped( m_data->string, left, len );
4389  m_data->SetLength( len ); // trim right
4390  }
4391  }
4392  else
4393  {
4394  Data* newData = Data::New( len );
4395  R::Copy( newData->string, left, len );
4396  DetachFromData();
4397  m_data = newData;
4398  }
4399  }
4400  else
4401  Clear();
4402  }
4403 
4408  void ReplaceChar( char_type c1, char_type c2, size_type i, size_type n, bool caseSensitive )
4409  {
4410  if ( n > 0 )
4411  {
4412  size_type len = Length();
4413  if ( i < len )
4414  {
4415  n = pcl::Min( n, len-i );
4416  if ( caseSensitive )
4417  {
4418  for ( iterator p = m_data->string + i, p1 = p + n; p < p1; ++p )
4419  if ( *p == c1 )
4420  {
4421  distance_type d = p - m_data->string;
4422  EnsureUnique();
4423  p = m_data->string + d;
4424  *p = c2;
4425  for ( iterator p1 = m_data->string + i + n; ++p < p1; )
4426  if ( *p == c1 )
4427  *p = c2;
4428  break;
4429  }
4430  }
4431  else
4432  {
4433  c1 = R::ToCaseFolded( c1 );
4434  for ( iterator p = m_data->string + i, p1 = p + n; p < p1; ++p )
4435  if ( R::ToCaseFolded( *p ) == c1 )
4436  {
4437  distance_type d = p - m_data->string;
4438  EnsureUnique();
4439  p = m_data->string + d;
4440  *p = c2;
4441  for ( iterator p1 = m_data->string + i + n; ++p < p1; )
4442  if ( R::ToCaseFolded( *p ) == c1 )
4443  *p = c2;
4444  break;
4445  }
4446  }
4447  }
4448  }
4449  }
4450 
4455  void ReplaceString( const_iterator t1, size_type n1, const_iterator t2, size_type n2, size_type i, bool caseSensitive )
4456  {
4457  if ( n1 > 0 )
4458  {
4459  size_type len = Length();
4460  if ( i < len )
4461  {
4462  SearchEngine S( t1, n1, caseSensitive );
4463  if ( n1 == n2 )
4464  {
4465  EnsureUnique();
4466  for ( size_type p = i; (p = S( m_data->string, p, len )) < len; p += n1 )
4467  R::Copy( m_data->string + p, t2, n2 );
4468  }
4469  else
4470  {
4471  Array<size_type> P;
4472  for ( size_type p = i; (p = S( m_data->string, p, len )) < len; p += n1 )
4473  P.Add( p );
4474  if ( !P.IsEmpty() )
4475  {
4476  size_type newLen = len;
4477  if ( n1 < n2 )
4478  newLen += P.Length()*(n2 - n1);
4479  else
4480  newLen -= P.Length()*(n1 - n2);
4481 
4482  if ( newLen > 0 )
4483  {
4484  Data* newData = Data::New( newLen );
4485  size_type targetIndex = 0;
4486  size_type sourceIndex = 0;
4487  for ( size_type p : P )
4488  {
4489  size_type n = p - sourceIndex;
4490  if ( n > 0 )
4491  R::Copy( newData->string+targetIndex, m_data->string+sourceIndex, n );
4492  R::Copy( newData->string+targetIndex+n, t2, n2 );
4493  targetIndex += n + n2;
4494  sourceIndex = p + n1;
4495  }
4496  if ( sourceIndex < len )
4497  R::Copy( newData->string+targetIndex, m_data->string+sourceIndex, len-sourceIndex );
4498  DetachFromData();
4499  m_data = newData;
4500  }
4501  else
4502  Clear();
4503  }
4504  }
4505  }
4506  }
4507  }
4508 
4526  class PCL_CLASS SearchEngine
4527  {
4528  public:
4529 
4540  SearchEngine( const_iterator pattern, size_type patternLength,
4541  bool caseSensitive = true, bool searchLast = false, bool useBoyerMoore = true )
4542  : m_pattern( pattern )
4543  , m_patternLength( int( patternLength ) )
4544  , m_caseSensitive( caseSensitive )
4545  , m_searchLast( searchLast )
4546  , m_useBoyerMoore( useBoyerMoore && m_patternLength > 3 )
4547  {
4548  if ( m_useBoyerMoore )
4549  InitSkipList();
4550  }
4551 
4564  size_type operator()( const_iterator text, size_type startIndex, size_type endIndex ) const noexcept
4565  {
4566  if ( endIndex <= startIndex
4567  || m_patternLength <= 0
4568  || endIndex-startIndex < size_type( m_patternLength )
4569  || text == nullptr
4570  || m_pattern == nullptr )
4571  return endIndex;
4572 
4573  if ( m_caseSensitive )
4574  {
4575  if ( m_useBoyerMoore )
4576  {
4577  if ( m_searchLast )
4578  {
4579  for ( size_type i = startIndex, r = endIndex-m_patternLength; i <= r; )
4580  {
4581  int skip = 0;
4582  const_iterator t = text + r - i;
4583  const_iterator p = m_pattern;
4584  for ( int j = m_patternLength; --j >= 0; )
4585  {
4586  char_type c = *t++;
4587  if ( c != *p++ )
4588  {
4589  skip = j - m_skipList[uint8( c )];
4590  if ( skip < 1 )
4591  skip = 1;
4592  break;
4593  }
4594  }
4595  if ( skip == 0 )
4596  return r - i;
4597  i += skip;
4598  }
4599  }
4600  else
4601  {
4602  for ( size_type i = startIndex, r = endIndex-m_patternLength; i <= r; )
4603  {
4604  int skip = 0;
4605  const_iterator t = text + i + m_patternLength;
4606  const_iterator p = m_pattern + m_patternLength;
4607  for ( int j = m_patternLength; --j >= 0; )
4608  {
4609  char_type c = *--t;
4610  if ( c != *--p )
4611  {
4612  // ### N.B.: Could do better with a precomputed pattern mismatch table.
4613  skip = j - m_skipList[uint8( c )];
4614  if ( skip < 1 )
4615  skip = 1;
4616  break;
4617  }
4618  }
4619  if ( skip == 0 )
4620  return i;
4621  i += skip;
4622  }
4623  }
4624  }
4625  else
4626  {
4627  // Use a brute force search for very small patterns.
4628  if ( m_searchLast )
4629  {
4630  for ( size_type i = endIndex-m_patternLength; ; --i )
4631  {
4632  const_iterator t = text + i;
4633  const_iterator p = m_pattern;
4634  for ( int j = m_patternLength; ; ++t, ++p )
4635  {
4636  if ( *t != *p )
4637  break;
4638  if ( --j == 0 )
4639  return i;
4640  }
4641  if ( i == startIndex )
4642  break;
4643  }
4644  }
4645  else
4646  {
4647  for ( size_type i = startIndex, r = endIndex-m_patternLength; ; ++i )
4648  {
4649  const_iterator t = text + i;
4650  const_iterator p = m_pattern;
4651  for ( int j = m_patternLength; ; ++t, ++p )
4652  {
4653  if ( *t != *p )
4654  break;
4655  if ( --j == 0 )
4656  return i;
4657  }
4658  if ( i == r )
4659  break;
4660  }
4661  }
4662  }
4663  }
4664  else
4665  {
4666  if ( m_useBoyerMoore )
4667  {
4668  if ( m_searchLast )
4669  {
4670  for ( size_type i = startIndex, r = endIndex-m_patternLength; i <= r; )
4671  {
4672  int skip = 0;
4673  const_iterator t = text + r - i;
4674  const_iterator p = m_pattern;
4675  for ( int j = m_patternLength; --j >= 0; )
4676  {
4677  char_type c = R::ToCaseFolded( *t++ );
4678  if ( c != R::ToCaseFolded( *p++ ) )
4679  {
4680  skip = j - m_skipList[uint8( c )];
4681  if ( skip < 1 )
4682  skip = 1;
4683  break;
4684  }
4685  }
4686  if ( skip == 0 )
4687  return r - i;
4688  i += skip;
4689  }
4690  }
4691  else
4692  {
4693  for ( size_type i = startIndex, r = endIndex-m_patternLength; i <= r; )
4694  {
4695  int skip = 0;
4696  const_iterator t = text + i + m_patternLength;
4697  const_iterator p = m_pattern + m_patternLength;
4698  for ( int j = m_patternLength; --j >= 0; )
4699  {
4700  char_type c = R::ToCaseFolded( *--t );
4701  if ( c != R::ToCaseFolded( *--p ) )
4702  {
4703  // ### N.B.: Could do better with a precomputed pattern mismatch table.
4704  skip = j - m_skipList[uint8( c )];
4705  if ( skip < 1 )
4706  skip = 1;
4707  break;
4708  }
4709  }
4710  if ( skip == 0 )
4711  return i;
4712  i += skip;
4713  }
4714  }
4715  }
4716  else
4717  {
4718  // Use a brute force search for very small patterns.
4719  if ( m_searchLast )
4720  {
4721  for ( size_type i = endIndex-m_patternLength; ; --i )
4722  {
4723  const_iterator t = text + i;
4724  const_iterator p = m_pattern;
4725  for ( int j = m_patternLength; ; ++t, ++p )
4726  {
4727  if ( R::ToCaseFolded( *t ) != R::ToCaseFolded( *p ) )
4728  break;
4729  if ( --j == 0 )
4730  return i;
4731  }
4732  if ( i == startIndex )
4733  break;
4734  }
4735  }
4736  else
4737  {
4738  for ( size_type i = startIndex, r = endIndex-m_patternLength; ; ++i )
4739  {
4740  const_iterator t = text + i;
4741  const_iterator p = m_pattern;
4742  for ( int j = m_patternLength; ; ++t, ++p )
4743  {
4744  if ( R::ToCaseFolded( *t ) != R::ToCaseFolded( *p ) )
4745  break;
4746  if ( --j == 0 )
4747  return i;
4748  }
4749  if ( i == r )
4750  break;
4751  }
4752  }
4753  }
4754  }
4755  return endIndex;
4756  }
4757 
4758  private:
4759 
4760  int m_skipList[ 256 ];
4761  const_iterator m_pattern;
4762  int m_patternLength;
4763  bool m_caseSensitive : 1;
4764  bool m_searchLast : 1;
4765  bool m_useBoyerMoore : 1;
4766 
4767  void InitSkipList() noexcept
4768  {
4769  ::memset( m_skipList, 0xff, sizeof( m_skipList ) ); // fill with -1
4770  if ( m_searchLast )
4771  {
4772  const_iterator p = m_pattern + m_patternLength;
4773  if ( m_caseSensitive )
4774  for ( int i = 0; i < m_patternLength; ++i )
4775  m_skipList[uint8( *--p )] = i;
4776  else
4777  for ( int i = 0; i < m_patternLength; ++i )
4778  m_skipList[uint8( R::ToCaseFolded( *--p ) )] = i;
4779  }
4780  else
4781  {
4782  const_iterator p = m_pattern;
4783  if ( m_caseSensitive )
4784  for ( int i = 0; i < m_patternLength; ++i )
4785  m_skipList[uint8( *p++ )] = i;
4786  else
4787  for ( int i = 0; i < m_patternLength; ++i )
4788  m_skipList[uint8( R::ToCaseFolded( *p++ ) )] = i;
4789  }
4790  }
4791  };
4792 
4793  // -------------------------------------------------------------------------
4794 
4800  class PCL_CLASS Data : public ReferenceCounter
4801  {
4802  private:
4803 
4804 #ifndef __PCL_NO_STRING_FREE_LIST
4805  static Data* freeList;
4806  static AtomicInt freeLock;
4807 #endif
4808 
4809  public:
4810 
4811  iterator string = nullptr;
4812  iterator end = nullptr;
4813  iterator capacity = nullptr;
4814  allocator alloc;
4815 
4819  Data() = default;
4820 
4824  Data( size_type len )
4825  {
4826  Allocate( len );
4827  }
4828 
4833  Data( size_type len, size_type total )
4834  {
4835  Allocate( len, total );
4836  }
4837 
4841  ~Data()
4842  {
4843  Deallocate();
4844  }
4845 
4856  void Allocate( size_type len, size_type total )
4857  {
4858  total = (len <= total) ? alloc.PagedLength( total+1 ) : len+1; // +1 is room for a null terminating character
4859  string = alloc.Allocate( total );
4860  capacity = string + total;
4861  SetLength( len );
4862  }
4863 
4868  void Allocate( size_type len )
4869  {
4870  Allocate( len, len );
4871  }
4872 
4881  void Reserve( size_type len, size_type total )
4882  {
4883  PCL_PRECONDITION( len <= total )
4884  string = alloc.Allocate( total+1 );
4885  capacity = string + total+1;
4886  SetLength( pcl::Min( len, total ) );
4887  }
4888 
4892  void Deallocate()
4893  {
4894  PCL_CHECK( (string == nullptr) ? end == nullptr : string < end )
4895  if ( string != nullptr )
4896  {
4897  alloc.Deallocate( string );
4898  Reset();
4899  }
4900  }
4901 
4906  bool ShouldReallocate( size_type len ) const noexcept
4907  {
4908  size_type m = capacity - string;
4909  return m <= len || alloc.ReallocatedLength( m, len+1 ) < (m >> 1);
4910  }
4911 
4916  void SetLength( size_type len ) noexcept
4917  {
4918  *(end = (string + len)) = R::Null();
4919  }
4920 
4924  void Reset() noexcept
4925  {
4926  string = end = capacity = nullptr;
4927  }
4928 
4935 #ifndef __PCL_NO_STRING_FREE_LIST
4936  static Data* NextFree() noexcept
4937  {
4938  if ( freeLock.TestAndSet( 0, 1 ) )
4939  {
4940  Data* data = freeList;
4941  if ( data != nullptr )
4942  freeList = reinterpret_cast<Data*>( data->string );
4943  freeLock.Store( 0 );
4944  return data;
4945  }
4946  return nullptr;
4947  }
4948 #endif // !__PCL_NO_STRING_FREE_LIST
4949 
4957  static Data* New()
4958  {
4959 #ifndef __PCL_NO_STRING_FREE_LIST
4960  Data* data = NextFree();
4961  if ( data != nullptr )
4962  {
4963  data->string = nullptr;
4964  return data;
4965  }
4966 #endif // !__PCL_NO_STRING_FREE_LIST
4967  return new Data;
4968  }
4969 
4977  static Data* New( size_type len )
4978  {
4979 #ifndef __PCL_NO_STRING_FREE_LIST
4980  Data* data = NextFree();
4981  if ( data != nullptr )
4982  {
4983  data->Allocate( len ); // ### FIXME: If allocation fails, data is a leak.
4984  return data;
4985  }
4986 #endif // !__PCL_NO_STRING_FREE_LIST
4987  return new Data( len );
4988  }
4989 
4997  static Data* New( size_type len, size_type total )
4998  {
4999 #ifndef __PCL_NO_STRING_FREE_LIST
5000  Data* data = NextFree();
5001  if ( data != nullptr )
5002  {
5003  data->Allocate( len, total ); // ### FIXME: If allocation fails, data is a leak.
5004  return data;
5005  }
5006 #endif // !__PCL_NO_STRING_FREE_LIST
5007  return new Data( len, total );
5008  }
5009 
5017  static void Dispose( Data* data )
5018  {
5019  PCL_PRECONDITION( data != nullptr )
5020  PCL_CHECK( data->RefCount() == 0 )
5021 #ifndef __PCL_NO_STRING_FREE_LIST
5022  if ( freeLock.TestAndSet( 0, 1 ) )
5023  {
5024  data->Attach();
5025  data->Deallocate();
5026  data->string = reinterpret_cast<iterator>( freeList );
5027  freeList = data;
5028  freeLock.Store( 0 );
5029  }
5030  else
5031 #endif // !__PCL_NO_STRING_FREE_LIST
5032  delete data;
5033  }
5034 
5042  static size_type DeleteFreeList()
5043  {
5044  size_type count = 0;
5045 #ifndef __PCL_NO_STRING_FREE_LIST
5046  while ( freeList != nullptr )
5047  {
5048  Data* data = freeList;
5049  freeList = reinterpret_cast<Data*>( data->string );
5050  data->string = nullptr;
5051  delete data;
5052  ++count;
5053  }
5054 #endif // !__PCL_NO_STRING_FREE_LIST
5055  return count;
5056  }
5057  };
5058 
5059  /*
5060  * The reference-counted string data.
5061  */
5062  Data* m_data = nullptr;
5063 };
5064 
5065 #ifndef __PCL_NO_STRING_FREE_LIST
5066 
5067 template <class T, class R, class A>
5068 typename GenericString<T,R,A>::Data* GenericString<T,R,A>::Data::freeList = nullptr;
5069 
5070 template <class T, class R, class A>
5071 AtomicInt GenericString<T,R,A>::Data::freeLock;
5072 
5073 #endif // !__PCL_NO_STRING_FREE_LIST
5074 
5078 template <class T, class R, class A> inline
5080 {
5081  s1.Swap( s2 );
5082 }
5083 
5084 // ----------------------------------------------------------------------------
5085 
5090 // ----------------------------------------------------------------------------
5091 
5096 template <class T, class R1, class A1, class R2, class A2> inline
5097 bool operator ==( const GenericString<T,R1,A1>& s1, const GenericString<T,R2,A2>& s2 ) noexcept
5098 {
5099  return s1.CompareCodePoints( s2 ) == 0;
5100 }
5101 
5109 template <class T, class R1, class A1, class R2, class A2> inline
5110 bool operator <( const GenericString<T,R1,A1>& s1, const GenericString<T,R2,A2>& s2 ) noexcept
5111 {
5112  return s1.CompareCodePoints( s2 ) < 0;
5113 }
5114 
5122 template <class T, class R1, class A1, class R2, class A2> inline
5123 bool operator <=( const GenericString<T,R1,A1>& s1, const GenericString<T,R2,A2>& s2 ) noexcept
5124 {
5125  return s1.CompareCodePoints( s2 ) <= 0;
5126 }
5127 
5135 template <class T, class R1, class A1, class R2, class A2> inline
5136 bool operator >( const GenericString<T,R1,A1>& s1, const GenericString<T,R2,A2>& s2 ) noexcept
5137 {
5138  return s1.CompareCodePoints( s2 ) > 0;
5139 }
5140 
5148 template <class T, class R1, class A1, class R2, class A2> inline
5149 bool operator >=( const GenericString<T,R1,A1>& s1, const GenericString<T,R2,A2>& s2 ) noexcept
5150 {
5151  return s1.CompareCodePoints( s2 ) >= 0;
5152 }
5153 
5154 // ----------------------------------------------------------------------------
5155 
5160 template <class T, class R, class A> inline
5162 {
5163  return s1.CompareCodePoints( t2 ) == 0;
5164 }
5165 
5173 template <class T, class R, class A> inline
5175 {
5176  return s1.CompareCodePoints( t2 ) < 0;
5177 }
5178 
5186 template <class T, class R, class A> inline
5188 {
5189  return s1.CompareCodePoints( t2 ) <= 0;
5190 }
5191 
5199 template <class T, class R, class A> inline
5201 {
5202  return s1.CompareCodePoints( t2 ) > 0;
5203 }
5204 
5212 template <class T, class R, class A> inline
5214 {
5215  return s1.CompareCodePoints( t2 ) >= 0;
5216 }
5217 
5218 // ----------------------------------------------------------------------------
5219 
5224 template <class T, class R, class A> inline
5226 {
5227  return s2.CompareCodePoints( t1 ) == 0;
5228 }
5229 
5237 template <class T, class R, class A> inline
5239 {
5240  return s2.CompareCodePoints( t1 ) > 0;
5241 }
5242 
5250 template <class T, class R, class A> inline
5252 {
5253  return s2.CompareCodePoints( t1 ) >= 0;
5254 }
5255 
5263 template <class T, class R, class A> inline
5265 {
5266  return s2.CompareCodePoints( t1 ) < 0;
5267 }
5268 
5276 template <class T, class R, class A> inline
5278 {
5279  return s2.CompareCodePoints( t1 ) <= 0;
5280 }
5281 
5282 // ----------------------------------------------------------------------------
5283 
5288 template <class T, class R, class A> inline
5290 {
5291  return s1.CompareCodePoints( c2 ) == 0;
5292 }
5293 
5301 template <class T, class R, class A> inline
5302 bool operator <( const GenericString<T,R,A>& s1, typename GenericString<T,R,A>::char_type c2 ) noexcept
5303 {
5304  return s1.CompareCodePoints( c2 ) < 0;
5305 }
5306 
5314 template <class T, class R, class A> inline
5316 {
5317  return s1.CompareCodePoints( c2 ) <= 0;
5318 }
5319 
5327 template <class T, class R, class A> inline
5328 bool operator >( const GenericString<T,R,A>& s1, typename GenericString<T,R,A>::char_type c2 ) noexcept
5329 {
5330  return s1.CompareCodePoints( c2 ) > 0;
5331 }
5332 
5340 template <class T, class R, class A> inline
5342 {
5343  return s1.CompareCodePoints( c2 ) >= 0;
5344 }
5345 
5346 // ----------------------------------------------------------------------------
5347 
5352 template <class T, class R, class A> inline
5354 {
5355  return s2.CompareCodePoints( c1 ) == 0;
5356 }
5357 
5365 template <class T, class R, class A> inline
5366 bool operator <( typename GenericString<T,R,A>::char_type c1, const GenericString<T,R,A>& s2 ) noexcept
5367 {
5368  return s2.CompareCodePoints( c1 ) > 0;
5369 }
5370 
5378 template <class T, class R, class A> inline
5380 {
5381  return s2.CompareCodePoints( c1 ) >= 0;
5382 }
5383 
5391 template <class T, class R, class A> inline
5392 bool operator >( typename GenericString<T,R,A>::char_type c1, const GenericString<T,R,A>& s2 ) noexcept
5393 {
5394  return s2.CompareCodePoints( c1 ) < 0;
5395 }
5396 
5404 template <class T, class R, class A> inline
5406 {
5407  return s2.CompareCodePoints( c1 ) <= 0;
5408 }
5409 
5410 // ----------------------------------------------------------------------------
5411 
5424 class PCL_CLASS IsoString : public GenericString<char, IsoCharTraits, PCL_STRING_ALLOCATOR>
5425 {
5426 public:
5427 
5432 
5437 
5442 
5447 
5452 
5457 
5462 
5467 
5472 
5477 
5482 
5489 
5494 
5499 
5504 
5508  using const_c_ustring = ustring_base::const_c_string;
5509 
5514 
5519 
5520  // -------------------------------------------------------------------------
5521 
5525  IsoString() = default;
5526 
5532  : string_base( s )
5533  {
5534  }
5535 
5539  IsoString( const IsoString& ) = default;
5540 
5546  : string_base( std::move( s ) )
5547  {
5548  }
5549 
5553  IsoString( IsoString&& ) = default;
5554 
5562  explicit
5564  {
5565  (void)operator =( s );
5566  }
5567 
5572  : string_base( t )
5573  {
5574  }
5575 
5581  : string_base( t, i, n )
5582  {
5583  }
5584 
5589  : string_base( c, n )
5590  {
5591  }
5592 
5598  : string_base( i, j )
5599  {
5600  }
5601 
5610  IsoString( std::initializer_list<char_type> l )
5611  : IsoString( l.begin(), l.end() )
5612  {
5613  }
5614 
5624  explicit
5626  {
5627  (void)operator =( t );
5628  }
5629 
5640  IsoString( const_c_ustring t, size_type i, size_type n );
5641 
5649  explicit
5650  IsoString( const ByteArray& B )
5651  : IsoString( const_iterator( B.Begin() ), const_iterator( B.End() ) )
5652  {
5653  }
5654 
5658  explicit
5659  IsoString( bool x )
5660  : string_base( x ? "true" : "false" )
5661  {
5662  }
5663 
5668  explicit
5669  IsoString( short x )
5670  {
5671  (void)Format( "%hd", x );
5672  }
5673 
5678  explicit
5679  IsoString( unsigned short x )
5680  {
5681  (void)Format( "%hu", x );
5682  }
5683 
5688  explicit
5689  IsoString( int x )
5690  {
5691  (void)Format( "%i", x );
5692  }
5693 
5698  explicit
5699  IsoString( unsigned int x )
5700  {
5701  (void)Format( "%u", x );
5702  }
5703 
5708  explicit
5709  IsoString( long x )
5710  {
5711  (void)Format( "%ld", x );
5712  }
5713 
5718  explicit
5719  IsoString( unsigned long x )
5720  {
5721  (void)Format( "%lu", x );
5722  }
5723 
5728  explicit
5729  IsoString( long long x )
5730  {
5731  (void)Format( "%lli", x );
5732  }
5733 
5738  explicit
5739  IsoString( unsigned long long x )
5740  {
5741  (void)Format( "%llu", x );
5742  }
5743 
5748  explicit
5749  IsoString( float x )
5750  {
5751  (void)Format( "%.7g", x );
5752  }
5753 
5758  explicit
5759  IsoString( double x )
5760  {
5761  (void)Format( "%.16g", x );
5762  }
5763 
5768  explicit
5769  IsoString( long double x )
5770  {
5771 #ifdef _MSC_VER
5772  (void)Format( "%.16Lg", x );
5773 #else
5774  (void)Format( "%.18Lg", x );
5775 #endif
5776  }
5777 
5778 #ifndef __PCL_NO_STRING_COMPLEX
5779 
5784  explicit
5786  {
5787  (void)Format( "{%.7g,%.7g}", x.Real(), x.Imag() );
5788  }
5789 
5794  explicit
5796  {
5797  (void)Format( "{%.16g,%.16g}", x.Real(), x.Imag() );
5798  }
5799 
5804  explicit
5806  {
5807 #ifdef _MSC_VER
5808  (void)Format( "{%.16Lg,%.16Lg}", x.Real(), x.Imag() );
5809 #else
5810  (void)Format( "{%.18Lg,%.18Lg}", x.Real(), x.Imag() );
5811 #endif
5812  }
5813 
5814 #endif // !__PCL_NO_STRING_COMPLEX
5815 
5816 #ifdef __PCL_QT_INTERFACE
5817 
5818  explicit
5819  IsoString( const QString& qs )
5820  : string_base( qs.isEmpty() ? iterator( nullptr ) : iterator( PCL_GET_CHARPTR_FROM_QSTRING( qs ) ) )
5821  {
5822  }
5823 
5824  explicit
5825  IsoString( const QAnyStringView& qv )
5826  : string_base( qv.isEmpty() ? iterator( nullptr ) : iterator( PCL_GET_CHARPTR_FROM_QSTRINGVIEW( qv ) ) )
5827  {
5828  }
5829 
5830  explicit
5831  IsoString( const QByteArray& qb )
5832  : string_base( qb.isEmpty() ? iterator( nullptr ) : iterator( PCL_GET_CHARPTR_FROM_QBYTEARRAY( qb ) ) )
5833  {
5834  }
5835 
5836  explicit
5837  IsoString( const QDate& qd )
5838  : string_base( iterator( PCL_GET_CHARPTR_FROM_QSTRING( qd.toString( PCL_QDATE_FMT_STR ) ) ) )
5839  {
5840  }
5841 
5842  explicit
5843  IsoString( const QDateTime& qdt )
5844  : string_base( iterator( PCL_GET_CHARPTR_FROM_QSTRING( qdt.toString( PCL_QDATETIME_FMT_STR ) ) ) )
5845  {
5846  }
5847 
5848 #endif
5849 
5850  // -------------------------------------------------------------------------
5851 
5855  IsoString& operator =( const IsoString& s )
5856  {
5857  Assign( s );
5858  return *this;
5859  }
5860 
5864  IsoString& operator =( IsoString&& s )
5865  {
5866  Transfer( s );
5867  return *this;
5868  }
5869 
5874  IsoString& operator =( const string_base& s )
5875  {
5876  Assign( s );
5877  return *this;
5878  }
5879 
5884  IsoString& operator =( string_base&& s )
5885  {
5886  Transfer( s );
5887  return *this;
5888  }
5889 
5900  IsoString& operator =( const ustring_base& s )
5901  {
5902  return operator =( s.Begin() );
5903  }
5904 
5909  IsoString& operator =( const_c_string t )
5910  {
5911  Assign( t );
5912  return *this;
5913  }
5914 
5919  IsoString& operator =( char_type c )
5920  {
5921  Assign( c, 1 );
5922  return *this;
5923  }
5924 
5935  IsoString& operator =( const_c_ustring t );
5936 
5937 #ifdef __PCL_QT_INTERFACE
5938 
5939  IsoString& operator =( const QString& qs )
5940  {
5941  if ( qs.isEmpty() )
5942  Clear();
5943  else
5944  Assign( PCL_GET_CHARPTR_FROM_QSTRING( qs ) );
5945  return *this;
5946  }
5947 
5948  IsoString& operator =( const QByteArray& qb )
5949  {
5950  if ( qb.isEmpty() )
5951  Clear();
5952  else
5953  Assign( PCL_GET_CHARPTR_FROM_QBYTEARRAY( qb ) );
5954  return *this;
5955  }
5956 
5957  IsoString& operator =( const QDate& qd )
5958  {
5959  Assign( PCL_GET_CHARPTR_FROM_QSTRING( qd.toString( PCL_QDATE_FMT_STR ) ) );
5960  return *this;
5961  }
5962 
5963  IsoString& operator =( const QDateTime& qdt )
5964  {
5965  Assign( PCL_GET_CHARPTR_FROM_QSTRING( qdt.toString( PCL_QDATETIME_FMT_STR ) ) );
5966  return *this;
5967  }
5968 
5969 #endif
5970 
5971  // -------------------------------------------------------------------------
5972 
5973  IsoString SetToLength( size_type n ) const
5974  {
5975  return string_base::SetToLength( n );
5976  }
5977 
5978  IsoString ResizedToNullTerminated() const
5979  {
5980  return string_base::ResizedToNullTerminated();
5981  }
5982 
5983  IsoString Squeezed() const
5984  {
5985  return string_base::Squeezed();
5986  }
5987 
5988  // -------------------------------------------------------------------------
5989 
5990  IsoString Substring( size_type i, size_type n = maxPos ) const
5991  {
5992  return string_base::Substring( i, n );
5993  }
5994 
5995  IsoString Left( size_type n ) const
5996  {
5997  return string_base::Left( n );
5998  }
5999 
6000  IsoString Right( size_type n ) const
6001  {
6002  return string_base::Right( n );
6003  }
6004 
6005  IsoString Suffix( size_type i ) const
6006  {
6007  return string_base::Suffix( i );
6008  }
6009 
6010  IsoString Prefix( size_type i ) const
6011  {
6012  return string_base::Prefix( i );
6013  }
6014 
6015  // -------------------------------------------------------------------------
6016 
6017  IsoString Trimmed() const
6018  {
6019  return string_base::Trimmed();
6020  }
6021 
6022  IsoString TrimmedLeft() const
6023  {
6024  return string_base::TrimmedLeft();
6025  }
6026 
6027  IsoString TrimmedRight() const
6028  {
6029  return string_base::TrimmedRight();
6030  }
6031 
6032  // -------------------------------------------------------------------------
6033 
6034  IsoString LeftJustified( size_type width, char_type fill = IsoCharTraits::Blank() ) const
6035  {
6036  return string_base::LeftJustified( width, fill );
6037  }
6038 
6039  IsoString RightJustified( size_type width, char_type fill = IsoCharTraits::Blank() ) const
6040  {
6041  return string_base::RightJustified( width, fill );
6042  }
6043 
6044  IsoString CenterJustified( size_type width, char_type fill = IsoCharTraits::Blank() ) const
6045  {
6046  return string_base::CenterJustified( width, fill );
6047  }
6048 
6049  // -------------------------------------------------------------------------
6050 
6051  IsoString Enclosed( char_type c ) const
6052  {
6053  return string_base::Enclosed( c );
6054  }
6055 
6056  IsoString SingleQuoted() const
6057  {
6058  return string_base::SingleQuoted();
6059  }
6060 
6061  IsoString DoubleQuoted() const
6062  {
6063  return string_base::DoubleQuoted();
6064  }
6065 
6066  IsoString Unquoted() const
6067  {
6068  return string_base::Unquoted();
6069  }
6070 
6071  // -------------------------------------------------------------------------
6072 
6073  IsoString CaseFolded() const
6074  {
6075  return string_base::CaseFolded();
6076  }
6077 
6078  IsoString Lowercase() const
6079  {
6080  return string_base::Lowercase();
6081  }
6082 
6083  IsoString Uppercase() const
6084  {
6085  return string_base::Uppercase();
6086  }
6087 
6088  // -------------------------------------------------------------------------
6089 
6090  IsoString Reversed() const
6091  {
6092  return string_base::Reversed();
6093  }
6094 
6095  IsoString Sorted() const
6096  {
6097  return string_base::Sorted();
6098  }
6099 
6100  template <class BP>
6101  IsoString Sorted( BP p ) const
6102  {
6103  return string_base::Sorted( p );
6104  }
6105 
6106  // -------------------------------------------------------------------------
6107 
6117  template <class C>
6118  IsoString& ToSeparated( const C& c, char_type separator )
6119  {
6120  Clear();
6121  return c.ToSeparated( *this, separator );
6122  }
6123 
6140  template <class C, class AF>
6141  IsoString& ToSeparated( const C& c, char_type separator, AF append )
6142  {
6143  Clear();
6144  return c.ToSeparated( *this, separator, append );
6145  }
6146 
6156  template <class C>
6157  IsoString& ToSeparated( const C& c, const IsoString& separator )
6158  {
6159  Clear();
6160  return c.ToSeparated( *this, separator );
6161  }
6162 
6179  template <class C, class AF>
6180  IsoString& ToSeparated( const C& c, const IsoString& separator, AF append )
6181  {
6182  Clear();
6183  return c.ToSeparated( *this, separator, append );
6184  }
6185 
6195  template <class C>
6196  IsoString& ToSeparated( const C& c, const_c_string separator )
6197  {
6198  return ToSeparated( c, IsoString( separator ) );
6199  }
6200 
6217  template <class C, class AF>
6218  IsoString& ToSeparated( const C& c, const_c_string separator, AF append )
6219  {
6220  return ToSeparated( c, IsoString( separator ), append );
6221  }
6222 
6232  template <class C>
6234  {
6235  return ToSeparated( c, IsoCharTraits::Comma() );
6236  }
6237 
6247  template <class C>
6249  {
6250  return ToSeparated( c, IsoCharTraits::Colon() );
6251  }
6252 
6262  template <class C>
6264  {
6265  return ToSeparated( c, IsoCharTraits::Blank() );
6266  }
6267 
6277  template <class C>
6278  IsoString& ToTabSeparated( const C& c )
6279  {
6280  return ToSeparated( c, IsoCharTraits::Tab() );
6281  }
6282 
6292  template <class C>
6294  {
6295  return ToSeparated( c, IsoCharTraits::LF() );
6296  }
6297 
6307  template <class C>
6309  {
6310  return ToSeparated( c, IsoCharTraits::Null() );
6311  }
6312 
6321  template <class C>
6322  IsoString& ToHyphenated( const C& c )
6323  {
6324  return ToSeparated( c, IsoCharTraits::Hyphen() );
6325  }
6326 
6327  // -------------------------------------------------------------------------
6328 
6344 
6352  {
6353  return IsoString( *this ).ToEncodedHTMLSpecialChars();
6354  }
6355 
6373 
6382  {
6383  return IsoString( *this ).ToDecodedHTMLSpecialChars();
6384  }
6385 
6397  static IsoString ToURLEncoded( const void* data, size_type length );
6398 
6411  template <class C>
6412  static IsoString ToURLEncoded( const C& c )
6413  {
6414  return ToURLEncoded( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
6415  }
6416 
6427 
6435  {
6436  return IsoString( *this ).ToURLEncoded();
6437  }
6438 
6450  static ByteArray FromURLEncoded( const void* data, size_type length );
6451 
6459  template <class C>
6460  static ByteArray FromURLEncoded( const C& c )
6461  {
6462  return FromURLEncoded( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
6463  }
6464 
6477  {
6478  return FromURLEncoded( Begin(), Length() );
6479  }
6480 
6492  static IsoString ToURLDecoded( const void* data, size_type length );
6493 
6500  template <class C>
6501  static IsoString ToURLDecoded( const C& c )
6502  {
6503  return ToURLDecoded( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
6504  }
6505 
6516 
6524  {
6525  return IsoString( *this ).ToURLDecoded();
6526  }
6527 
6528  // -------------------------------------------------------------------------
6529 
6530 #ifdef __PCL_QT_INTERFACE
6531 
6532  operator QString() const
6533  {
6534  return QString( c_str() );
6535  }
6536 
6537  operator QAnyStringView() const
6538  {
6539  return QAnyStringView( c_str() );
6540  }
6541 
6542  operator QByteArray() const
6543  {
6544  return QByteArray( c_str() );
6545  }
6546 
6547  operator QDate() const
6548  {
6549  return QDate::fromString( c_str(), PCL_QDATE_FMT_STR );
6550  }
6551 
6552  operator QDateTime() const
6553  {
6554  return QDateTime::fromString( c_str(), PCL_QDATETIME_FMT_STR );
6555  }
6556 
6557 #endif
6558 
6571  {
6572  va_list paramList;
6573  va_start( paramList, fmt );
6574 
6575  (void)VFormat( fmt, paramList );
6576 
6577  va_end( paramList );
6578  return *this;
6579  }
6580 
6593  {
6594  va_list paramList;
6595  va_start( paramList, fmt );
6596 
6597  (void)AppendVFormat( fmt, paramList );
6598 
6599  va_end( paramList );
6600  return *this;
6601  }
6602 
6615  int VFormat( const_c_string fmt, va_list paramList );
6616 
6629  int AppendVFormat( const_c_string fmt, va_list paramList );
6630 
6631  // -------------------------------------------------------------------------
6632 
6643  {
6644  ustring_base s;
6645  s.SetLength( Length() );
6646  uchar_iterator p = s.Begin();
6647  for ( const_iterator i = m_data->string; i < m_data->end; ++p, ++i )
6648  *p = uchar_type( *i );
6649  return s;
6650  }
6651 
6659  ustring_base UTF8ToUTF16( size_type i = 0, size_type n = maxPos ) const; // implemented inline after String
6660 
6677 
6678 #ifdef __PCL_QT_INTERFACE
6679 
6680  QString ToQString() const
6681  {
6682  return operator QString();
6683  }
6684 
6685  QByteArray ToQByteArray() const
6686  {
6687  return operator QByteArray();
6688  }
6689 
6690  QDate ToQDate() const
6691  {
6692  return operator QDate();
6693  }
6694 
6695  QDateTime ToQDateTime() const
6696  {
6697  return operator QDateTime();
6698  }
6699 
6700 #endif
6701 
6712  bool ToBool() const;
6713 
6728  bool TryToBool( bool& value ) const noexcept;
6729 
6743  float ToFloat() const;
6744 
6759  bool TryToFloat( float& value ) const noexcept;
6760 
6784  double ToDouble() const;
6785 
6800  bool TryToDouble( double& value ) const noexcept;
6801 
6819  long ToInt() const
6820  {
6821  return ToInt( 0 );
6822  }
6823 
6847  bool TryToInt( int& value ) const noexcept
6848  {
6849  return TryToInt( value, 0 );
6850  }
6851 
6878  long ToInt( int base ) const;
6879 
6897  bool TryToInt( int& value, int base ) const noexcept;
6898 
6916  unsigned long ToUInt() const
6917  {
6918  return ToUInt( 0 );
6919  }
6920 
6944  bool TryToUInt( unsigned& value ) const noexcept
6945  {
6946  return TryToUInt( value, 0 );
6947  }
6948 
6965  unsigned long ToUInt( int base ) const;
6966 
6984  bool TryToUInt( unsigned& value, int base ) const noexcept;
6985 
7000  long long ToInt64() const
7001  {
7002  return ToInt64( 0 );
7003  }
7004 
7029  bool TryToInt64( long long& value ) const noexcept
7030  {
7031  return TryToInt64( value, 0 );
7032  }
7033 
7048  long long ToInt64( int base ) const;
7049 
7067  bool TryToInt64( long long& value, int base ) const noexcept;
7068 
7083  unsigned long long ToUInt64() const
7084  {
7085  return ToUInt64( 0 );
7086  }
7087 
7112  bool TryToUInt64( unsigned long long& value ) const noexcept
7113  {
7114  return TryToUInt64( value, 0 );
7115  }
7116 
7131  unsigned long long ToUInt64( int base ) const;
7132 
7150  bool TryToUInt64( unsigned long long& value, int base ) const noexcept;
7151 
7183  Array<float> ParseListOfFloat( char separator = ',', size_type maxCount = ~size_type( 0 ) ) const;
7184 
7216  Array<double> ParseListOfDouble( char separator = ',', size_type maxCount = ~size_type( 0 ) ) const;
7217 
7218 #ifndef __PCL_NO_STRING_VECTOR
7219 
7227  GenericVector<float> ParseListOfFloatAsVector( char separator = ',', int maxCount = int_max ) const;
7228 
7236  GenericVector<double> ParseListOfDoubleAsVector( char separator = ',', int maxCount = int_max ) const;
7237 
7238 #endif // !__PCL_NO_STRING_VECTOR
7239 
7267  double SexagesimalToDouble( const IsoString& separator = ':' ) const
7268  {
7269  int sign, s1, s2; double s3;
7270  ParseSexagesimal( sign, s1, s2, s3, separator );
7271  return sign*(s1 + (s2 + s3/60)/60);
7272  }
7273 
7274  double SexagesimalToDouble( char separator ) const
7275  {
7276  return SexagesimalToDouble( IsoString( separator ) );
7277  }
7278 
7279  double SexagesimalToDouble( const ustring_base& separator ) const
7280  {
7281  return SexagesimalToDouble( IsoString( separator ) );
7282  }
7283 
7297  double SexagesimalToDouble( const Array<char_type>& separators ) const
7298  {
7299  int sign, s1, s2; double s3;
7300  ParseSexagesimal( sign, s1, s2, s3, separators );
7301  return sign*(s1 + (s2 + s3/60)/60);
7302  }
7303 
7321  bool TrySexagesimalToDouble( double& value, const IsoString& separator = ':' ) const noexcept
7322  {
7323  int sign, s1, s2; double s3;
7324  if ( TryParseSexagesimal( sign, s1, s2, s3, separator ) )
7325  {
7326  value = sign*(s1 + (s2 + s3/60)/60);
7327  return true;
7328  }
7329  return false;
7330  }
7331 
7332  bool TrySexagesimalToDouble( double& value, char separator ) const noexcept
7333  {
7334  return TrySexagesimalToDouble( value, IsoString( separator ) );
7335  }
7336 
7337  bool TrySexagesimalToDouble( double& value, const ustring_base& separator ) const noexcept
7338  {
7339  return TrySexagesimalToDouble( value, IsoString( separator ) );
7340  }
7341 
7354  bool TrySexagesimalToDouble( double& value, const Array<char_type>& separators ) const noexcept
7355  {
7356  int sign, s1, s2; double s3;
7357  if ( TryParseSexagesimal( sign, s1, s2, s3, separators ) )
7358  {
7359  value = sign*(s1 + (s2 + s3/60)/60);
7360  return true;
7361  }
7362  return false;
7363  }
7364 
7391  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const IsoString& separator = ':' ) const;
7392 
7393  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, char separator ) const
7394  {
7395  ParseSexagesimal( sign, s1, s2, s3, IsoString( separator ) );
7396  }
7397 
7398  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const ustring_base& separator ) const
7399  {
7400  ParseSexagesimal( sign, s1, s2, s3, IsoString( separator ) );
7401  }
7402 
7417  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const Array<char_type>& separators ) const;
7418 
7433  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const IsoString& separator = ':' ) const noexcept;
7434 
7435  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, char separator ) const noexcept
7436  {
7437  return TryParseSexagesimal( sign, s1, s2, s3, IsoString( separator ) );
7438  }
7439 
7440  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const ustring_base& separator ) const noexcept
7441  {
7442  return TryParseSexagesimal( sign, s1, s2, s3, IsoString( separator ) );
7443  }
7444 
7458  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const Array<char_type>& separators ) const noexcept;
7459 
7484  static IsoString ToSexagesimal( int sign, double s1, double s2, double s3,
7486 
7498  {
7499  return ToSexagesimal( (d < 0) ? -1 : +1, Abs( d ), 0, 0, options );
7500  }
7501 
7525  void ParseISO8601DateTime( int& year, int& month, int& day, double& dayf, double& tz ) const;
7526 
7540  bool TryParseISO8601DateTime( int& year, int& month, int& day, double& dayf, double& tz ) const noexcept;
7541 
7565  static IsoString ToISO8601DateTime( int year, int month, int day, double dayf, double tz = 0,
7567 
7579 
7591 
7599  static IsoString ToHex( const void* data, size_type length );
7600 
7613  template <class C>
7614  static IsoString ToHex( const C& c )
7615  {
7616  return ToHex( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
7617  }
7618 
7630  static IsoString ToBase64( const void* data, size_type length );
7631 
7645  template <class C>
7646  static IsoString ToBase64( const C& c )
7647  {
7648  return ToBase64( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
7649  }
7650 
7665  static IsoString ToBase64URL( const void* data, size_type length )
7666  {
7667  IsoString b64 = ToBase64( data, length );
7668  b64.DeleteChar( '=' );
7669  for ( char_type& c : b64 )
7670  if ( c == '+' )
7671  c = '-';
7672  else if ( c == '/' )
7673  c = '_';
7674  return b64;
7675  }
7676 
7688  template <class C>
7689  static IsoString ToBase64URL( const C& c )
7690  {
7691  return ToBase64URL( c.Begin(), c.Length()*sizeof( *c.Begin() ) );
7692  }
7693 
7702  {
7703  return ByteArray( Begin(), End() );
7704  }
7705 
7719 
7733 
7744  {
7745  IsoString b64 = *this;
7746  for ( char_type& c : b64 )
7747  if ( c == '-' )
7748  c = '+';
7749  else if ( c == '_' )
7750  c = '/';
7751  return b64.FromBase64();
7752  }
7753 
7760  static IsoString Random( size_type n, RandomizationOptions options = RandomizationOption::Default );
7761 
7773  static IsoString UUID();
7774 };
7775 
7776 // ----------------------------------------------------------------------------
7777 
7787 {
7788  IsoString s( s1 );
7789  s.Append( s2 );
7790  return s;
7791 }
7792 
7799 {
7800  s1.Append( s2 );
7801  return IsoString( std::move( s1 ) );
7802 }
7803 
7810 {
7811  s1.Append( s2 );
7812  return std::move( s1 );
7813 }
7814 
7821 {
7822  s2.Prepend( s1 );
7823  return IsoString( std::move( s2 ) );
7824 }
7825 
7832 {
7833  s2.Prepend( s1 );
7834  return std::move( s2 );
7835 }
7836 
7843 {
7844  s1.Append( s2 );
7845  return IsoString( std::move( s1 ) );
7846 }
7847 
7854 {
7855  s1.Append( s2 );
7856  return std::move( s1 );
7857 }
7858 
7865 {
7866  s1.Append( s2 );
7867  return IsoString( std::move( s1 ) );
7868 }
7869 
7876 {
7877  s1.Append( s2 );
7878  return std::move( s1 );
7879 }
7880 
7881 // ----------------------------------------------------------------------------
7882 
7889 {
7890  IsoString s = s1;
7891  s.Append( t2 );
7892  return s;
7893 }
7894 
7901 {
7902  s1.Append( t2 );
7903  return IsoString( std::move( s1 ) );
7904 }
7905 
7912 {
7913  s1.Append( t2 );
7914  return std::move( s1 );
7915 }
7916 
7923 {
7924  IsoString s = s2;
7925  s.Prepend( t1 );
7926  return s;
7927 }
7928 
7935 {
7936  s2.Prepend( t1 );
7937  return IsoString( std::move( s2 ) );
7938 }
7939 
7946 {
7947  s2.Prepend( t1 );
7948  return std::move( s2 );
7949 }
7950 
7951 // ----------------------------------------------------------------------------
7952 
7959 {
7960  IsoString s = s1;
7961  s.Append( c2 );
7962  return s;
7963 }
7964 
7971 {
7972  s1.Append( c2 );
7973  return IsoString( std::move( s1 ) );
7974 }
7975 
7982 {
7983  s1.Append( c2 );
7984  return std::move( s1 );
7985 }
7986 
7993 {
7994  IsoString s = s2;
7995  s.Prepend( c1 );
7996  return s;
7997 }
7998 
8005 {
8006  s2.Prepend( c1 );
8007  return IsoString( std::move( s2 ) );
8008 }
8009 
8016 {
8017  s2.Prepend( c1 );
8018  return std::move( s2 );
8019 }
8020 
8021 // ----------------------------------------------------------------------------
8022 
8029 {
8030  s1.Append( s2 );
8031  return s1;
8032 }
8033 
8040 {
8041  s1.Append( s2 );
8042  return s1;
8043 }
8044 
8051 {
8052  s1.Append( t2 );
8053  return s1;
8054 }
8055 
8062 {
8063  s1.Append( t2 );
8064  return s1;
8065 }
8066 
8073 {
8074  s1.Append( c2 );
8075  return s1;
8076 }
8077 
8084 {
8085  s1.Append( c2 );
8086  return s1;
8087 }
8088 
8089 // ----------------------------------------------------------------------------
8090 
8091 #ifndef __PCL_NO_STRING_OSTREAM
8092 
8093 inline std::ostream& operator <<( std::ostream& o, const IsoString& s )
8094 {
8095  return o << s.c_str();
8096 }
8097 
8098 #endif
8099 
8100 // ----------------------------------------------------------------------------
8101 
8112 class PCL_CLASS String : public GenericString<char16_type, CharTraits, PCL_STRING_ALLOCATOR>
8113 {
8114 public:
8115 
8120 
8125 
8130 
8135 
8140 
8145 
8150 
8151  /*
8152  * Null-terminated UTF-16 string - C++11 compatibility.
8153  */
8154  using c16_string = char16_t*;
8155 
8156  /*
8157  * Immutable null-terminated UTF-16 string - C++11 compatibility.
8158  */
8159  using const_c16_string = const char16_t*;
8160 
8165 
8170 
8175 
8180 
8189 
8194 
8199 
8204 
8209 
8214 
8219 
8220  // -------------------------------------------------------------------------
8221 
8225  String() = default;
8226 
8231  String( const string_base& s )
8232  : string_base( s )
8233  {
8234  }
8235 
8239  String( const String& ) = default;
8240 
8246  : string_base( std::move( s ) )
8247  {
8248  }
8249 
8253  String( String&& ) = default;
8254 
8259  String( const string8_base& s )
8260  {
8261  Assign( s );
8262  }
8263 
8268  : string_base( t )
8269  {
8270  }
8271 
8277  : string_base( t, i, n )
8278  {
8279  }
8280 
8285  : string_base( c, n )
8286  {
8287  }
8288 
8294  : string_base( i, j )
8295  {
8296  }
8297 
8306  String( std::initializer_list<char_type> l )
8307  : String( l.begin(), l.end() )
8308  {
8309  }
8310 
8315  String( const char16_t* t )
8316  : string_base( reinterpret_cast<const_iterator>( t ) )
8317  {
8318  }
8319 
8325  String( const char16_t* t, size_type i, size_type n )
8326  : string_base( reinterpret_cast<const_iterator>( t ), i, n )
8327  {
8328  }
8329 
8333  String( char16_t c, size_type n )
8334  : string_base( char_type( c ), n )
8335  {
8336  }
8337 
8342  String( const wchar_t* t )
8343  {
8344  Assign( t );
8345  }
8346 
8352  String( const wchar_t* t, size_type i, size_type n )
8353  {
8354  Assign( t, i, n );
8355  }
8356 
8360  String( wchar_t c, size_type n )
8361  : string_base( char_type( c ), n )
8362  {
8363  }
8364 
8370  {
8371  Assign( t );
8372  }
8373 
8380  {
8381  Assign( t, i, n );
8382  }
8383 
8389  {
8390  Assign( i, j );
8391  }
8392 
8401  String( std::initializer_list<char8_type> l )
8402  : String( l.begin(), l.end() )
8403  {
8404  }
8405 
8411  : string_base( char_type( c ), n )
8412  {
8413  }
8414 
8418  explicit
8419  String( bool x )
8420  {
8421  Assign( x ? "true" : "false" );
8422  }
8423 
8428  explicit
8429  String( short x )
8430  {
8431  (void)Format( L"%hd", x );
8432  }
8433 
8438  explicit
8439  String( unsigned short x )
8440  {
8441  (void)Format( L"%hu", x );
8442  }
8443 
8448  explicit
8449  String( int x )
8450  {
8451  (void)Format( L"%i", x );
8452  }
8453 
8458  explicit
8459  String( unsigned int x )
8460  {
8461  (void)Format( L"%u", x );
8462  }
8463 
8468  explicit
8469  String( long x )
8470  {
8471  (void)Format( L"%ld", x );
8472  }
8473 
8478  explicit
8479  String( unsigned long x )
8480  {
8481  (void)Format( L"%lu", x );
8482  }
8483 
8488  explicit
8489  String( long long x )
8490  {
8491  (void)Format( L"%lli", x );
8492  }
8493 
8498  explicit
8499  String( unsigned long long x )
8500  {
8501  (void)Format( L"%llu", x );
8502  }
8503 
8508  explicit
8509  String( float x )
8510  {
8511  (void)Format( L"%.7g", x );
8512  }
8513 
8518  explicit
8519  String( double x )
8520  {
8521  (void)Format( L"%.16g", x );
8522  }
8523 
8528  explicit
8529  String( long double x )
8530  {
8531 #ifdef _MSC_VER
8532  (void)Format( L"%.16Lg", x );
8533 #else
8534  (void)Format( L"%.18Lg", x );
8535 #endif
8536  }
8537 
8538 #ifndef __PCL_NO_STRING_COMPLEX
8539 
8543  explicit
8545  {
8546  (void)Format( L"{%.7g,%.7g}", x.Real(), x.Imag() );
8547  }
8548 
8552  explicit
8554  {
8555  (void)Format( L"{%.16g,%.16g}", x.Real(), x.Imag() );
8556  }
8557 
8561  explicit
8563  {
8564 #ifdef _MSC_VER
8565  (void)Format( L"{%.16Lg,%.16Lg}", x.Real(), x.Imag() );
8566 #else
8567  (void)Format( L"{%.18Lg,%.18Lg}", x.Real(), x.Imag() );
8568 #endif
8569  }
8570 
8571 #endif // !__PCL_NO_STRING_COMPLEX
8572 
8573 #ifdef __PCL_QT_INTERFACE
8574 
8575  explicit
8576  String( const QString& qs )
8577  : string_base( qs.isEmpty() ? iterator( nullptr ) : iterator( PCL_GET_CHAR16PTR_FROM_QSTRING( qs ) ) )
8578  {
8579  }
8580 
8581  explicit
8582  String( const QDate& qd )
8583  : string_base( iterator( PCL_GET_CHAR16PTR_FROM_QSTRING( qd.toString( PCL_QDATE_FMT_STR ) ) ) )
8584  {
8585  }
8586 
8587  explicit
8588  String( const QDateTime& qdt )
8589  : string_base( iterator( PCL_GET_CHAR16PTR_FROM_QSTRING( qdt.toString( PCL_QDATETIME_FMT_STR ) ) ) )
8590  {
8591  }
8592 
8593 #endif
8594 
8595  // -------------------------------------------------------------------------
8596 
8600  String& operator =( const String& s )
8601  {
8602  string_base::Assign( s );
8603  return *this;
8604  }
8605 
8609  String& operator =( String&& s )
8610  {
8611  string_base::Transfer( s );
8612  return *this;
8613  }
8614 
8619  String& operator =( const string_base& s )
8620  {
8621  string_base::Assign( s );
8622  return *this;
8623  }
8624 
8629  String& operator =( string_base&& s )
8630  {
8631  string_base::Transfer( s );
8632  return *this;
8633  }
8634 
8639  String& operator =( const string8_base& s )
8640  {
8641  Assign( s );
8642  return *this;
8643  }
8644 
8649  String& operator =( const_iterator t )
8650  {
8651  string_base::Assign( t );
8652  return *this;
8653  }
8654 
8659  String& operator =( char_type c )
8660  {
8661  string_base::Assign( c );
8662  return *this;
8663  }
8664 
8669  String& operator =( const char16_t* t )
8670  {
8671  string_base::Assign( reinterpret_cast<const_iterator>( t ) );
8672  return *this;
8673  }
8674 
8679  String& operator =( char16_t c )
8680  {
8681  string_base::Assign( char_type( c ) );
8682  return *this;
8683  }
8684 
8689  String& operator =( const wchar_t* t )
8690  {
8691  Assign( t );
8692  return *this;
8693  }
8694 
8699  String& operator =( wchar_t c )
8700  {
8701  Assign( c );
8702  return *this;
8703  }
8704 
8709  String& operator =( const_c_string8 t )
8710  {
8711  Assign( t );
8712  return *this;
8713  }
8714 
8719  String& operator =( char8_type c )
8720  {
8721  Assign( c );
8722  return *this;
8723  }
8724 
8725 #ifdef __PCL_QT_INTERFACE
8726 
8727  String& operator =( const QString& qs )
8728  {
8729  if ( qs.isEmpty() )
8730  Clear();
8731  else
8732  string_base::Assign( PCL_GET_CHAR16PTR_FROM_QSTRING( qs ) );
8733  return *this;
8734  }
8735 
8736  String& operator =( const QDate& qd )
8737  {
8738  string_base::Assign( PCL_GET_CHAR16PTR_FROM_QSTRING( qd.toString( PCL_QDATE_FMT_STR ) ) );
8739  return *this;
8740  }
8741 
8742  String& operator =( const QDateTime& qdt )
8743  {
8744  string_base::Assign( PCL_GET_CHAR16PTR_FROM_QSTRING( qdt.toString( PCL_QDATETIME_FMT_STR ) ) );
8745  return *this;
8746  }
8747 
8748 #endif
8749 
8750  // -------------------------------------------------------------------------
8751 
8755  void Assign( const String& s )
8756  {
8757  string_base::Assign( s );
8758  }
8759 
8764  void Assign( const String& s, size_type i, size_type n )
8765  {
8766  string_base::Assign( s, i, n );
8767  }
8768 
8773  {
8774  string_base::Assign( t );
8775  }
8776 
8782  {
8783  string_base::Assign( i, j );
8784  }
8785 
8792  void Assign( std::initializer_list<char_type> l )
8793  {
8794  Assign( l.begin(), l.end() );
8795  }
8796 
8803  {
8804  string_base::Assign( t, i, n );
8805  }
8806 
8810  void Assign( char_type c, size_type n = 1 )
8811  {
8812  string_base::Assign( c, n );
8813  }
8814 
8818  void Assign( const char16_t* t )
8819  {
8820  string_base::Assign( reinterpret_cast<const_iterator>( t ) );
8821  }
8822 
8828  void Assign( const char16_t* t, size_type i, size_type n )
8829  {
8830  string_base::Assign( reinterpret_cast<const_iterator>( t ), i, n );
8831  }
8832 
8836  void Assign( char16_t c, size_type n = 1 )
8837  {
8838  string_base::Assign( char_type( c ), n );
8839  }
8840 
8844  void Assign( const wchar_t* t );
8845 
8851  void Assign( const wchar_t* t, size_type i, size_type n );
8852 
8856  void Assign( wchar_t c, size_type n = 1 )
8857  {
8858  string_base::Assign( char_type( c ), n );
8859  }
8860 
8864  void Assign( const string8_base& s )
8865  {
8866  size_type n = s.Length();
8867  if ( n > 0 )
8868  {
8869  MaybeReallocate( n );
8870  const_char8_iterator t = s.Begin();
8871  PCL_IVDEP
8872  for ( iterator i = m_data->string; i < m_data->end; ++i, ++t )
8873  *i = char_type( uint8( *t ) );
8874  }
8875  else
8876  Clear();
8877  }
8878 
8884  {
8885  size_type n = char8_traits::Length( t );
8886  if ( n > 0 )
8887  {
8888  MaybeReallocate( n );
8889  PCL_IVDEP
8890  for ( iterator i = m_data->string; i < m_data->end; ++i, ++t )
8891  *i = char_type( uint8( *t ) );
8892  }
8893  else
8894  Clear();
8895  }
8896 
8903  {
8904  size_type len = char8_traits::Length( t );
8905  if ( i < len )
8906  {
8907  n = pcl::Min( n, len-i );
8908  MaybeReallocate( n );
8909  t += i;
8910  PCL_IVDEP
8911  for ( iterator i = m_data->string; i < m_data->end; ++i, ++t )
8912  *i = char_type( uint8( *t ) );
8913  }
8914  else
8915  Clear();
8916  }
8917 
8923  {
8924  if ( p < q )
8925  {
8926  MaybeReallocate( q - p );
8927  PCL_IVDEP
8928  for ( iterator i = m_data->string; i < m_data->end; ++i, ++p )
8929  *i = char_type( uint8( *p ) );
8930  }
8931  else
8932  Clear();
8933  }
8934 
8942  void Assign( std::initializer_list<char8_type> l )
8943  {
8944  Assign( l.begin(), l.end() );
8945  }
8946 
8950  void Assign( char8_type c, size_type n = 1 )
8951  {
8952  string_base::Assign( char_type( c ), n );
8953  }
8954 
8955  // -------------------------------------------------------------------------
8956 
8957  void Insert( size_type i, const String& s )
8958  {
8959  string_base::Insert( i, s );
8960  }
8961 
8962  void Insert( size_type i, const_iterator p, const_iterator q )
8963  {
8964  string_base::Insert( i, p, q );
8965  }
8966 
8967  void Insert( size_type i, const_iterator t )
8968  {
8969  string_base::Insert( i, t );
8970  }
8971 
8972  void Insert( size_type i, const_iterator t, size_type n )
8973  {
8974  string_base::Insert( i, t, n );
8975  }
8976 
8977  void Insert( size_type i, char_type c, size_type n = 1 )
8978  {
8979  string_base::Insert( i, c, n );
8980  }
8981 
8982  void Insert( size_type i, const char16_t* t )
8983  {
8984  string_base::Insert( i, reinterpret_cast<const_iterator>( t ) );
8985  }
8986 
8987  void Insert( size_type i, char16_t c, size_type n = 1 )
8988  {
8989  string_base::Insert( i, String( c, n ) );
8990  }
8991 
8992  void Insert( size_type i, const wchar_t* t )
8993  {
8994 #ifdef __PCL_WINDOWS
8995  string_base::Insert( i, reinterpret_cast<const_iterator>( t ) );
8996 #else
8997  string_base::Insert( i, String( t ) );
8998 #endif
8999  }
9000 
9001  void Insert( size_type i, wchar_t c, size_type n = 1 )
9002  {
9003  string_base::Insert( i, String( c, n ) );
9004  }
9005 
9006  void Insert( size_type i, const string8_base& s, size_type n )
9007  {
9008  n = pcl::Min( n, s.Length() );
9009  if ( n > 0 )
9010  {
9011  UninitializedGrow( i, n ); // -> 0 <= i <= len
9012  const_char8_iterator t = s.Begin();
9013  PCL_IVDEP
9014  for ( iterator p = m_data->string+i, q = p+n; p < q; ++p, ++t )
9015  *p = char_type( uint8( *t ) );
9016  }
9017  }
9018 
9019  void Insert( size_type i, const string8_base& s )
9020  {
9021  size_type n = s.Length();
9022  if ( n > 0 )
9023  {
9024  UninitializedGrow( i, n ); // -> 0 <= i <= len
9025  const_char8_iterator t = s.Begin();
9026  PCL_IVDEP
9027  for ( iterator p = m_data->string+i, q = p+n; p < q; ++p, ++t )
9028  *p = char_type( uint8( *t ) );
9029  }
9030  }
9031 
9032  void Insert( size_type i, const_c_string8 t )
9033  {
9034  size_type n = char8_traits::Length( t );
9035  if ( n > 0 )
9036  {
9037  UninitializedGrow( i, n ); // -> 0 <= i <= len
9038  PCL_IVDEP
9039  for ( iterator p = m_data->string+i, q = p+n; p < q; ++p, ++t )
9040  *p = char_type( uint8( *t ) );
9041  }
9042  }
9043 
9044  void Insert( size_type i, const_c_string8 t, size_type n )
9045  {
9046  n = pcl::Min( n, char8_traits::Length( t ) );
9047  if ( n > 0 )
9048  {
9049  UninitializedGrow( i, n ); // -> 0 <= i <= len
9050  PCL_IVDEP
9051  for ( iterator p = m_data->string+i, q = p+n; p < q; ++p, ++t )
9052  *p = char_type( uint8( *t ) );
9053  }
9054  }
9055 
9056  void Insert( size_type i, const_char8_iterator p, const_char8_iterator q )
9057  {
9058  if ( p < q )
9059  {
9060  size_type n = q - p;
9061  UninitializedGrow( i, n ); // -> 0 <= i <= len
9062  PCL_IVDEP
9063  for ( iterator r = m_data->string+i, s = r+n; r < s; ++r, ++p )
9064  *r = char_type( uint8( *p ) );
9065  }
9066  }
9067 
9068  void Insert( size_type i, char8_type c, size_type n = 1 )
9069  {
9070  string_base::Insert( i, char_type( c ), n );
9071  }
9072 
9073  // -------------------------------------------------------------------------
9074 
9075  void Append( const String& s )
9076  {
9077  string_base::Append( s );
9078  }
9079 
9080  String& operator +=( const String& s )
9081  {
9082  Append( s );
9083  return *this;
9084  }
9085 
9086  void Append( const_iterator i, const_iterator j )
9087  {
9088  string_base::Append( i, j );
9089  }
9090 
9091  void Append( const_iterator t )
9092  {
9093  string_base::Append( t );
9094  }
9095 
9096  String& operator +=( const_iterator t )
9097  {
9098  Append( t );
9099  return *this;
9100  }
9101 
9102  void Append( const_iterator t, size_type n )
9103  {
9104  string_base::Append( t, n );
9105  }
9106 
9107  void Append( char_type c, size_type n = 1 )
9108  {
9109  string_base::Append( c, n );
9110  }
9111 
9112  String& operator +=( char_type c )
9113  {
9114  Append( c );
9115  return *this;
9116  }
9117 
9118  void Append( const char16_t* t )
9119  {
9120  string_base::Append( reinterpret_cast<const_iterator>( t ) );
9121  }
9122 
9123  String& operator +=( const char16_t* t )
9124  {
9125  Append( t );
9126  return *this;
9127  }
9128 
9129  void Append( char16_t c, size_type n = 1 )
9130  {
9131  string_base::Append( char_type( c ), n );
9132  }
9133 
9134  String& operator +=( char16_t c )
9135  {
9136  Append( c );
9137  return *this;
9138  }
9139 
9140  void Append( const wchar_t* t )
9141  {
9142 #ifdef __PCL_WINDOWS
9143  string_base::Append( reinterpret_cast<const_iterator>( t ) );
9144 #else
9145  string_base::Append( String( t ) );
9146 #endif
9147  }
9148 
9149  String& operator +=( const wchar_t* t )
9150  {
9151  Append( t );
9152  return *this;
9153  }
9154 
9155  void Append( wchar_t c, size_type n = 1 )
9156  {
9157  string_base::Append( char_type( c ), n );
9158  }
9159 
9160  String& operator +=( wchar_t c )
9161  {
9162  Append( c );
9163  return *this;
9164  }
9165 
9166  void Append( const string8_base& s )
9167  {
9168  Insert( maxPos, s );
9169  }
9170 
9171  String& operator +=( const string8_base& s )
9172  {
9173  Append( s );
9174  return *this;
9175  }
9176 
9177  void Append( const string8_base& s, size_type n )
9178  {
9179  Insert( maxPos, s, n );
9180  }
9181 
9182  void Append( const_c_string8 t )
9183  {
9184  Insert( maxPos, t );
9185  }
9186 
9187  String& operator +=( const_c_string8 t )
9188  {
9189  Append( t );
9190  return *this;
9191  }
9192 
9193  void Append( const_c_string8 t, size_type n )
9194  {
9195  Insert( maxPos, t, n );
9196  }
9197 
9198  void Append( const_char8_iterator p, const_char8_iterator q )
9199  {
9200  Insert( maxPos, p, q );
9201  }
9202 
9203  void Append( char8_type c, size_type n = 1 )
9204  {
9205  string_base::Append( char_type( c ), n );
9206  }
9207 
9208  String& operator +=( char8_type c )
9209  {
9210  Append( c );
9211  return *this;
9212  }
9213 
9214  void Add( const String& s )
9215  {
9216  Append( s );
9217  }
9218 
9219  void Add( const_iterator i, const_iterator j )
9220  {
9221  Append( i, j );
9222  }
9223 
9224  void Add( const_iterator t )
9225  {
9226  Append( t );
9227  }
9228 
9229  void Add( const_iterator t, size_type n )
9230  {
9231  Append( t, n );
9232  }
9233 
9234  void Add( char_type c, size_type n = 1 )
9235  {
9236  Append( c, n );
9237  }
9238 
9239  void Add( const char16_t* t )
9240  {
9241  Append( t );
9242  }
9243 
9244  void Add( char16_t c, size_type n = 1 )
9245  {
9246  Append( c, n );
9247  }
9248 
9249  void Add( const wchar_t* t )
9250  {
9251  Append( t );
9252  }
9253 
9254  void Add( wchar_t c, size_type n = 1 )
9255  {
9256  Append( c, n );
9257  }
9258 
9259  void Add( const string8_base& s )
9260  {
9261  Append( s );
9262  }
9263 
9264  void Add( const string8_base& s, size_type n )
9265  {
9266  Append( s, n );
9267  }
9268 
9269  void Add( const_c_string8 t )
9270  {
9271  Append( t );
9272  }
9273 
9274  void Add( const_c_string8 t, size_type n )
9275  {
9276  Append( t, n );
9277  }
9278 
9279  void Add( const_char8_iterator p, const_char8_iterator q )
9280  {
9281  Append( p, q );
9282  }
9283 
9284  void Add( char8_type c, size_type n = 1 )
9285  {
9286  Append( c, n );
9287  }
9288 
9289  // -------------------------------------------------------------------------
9290 
9291  void Prepend( const String& s )
9292  {
9293  string_base::Prepend( s );
9294  }
9295 
9296  String& operator -=( const String& s )
9297  {
9298  Prepend( s );
9299  return *this;
9300  }
9301 
9302  void Prepend( const_iterator i, const_iterator j )
9303  {
9304  string_base::Prepend( i, j );
9305  }
9306 
9307  void Prepend( const_iterator t )
9308  {
9309  string_base::Prepend( t );
9310  }
9311 
9312  String& operator -=( const_iterator t )
9313  {
9314  Prepend( t );
9315  return *this;
9316  }
9317 
9318  void Prepend( const_iterator t, size_type n )
9319  {
9320  string_base::Prepend( t, n );
9321  }
9322 
9323  void Prepend( char_type c, size_type n = 1 )
9324  {
9325  string_base::Prepend( c, n );
9326  }
9327 
9328  String& operator -=( char_type c )
9329  {
9330  Prepend( c );
9331  return *this;
9332  }
9333 
9334  void Prepend( const char16_t* t )
9335  {
9336  string_base::Prepend( reinterpret_cast<const_iterator>( t ) );
9337  }
9338 
9339  String& operator -=( const char16_t* t )
9340  {
9341  Prepend( t );
9342  return *this;
9343  }
9344 
9345  void Prepend( char16_t c, size_type n = 1 )
9346  {
9347  string_base::Prepend( char_type( c ), n );
9348  }
9349 
9350  String& operator -=( char16_t c )
9351  {
9352  Prepend( c );
9353  return *this;
9354  }
9355 
9356  void Prepend( const wchar_t* t )
9357  {
9358 #ifdef __PCL_WINDOWS
9359  string_base::Prepend( reinterpret_cast<const_iterator>( t ) );
9360 #else
9361  string_base::Prepend( String( t ) );
9362 #endif
9363  }
9364 
9365  String& operator -=( const wchar_t* t )
9366  {
9367  Prepend( t );
9368  return *this;
9369  }
9370 
9371  void Prepend( wchar_t c, size_type n = 1 )
9372  {
9373  string_base::Prepend( char_type( c ), n );
9374  }
9375 
9376  String& operator -=( wchar_t c )
9377  {
9378  Prepend( c );
9379  return *this;
9380  }
9381 
9382  void Prepend( const string8_base& s )
9383  {
9384  Insert( 0, s );
9385  }
9386 
9387  String& operator -=( const string8_base& s )
9388  {
9389  Prepend( s );
9390  return *this;
9391  }
9392 
9393  void Prepend( const string8_base& s, size_type n )
9394  {
9395  Insert( 0, s, n );
9396  }
9397 
9398  void Prepend( const_c_string8 t )
9399  {
9400  Insert( 0, t );
9401  }
9402 
9403  String& operator -=( const_c_string8 t )
9404  {
9405  Prepend( t );
9406  return *this;
9407  }
9408 
9409  void Prepend( const_c_string8 t, size_type n )
9410  {
9411  Insert( 0, t, n );
9412  }
9413 
9414  void Prepend( const_char8_iterator p, const_char8_iterator q )
9415  {
9416  Insert( 0, p, q );
9417  }
9418 
9419  void Prepend( char8_type c, size_type n = 1 )
9420  {
9421  string_base::Prepend( String( c, n ) );
9422  }
9423 
9424  String& operator -=( char8_type c )
9425  {
9426  Prepend( c );
9427  return *this;
9428  }
9429 
9430  // -------------------------------------------------------------------------
9431 
9432  void Replace( size_type i, size_type n, const String& s )
9433  {
9434  string_base::Replace( i, n, s );
9435  }
9436 
9437  void Replace( size_type i, size_type n, const_iterator t )
9438  {
9439  string_base::Replace( i, n, t );
9440  }
9441 
9442  void Replace( size_type i, size_type n, char_type c, size_type nc = 1 )
9443  {
9444  string_base::Replace( i, n, c, nc );
9445  }
9446 
9447  void Replace( size_type i, size_type n, const char16_t* t )
9448  {
9449  string_base::Replace( i, n, reinterpret_cast<const_iterator>( t ) );
9450  }
9451 
9452  void Replace( size_type i, size_type n, char16_t c, size_type nc = 1 )
9453  {
9454  string_base::Replace( i, n, char_type( c ), nc );
9455  }
9456 
9457  void Replace( size_type i, size_type n, const wchar_t* t )
9458  {
9459 #ifdef __PCL_WINDOWS
9460  string_base::Replace( i, n, reinterpret_cast<const_iterator>( t ) );
9461 #else
9462  string_base::Replace( i, n, String( t ) );
9463 #endif
9464  }
9465 
9466  void Replace( size_type i, size_type n, wchar_t c, size_type nc = 1 )
9467  {
9468  string_base::Replace( i, n, char_type( c ), nc );
9469  }
9470 
9471  void Replace( size_type i, size_type n, const_c_string8 t )
9472  {
9473  if ( n > 0 )
9474  {
9475  size_type len = Length();
9476  if ( i < len )
9477  {
9478  n = pcl::Min( n, len-i );
9479  if ( n == len )
9480  Assign( t );
9481  else
9482  {
9483  size_type nt = char8_traits::Length( t );
9484  if ( nt > 0 )
9485  {
9486  if ( n < nt )
9487  UninitializedGrow( i, nt-n );
9488  else if ( nt < n )
9489  Delete( i, n-nt );
9490  else
9491  EnsureUnique();
9492 
9493  PCL_IVDEP
9494  for ( iterator p = m_data->string+i, q = p+nt; p < q; ++p, ++t )
9495  *p = char_type( *t );
9496  }
9497  else
9498  Delete( i, n );
9499  }
9500  }
9501  }
9502  }
9503 
9504  void Replace( size_type i, size_type n, char8_type c, size_type nc = 1 )
9505  {
9506  string_base::Replace( i, n, char_type( c ), nc );
9507  }
9508 
9509  // -------------------------------------------------------------------------
9510 
9511  void ReplaceChar( char_type c1, char_type c2, size_type i = 0, size_type n = maxPos )
9512  {
9513  string_base::ReplaceChar( c1, c2, i, n );
9514  }
9515 
9516  void ReplaceCharIC( char_type c1, char_type c2, size_type i = 0, size_type n = maxPos )
9517  {
9518  string_base::ReplaceCharIC( c1, c2, i, n );
9519  }
9520 
9521  void ReplaceChar( char16_t c1, char16_t c2, size_type i = 0, size_type n = maxPos )
9522  {
9523  string_base::ReplaceChar( char_type( c1 ), char_type( c2 ), i, n );
9524  }
9525 
9526  void ReplaceCharIC( char16_t c1, char16_t c2, size_type i = 0, size_type n = maxPos )
9527  {
9528  string_base::ReplaceCharIC( char_type( c1 ), char_type( c2 ), i, n );
9529  }
9530 
9531  void ReplaceChar( wchar_t c1, wchar_t c2, size_type i = 0, size_type n = maxPos )
9532  {
9533  string_base::ReplaceChar( char_type( c1 ), char_type( c2 ), i, n );
9534  }
9535 
9536  void ReplaceCharIC( wchar_t c1, wchar_t c2, size_type i = 0, size_type n = maxPos )
9537  {
9538  string_base::ReplaceCharIC( char_type( c1 ), char_type( c2 ), i, n );
9539  }
9540 
9541  void ReplaceChar( char8_type c1, char8_type c2, size_type i = 0, size_type n = maxPos )
9542  {
9543  string_base::ReplaceChar( char_type( c1 ), char_type( c2 ), i, n );
9544  }
9545 
9546  void ReplaceCharIC( char8_type c1, char8_type c2, size_type i = 0, size_type n = maxPos )
9547  {
9548  string_base::ReplaceCharIC( char_type( c1 ), char_type( c2 ), i, n );
9549  }
9550 
9551  // -------------------------------------------------------------------------
9552 
9553  void ReplaceString( const String& s1, const String& s2, size_type i = 0 )
9554  {
9555  string_base::ReplaceString( s1, s2, i );
9556  }
9557 
9558  void ReplaceStringIC( const String& s1, const String& s2, size_type i = 0 )
9559  {
9560  string_base::ReplaceStringIC( s1, s2, i );
9561  }
9562 
9563  void ReplaceString( const_iterator t1, const_iterator t2, size_type i = 0 )
9564  {
9565  string_base::ReplaceString( t1, t2, i );
9566  }
9567 
9568  void ReplaceStringIC( const_iterator t1, const_iterator t2, size_type i = 0 )
9569  {
9570  string_base::ReplaceStringIC( t1, t2, i );
9571  }
9572 
9573  void ReplaceString( const char16_t* t1, const char16_t* t2, size_type i = 0 )
9574  {
9575  string_base::ReplaceString( reinterpret_cast<const_iterator>( t1 ),
9576  reinterpret_cast<const_iterator>( t2 ), i );
9577  }
9578 
9579  void ReplaceStringIC( const char16_t* t1, const char16_t* t2, size_type i = 0 )
9580  {
9581  string_base::ReplaceStringIC( reinterpret_cast<const_iterator>( t1 ),
9582  reinterpret_cast<const_iterator>( t2 ), i );
9583  }
9584 
9585  void ReplaceString( const wchar_t* t1, const wchar_t* t2, size_type i = 0 )
9586  {
9587 #ifdef __PCL_WINDOWS
9588  string_base::ReplaceString( reinterpret_cast<const_iterator>( t1 ),
9589  reinterpret_cast<const_iterator>( t2 ), i );
9590 #else
9591  string_base::ReplaceString( String( t1 ), String( t2 ), i );
9592 #endif
9593  }
9594 
9595  void ReplaceStringIC( const wchar_t* t1, const wchar_t* t2, size_type i = 0 )
9596  {
9597 #ifdef __PCL_WINDOWS
9598  string_base::ReplaceStringIC( reinterpret_cast<const_iterator>( t1 ),
9599  reinterpret_cast<const_iterator>( t2 ), i );
9600 #else
9601  string_base::ReplaceStringIC( String( t1 ), String( t2 ), i );
9602 #endif
9603  }
9604 
9605  void ReplaceString( const_c_string8 t1, const_c_string8 t2, size_type i = 0 )
9606  {
9607  string_base::ReplaceString( String( t1 ), String( t2 ), i );
9608  }
9609 
9610  void ReplaceStringIC( const_c_string8 t1, const_c_string8 t2, size_type i = 0 )
9611  {
9612  string_base::ReplaceStringIC( String( t1 ), String( t2 ), i );
9613  }
9614 
9615  // -------------------------------------------------------------------------
9616 
9617  void DeleteChar( char_type c, size_type i = 0 )
9618  {
9619  string_base::DeleteChar( c, i );
9620  }
9621 
9622  void DeleteCharIC( char_type c, size_type i = 0 )
9623  {
9624  string_base::DeleteCharIC( c, i );
9625  }
9626 
9627  void DeleteChar( char16_t c, size_type i = 0 )
9628  {
9629  string_base::DeleteChar( char_type( c ), i );
9630  }
9631 
9632  void DeleteCharIC( char16_t c, size_type i = 0 )
9633  {
9634  string_base::DeleteCharIC( char_type( c ), i );
9635  }
9636 
9637  void DeleteChar( wchar_t c, size_type i = 0 )
9638  {
9639  string_base::DeleteChar( char_type( c ), i );
9640  }
9641 
9642  void DeleteCharIC( wchar_t c, size_type i = 0 )
9643  {
9644  string_base::DeleteCharIC( char_type( c ), i );
9645  }
9646 
9647  void DeleteChar( char8_type c, size_type i = 0 )
9648  {
9649  string_base::DeleteChar( char_type( c ), i );
9650  }
9651 
9652  void DeleteCharIC( char8_type c, size_type i = 0 )
9653  {
9654  string_base::DeleteCharIC( char_type( c ), i );
9655  }
9656 
9657  // -------------------------------------------------------------------------
9658 
9659  void DeleteString( const String& s, size_type i = 0 )
9660  {
9661  string_base::DeleteString( s, i );
9662  }
9663 
9664  void DeleteStringIC( const String& s, size_type i = 0 )
9665  {
9666  string_base::DeleteStringIC( s, i );
9667  }
9668 
9669  void DeleteString( const_iterator t, size_type i = 0 )
9670  {
9671  string_base::DeleteString( t, i );
9672  }
9673 
9674  void DeleteStringIC( const_iterator t, size_type i = 0 )
9675  {
9676  string_base::DeleteStringIC( t, i );
9677  }
9678 
9679  void DeleteString( const char16_t* t, size_type i = 0 )
9680  {
9681  string_base::DeleteString( reinterpret_cast<const_iterator>( t ), i );
9682  }
9683 
9684  void DeleteStringIC( const char16_t* t, size_type i = 0 )
9685  {
9686  string_base::DeleteStringIC( reinterpret_cast<const_iterator>( t ), i );
9687  }
9688 
9689  void DeleteString( const wchar_t* t, size_type i = 0 )
9690  {
9691 #ifdef __PCL_WINDOWS
9692  string_base::DeleteString( reinterpret_cast<const_iterator>( t ), i );
9693 #else
9694  string_base::DeleteString( String( t ), i );
9695 #endif
9696  }
9697 
9698  void DeleteStringIC( const wchar_t* t, size_type i = 0 )
9699  {
9700 #ifdef __PCL_WINDOWS
9701  string_base::DeleteStringIC( reinterpret_cast<const_iterator>( t ), i );
9702 #else
9703  string_base::DeleteStringIC( String( t ), i );
9704 #endif
9705  }
9706 
9707  void DeleteString( const_c_string8 t, size_type i = 0 )
9708  {
9709  string_base::DeleteString( String( t ), i );
9710  }
9711 
9712  void DeleteStringIC( const_c_string8 t, size_type i = 0 )
9713  {
9714  string_base::DeleteStringIC( String( t ), i );
9715  }
9716 
9717  // -------------------------------------------------------------------------
9718 
9719  bool StartsWith( const String& s ) const noexcept
9720  {
9721  return string_base::StartsWith( s );
9722  }
9723 
9724  bool StartsWith( const_iterator t ) const noexcept
9725  {
9726  return string_base::StartsWith( t );
9727  }
9728 
9729  bool StartsWith( char_type c ) const noexcept
9730  {
9731  return string_base::StartsWith( c );
9732  }
9733 
9734  bool StartsWithIC( const String& s ) const noexcept
9735  {
9736  return string_base::StartsWithIC( s );
9737  }
9738 
9739  bool StartsWithIC( const_iterator t ) const noexcept
9740  {
9741  return string_base::StartsWithIC( t );
9742  }
9743 
9744  bool StartsWithIC( char_type c ) const noexcept
9745  {
9746  return string_base::StartsWithIC( c );
9747  }
9748 
9749  bool StartsWith( const char16_t* t ) const noexcept
9750  {
9751  return string_base::StartsWith( reinterpret_cast<const_iterator>( t ) );
9752  }
9753 
9754  bool StartsWith( char16_t c ) const noexcept
9755  {
9756  return string_base::StartsWith( char_type( c ) );
9757  }
9758 
9759  bool StartsWithIC( const char16_t* t ) const noexcept
9760  {
9761  return string_base::StartsWithIC( reinterpret_cast<const_iterator>( t ) );
9762  }
9763 
9764  bool StartsWithIC( char16_t c ) const noexcept
9765  {
9766  return string_base::StartsWithIC( char_type( c ) );
9767  }
9768 
9769  bool StartsWith( const wchar_t* t ) const noexcept
9770  {
9771 #ifdef __PCL_WINDOWS
9772  return string_base::StartsWith( reinterpret_cast<const_iterator>( t ) );
9773 #else
9774  return string_base::StartsWith( String( t ) );
9775 #endif
9776  }
9777 
9778  bool StartsWith( wchar_t c ) const noexcept
9779  {
9780  return string_base::StartsWith( char_type( c ) );
9781  }
9782 
9783  bool StartsWithIC( const wchar_t* t ) const noexcept
9784  {
9785 #ifdef __PCL_WINDOWS
9786  return string_base::StartsWithIC( reinterpret_cast<const_iterator>( t ) );
9787 #else
9788  return string_base::StartsWithIC( String( t ) );
9789 #endif
9790  }
9791 
9792  bool StartsWithIC( wchar_t c ) const noexcept
9793  {
9794  return string_base::StartsWithIC( char_type( c ) );
9795  }
9796 
9797  bool StartsWith( const_c_string8 t ) const noexcept
9798  {
9799  size_type n = char8_traits::Length( t );
9800  if ( n == 0 || Length() < n )
9801  return false;
9802  for ( const_iterator p = m_data->string, q = p+n; p < q; ++p, ++t )
9803  if ( *p != char_type( *t ) )
9804  return false;
9805  return true;
9806  }
9807 
9808  bool StartsWith( char8_type c ) const noexcept
9809  {
9810  return string_base::StartsWith( char_type( c ) );
9811  }
9812 
9813  bool StartsWithIC( const_c_string8 t ) const noexcept
9814  {
9815  size_type n = char8_traits::Length( t );
9816  if ( n == 0 || Length() < n )
9817  return false;
9818  for ( const_iterator p = m_data->string, q = p+n; p < q; ++p, ++t )
9819  if ( char_traits::ToCaseFolded( *p ) != char_type( char8_traits::ToCaseFolded( *t ) ) )
9820  return false;
9821  return true;
9822  }
9823 
9824  bool StartsWithIC( char8_type c ) const noexcept
9825  {
9826  return string_base::StartsWithIC( char_type( c ) );
9827  }
9828 
9829  // -------------------------------------------------------------------------
9830 
9831  bool EndsWith( const String& s ) const noexcept
9832  {
9833  return string_base::EndsWith( s );
9834  }
9835 
9836  bool EndsWith( const_iterator t ) const noexcept
9837  {
9838  return string_base::EndsWith( t );
9839  }
9840 
9841  bool EndsWith( char_type c ) const noexcept
9842  {
9843  return string_base::EndsWith( c );
9844  }
9845 
9846  bool EndsWithIC( const String& s ) const noexcept
9847  {
9848  return string_base::EndsWithIC( s );
9849  }
9850 
9851  bool EndsWithIC( const_iterator t ) const noexcept
9852  {
9853  return string_base::EndsWithIC( t );
9854  }
9855 
9856  bool EndsWithIC( char_type c ) const noexcept
9857  {
9858  return string_base::EndsWithIC( c );
9859  }
9860 
9861  bool EndsWith( const char16_t* t ) const noexcept
9862  {
9863  return string_base::EndsWith( reinterpret_cast<const_iterator>( t ) );
9864  }
9865 
9866  bool EndsWith( char16_t c ) const noexcept
9867  {
9868  return string_base::EndsWith( char_type( c ) );
9869  }
9870 
9871  bool EndsWithIC( const char16_t* t ) const noexcept
9872  {
9873  return string_base::EndsWithIC( reinterpret_cast<const_iterator>( t ) );
9874  }
9875 
9876  bool EndsWithIC( char16_t c ) const noexcept
9877  {
9878  return string_base::EndsWithIC( char_type( c ) );
9879  }
9880 
9881  bool EndsWith( const wchar_t* t ) const noexcept
9882  {
9883 #ifdef __PCL_WINDOWS
9884  return string_base::EndsWith( reinterpret_cast<const_iterator>( t ) );
9885 #else
9886  return string_base::EndsWith( String( t ) );
9887 #endif
9888  }
9889 
9890  bool EndsWith( wchar_t c ) const noexcept
9891  {
9892  return string_base::EndsWith( char_type( c ) );
9893  }
9894 
9895  bool EndsWithIC( const wchar_t* t ) const noexcept
9896  {
9897 #ifdef __PCL_WINDOWS
9898  return string_base::EndsWithIC( reinterpret_cast<const_iterator>( t ) );
9899 #else
9900  return string_base::EndsWithIC( String( t ) );
9901 #endif
9902  }
9903 
9904  bool EndsWithIC( wchar_t c ) const noexcept
9905  {
9906  return string_base::EndsWithIC( char_type( c ) );
9907  }
9908 
9909  bool EndsWith( const_c_string8 t ) const noexcept
9910  {
9911  size_type n = char8_traits::Length( t );
9912  if ( n == 0 || Length() < n )
9913  return false;
9914  for ( const_iterator p = m_data->end-n; p < m_data->end; ++p, ++t )
9915  if ( *p != char_type( *t ) )
9916  return false;
9917  return true;
9918  }
9919 
9920  bool EndsWith( char8_type c ) const noexcept
9921  {
9922  return string_base::EndsWith( char_type( c ) );
9923  }
9924 
9925  bool EndsWithIC( const_c_string8 t ) const noexcept
9926  {
9927  size_type n = char8_traits::Length( t );
9928  if ( n == 0 || Length() < n )
9929  return false;
9930  for ( const_iterator p = m_data->end-n; p < m_data->end; ++p, ++t )
9931  if ( char_traits::ToCaseFolded( *p ) != char_type( char8_traits::ToCaseFolded( *t ) ) )
9932  return false;
9933  return true;
9934  }
9935 
9936  bool EndsWithIC( char8_type c ) const noexcept
9937  {
9938  return string_base::EndsWithIC( char_type( c ) );
9939  }
9940 
9941  // -------------------------------------------------------------------------
9942 
9943  size_type FindFirst( const String& s, size_type i = 0 ) const noexcept
9944  {
9945  return string_base::FindFirst( s, i );
9946  }
9947 
9948  size_type FindFirst( const_iterator t, size_type i = 0 ) const noexcept
9949  {
9950  return string_base::FindFirst( t, i );
9951  }
9952 
9953  size_type FindFirst( char_type c, size_type i = 0 ) const noexcept
9954  {
9955  return string_base::FindFirst( c, i );
9956  }
9957 
9958  size_type FindFirstIC( const String& s, size_type i = 0 ) const noexcept
9959  {
9960  return string_base::FindFirstIC( s, i );
9961  }
9962 
9963  size_type FindFirstIC( const_iterator t, size_type i = 0 ) const noexcept
9964  {
9965  return string_base::FindFirstIC( t, i );
9966  }
9967 
9968  size_type FindFirstIC( char_type c, size_type i = 0 ) const noexcept
9969  {
9970  return string_base::FindFirstIC( c, i );
9971  }
9972 
9973  size_type FindFirst( const char16_t* t, size_type i = 0 ) const noexcept
9974  {
9975  return string_base::FindFirst( reinterpret_cast<const_iterator>( t ), i );
9976  }
9977 
9978  size_type FindFirst( char16_t c, size_type i = 0 ) const noexcept
9979  {
9980  return string_base::FindFirst( char_type( c ), i );
9981  }
9982 
9983  size_type FindFirstIC( const char16_t* t, size_type i = 0 ) const noexcept
9984  {
9985  return string_base::FindFirstIC( reinterpret_cast<const_iterator>( t ), i );
9986  }
9987 
9988  size_type FindFirstIC( char16_t c, size_type i = 0 ) const noexcept
9989  {
9990  return string_base::FindFirstIC( char_type( c ), i );
9991  }
9992 
9993  size_type FindFirst( const wchar_t* t, size_type i = 0 ) const noexcept
9994  {
9995 #ifdef __PCL_WINDOWS
9996  return string_base::FindFirst( reinterpret_cast<const_iterator>( t ), i );
9997 #else
9998  return string_base::FindFirst( String( t ), i );
9999 #endif
10000  }
10001 
10002  size_type FindFirst( wchar_t c, size_type i = 0 ) const noexcept
10003  {
10004  return string_base::FindFirst( char_type( c ), i );
10005  }
10006 
10007  size_type FindFirstIC( const wchar_t* t, size_type i = 0 ) const noexcept
10008  {
10009 #ifdef __PCL_WINDOWS
10010  return string_base::FindFirstIC( reinterpret_cast<const_iterator>( t ), i );
10011 #else
10012  return string_base::FindFirstIC( String( t ), i );
10013 #endif
10014  }
10015 
10016  size_type FindFirstIC( wchar_t c, size_type i = 0 ) const noexcept
10017  {
10018  return string_base::FindFirstIC( char_type( c ), i );
10019  }
10020 
10021  size_type FindFirst( const_c_string8 t, size_type i = 0 ) const noexcept
10022  {
10023  return string_base::FindFirst( String( t ), i );
10024  }
10025 
10026  size_type FindFirst( char8_type c, size_type i = 0 ) const noexcept
10027  {
10028  return string_base::FindFirst( char_type( c ), i );
10029  }
10030 
10031  size_type FindFirstIC( const_c_string8 t, size_type i = 0 ) const noexcept
10032  {
10033  return string_base::FindFirstIC( String( t ), i );
10034  }
10035 
10036  size_type FindFirstIC( char8_type c, size_type i = 0 ) const noexcept
10037  {
10038  return string_base::FindFirstIC( char_type( c ), i );
10039  }
10040 
10041  //
10042 
10043  size_type Find( const String& s, size_type i = 0 ) const noexcept
10044  {
10045  return FindFirst( s, i );
10046  }
10047 
10048  size_type Find( const_iterator t, size_type i = 0 ) const noexcept
10049  {
10050  return FindFirst( t, i );
10051  }
10052 
10053  size_type Find( char_type c, size_type i = 0 ) const noexcept
10054  {
10055  return FindFirst( c, i );
10056  }
10057 
10058  size_type Find( const char16_t* t, size_type i = 0 ) const noexcept
10059  {
10060  return FindFirst( t, i );
10061  }
10062 
10063  size_type Find( char16_t c, size_type i = 0 ) const noexcept
10064  {
10065  return FindFirst( c, i );
10066  }
10067 
10068  size_type Find( const wchar_t* t, size_type i = 0 ) const noexcept
10069  {
10070  return FindFirst( t, i );
10071  }
10072 
10073  size_type Find( wchar_t c, size_type i = 0 ) const noexcept
10074  {
10075  return FindFirst( c, i );
10076  }
10077 
10078  size_type Find( const_c_string8 t, size_type i = 0 ) const noexcept
10079  {
10080  return FindFirst( t, i );
10081  }
10082 
10083  size_type Find( char8_type c, size_type i = 0 ) const noexcept
10084  {
10085  return FindFirst( c, i );
10086  }
10087 
10088  size_type FindIC( const String& s, size_type i = 0 ) const noexcept
10089  {
10090  return FindFirstIC( s, i );
10091  }
10092 
10093  size_type FindIC( const_iterator t, size_type i = 0 ) const noexcept
10094  {
10095  return FindFirstIC( t, i );
10096  }
10097 
10098  size_type FindIC( char_type c, size_type i = 0 ) const noexcept
10099  {
10100  return FindFirstIC( c, i );
10101  }
10102 
10103  size_type FindIC( const char16_t* t, size_type i = 0 ) const noexcept
10104  {
10105  return FindFirstIC( t, i );
10106  }
10107 
10108  size_type FindIC( char16_t c, size_type i = 0 ) const noexcept
10109  {
10110  return FindFirstIC( c, i );
10111  }
10112 
10113  size_type FindIC( const wchar_t* t, size_type i = 0 ) const noexcept
10114  {
10115  return FindFirstIC( t, i );
10116  }
10117 
10118  size_type FindIC( wchar_t c, size_type i = 0 ) const noexcept
10119  {
10120  return FindFirstIC( c, i );
10121  }
10122 
10123  size_type FindIC( const_c_string8 t, size_type i = 0 ) const noexcept
10124  {
10125  return FindFirstIC( t, i );
10126  }
10127 
10128  size_type FindIC( char8_type c, size_type i = 0 ) const noexcept
10129  {
10130  return FindFirstIC( c, i );
10131  }
10132 
10133  // -------------------------------------------------------------------------
10134 
10135  size_type FindLast( const String& s, size_type r = maxPos ) const noexcept
10136  {
10137  return string_base::FindLast( s, r );
10138  }
10139 
10140  size_type FindLast( const_iterator t, size_type r = maxPos ) const noexcept
10141  {
10142  return string_base::FindLast( t, r );
10143  }
10144 
10145  size_type FindLast( char_type c, size_type r = maxPos ) const noexcept
10146  {
10147  return string_base::FindLast( c, r );
10148  }
10149 
10150  size_type FindLastIC( const String& s, size_type r = maxPos ) const noexcept
10151  {
10152  return string_base::FindLastIC( s, r );
10153  }
10154 
10155  size_type FindLastIC( const_iterator t, size_type r = maxPos ) const noexcept
10156  {
10157  return string_base::FindLastIC( t, r );
10158  }
10159 
10160  size_type FindLastIC( char_type c, size_type r = maxPos ) const noexcept
10161  {
10162  return string_base::FindLastIC( c, r );
10163  }
10164 
10165  size_type FindLast( const char16_t* t, size_type r = maxPos ) const noexcept
10166  {
10167  return string_base::FindLast( reinterpret_cast<const_iterator>( t ), r );
10168  }
10169 
10170  size_type FindLast( char16_t c, size_type r = maxPos ) const noexcept
10171  {
10172  return string_base::FindLast( char_type( c ), r );
10173  }
10174 
10175  size_type FindLastIC( const char16_t* t, size_type r = maxPos ) const noexcept
10176  {
10177  return string_base::FindLastIC( reinterpret_cast<const_iterator>( t ), r );
10178  }
10179 
10180  size_type FindLastIC( char16_t c, size_type r = maxPos ) const noexcept
10181  {
10182  return string_base::FindLastIC( char_type( c ), r );
10183  }
10184 
10185  size_type FindLast( const wchar_t* t, size_type r = maxPos ) const noexcept
10186  {
10187 #ifdef __PCL_WINDOWS
10188  return string_base::FindLast( reinterpret_cast<const_iterator>( t ), r );
10189 #else
10190  return string_base::FindLast( String( t ), r );
10191 #endif
10192  }
10193 
10194  size_type FindLast( wchar_t c, size_type r = maxPos ) const noexcept
10195  {
10196  return string_base::FindLast( char_type( c ), r );
10197  }
10198 
10199  size_type FindLastIC( const wchar_t* t, size_type r = maxPos ) const noexcept
10200  {
10201 #ifdef __PCL_WINDOWS
10202  return string_base::FindLastIC( reinterpret_cast<const_iterator>( t ), r );
10203 #else
10204  return string_base::FindLastIC( String( t ), r );
10205 #endif
10206  }
10207 
10208  size_type FindLastIC( wchar_t c, size_type r = maxPos ) const noexcept
10209  {
10210  return string_base::FindLastIC( char_type( c ), r );
10211  }
10212 
10213  size_type FindLast( const_c_string8 t, size_type r = maxPos ) const noexcept
10214  {
10215  return string_base::FindLast( String( t ), r );
10216  }
10217 
10218  size_type FindLast( char8_type c, size_type r = maxPos ) const noexcept
10219  {
10220  return string_base::FindLast( char_type( c ), r );
10221  }
10222 
10223  size_type FindLastIC( const_c_string8 t, size_type r = maxPos ) const noexcept
10224  {
10225  return string_base::FindLastIC( String( t ), r );
10226  }
10227 
10228  size_type FindLastIC( char8_type c, size_type r = maxPos ) const noexcept
10229  {
10230  return string_base::FindLastIC( char_type( c ), r );
10231  }
10232 
10233  // -------------------------------------------------------------------------
10234 
10235  bool Contains( const String& s ) const noexcept
10236  {
10237  return string_base::Contains( s );
10238  }
10239 
10240  bool Contains( const_iterator t ) const noexcept
10241  {
10242  return string_base::Contains( t );
10243  }
10244 
10245  bool Contains( char_type c ) const noexcept
10246  {
10247  return string_base::Contains( c );
10248  }
10249 
10250  bool ContainsIC( const String& s ) const noexcept
10251  {
10252  return string_base::ContainsIC( s );
10253  }
10254 
10255  bool ContainsIC( const_iterator t ) const noexcept
10256  {
10257  return string_base::ContainsIC( t );
10258  }
10259 
10260  bool ContainsIC( char_type c ) const noexcept
10261  {
10262  return string_base::ContainsIC( c );
10263  }
10264 
10265  bool Contains( const char16_t* t ) const noexcept
10266  {
10267  return string_base::Contains( reinterpret_cast<const_iterator>( t ) );
10268  }
10269 
10270  bool Contains( char16_t c ) const noexcept
10271  {
10272  return string_base::Contains( char_type( c ) );
10273  }
10274 
10275  bool ContainsIC( const char16_t* t ) const noexcept
10276  {
10277  return string_base::ContainsIC( reinterpret_cast<const_iterator>( t ) );
10278  }
10279 
10280  bool ContainsIC( char16_t c ) const noexcept
10281  {
10282  return string_base::ContainsIC( char_type( c ) );
10283  }
10284 
10285  bool Contains( const wchar_t* t ) const noexcept
10286  {
10287 #ifdef __PCL_WINDOWS
10288  return string_base::Contains( reinterpret_cast<const_iterator>( t ) );
10289 #else
10290  return string_base::Contains( String( t ) );
10291 #endif
10292  }
10293 
10294  bool Contains( wchar_t c ) const noexcept
10295  {
10296  return string_base::Contains( char_type( c ) );
10297  }
10298 
10299  bool ContainsIC( const wchar_t* t ) const noexcept
10300  {
10301 #ifdef __PCL_WINDOWS
10302  return string_base::ContainsIC( reinterpret_cast<const_iterator>( t ) );
10303 #else
10304  return string_base::ContainsIC( String( t ) );
10305 #endif
10306  }
10307 
10308  bool ContainsIC( wchar_t c ) const noexcept
10309  {
10310  return string_base::ContainsIC( char_type( c ) );
10311  }
10312 
10313  bool Contains( const_c_string8 t ) const noexcept
10314  {
10315  return string_base::Contains( String( t ) );
10316  }
10317 
10318  bool Contains( char8_type c ) const noexcept
10319  {
10320  return string_base::Contains( char_type( c ) );
10321  }
10322 
10323  bool ContainsIC( const_c_string8 t ) const noexcept
10324  {
10325  return string_base::ContainsIC( String( t ) );
10326  }
10327 
10328  bool ContainsIC( char8_type c ) const noexcept
10329  {
10330  return string_base::ContainsIC( char_type( c ) );
10331  }
10332 
10333  // -------------------------------------------------------------------------
10334 
10335  int CompareCodePoints( const String& s, bool caseSensitive = true ) const noexcept
10336  {
10337  return string_base::CompareCodePoints( s, caseSensitive );
10338  }
10339 
10340  int CompareCodePoints( const_iterator t, bool caseSensitive = true ) const noexcept
10341  {
10342  return string_base::CompareCodePoints( t, caseSensitive );
10343  }
10344 
10345  int CompareCodePoints( char_type c, bool caseSensitive = true ) const noexcept
10346  {
10347  return string_base::CompareCodePoints( c, caseSensitive );
10348  }
10349 
10350  int CompareCodePoints( const char16_t* t, bool caseSensitive = true ) const noexcept
10351  {
10352  return string_base::CompareCodePoints( reinterpret_cast<const_iterator>( t ), caseSensitive );
10353  }
10354 
10355  int CompareCodePoints( char16_t c, bool caseSensitive = true ) const noexcept
10356  {
10357  return string_base::CompareCodePoints( char_type( c ), caseSensitive );
10358  }
10359 
10360  int CompareCodePoints( const wchar_t* t, bool caseSensitive = true ) const noexcept
10361  {
10362 #ifdef __PCL_WINDOWS
10363  return string_base::CompareCodePoints( reinterpret_cast<const_iterator>( t ), caseSensitive );
10364 #else
10365  return string_base::CompareCodePoints( String( t ), caseSensitive );
10366 #endif
10367  }
10368 
10369  int CompareCodePoints( wchar_t c, bool caseSensitive = true ) const noexcept
10370  {
10371  return string_base::CompareCodePoints( char_type( c ), caseSensitive );
10372  }
10373 
10374  int CompareCodePoints( const_c_string8 t, bool caseSensitive = true ) const noexcept
10375  {
10376  return string_base::CompareCodePoints( String( t ), caseSensitive );
10377  }
10378 
10379  int CompareCodePoints( char8_type c, bool caseSensitive = true ) const noexcept
10380  {
10381  return string_base::CompareCodePoints( char_type( c ), caseSensitive );
10382  }
10383 
10384  // -------------------------------------------------------------------------
10385 
10386  int Compare( const String& s, bool caseSensitive = true, bool localeAware = true ) const noexcept
10387  {
10388  return string_base::Compare( s, caseSensitive, localeAware );
10389  }
10390 
10391  int Compare( const_iterator t, bool caseSensitive = true, bool localeAware = true ) const noexcept
10392  {
10393  return string_base::Compare( t, caseSensitive, localeAware );
10394  }
10395 
10396  int Compare( char_type c, bool caseSensitive = true, bool localeAware = true ) const noexcept
10397  {
10398  return string_base::Compare( c, caseSensitive, localeAware );
10399  }
10400 
10401  int CompareIC( const String& s, bool localeAware = true ) const noexcept
10402  {
10403  return string_base::CompareIC( s, localeAware );
10404  }
10405 
10406  int CompareIC( const_iterator t, bool localeAware = true ) const noexcept
10407  {
10408  return string_base::CompareIC( t, localeAware );
10409  }
10410 
10411  int CompareIC( char_type c, bool localeAware = true ) const noexcept
10412  {
10413  return string_base::CompareIC( c, localeAware );
10414  }
10415 
10416  int Compare( const char16_t* t, bool caseSensitive = true, bool localeAware = true ) const noexcept
10417  {
10418  return string_base::Compare( reinterpret_cast<const_iterator>( t ), caseSensitive, localeAware );
10419  }
10420 
10421  int Compare( char16_t c, bool caseSensitive = true, bool localeAware = true ) const noexcept
10422  {
10423  return string_base::Compare( char_type( c ), caseSensitive, localeAware );
10424  }
10425 
10426  int CompareIC( const char16_t* t, bool localeAware = true ) const noexcept
10427  {
10428  return string_base::CompareIC( reinterpret_cast<const_iterator>( t ), localeAware );
10429  }
10430 
10431  int CompareIC( char16_t c, bool localeAware = true ) const noexcept
10432  {
10433  return string_base::CompareIC( char_type( c ), localeAware );
10434  }
10435 
10436  int Compare( const wchar_t* t, bool caseSensitive = true, bool localeAware = true ) const noexcept
10437  {
10438 #ifdef __PCL_WINDOWS
10439  return string_base::Compare( reinterpret_cast<const_iterator>( t ), caseSensitive, localeAware );
10440 #else
10441  return string_base::Compare( String( t ), caseSensitive, localeAware );
10442 #endif
10443  }
10444 
10445  int Compare( wchar_t c, bool caseSensitive = true, bool localeAware = true ) const noexcept
10446  {
10447  return string_base::Compare( char_type( c ), caseSensitive, localeAware );
10448  }
10449 
10450  int CompareIC( const wchar_t* t, bool localeAware = true ) const noexcept
10451  {
10452 #ifdef __PCL_WINDOWS
10453  return string_base::CompareIC( reinterpret_cast<const_iterator>( t ), localeAware );
10454 #else
10455  return string_base::CompareIC( String( t ), localeAware );
10456 #endif
10457  }
10458 
10459  int CompareIC( wchar_t c, bool localeAware = true ) const noexcept
10460  {
10461  return string_base::CompareIC( char_type( c ), localeAware );
10462  }
10463 
10464  int Compare( const_c_string8 t, bool caseSensitive = true, bool localeAware = true ) const noexcept
10465  {
10466  return string_base::Compare( String( t ), caseSensitive, localeAware );
10467  }
10468 
10469  int Compare( char8_type 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_c_string8 t, bool localeAware = true ) const noexcept
10475  {
10476  return string_base::CompareIC( String( t ), localeAware );
10477  }
10478 
10479  int CompareIC( char8_type c, bool localeAware = true ) const noexcept
10480  {
10481  return string_base::CompareIC( char_type( c ), localeAware );
10482  }
10483 
10484  // -------------------------------------------------------------------------
10485 
10486  bool WildMatch( const String& pattern, bool caseSensitive = true ) const noexcept
10487  {
10488  return string_base::WildMatch( pattern, caseSensitive );
10489  }
10490 
10491  bool WildMatchIC( const String& pattern ) const noexcept
10492  {
10493  return string_base::WildMatchIC( pattern );
10494  }
10495 
10496  bool WildMatch( const_iterator pattern, bool caseSensitive = true ) const noexcept
10497  {
10498  return string_base::WildMatch( pattern, caseSensitive );
10499  }
10500 
10501  bool WildMatchIC( const_iterator pattern ) const noexcept
10502  {
10503  return string_base::WildMatchIC( pattern );
10504  }
10505 
10506  bool WildMatch( const string8_base& pattern, bool caseSensitive = true ) const noexcept
10507  {
10508  return char_traits::WildMatch( m_data->string, Length(), pattern.Begin(), pattern.Length(), caseSensitive );
10509  }
10510 
10511  bool WildMatchIC( const string8_base& pattern ) const noexcept
10512  {
10513  return char_traits::WildMatch( m_data->string, Length(), pattern.Begin(), pattern.Length(), false/*caseSensitive*/ );
10514  }
10515 
10516  bool WildMatch( const_c_string8 pattern, bool caseSensitive = true ) const noexcept
10517  {
10518  return char_traits::WildMatch( m_data->string, Length(), pattern, char8_traits::Length( pattern ), caseSensitive );
10519  }
10520 
10521  bool WildMatchIC( const_c_string8 pattern ) const noexcept
10522  {
10523  return char_traits::WildMatch( m_data->string, Length(), pattern, char8_traits::Length( pattern ), false/*caseSensitive*/ );
10524  }
10525 
10526  // -------------------------------------------------------------------------
10527 
10528  String SetToLength( size_type n ) const
10529  {
10530  return string_base::SetToLength( n );
10531  }
10532 
10533  String ResizedToNullTerminated() const
10534  {
10535  return string_base::ResizedToNullTerminated();
10536  }
10537 
10538  String Squeezed() const
10539  {
10540  return string_base::Squeezed();
10541  }
10542 
10543  // -------------------------------------------------------------------------
10544 
10545  String Substring( size_type i, size_type n = maxPos ) const
10546  {
10547  return string_base::Substring( i, n );
10548  }
10549 
10550  String Left( size_type n ) const
10551  {
10552  return string_base::Left( n );
10553  }
10554 
10555  String Right( size_type n ) const
10556  {
10557  return string_base::Right( n );
10558  }
10559 
10560  String Suffix( size_type i ) const
10561  {
10562  return string_base::Suffix( i );
10563  }
10564 
10565  String Prefix( size_type i ) const
10566  {
10567  return string_base::Prefix( i );
10568  }
10569 
10570  // -------------------------------------------------------------------------
10571 
10572  template <class C>
10573  size_type Break( C& list, const String& s, bool trim = false, size_type i = 0 ) const
10574  {
10575  return string_base::Break( list, s, trim, i );
10576  }
10577 
10578  template <class C>
10579  size_type Break( C& list, const string8_base& s, bool trim = false, size_type i = 0 ) const
10580  {
10581  return string_base::Break( list, String( s ), trim, i );
10582  }
10583 
10584  template <class C>
10585  size_type Break( C& list, const_c_string8 s, bool trim = false, size_type i = 0 ) const
10586  {
10587  return string_base::Break( list, String( s ), trim, i );
10588  }
10589 
10590  template <class C>
10591  size_type Break( C& list, char_type c, bool trim = false, size_type i = 0 ) const
10592  {
10593  return string_base::Break( list, c, trim, i );
10594  }
10595 
10596  template <class C>
10597  size_type Break( C& list, char8_type c, bool trim = false, size_type i = 0 ) const
10598  {
10599  return string_base::Break( list, char_type( c ), trim, i );
10600  }
10601 
10602  template <class C, typename S>
10603  size_type Break( C& list, const Array<S>& ca, bool trim = false, size_type i = 0 ) const
10604  {
10605  return string_base::Break( list, ca, trim, i );
10606  }
10607 
10608  // -------------------------------------------------------------------------
10609 
10610  template <class C>
10611  size_type BreakIC( C& list, const String& s, bool trim = false, size_type i = 0 ) const
10612  {
10613  return string_base::BreakIC( list, s, trim, i );
10614  }
10615 
10616  template <class C>
10617  size_type BreakIC( C& list, const string8_base& s, bool trim = false, size_type i = 0 ) const
10618  {
10619  return string_base::BreakIC( list, String( s ), trim, i );
10620  }
10621 
10622  template <class C>
10623  size_type BreakIC( C& list, const_c_string8 s, bool trim = false, size_type i = 0 ) const
10624  {
10625  return string_base::BreakIC( list, String( s ), trim, i );
10626  }
10627 
10628  template <class C>
10629  size_type BreakIC( C& list, char_type c, bool trim = false, size_type i = 0 ) const
10630  {
10631  return string_base::BreakIC( list, c, trim, i );
10632  }
10633 
10634  template <class C>
10635  size_type BreakIC( C& list, char8_type c, bool trim = false, size_type i = 0 ) const
10636  {
10637  return string_base::BreakIC( list, char_type( c ), trim, i );
10638  }
10639 
10640  // -------------------------------------------------------------------------
10641 
10642  String Trimmed() const
10643  {
10644  return string_base::Trimmed();
10645  }
10646 
10647  String TrimmedLeft() const
10648  {
10649  return string_base::TrimmedLeft();
10650  }
10651 
10652  String TrimmedRight() const
10653  {
10654  return string_base::TrimmedRight();
10655  }
10656 
10657  // -------------------------------------------------------------------------
10658 
10659  String LeftJustified( size_type width, char_type fill = CharTraits::Blank() ) const
10660  {
10661  return string_base::LeftJustified( width, fill );
10662  }
10663 
10664  String RightJustified( size_type width, char_type fill = CharTraits::Blank() ) const
10665  {
10666  return string_base::RightJustified( width, fill );
10667  }
10668 
10669  String CenterJustified( size_type width, char_type fill = CharTraits::Blank() ) const
10670  {
10671  return string_base::CenterJustified( width, fill );
10672  }
10673 
10674  // -------------------------------------------------------------------------
10675 
10676  String Enclosed( char_type c ) const
10677  {
10678  return string_base::Enclosed( c );
10679  }
10680 
10681  String SingleQuoted() const
10682  {
10683  return string_base::SingleQuoted();
10684  }
10685 
10686  String DoubleQuoted() const
10687  {
10688  return string_base::DoubleQuoted();
10689  }
10690 
10691  String Unquoted() const
10692  {
10693  return string_base::Unquoted();
10694  }
10695 
10696  // -------------------------------------------------------------------------
10697 
10698  String CaseFolded() const
10699  {
10700  return string_base::CaseFolded();
10701  }
10702 
10703  String Lowercase() const
10704  {
10705  return string_base::Lowercase();
10706  }
10707 
10708  String Uppercase() const
10709  {
10710  return string_base::Uppercase();
10711  }
10712 
10713  // -------------------------------------------------------------------------
10714 
10715  String Reversed() const
10716  {
10717  return string_base::Reversed();
10718  }
10719 
10720  String Sorted() const
10721  {
10722  return string_base::Sorted();
10723  }
10724 
10725  template <class BP>
10726  String Sorted( BP p ) const
10727  {
10728  return string_base::Sorted( p );
10729  }
10730 
10731  // -------------------------------------------------------------------------
10732 
10742  template <class C>
10743  String& ToSeparated( const C& c, char_type separator )
10744  {
10745  Clear();
10746  return c.ToSeparated( *this, separator );
10747  }
10748 
10765  template <class C, class AF>
10766  String& ToSeparated( const C& c, char_type separator, AF append )
10767  {
10768  Clear();
10769  return c.ToSeparated( *this, separator, append );
10770  }
10771 
10781  template <class C>
10782  String& ToSeparated( const C& c, const String& separator )
10783  {
10784  Clear();
10785  return c.ToSeparated( *this, separator );
10786  }
10787 
10804  template <class C, class AF>
10805  String& ToSeparated( const C& c, const String& separator, AF append )
10806  {
10807  Clear();
10808  return c.ToSeparated( *this, separator, append );
10809  }
10810 
10820  template <class C>
10821  String& ToSeparated( const C& c, const_c_string separator )
10822  {
10823  return ToSeparated( c, String( separator ) );
10824  }
10825 
10842  template <class C, class AF>
10843  String& ToSeparated( const C& c, const_c_string separator, AF append )
10844  {
10845  return ToSeparated( c, String( separator ), append );
10846  }
10847 
10858  template <class C>
10859  String& ToSeparated( const C& c, const_c_string8 separator )
10860  {
10861  return ToSeparated( c, String( separator ) );
10862  }
10863 
10880  template <class C, class AF>
10881  String& ToSeparated( const C& c, const_c_string8 separator, AF append )
10882  {
10883  return ToSeparated( c, String( separator ), append );
10884  }
10885 
10895  template <class C>
10896  String& ToCommaSeparated( const C& c )
10897  {
10898  return ToSeparated( c, CharTraits::Comma() );
10899  }
10900 
10910  template <class C>
10911  String& ToColonSeparated( const C& c )
10912  {
10913  return ToSeparated( c, CharTraits::Colon() );
10914  }
10915 
10925  template <class C>
10926  String& ToSpaceSeparated( const C& c )
10927  {
10928  return ToSeparated( c, CharTraits::Blank() );
10929  }
10930 
10940  template <class C>
10941  String& ToTabSeparated( const C& c )
10942  {
10943  return ToSeparated( c, CharTraits::Tab() );
10944  }
10945 
10955  template <class C>
10957  {
10958  return ToSeparated( c, CharTraits::LF() );
10959  }
10960 
10970  template <class C>
10971  String& ToNullSeparated( const C& c )
10972  {
10973  return ToSeparated( c, CharTraits::Null() );
10974  }
10975 
10984  template <class C>
10985  String& ToHyphenated( const C& c )
10986  {
10987  return ToSeparated( c, CharTraits::Hyphen() );
10988  }
10989 
10990  // -------------------------------------------------------------------------
10991 
11007 
11015  {
11016  return String( *this ).ToEncodedHTMLSpecialChars();
11017  }
11018 
11036 
11045  {
11046  return String( *this ).ToDecodedHTMLSpecialChars();
11047  }
11048 
11049  // -------------------------------------------------------------------------
11050 
11051 #ifdef __PCL_QT_INTERFACE
11052 
11053  operator QString() const
11054  {
11055  return PCL_GET_QSTRING_FROM_CHAR16PTR( c_str() );
11056  }
11057 
11058  operator QDate() const
11059  {
11060  return QDate::fromString( operator QString(), PCL_QDATE_FMT_STR );
11061  }
11062 
11063  operator QDateTime() const
11064  {
11065  return QDateTime::fromString( operator QString(), PCL_QDATETIME_FMT_STR );
11066  }
11067 
11068 #endif
11069 
11082  {
11083  va_list paramList;
11084  va_start( paramList, fmt );
11085 
11086  (void)VFormat( fmt, paramList );
11087 
11088  va_end( paramList );
11089  return *this;
11090  }
11091 
11104  {
11105  va_list paramList;
11106  va_start( paramList, fmt );
11107 
11108  (void)AppendVFormat( fmt, paramList );
11109 
11110  va_end( paramList );
11111  return *this;
11112  }
11113 
11126  int VFormat( const_c_string8 fmt, va_list paramList )
11127  {
11128  IsoString s;
11129  int count = s.VFormat( fmt, paramList );
11130  Assign( s );
11131  return count;
11132  }
11133 
11146  int AppendVFormat( const_c_string8 fmt, va_list paramList )
11147  {
11148  IsoString s;
11149  int count = s.VFormat( fmt, paramList );
11150  Append( s );
11151  return count;
11152  }
11153 
11166  String& Format( const wchar_t* fmt, ... )
11167  {
11168  va_list paramList;
11169  va_start( paramList, fmt );
11170 
11171  (void)VFormat( fmt, paramList );
11172 
11173  va_end( paramList );
11174  return *this;
11175  }
11176 
11189  String& AppendFormat( const wchar_t* fmt, ... )
11190  {
11191  va_list paramList;
11192  va_start( paramList, fmt );
11193 
11194  (void)AppendVFormat( fmt, paramList );
11195 
11196  va_end( paramList );
11197  return *this;
11198  }
11199 
11213  int VFormat( const wchar_t* fmt, va_list paramList );
11214 
11228  int AppendVFormat( const wchar_t* fmt, va_list paramList );
11229 
11230  // -------------------------------------------------------------------------
11231 
11241  static String UTF8ToUTF16( const_c_string8 string, size_type i = 0, size_type n = maxPos );
11242 
11252  static IsoString UTF16ToUTF8( const_c_string string, size_type i = 0, size_type n = maxPos );
11253 
11263  static Array<uint32> UTF16ToUTF32( const_c_string string, size_type i = 0, size_type n = maxPos );
11264 
11274  static String UTF32ToUTF16( const uint32* string, size_type i = 0, size_type n = maxPos );
11275 
11276  // -------------------------------------------------------------------------
11277 
11288 
11299 
11307  IsoString ToUTF8( size_type i = 0, size_type n = maxPos ) const
11308  {
11309  return UTF16ToUTF8( Begin(), i, n );
11310  }
11311 
11327  IsoString ToMBS() const;
11328 
11338  {
11339 #ifdef __PCL_WINDOWS
11340  return ToMBS();
11341 #else
11342  return ToUTF8();
11343 #endif
11344  }
11345 
11366  Array<wchar_t> ToWCharArray( size_type i = 0, size_type n = maxPos ) const
11367  {
11368  if ( n > 0 )
11369  {
11370  size_type len = Length();
11371  if ( i < len )
11372  {
11373  n = pcl::Min( n, len-i );
11374  Array<wchar_t> a( n+1, wchar_t( 0 ) );
11375 #ifdef __PCL_WINDOWS
11376  char_traits::Copy( reinterpret_cast<iterator>( a.Begin() ), m_data->string+i, n );
11377 #else
11378  Array<wchar_t>::iterator w = a.Begin();
11379  for ( const_iterator s = m_data->string+i, e = s+n; s < e; ++w, ++s )
11380  *w = wchar_t( *s );
11381 #endif // __PCL_WINDOWS
11382  return a;
11383  }
11384  }
11385 
11386  return Array<wchar_t>( size_type( 1 ), wchar_t( 0 ) );
11387  }
11388 
11397  Array<uint32> ToUTF32( size_type i = 0, size_type n = maxPos ) const
11398  {
11399  return UTF16ToUTF32( Begin(), i, n );
11400  }
11401 
11402 #ifdef __PCL_QT_INTERFACE
11403 
11404  QString ToQString() const
11405  {
11406  return operator QString();
11407  }
11408 
11409  QDate ToQDate() const
11410  {
11411  return operator QDate();
11412  }
11413 
11414  QDateTime ToQDateTime() const
11415  {
11416  return operator QDateTime();
11417  }
11418 
11419 #endif
11420 
11431  bool ToBool() const;
11432 
11447  bool TryToBool( bool& value ) const noexcept;
11448 
11462  float ToFloat() const;
11463 
11478  bool TryToFloat( float& value ) const noexcept;
11479 
11503  double ToDouble() const;
11504 
11519  bool TryToDouble( double& value ) const noexcept;
11520 
11537  long ToInt() const
11538  {
11539  return ToInt( 0 );
11540  }
11541 
11565  bool TryToInt( int& value ) const noexcept
11566  {
11567  return TryToInt( value, 0 );
11568  }
11569 
11596  long ToInt( int base ) const;
11597 
11615  bool TryToInt( int& value, int base ) const noexcept;
11616 
11634  unsigned long ToUInt() const
11635  {
11636  return ToUInt( 0 );
11637  }
11638 
11662  bool TryToUInt( unsigned& value ) const noexcept
11663  {
11664  return TryToUInt( value, 0 );
11665  }
11666 
11683  unsigned long ToUInt( int base ) const;
11684 
11702  bool TryToUInt( unsigned& value, int base ) const noexcept;
11703 
11718  long long ToInt64() const
11719  {
11720  return ToInt64( 0 );
11721  }
11722 
11747  bool TryToInt64( long long& value ) const noexcept
11748  {
11749  return TryToInt64( value, 0 );
11750  }
11751 
11766  long long ToInt64( int base ) const;
11767 
11785  bool TryToInt64( long long& value, int base ) const noexcept;
11786 
11801  unsigned long long ToUInt64() const
11802  {
11803  return ToUInt64( 0 );
11804  }
11805 
11830  bool TryToUInt64( unsigned long long& value ) const noexcept
11831  {
11832  return TryToUInt64( value, 0 );
11833  }
11834 
11849  unsigned long long ToUInt64( int base ) const;
11850 
11868  bool TryToUInt64( unsigned long long& value, int base ) const noexcept;
11869 
11901  Array<float> ParseListOfFloat( char separator = ',', size_type maxCount = ~size_type( 0 ) ) const;
11902 
11934  Array<double> ParseListOfDouble( char separator = ',', size_type maxCount = ~size_type( 0 ) ) const;
11935 
11936 #ifndef __PCL_NO_STRING_VECTOR
11937 
11945  GenericVector<float> ParseListOfFloatAsVector( char separator = ',', int maxCount = int_max ) const;
11946 
11954  GenericVector<double> ParseListOfDoubleAsVector( char separator = ',', int maxCount = int_max ) const;
11955 
11956 #endif // !__PCL_NO_STRING_VECTOR
11957 
11985  double SexagesimalToDouble( const String& separator = ':' ) const
11986  {
11987  int sign, s1, s2; double s3;
11988  ParseSexagesimal( sign, s1, s2, s3, separator );
11989  return sign*(s1 + (s2 + s3/60)/60);
11990  }
11991 
12005  double SexagesimalToDouble( const Array<char_type>& separators ) const
12006  {
12007  int sign, s1, s2; double s3;
12008  ParseSexagesimal( sign, s1, s2, s3, separators );
12009  return sign*(s1 + (s2 + s3/60)/60);
12010  }
12011 
12029  bool TrySexagesimalToDouble( double& value, const String& separator = ':' ) const noexcept
12030  {
12031  int sign, s1, s2; double s3;
12032  if ( TryParseSexagesimal( sign, s1, s2, s3, separator ) )
12033  {
12034  value = sign*(s1 + (s2 + s3/60)/60);
12035  return true;
12036  }
12037  return false;
12038  }
12039 
12052  bool TrySexagesimalToDouble( double& value, const Array<char_type>& separators ) const noexcept
12053  {
12054  int sign, s1, s2; double s3;
12055  if ( TryParseSexagesimal( sign, s1, s2, s3, separators ) )
12056  {
12057  value = sign*(s1 + (s2 + s3/60)/60);
12058  return true;
12059  }
12060  return false;
12061  }
12062 
12089  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const String& separator = ':' ) const;
12090 
12105  void ParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const Array<char_type>& separators ) const;
12106 
12121  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const String& separator = ':' ) const noexcept;
12122 
12136  bool TryParseSexagesimal( int& sign, int& s1, int& s2, double& s3, const Array<char_type>& separators ) const noexcept;
12137 
12162  static String ToSexagesimal( int sign, double s1, double s2, double s3,
12164 
12175  static String ToSexagesimal( double d, const SexagesimalConversionOptions& options = SexagesimalConversionOptions() )
12176  {
12177  return ToSexagesimal( (d < 0) ? -1 : +1, Abs( d ), 0, 0, options );
12178  }
12179 
12203  void ParseISO8601DateTime( int& year, int& month, int& day, double& dayf, double& tz ) const;
12204 
12218  bool TryParseISO8601DateTime( int& year, int& month, int& day, double& dayf, double& tz ) const noexcept;
12219 
12243  static String ToISO8601DateTime( int year, int month, int day, double dayf, double tz = 0,
12245 
12257 
12269 
12276  static String Random( size_type n, RandomizationOptions options = RandomizationOption::Default );
12277 
12289  static String UUID();
12290 };
12291 
12292 // ----------------------------------------------------------------------------
12293 // ----------------------------------------------------------------------------
12294 
12296 {
12297  size_type len = uchar_traits::Length( t );
12298  if ( p < len )
12299  {
12300  m_data->Allocate( n = pcl::Min( n, len-p ) );
12301  t += p;
12302  for ( iterator i = m_data->string; i < m_data->end; ++i, ++t )
12303  *i = char_type( uint8( *t ) );
12304  }
12305 }
12306 
12308 {
12309  size_type len = uchar_traits::Length( t );
12310  if ( len > 0 )
12311  {
12312  MaybeReallocate( len );
12313  for ( iterator i = m_data->string; i < m_data->end; ++i, ++t )
12314  *i = char_type( uint8( *t ) );
12315  }
12316  else
12317  Clear();
12318 
12319  return *this;
12320 }
12321 
12323 {
12324  return String::UTF8ToUTF16( Begin(), i, n );
12325 }
12326 
12327 // ----------------------------------------------------------------------------
12328 
12338 inline String operator +( const String::string_base& s1, const String::string_base& s2 )
12339 {
12340  String s = s1;
12341  s.Append( s2 );
12342  return s;
12343 }
12344 
12350 inline String operator +( String::string_base&& s1, const String::string_base& s2 )
12351 {
12352  s1.Append( s2 );
12353  return String( std::move( s1 ) );
12354 }
12355 
12361 inline String operator +( String&& s1, const String::string_base& s2 )
12362 {
12363  s1.Append( s2 );
12364  return std::move( s1 );
12365 }
12366 
12372 inline String operator +( const String::string_base& s1, String::string_base&& s2 )
12373 {
12374  s2.Prepend( s1 );
12375  return String( std::move( s2 ) );
12376 }
12377 
12383 inline String operator +( const String::string_base& s1, String&& s2 )
12384 {
12385  s2.Prepend( s1 );
12386  return std::move( s2 );
12387 }
12388 
12394 inline String operator +( String::string_base&& s1, String::string_base&& s2 )
12395 {
12396  s1.Append( s2 );
12397  return String( std::move( s1 ) );
12398 }
12399 
12406 {
12407  s1.Append( s2 );
12408  return std::move( s1 );
12409 }
12410 
12417 {
12418  s1.Append( s2 );
12419  return String( std::move( s1 ) );
12420 }
12421 
12427 inline String operator +( String&& s1, String&& s2 )
12428 {
12429  s1.Append( s2 );
12430  return std::move( s1 );
12431 }
12432 
12433 // ----------------------------------------------------------------------------
12434 
12441 {
12442  String s = s1;
12443  s.Append( t2 );
12444  return s;
12445 }
12446 
12453 {
12454  s1.Append( t2 );
12455  return String( std::move( s1 ) );
12456 }
12457 
12464 {
12465  s1.Append( t2 );
12466  return std::move( s1 );
12467 }
12468 
12475 {
12476  String s = s2;
12477  s.Prepend( t1 );
12478  return s;
12479 }
12480 
12487 {
12488  s2.Prepend( t1 );
12489  return String( std::move( s2 ) );
12490 }
12491 
12498 {
12499  s2.Prepend( t1 );
12500  return std::move( s2 );
12501 }
12502 
12503 // ----------------------------------------------------------------------------
12504 
12510 inline String operator +( const String::string_base& s1, String::char_type c2 )
12511 {
12512  String s = s1;
12513  s.Append( c2 );
12514  return s;
12515 }
12516 
12522 inline String operator +( String::string_base&& s1, String::char_type c2 )
12523 {
12524  s1.Append( c2 );
12525  return String( std::move( s1 ) );
12526 }
12527 
12534 {
12535  s1.Append( c2 );
12536  return std::move( s1 );
12537 }
12538 
12544 inline String operator +( String::char_type c1, const String::string_base& s2 )
12545 {
12546  String s = s2;
12547  s.Prepend( c1 );
12548  return s;
12549 }
12550 
12556 inline String operator +( String::char_type c1, String::string_base&& s2 )
12557 {
12558  s2.Prepend( c1 );
12559  return String( std::move( s2 ) );
12560 }
12561 
12568 {
12569  s2.Prepend( c1 );
12570  return std::move( s2 );
12571 }
12572 
12573 // ----------------------------------------------------------------------------
12574 
12580 inline String operator +( const String::string_base& s1, const char16_t* t2 )
12581 {
12582  String s = s1;
12583  s.Append( t2 );
12584  return s;
12585 }
12586 
12592 inline String operator +( String::string_base&& s1, const char16_t* t2 )
12593 {
12594  String s = std::move( s1 );
12595  s.Append( t2 );
12596  return s;
12597 }
12598 
12604 inline String operator +( String&& s1, const char16_t* t2 )
12605 {
12606  s1.Append( t2 );
12607  return std::move( s1 );
12608 }
12609 
12615 inline String operator +( const char16_t* t1, const String::string_base& s2 )
12616 {
12617  String s = s2;
12618  s.Prepend( t1 );
12619  return s;
12620 }
12621 
12627 inline String operator +( const char16_t* t1, String::string_base&& s2 )
12628 {
12629  String s = std::move( s2 );
12630  s.Prepend( t1 );
12631  return s;
12632 }
12633 
12639 inline String operator +( const char16_t* t1, String&& s2 )
12640 {
12641  s2.Prepend( t1 );
12642  return std::move( s2 );
12643 }
12644 
12645 // ----------------------------------------------------------------------------
12646 
12652 inline String operator +( const String::string_base& s1, char16_t c2 )
12653 {
12654  String s = s1;
12655  s.Append( c2 );
12656  return s;
12657 }
12658 
12664 inline String operator +( String::string_base&& s1, char16_t c2 )
12665 {
12666  String s = std::move( s1 );
12667  s.Append( c2 );
12668  return s;
12669 }
12670 
12676 inline String operator +( String&& s1, char16_t c2 )
12677 {
12678  s1.Append( c2 );
12679  return std::move( s1 );
12680 }
12681 
12687 inline String operator +( char16_t c1, const String::string_base& s2 )
12688 {
12689  String s = s2;
12690  s.Prepend( c1 );
12691  return s;
12692 }
12693 
12699 inline String operator +( char16_t c1, String::string_base&& s2 )
12700 {
12701  String s = std::move( s2 );
12702  s.Prepend( c1 );
12703  return s;
12704 }
12705 
12711 inline String operator +( char16_t c1, String&& s2 )
12712 {
12713  s2.Prepend( c1 );
12714  return std::move( s2 );
12715 }
12716 
12717 // ----------------------------------------------------------------------------
12718 
12724 inline String operator +( const String::string_base& s1, const wchar_t* t2 )
12725 {
12726  String s = s1;
12727  s.Append( t2 );
12728  return s;
12729 }
12730 
12736 inline String operator +( String::string_base&& s1, const wchar_t* t2 )
12737 {
12738  String s = std::move( s1 );
12739  s.Append( t2 );
12740  return s;
12741 }
12742 
12748 inline String operator +( String&& s1, const wchar_t* t2 )
12749 {
12750  s1.Append( t2 );
12751  return std::move( s1 );
12752 }
12753 
12759 inline String operator +( const wchar_t* t1, const String::string_base& s2 )
12760 {
12761  String s = s2;
12762  s.Prepend( t1 );
12763  return s;
12764 }
12765 
12771 inline String operator +( const wchar_t* t1, String::string_base&& s2 )
12772 {
12773  String s = std::move( s2 );
12774  s.Prepend( t1 );
12775  return s;
12776 }
12777 
12783 inline String operator +( const wchar_t* t1, String&& s2 )
12784 {
12785  s2.Prepend( t1 );
12786  return std::move( s2 );
12787 }
12788 
12789 // ----------------------------------------------------------------------------
12790 
12796 inline String operator +( const String::string_base& s1, wchar_t c2 )
12797 {
12798  String s = s1;
12799  s.Append( c2 );
12800  return s;
12801 }
12802 
12808 inline String operator +( String::string_base&& s1, wchar_t c2 )
12809 {
12810  String s = std::move( s1 );
12811  s.Append( c2 );
12812  return s;
12813 }
12814 
12820 inline String operator +( String&& s1, wchar_t c2 )
12821 {
12822  s1.Append( c2 );
12823  return std::move( s1 );
12824 }
12825 
12831 inline String operator +( wchar_t c1, const String::string_base& s2 )
12832 {
12833  String s = s2;
12834  s.Prepend( c1 );
12835  return s;
12836 }
12837 
12843 inline String operator +( wchar_t c1, String::string_base&& s2 )
12844 {
12845  String s = std::move( s2 );
12846  s.Prepend( c1 );
12847  return s;
12848 }
12849 
12855 inline String operator +( wchar_t c1, String&& s2 )
12856 {
12857  s2.Prepend( c1 );
12858  return std::move( s2 );
12859 }
12860 
12861 // ----------------------------------------------------------------------------
12862 
12869 {
12870  String s = s1;
12871  s.Append( s2 );
12872  return s;
12873 }
12874 
12881 {
12882  String s = std::move( s1 );
12883  s.Append( s2 );
12884  return s;
12885 }
12886 
12893 {
12894  s1.Append( s2 );
12895  return std::move( s1 );
12896 }
12897 
12904 {
12905  String s = s2;
12906  s.Prepend( s1 );
12907  return s;
12908 }
12909 
12916 {
12917  String s = std::move( s2 );
12918  s.Prepend( s1 );
12919  return s;
12920 }
12921 
12928 {
12929  s2.Prepend( s1 );
12930  return std::move( s2 );
12931 }
12932 
12933 // ----------------------------------------------------------------------------
12934 
12941 {
12942  String s = s1;
12943  s.Append( t2 );
12944  return s;
12945 }
12946 
12953 {
12954  String s = std::move( s1 );
12955  s.Append( t2 );
12956  return s;
12957 }
12958 
12965 {
12966  s1.Append( t2 );
12967  return std::move( s1 );
12968 }
12969 
12976 {
12977  String s = s2;
12978  s.Prepend( t1 );
12979  return s;
12980 }
12981 
12988 {
12989  String s = std::move( s2 );
12990  s.Prepend( t1 );
12991  return s;
12992 }
12993 
13000 {
13001  s2.Prepend( t1 );
13002  return std::move( s2 );
13003 }
13004 
13005 // ----------------------------------------------------------------------------
13006 
13013 {
13014  String s = s1;
13015  s.Append( c2 );
13016  return s;
13017 }
13018 
13025 {
13026  s1.Append( String::char_type( c2 ) );
13027  return String( std::move( s1 ) );
13028 }
13029 
13036 {
13037  s1.Append( c2 );
13038  return std::move( s1 );
13039 }
13040 
13047 {
13048  String s = s2;
13049  s.Prepend( c1 );
13050  return s;
13051 }
13052 
13059 {
13060  s2.Prepend( String::char_type( c1 ) );
13061  return String( std::move( s2 ) );
13062 }
13063 
13070 {
13071  s2.Prepend( c1 );
13072  return std::move( s2 );
13073 }
13074 
13075 // ----------------------------------------------------------------------------
13076 
13083 {
13084  s1.Append( s2 );
13085  return s1;
13086 }
13087 
13093 inline String& operator <<( String&& s1, const String::string_base& s2 )
13094 {
13095  s1.Append( s2 );
13096  return s1;
13097 }
13098 
13105 {
13106  s1.Append( t2 );
13107  return s1;
13108 }
13109 
13116 {
13117  s1.Append( t2 );
13118  return s1;
13119 }
13120 
13127 {
13128  s1.Append( c2 );
13129  return s1;
13130 }
13131 
13138 {
13139  s1.Append( c2 );
13140  return s1;
13141 }
13142 
13148 inline String& operator <<( String& s1, const char16_t* t2 )
13149 {
13150  s1.Append( t2 );
13151  return s1;
13152 }
13153 
13159 inline String& operator <<( String&& s1, const char16_t* t2 )
13160 {
13161  s1.Append( t2 );
13162  return s1;
13163 }
13164 
13170 inline String& operator <<( String& s1, char16_t c2 )
13171 {
13172  s1.Append( c2 );
13173  return s1;
13174 }
13175 
13181 inline String& operator <<( String&& s1, char16_t c2 )
13182 {
13183  s1.Append( c2 );
13184  return s1;
13185 }
13186 
13192 inline String& operator <<( String& s1, const wchar_t* t2 )
13193 {
13194  s1.Append( t2 );
13195  return s1;
13196 }
13197 
13203 inline String& operator <<( String&& s1, const wchar_t* t2 )
13204 {
13205  s1.Append( t2 );
13206  return s1;
13207 }
13208 
13214 inline String& operator <<( String& s1, wchar_t c2 )
13215 {
13216  s1.Append( c2 );
13217  return s1;
13218 }
13219 
13225 inline String& operator <<( String&& s1, wchar_t c2 )
13226 {
13227  s1.Append( c2 );
13228  return s1;
13229 }
13230 
13237 {
13238  s1.Append( s2 );
13239  return s1;
13240 }
13241 
13247 inline String& operator <<( String&& s1, const String::string8_base& s2 )
13248 {
13249  s1.Append( s2 );
13250  return s1;
13251 }
13252 
13259 {
13260  s1.Append( t2 );
13261  return s1;
13262 }
13263 
13270 {
13271  s1.Append( t2 );
13272  return s1;
13273 }
13274 
13281 {
13282  s1.Append( c2 );
13283  return s1;
13284 }
13285 
13292 {
13293  s1.Append( c2 );
13294  return s1;
13295 }
13296 
13297 // ----------------------------------------------------------------------------
13298 
13307 inline bool operator ==( const String& s1, const char16_t* t2 ) noexcept
13308 {
13309  return s1.CompareCodePoints( t2 ) == 0;
13310 }
13311 
13318 inline bool operator <( const String& s1, const char16_t* t2 ) noexcept
13319 {
13320  return s1.CompareCodePoints( t2 ) < 0;
13321 }
13322 
13329 inline bool operator <=( const String& s1, const char16_t* t2 ) noexcept
13330 {
13331  return s1.CompareCodePoints( t2 ) <= 0;
13332 }
13333 
13340 inline bool operator >( const String& s1, const char16_t* t2 ) noexcept
13341 {
13342  return s1.CompareCodePoints( t2 ) > 0;
13343 }
13344 
13351 inline bool operator >=( const String& s1, const char16_t* t2 ) noexcept
13352 {
13353  return s1.CompareCodePoints( t2 ) >= 0;
13354 }
13355 
13356 // ----------------------------------------------------------------------------
13357 
13362 inline bool operator ==( const char16_t* t1, const String& s2 ) noexcept
13363 {
13364  return s2.CompareCodePoints( t1 ) == 0;
13365 }
13366 
13373 inline bool operator <( const char16_t* t1, const String& s2 ) noexcept
13374 {
13375  return s2.CompareCodePoints( t1 ) > 0;
13376 }
13377 
13384 inline bool operator <=( const char16_t* t1, const String& s2 ) noexcept
13385 {
13386  return s2.CompareCodePoints( t1 ) >= 0;
13387 }
13388 
13395 inline bool operator >( const char16_t* t1, const String& s2 ) noexcept
13396 {
13397  return s2.CompareCodePoints( t1 ) < 0;
13398 }
13399 
13406 inline bool operator >=( const char16_t* t1, const String& s2 ) noexcept
13407 {
13408  return s2.CompareCodePoints( t1 ) <= 0;
13409 }
13410 
13411 // ----------------------------------------------------------------------------
13412 
13417 inline bool operator ==( const String& s1, char16_t c2 ) noexcept
13418 {
13419  return s1.CompareCodePoints( c2 ) == 0;
13420 }
13421 
13428 inline bool operator <( const String& s1, char16_t c2 ) noexcept
13429 {
13430  return s1.CompareCodePoints( c2 ) < 0;
13431 }
13432 
13439 inline bool operator <=( const String& s1, char16_t c2 ) noexcept
13440 {
13441  return s1.CompareCodePoints( c2 ) <= 0;
13442 }
13443 
13450 inline bool operator >( const String& s1, char16_t c2 ) noexcept
13451 {
13452  return s1.CompareCodePoints( c2 ) > 0;
13453 }
13454 
13461 inline bool operator >=( const String& s1, char16_t c2 ) noexcept
13462 {
13463  return s1.CompareCodePoints( c2 ) >= 0;
13464 }
13465 
13466 // ----------------------------------------------------------------------------
13467 
13472 inline bool operator ==( char16_t c1, const String& s2 ) noexcept
13473 {
13474  return s2.CompareCodePoints( c1 ) == 0;
13475 }
13476 
13483 inline bool operator <( char16_t c1, const String& s2 ) noexcept
13484 {
13485  return s2.CompareCodePoints( c1 ) > 0;
13486 }
13487 
13494 inline bool operator <=( char16_t c1, const String& s2 ) noexcept
13495 {
13496  return s2.CompareCodePoints( c1 ) >= 0;
13497 }
13498 
13505 inline bool operator >( char16_t c1, const String& s2 ) noexcept
13506 {
13507  return s2.CompareCodePoints( c1 ) < 0;
13508 }
13509 
13516 inline bool operator >=( char16_t c1, const String& s2 ) noexcept
13517 {
13518  return s2.CompareCodePoints( c1 ) <= 0;
13519 }
13520 
13521 // ----------------------------------------------------------------------------
13522 
13527 inline bool operator ==( const String& s1, const wchar_t* t2 ) noexcept
13528 {
13529  return s1.CompareCodePoints( t2 ) == 0;
13530 }
13531 
13538 inline bool operator <( const String& s1, const wchar_t* t2 ) noexcept
13539 {
13540  return s1.CompareCodePoints( t2 ) < 0;
13541 }
13542 
13549 inline bool operator <=( const String& s1, const wchar_t* t2 ) noexcept
13550 {
13551  return s1.CompareCodePoints( t2 ) <= 0;
13552 }
13553 
13560 inline bool operator >( const String& s1, const wchar_t* t2 ) noexcept
13561 {
13562  return s1.CompareCodePoints( t2 ) > 0;
13563 }
13564 
13571 inline bool operator >=( const String& s1, const wchar_t* t2 ) noexcept
13572 {
13573  return s1.CompareCodePoints( t2 ) >= 0;
13574 }
13575 
13576 // ----------------------------------------------------------------------------
13577 
13582 inline bool operator ==( const wchar_t* t1, const String& s2 ) noexcept
13583 {
13584  return s2.CompareCodePoints( t1 ) == 0;
13585 }
13586 
13593 inline bool operator <( const wchar_t* t1, const String& s2 ) noexcept
13594 {
13595  return s2.CompareCodePoints( t1 ) > 0;
13596 }
13597 
13604 inline bool operator <=( const wchar_t* t1, const String& s2 ) noexcept
13605 {
13606  return s2.CompareCodePoints( t1 ) >= 0;
13607 }
13608 
13615 inline bool operator >( const wchar_t* t1, const String& s2 ) noexcept
13616 {
13617  return s2.CompareCodePoints( t1 ) < 0;
13618 }
13619 
13626 inline bool operator >=( const wchar_t* t1, const String& s2 ) noexcept
13627 {
13628  return s2.CompareCodePoints( t1 ) <= 0;
13629 }
13630 
13631 // ----------------------------------------------------------------------------
13632 
13637 inline bool operator ==( const String& s1, wchar_t c2 ) noexcept
13638 {
13639  return s1.CompareCodePoints( c2 ) == 0;
13640 }
13641 
13648 inline bool operator <( const String& s1, wchar_t c2 ) noexcept
13649 {
13650  return s1.CompareCodePoints( c2 ) < 0;
13651 }
13652 
13659 inline bool operator <=( const String& s1, wchar_t c2 ) noexcept
13660 {
13661  return s1.CompareCodePoints( c2 ) <= 0;
13662 }
13663 
13670 inline bool operator >( const String& s1, wchar_t c2 ) noexcept
13671 {
13672  return s1.CompareCodePoints( c2 ) > 0;
13673 }
13674 
13681 inline bool operator >=( const String& s1, wchar_t c2 ) noexcept
13682 {
13683  return s1.CompareCodePoints( c2 ) >= 0;
13684 }
13685 
13686 // ----------------------------------------------------------------------------
13687 
13692 inline bool operator ==( wchar_t c1, const String& s2 ) noexcept
13693 {
13694  return s2.CompareCodePoints( c1 ) == 0;
13695 }
13696 
13703 inline bool operator <( wchar_t c1, const String& s2 ) noexcept
13704 {
13705  return s2.CompareCodePoints( c1 ) > 0;
13706 }
13707 
13714 inline bool operator <=( wchar_t c1, const String& s2 ) noexcept
13715 {
13716  return s2.CompareCodePoints( c1 ) >= 0;
13717 }
13718 
13725 inline bool operator >( wchar_t c1, const String& s2 ) noexcept
13726 {
13727  return s2.CompareCodePoints( c1 ) < 0;
13728 }
13729 
13736 inline bool operator >=( wchar_t c1, const String& s2 ) noexcept
13737 {
13738  return s2.CompareCodePoints( c1 ) <= 0;
13739 }
13740 
13741 // ----------------------------------------------------------------------------
13742 
13747 inline bool operator ==( const String& s1, String::const_c_string8 t2 ) noexcept
13748 {
13749  return s1.CompareCodePoints( t2 ) == 0;
13750 }
13751 
13758 inline bool operator <( const String& s1, String::const_c_string8 t2 ) noexcept
13759 {
13760  return s1.CompareCodePoints( t2 ) < 0;
13761 }
13762 
13769 inline bool operator <=( const String& s1, String::const_c_string8 t2 ) noexcept
13770 {
13771  return s1.CompareCodePoints( t2 ) <= 0;
13772 }
13773 
13780 inline bool operator >( const String& s1, String::const_c_string8 t2 ) noexcept
13781 {
13782  return s1.CompareCodePoints( t2 ) > 0;
13783 }
13784 
13791 inline bool operator >=( const String& s1, String::const_c_string8 t2 ) noexcept
13792 {
13793  return s1.CompareCodePoints( t2 ) >= 0;
13794 }
13795 
13796 // ----------------------------------------------------------------------------
13797 
13802 inline bool operator ==( String::const_c_string8 t1, const String& s2 ) noexcept
13803 {
13804  return s2.CompareCodePoints( t1 ) == 0;
13805 }
13806 
13813 inline bool operator <( String::const_c_string8 t1, const String& s2 ) noexcept
13814 {
13815  return s2.CompareCodePoints( t1 ) > 0;
13816 }
13817 
13824 inline bool operator <=( String::const_c_string8 t1, const String& s2 ) noexcept
13825 {
13826  return s2.CompareCodePoints( t1 ) >= 0;
13827 }
13828 
13835 inline bool operator >( String::const_c_string8 t1, const String& s2 ) noexcept
13836 {
13837  return s2.CompareCodePoints( t1 ) < 0;
13838 }
13839 
13846 inline bool operator >=( String::const_c_string8 t1, const String& s2 ) noexcept
13847 {
13848  return s2.CompareCodePoints( t1 ) <= 0;
13849 }
13850 
13851 // ----------------------------------------------------------------------------
13852 
13857 inline bool operator ==( const String& s1, String::char8_type c2 ) noexcept
13858 {
13859  return s1.CompareCodePoints( c2 ) == 0;
13860 }
13861 
13868 inline bool operator <( const String& s1, String::char8_type c2 ) noexcept
13869 {
13870  return s1.CompareCodePoints( c2 ) < 0;
13871 }
13872 
13879 inline bool operator <=( const String& s1, String::char8_type c2 ) noexcept
13880 {
13881  return s1.CompareCodePoints( c2 ) <= 0;
13882 }
13883 
13890 inline bool operator >( const String& s1, String::char8_type c2 ) noexcept
13891 {
13892  return s1.CompareCodePoints( c2 ) > 0;
13893 }
13894 
13901 inline bool operator >=( const String& s1, String::char8_type c2 ) noexcept
13902 {
13903  return s1.CompareCodePoints( c2 ) >= 0;
13904 }
13905 
13906 // ----------------------------------------------------------------------------
13907 
13912 inline bool operator ==( String::char8_type c1, const String& s2 ) noexcept
13913 {
13914  return s2.CompareCodePoints( c1 ) == 0;
13915 }
13916 
13923 inline bool operator <( String::char8_type c1, const String& s2 ) noexcept
13924 {
13925  return s2.CompareCodePoints( c1 ) > 0;
13926 }
13927 
13934 inline bool operator <=( String::char8_type c1, const String& s2 ) noexcept
13935 {
13936  return s2.CompareCodePoints( c1 ) >= 0;
13937 }
13938 
13945 inline bool operator >( String::char8_type c1, const String& s2 ) noexcept
13946 {
13947  return s2.CompareCodePoints( c1 ) < 0;
13948 }
13949 
13956 inline bool operator >=( String::char8_type c1, const String& s2 ) noexcept
13957 {
13958  return s2.CompareCodePoints( c1 ) <= 0;
13959 }
13960 
13961 // ----------------------------------------------------------------------------
13962 
13963 #ifndef __PCL_NO_STRING_OSTREAM
13964 
13965 inline std::wostream& operator <<( std::wostream& o, const String& s )
13966 {
13967 #ifdef __PCL_WINDOWS
13968  return o << reinterpret_cast<const wchar_t*>( s.c_str() );
13969 #else
13970  Array<wchar_t> w = s.ToWCharArray();
13971  return o << w.Begin();
13972 #endif
13973 }
13974 
13975 inline std::ostream& operator <<( std::ostream& o, const String& s )
13976 {
13977  return o << s.ToUTF8();
13978 }
13979 
13980 #endif // __PCL_NO_STRING_OSTREAM
13981 
13982 // ----------------------------------------------------------------------------
13983 
13984 } // pcl
13985 
13986 #endif // __PCL_String_h
13987 
13988 // ----------------------------------------------------------------------------
13989 // EOF pcl/String.h - Released 2024-06-18T15:48:54Z
Provides memory allocation for PCL containers.
Definition: Allocator.h:132
Generic dynamic array.
Definition: Array.h:100
bool IsEmpty() const noexcept
Definition: Array.h:312
T * iterator
Definition: Array.h:113
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
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:3040
iterator begin()
Definition: String.h:1113
void Append(const_c_string t)
Definition: String.h:1788
int CompareIC(const_c_string t, bool localeAware=true) const noexcept
Definition: String.h:3846
void JustifyCenter(size_type width, char_type fill=R::Blank())
Definition: String.h:3559
int CompareCodePoints(const GenericString< T, R1, A1 > &s, bool caseSensitive=true) const noexcept
Definition: String.h:3634
static size_type DeleteFreeList()
Definition: String.h:4266
iterator end()
Definition: String.h:1129
void Transfer(GenericString &s)
Definition: String.h:1212
bool WildMatch(const GenericString< T, R1, A1 > &pattern, bool caseSensitive=true) const noexcept
Definition: String.h:3896
bool ContainsIC(const_c_string t) const noexcept
Definition: String.h:3261
void ToUppercase()
Definition: String.h:4003
size_type FindFirst(const_c_string t, size_type i=0) const noexcept
Definition: String.h:2996
reverse_iterator ReverseBegin()
Definition: String.h:1038
const_iterator begin() const noexcept
Definition: String.h:1121
size_type Find(const GenericString< T, R1, A1 > &s, size_type i=0) const noexcept
Definition: String.h:3068
void ReplaceString(const GenericString< T, R1, A1 > &s1, const GenericString< T, R2, A2 > &s2, size_type i=0)
Definition: String.h:2083
bool StartsWith(const_c_string t) const noexcept
Definition: String.h:2842
void Insert(size_type i, const_c_string t, size_type n)
Definition: String.h:1723
const T * const_c_string
Definition: String.h:524
void JustifyRight(size_type width, char_type fill=R::Blank())
Definition: String.h:3540
void Fill(char_type c)
Definition: String.h:1380
void ReplaceChar(char_type c1, char_type c2, size_type i=0, size_type n=maxPos)
Definition: String.h:2060
bool StartsWithIC(char_type c) const noexcept
Definition: String.h:2895
void Add(const_c_string t, size_type n)
Definition: String.h:1834
void Swap(GenericString &s) noexcept
Definition: String.h:1366
void Insert(size_type i, char_type c, size_type n=1)
Definition: String.h:1735
GenericString ResizedToNullTerminated() const
Definition: String.h:1560
size_type BreakIC(C &list, char_type c, bool trim=false, size_type i=0) const
Definition: String.h:2763
GenericString SetToLength(size_type n) const
Definition: String.h:1535
void TrimRight()
Definition: String.h:3319
iterator At(size_type i)
Definition: String.h:887
void DeleteLeft(size_type i)
Definition: String.h:2176
void EnsureDoubleQuoted()
Definition: String.h:3449
bool EndsWithIC(char_type c) const noexcept
Definition: String.h:2973
void c_copy(iterator dst, size_type maxCharsToCopy, size_type i=0) const noexcept
Definition: String.h:1654
GenericString Left(size_type n) const
Definition: String.h:2300
void Prepend(const GenericString< T, R1, A1 > &s)
Definition: String.h:1872
size_type FindIC(const_c_string t, size_type i=0) const noexcept
Definition: String.h:3101
GenericString(char_type c, size_type n=1)
Definition: String.h:663
void Assign(const_iterator i, const_iterator j)
Definition: String.h:1299
char_type LastChar() const noexcept
Definition: String.h:2819
size_type FindLast(const_c_string t, size_type r=maxPos) const noexcept
Definition: String.h:3140
size_type FindIC(const GenericString< T, R1, A1 > &s, size_type i=0) const noexcept
Definition: String.h:3093
void Assign(const_c_string t, size_type i, size_type n)
Definition: String.h:1335
GenericString(const_iterator i, const_iterator j)
Definition: String.h:619
void Assign(const GenericString &s, size_type i, size_type n)
Definition: String.h:1255
void EnsureUnique()
Definition: String.h:718
GenericString Enclosed(char_type c) const
Definition: String.h:3412
GenericString Suffix(size_type i) const
Definition: String.h:2346
void Insert(size_type i, const_iterator p, const_iterator q)
Definition: String.h:1695
void EnsureEnclosed(char_type c)
Definition: String.h:3368
reverse_iterator ReverseEnd()
Definition: String.h:1072
void ToCaseFolded()
Definition: String.h:3975
size_type FindLast(const GenericString< T, R1, A1 > &s, size_type r=maxPos) const noexcept
Definition: String.h:3124
const_iterator end() const noexcept
Definition: String.h:1137
GenericString Lowercase() const
Definition: String.h:4028
bool Contains(const GenericString< T, R1, A1 > &s) const noexcept
Definition: String.h:3222
size_type FindFirst(char_type c, size_type i=0) const noexcept
Definition: String.h:3008
GenericString(std::initializer_list< char_type > l)
Definition: String.h:639
void Assign(std::initializer_list< char_type > l)
Definition: String.h:1317
void Insert(size_type i, const_c_string t)
Definition: String.h:1709
void Add(char_type c, size_type n=1)
Definition: String.h:1852
GenericString TrimmedRight() const
Definition: String.h:3355
void Reserve(size_type n)
Definition: String.h:1462
GenericString Unquoted() const
Definition: String.h:3504
bool StartsWith(char_type c) const noexcept
Definition: String.h:2856
uint64 Hash64(uint64 seed=0) const noexcept
Definition: String.h:4232
void Assign(const GenericString &s)
Definition: String.h:1181
void ReplaceStringIC(const GenericString< T, R1, A1 > &s1, const GenericString< T, R2, A2 > &s2, size_type i=0)
Definition: String.h:2107
bool StartsWithIC(const GenericString< T, R1, A1 > &s) const noexcept
Definition: String.h:2866
GenericString Uppercase() const
Definition: String.h:4039
bool ContainsIC(const GenericString< T, R1, A1 > &s) const noexcept
Definition: String.h:3250
size_type FindLast(char_type c, size_type r=maxPos) const noexcept
Definition: String.h:3152
GenericString SingleQuoted() const
Definition: String.h:3436
char_type FirstChar() const noexcept
Definition: String.h:2810
void Append(const_c_string t, size_type n)
Definition: String.h:1780
void Assign(const_c_string t)
Definition: String.h:1267
GenericString Trimmed() const
Definition: String.h:3331
void Prepend(const_c_string t)
Definition: String.h:1913
GenericString Sorted() const
Definition: String.h:4087
size_type IndexAt(const_iterator i) const noexcept
Definition: String.h:1103
GenericString LeftJustified(size_type width, char_type fill=R::Blank()) const
Definition: String.h:3577
size_type FindIC(char_type c, size_type i=0) const noexcept
Definition: String.h:3109
static size_type BytesPerChar() noexcept
Definition: String.h:738
void Replace(size_type i, size_type n, const GenericString< T, R1, A1 > &s)
Definition: String.h:1951
void DeleteCharIC(char_type c, size_type i=0)
Definition: String.h:2198
GenericString Right(size_type n) const
Definition: String.h:2322
bool IsValid() const noexcept
Definition: String.h:806
GenericString RightJustified(size_type width, char_type fill=R::Blank()) const
Definition: String.h:3590
bool WildMatch(const_c_string pattern, bool caseSensitive=true) const noexcept
Definition: String.h:3935
size_type Break(C &list, char_type c, bool trim=false, size_type i=0) const
Definition: String.h:2500
int Compare(const GenericString< T, R1, A1 > &s, bool caseSensitive=true, bool localeAware=true) const noexcept
Definition: String.h:3727
void ToLowercase()
Definition: String.h:3989
bool StartsWith(const GenericString< T, R1, A1 > &s) const noexcept
Definition: String.h:2828
size_type UpperBound() const noexcept
Definition: String.h:844
GenericString Prefix(size_type i) const
Definition: String.h:2357
const_reverse_iterator ReverseBegin() const noexcept
Definition: String.h:1054
int CompareCodePoints(const_c_string t, bool caseSensitive=true) const noexcept
Definition: String.h:3663
int CompareIC(char_type c, bool localeAware=true) const noexcept
Definition: String.h:3875
GenericString(const GenericString &s)
Definition: String.h:571
bool EndsWithIC(const GenericString< T, R1, A1 > &s) const noexcept
Definition: String.h:2943
bool IsEmpty() const noexcept
Definition: String.h:818
bool HasWildcards() const noexcept
Definition: String.h:3963
bool IsValidIdentifier() const noexcept
Definition: String.h:4211
const allocator & Allocator() const noexcept
Definition: String.h:855
void DeleteRight(size_type i)
Definition: String.h:2167
bool StartsWithIC(const_c_string t) const noexcept
Definition: String.h:2880
int CompareCodePoints(char_type c, bool caseSensitive=true) const noexcept
Definition: String.h:3695
GenericString CenterJustified(size_type width, char_type fill=R::Blank()) const
Definition: String.h:3603
void Add(const_c_string t)
Definition: String.h:1843
void Append(const_iterator i, const_iterator j)
Definition: String.h:1771
void DeleteString(const GenericString< T, R1, A1 > &s, size_type i=0)
Definition: String.h:2209
void Fill(char_type c, size_type i, size_type n=maxPos)
Definition: String.h:1409
void Replace(size_type i, size_type n, const_c_string t)
Definition: String.h:1990
iterator Begin()
Definition: String.h:976
void SetLength(size_type n)
Definition: String.h:1505
bool WildMatchIC(const GenericString< T, R1, A1 > &pattern) const noexcept
Definition: String.h:3915
size_type FindFirstIC(char_type c, size_type i=0) const noexcept
Definition: String.h:3055
GenericString(const_c_string t, size_type i, size_type n)
Definition: String.h:648
bool IsAliasOf(const GenericString &s) const noexcept
Definition: String.h:704
bool IsNumeral() const noexcept
Definition: String.h:4135
void Prepend(const_iterator i, const_iterator j)
Definition: String.h:1895
GenericString Sorted(BP p) const
Definition: String.h:4114
void DeleteStringIC(const_c_string t, size_type i=0)
Definition: String.h:2244
void Prepend(char_type c, size_type n=1)
Definition: String.h:1931
bool IsSymbol() const noexcept
Definition: String.h:4157
bool EndsWith(char_type c) const noexcept
Definition: String.h:2933
void SecureFill(char c='\0') noexcept
Definition: String.h:1448
size_type Break(C &list, const Array< S > &ca, bool trim=false, size_type i=0) const
Definition: String.h:2565
bool Contains(char_type c) const noexcept
Definition: String.h:3238
GenericString Reversed() const
Definition: String.h:4064
void DeleteString(const_c_string t, size_type i=0)
Definition: String.h:2219
bool WildMatchIC(const_c_string pattern) const noexcept
Definition: String.h:3954
uint32 Hash32(uint32 seed=0) const noexcept
Definition: String.h:4245
uint64 Hash(uint64 seed=0) const noexcept
Definition: String.h:4254
size_type FindLastIC(char_type c, size_type r=maxPos) const noexcept
Definition: String.h:3208
void Delete(size_type i, size_type n=1)
Definition: String.h:2129
size_type FindFirstIC(const GenericString< T, R1, A1 > &s, size_type i=0) const noexcept
Definition: String.h:3025
size_type Size() const noexcept
Definition: String.h:749
void DeleteChar(char_type c, size_type i=0)
Definition: String.h:2186
void DeleteStringIC(const GenericString< T, R1, A1 > &s, size_type i=0)
Definition: String.h:2232
int CompareIC(const GenericString< T, R1, A1 > &s, bool localeAware=true) const noexcept
Definition: String.h:3820
GenericString(const_c_string t)
Definition: String.h:590
int Compare(const_c_string t, bool caseSensitive=true, bool localeAware=true) const noexcept
Definition: String.h:3760
const_iterator End() const noexcept
Definition: String.h:1020
size_type Break(C &list, const GenericString< T, R1, A1 > &s, bool trim=false, size_type i=0) const
Definition: String.h:2380
void JustifyLeft(size_type width, char_type fill=R::Blank())
Definition: String.h:3522
void ResizeToNullTerminated()
Definition: String.h:1551
void Add(const GenericString< T, R1, A1 > &s)
Definition: String.h:1816
size_type Find(const_c_string t, size_type i=0) const noexcept
Definition: String.h:3076
size_type LowerBound() const noexcept
Definition: String.h:831
void Append(const GenericString< T, R1, A1 > &s)
Definition: String.h:1748
void Replace(size_type i, size_type n, char_type c, size_type nc=1)
Definition: String.h:2025
bool Contains(const_c_string t) const noexcept
Definition: String.h:3230
void ReplaceString(const_c_string t1, const_c_string t2, size_type i=0)
Definition: String.h:2094
void ReplaceStringIC(const_c_string t1, const_c_string t2, size_type i=0)
Definition: String.h:2120
void SetAllocator(const allocator &a)
Definition: String.h:869
size_type FindFirst(const GenericString< T, R1, A1 > &s, size_type i=0) const noexcept
Definition: String.h:2984
size_type Capacity() const noexcept
Definition: String.h:773
iterator End()
Definition: String.h:1006
const T * const_iterator
Definition: String.h:534
size_type Available() const noexcept
Definition: String.h:785
void Prepend(const_c_string t, size_type n)
Definition: String.h:1904
void Sort(BP p)
Definition: String.h:4100
void ReplaceCharIC(char_type c1, char_type c2, size_type i=0, size_type n=maxPos)
Definition: String.h:2072
void EnsureSingleQuoted()
Definition: String.h:3425
bool ContainsIC(char_type c) const noexcept
Definition: String.h:3272
size_type BreakIC(C &list, const GenericString< T, R1, A1 > &s, bool trim=false, size_type i=0) const
Definition: String.h:2632
bool EndsWithIC(const_c_string t) const noexcept
Definition: String.h:2958
size_type Find(char_type c, size_type i=0) const noexcept
Definition: String.h:3084
size_type Break(C &list, const_c_string s, bool trim=false, size_type i=0) const
Definition: String.h:2440
void Transfer(GenericString &&s)
Definition: String.h:1224
GenericString DoubleQuoted() const
Definition: String.h:3460
size_type FindLastIC(const GenericString< T, R1, A1 > &s, size_type r=maxPos) const noexcept
Definition: String.h:3174
void Append(char_type c, size_type n=1)
Definition: String.h:1806
void Add(const_iterator i, const_iterator j)
Definition: String.h:1825
const_iterator Begin() const noexcept
Definition: String.h:990
bool EndsWith(const_c_string t) const noexcept
Definition: String.h:2919
bool IsUnique() const noexcept
Definition: String.h:692
void Insert(size_type i, const GenericString< T, R1, A1 > &s)
Definition: String.h:1678
const_iterator At(size_type i) const noexcept
Definition: String.h:903
void Assign(char_type c, size_type n=1)
Definition: String.h:1352
GenericString CaseFolded() const
Definition: String.h:4017
c_string Release()
Definition: String.h:1630
GenericString Squeezed() const
Definition: String.h:1610
int Compare(char_type c, bool caseSensitive=true, bool localeAware=true) const noexcept
Definition: String.h:3794
const_c_string c_str() const noexcept
Definition: String.h:1150
GenericString Substring(size_type i, size_type n=maxPos) const
Definition: String.h:2275
const_reverse_iterator ReverseEnd() const noexcept
Definition: String.h:1088
GenericString TrimmedLeft() const
Definition: String.h:3343
size_type FindLastIC(const_c_string t, size_type r=maxPos) const noexcept
Definition: String.h:3193
size_type Length() const noexcept
Definition: String.h:760
bool IsValidIdentifier(distance_type &pos) const noexcept
Definition: String.h:4180
bool EndsWith(const GenericString< T, R1, A1 > &s) const noexcept
Definition: String.h:2904
GenericString(GenericString &&s)
Definition: String.h:580
size_type BreakIC(C &list, const_c_string s, bool trim=false, size_type i=0) const
Definition: String.h:2698
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:5425
IsoString(const ustring_base &s)
Definition: String.h:5563
IsoString(Complex< float > &x)
Definition: String.h:5785
IsoString EncodedHTMLSpecialChars() const
Definition: String.h:6351
IsoString()=default
IsoString(std::initializer_list< char_type > l)
Definition: String.h:5610
string_base::const_iterator const_iterator
Definition: String.h:5471
GenericVector< double > ParseListOfDoubleAsVector(char separator=',', int maxCount=int_max) const
IsoString(const ByteArray &B)
Definition: String.h:5650
bool TryToInt(int &value, int base) const noexcept
IsoString & ToSeparated(const C &c, char_type separator)
Definition: String.h:6118
static IsoString ToURLEncoded(const void *data, size_type length)
ustring_base::char_type uchar_type
Definition: String.h:5493
double ToDouble() const
IsoString & ToURLDecoded()
IsoString & ToCommaSeparated(const C &c)
Definition: String.h:6233
IsoString & ToHyphenated(const C &c)
Definition: String.h:6322
int AppendVFormat(const_c_string fmt, va_list paramList)
bool TryToUInt(unsigned &value) const noexcept
Definition: String.h:6944
IsoString & ToSeparated(const C &c, const_c_string separator)
Definition: String.h:6196
IsoString(short x)
Definition: String.h:5669
IsoString & ToSeparated(const C &c, char_type separator, AF append)
Definition: String.h:6141
IsoString URLDecoded() const
Definition: String.h:6523
string_base::iterator iterator
Definition: String.h:5466
bool TryToInt64(long long &value, int base) const noexcept
ByteArray FromBase64() const
IsoString(unsigned long x)
Definition: String.h:5719
IsoString(const string_base &s)
Definition: String.h:5531
static IsoString ToBase64URL(const void *data, size_type length)
Definition: String.h:7665
ByteArray FromHex() const
bool TryToInt64(long long &value) const noexcept
Definition: String.h:7029
IsoString(unsigned long long x)
Definition: String.h:5739
IsoString(long long x)
Definition: String.h:5729
static ByteArray FromURLEncoded(const C &c)
Definition: String.h:6460
IsoString(const IsoString &)=default
unsigned long long ToUInt64(int base) const
bool TryToDouble(double &value) const noexcept
IsoString(bool x)
Definition: String.h:5659
ustring_base::const_c_string const_c_ustring
Definition: String.h:5508
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:6248
bool TryToInt(int &value) const noexcept
Definition: String.h:6847
unsigned long long ToUInt64() const
Definition: String.h:7083
IsoString & ToSpaceSeparated(const C &c)
Definition: String.h:6263
IsoString(long double x)
Definition: String.h:5769
IsoString DecodedHTMLSpecialChars() const
Definition: String.h:6381
static IsoString ToURLDecoded(const C &c)
Definition: String.h:6501
IsoString & ToNewLineSeparated(const C &c)
Definition: String.h:6293
long ToInt(int base) const
IsoString(int x)
Definition: String.h:5689
static IsoString ToURLEncoded(const C &c)
Definition: String.h:6412
IsoString & ToSeparated(const C &c, const_c_string separator, AF append)
Definition: String.h:6218
IsoString(Complex< long double > &x)
Definition: String.h:5805
long long ToInt64() const
Definition: String.h:7000
static IsoString ToBase64(const void *data, size_type length)
IsoString & ToTabSeparated(const C &c)
Definition: String.h:6278
IsoString(unsigned int x)
Definition: String.h:5699
bool TryToUInt64(unsigned long long &value) const noexcept
Definition: String.h:7112
IsoString(Complex< double > &x)
Definition: String.h:5795
IsoString(string_base &&s)
Definition: String.h:5545
unsigned long ToUInt(int base) const
IsoString & ToDecodedHTMLSpecialChars()
IsoString(char_type c, size_type n=1)
Definition: String.h:5588
ByteArray ToByteArray() const
Definition: String.h:7701
static IsoString ToHex(const C &c)
Definition: String.h:7614
ByteArray FromBase64URL() const
Definition: String.h:7743
IsoString(const_c_ustring t)
Definition: String.h:5625
long ToInt() const
Definition: String.h:6819
IsoString & AppendFormat(const_c_string fmt,...)
Definition: String.h:6592
ustring_base::c_string c_ustring
Definition: String.h:5503
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:5709
static IsoString UUID()
IsoString & ToSeparated(const C &c, const IsoString &separator)
Definition: String.h:6157
static IsoString ToBase64URL(const C &c)
Definition: String.h:7689
IsoString & ToSeparated(const C &c, const IsoString &separator, AF append)
Definition: String.h:6180
static IsoString Random(size_type n, RandomizationOptions options=RandomizationOption::Default)
IsoString & Format(const_c_string fmt,...)
Definition: String.h:6570
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:5446
IsoString(const_iterator i, const_iterator j)
Definition: String.h:5597
string_base::char_type char_type
Definition: String.h:5436
static IsoString CurrentLocalISO8601DateTime(const ISO8601ConversionOptions &options=ISO8601ConversionOptions())
string_base::const_c_string const_c_string
Definition: String.h:5461
IsoString & ToURLEncoded()
IsoString(unsigned short x)
Definition: String.h:5679
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:12322
IsoString(const_c_string t)
Definition: String.h:5571
string_base::c_string c_string
Definition: String.h:5456
IsoString(double x)
Definition: String.h:5759
IsoString & ToNullSeparated(const C &c)
Definition: String.h:6308
IsoString & operator=(const IsoString &s)
Definition: String.h:5855
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:6916
IsoString URLEncoded() const
Definition: String.h:6434
ustring_base::const_iterator const_uchar_iterator
Definition: String.h:5518
ByteArray FromURLEncoded() const
Definition: String.h:6476
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:5513
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:7646
IsoString(const_c_string t, size_type i, size_type n)
Definition: String.h:5580
IsoString(float x)
Definition: String.h:5749
ustring_base ToString() const
Definition: String.h:6642
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:8113
String & ToNewLineSeparated(const C &c)
Definition: String.h:10956
String & ToSeparated(const C &c, const String &separator)
Definition: String.h:10782
String(float x)
Definition: String.h:8509
String(const_char8_iterator i, const_char8_iterator j)
Definition: String.h:8388
String(Complex< long double > &x)
Definition: String.h:8562
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:8764
String(long x)
Definition: String.h:8469
void Assign(std::initializer_list< char_type > l)
Definition: String.h:8792
IsoString ToMBS() const
void Assign(const_iterator i, const_iterator j)
Definition: String.h:8781
IsoString ToLocal8Bit() const
Definition: String.h:11337
String(const wchar_t *t)
Definition: String.h:8342
string_base::char_type char_type
Definition: String.h:8124
String & ToSeparated(const C &c, char_type separator)
Definition: String.h:10743
long ToInt() const
Definition: String.h:11537
String(unsigned short x)
Definition: String.h:8439
int AppendVFormat(const_c_string8 fmt, va_list paramList)
Definition: String.h:11146
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:10766
Array< uint32 > ToUTF32(size_type i=0, size_type n=maxPos) const
Definition: String.h:11397
void ParseISO8601DateTime(int &year, int &month, int &day, double &dayf, double &tz) const
string8_base::const_c_string const_c_string8
Definition: String.h:8208
string_base::block_allocator block_allocator
Definition: String.h:8134
String & AppendFormat(const wchar_t *fmt,...)
Definition: String.h:11189
Array< wchar_t > ToWCharArray(size_type i=0, size_type n=maxPos) const
Definition: String.h:11366
String & ToSpaceSeparated(const C &c)
Definition: String.h:10926
string_base::iterator iterator
Definition: String.h:8164
String DecodedHTMLSpecialChars() const
Definition: String.h:11044
String(const wchar_t *t, size_type i, size_type n)
Definition: String.h:8352
long long ToInt64() const
Definition: String.h:11718
String & Format(const wchar_t *fmt,...)
Definition: String.h:11166
String(std::initializer_list< char_type > l)
Definition: String.h:8306
String(const_c_string8 t, size_type i, size_type n)
Definition: String.h:8379
String(String &&)=default
String & ToSeparated(const C &c, const_c_string8 separator)
Definition: String.h:10859
String(std::initializer_list< char8_type > l)
Definition: String.h:8401
bool ToBool() const
void Assign(const_char8_iterator p, const_char8_iterator q)
Definition: String.h:8922
GenericVector< float > ParseListOfFloatAsVector(char separator=',', int maxCount=int_max) const
bool TryToUInt64(unsigned long long &value) const noexcept
Definition: String.h:11830
float ToFloat() const
String(Complex< double > &x)
Definition: String.h:8553
String(double x)
Definition: String.h:8519
string8_base::c_string c_string8
Definition: String.h:8203
String(const_c_string8 t)
Definition: String.h:8369
void Assign(std::initializer_list< char8_type > l)
Definition: String.h:8942
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:8864
String & ToSeparated(const C &c, const String &separator, AF append)
Definition: String.h:10805
String(char_type c, size_type n)
Definition: String.h:8284
String(const string_base &s)
Definition: String.h:8231
void Assign(const_c_string8 t, size_type i, size_type n)
Definition: String.h:8902
String(bool x)
Definition: String.h:8419
String & ToSeparated(const C &c, const_c_string separator)
Definition: String.h:10821
String(char8_type c, size_type n=1)
Definition: String.h:8410
void Assign(const_iterator t, size_type i, size_type n)
Definition: String.h:8802
String(const String &)=default
string8_base::const_iterator const_char8_iterator
Definition: String.h:8218
string_base::const_iterator const_iterator
Definition: String.h:8169
IsoString ToIsoString() const
String(string_base &&s)
Definition: String.h:8245
String(int x)
Definition: String.h:8449
void Assign(const char16_t *t, size_type i, size_type n)
Definition: String.h:8828
String & AppendFormat(const_c_string8 fmt,...)
Definition: String.h:11103
void Assign(char_type c, size_type n=1)
Definition: String.h:8810
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:11081
String(const_iterator t)
Definition: String.h:8267
String(long double x)
Definition: String.h:8529
String & ToNullSeparated(const C &c)
Definition: String.h:10971
String(Complex< float > &x)
Definition: String.h:8544
String(const string8_base &s)
Definition: String.h:8259
Array< float > ParseListOfFloat(char separator=',', size_type maxCount=~size_type(0)) const
void Assign(char16_t c, size_type n=1)
Definition: String.h:8836
bool TryToInt64(long long &value) const noexcept
Definition: String.h:11747
long ToInt(int base) const
bool TryToUInt(unsigned &value) const noexcept
Definition: String.h:11662
bool TryToInt(int &value) const noexcept
Definition: String.h:11565
void Assign(const_iterator t)
Definition: String.h:8772
void Assign(char8_type c, size_type n=1)
Definition: String.h:8950
unsigned long ToUInt() const
Definition: String.h:11634
String & ToSeparated(const C &c, const_c_string separator, AF append)
Definition: String.h:10843
string8_base::char_type char8_type
Definition: String.h:8193
void Assign(const char16_t *t)
Definition: String.h:8818
String(const_iterator i, const_iterator j)
Definition: String.h:8293
String & ToHyphenated(const C &c)
Definition: String.h:10985
void Assign(wchar_t c, size_type n=1)
Definition: String.h:8856
string8_base::iterator char8_iterator
Definition: String.h:8213
long long ToInt64(int base) const
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:8325
int VFormat(const wchar_t *fmt, va_list paramList)
String & ToCommaSeparated(const C &c)
Definition: String.h:10896
int VFormat(const_c_string8 fmt, va_list paramList)
Definition: String.h:11126
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:8499
String & ToColonSeparated(const C &c)
Definition: String.h:10911
String(const char16_t *t)
Definition: String.h:8315
void Assign(const_c_string8 t)
Definition: String.h:8883
string_base::c_string c_string
Definition: String.h:8144
string_base::const_c_string const_c_string
Definition: String.h:8149
String(char16_t c, size_type n)
Definition: String.h:8333
void Assign(const String &s)
Definition: String.h:8755
bool TryToUInt64(unsigned long long &value, int base) const noexcept
GenericString< char16_type, CharTraits, PCL_STRING_ALLOCATOR > string_base
Definition: String.h:8119
bool TryToDouble(double &value) const noexcept
String EncodedHTMLSpecialChars() const
Definition: String.h:11014
unsigned long long ToUInt64(int base) const
String(const_iterator t, size_type i, size_type n)
Definition: String.h:8276
String(unsigned int x)
Definition: String.h:8459
String(wchar_t c, size_type n)
Definition: String.h:8360
String & ToSeparated(const C &c, const_c_string8 separator, AF append)
Definition: String.h:10881
int AppendVFormat(const wchar_t *fmt, va_list paramList)
String & ToEncodedHTMLSpecialChars()
String & ToTabSeparated(const C &c)
Definition: String.h:10941
String & ToDecodedHTMLSpecialChars()
String(unsigned long x)
Definition: String.h:8479
String(short x)
Definition: String.h:8429
IsoString ToUTF8(size_type i=0, size_type n=maxPos) const
Definition: String.h:11307
unsigned long long ToUInt64() const
Definition: String.h:11801
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:8489
unsigned long ToUInt(int base) const
IsoString To7BitASCII() const
Array< T, A > & operator<<(Array< T, A > &x, const V &v)
Definition: Array.h:2295
bool operator==(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
Definition: Array.h:2267
bool operator<(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
Definition: Array.h:2278
Complex< T1 > operator*(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Definition: Complex.h:548
Complex< T1 > operator+(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Definition: Complex.h:464
T Abs(const Complex< T > &c) noexcept
Definition: Complex.h:429
bool operator<=(const T1 &a, const T2 &b)
Definition: Relational.h:96
bool operator>=(const T1 &a, const T2 &b)
Definition: Relational.h:117
bool operator>(const T1 &a, const T2 &b)
Definition: Relational.h:106
uint64 Hash64(const void *data, size_type size, uint64 seed=0) noexcept
Definition: Math.h:4750
uint32 Hash32(const void *data, size_type size, uint32 seed=0) noexcept
Definition: Math.h:4904
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:7267
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:7354
static IsoString ToSexagesimal(double d, const SexagesimalConversionOptions &options=SexagesimalConversionOptions())
Definition: String.h:7497
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:7297
bool TryParseSexagesimal(int &sign, int &s1, int &s2, double &s3, const IsoString &separator=':') const noexcept
double SexagesimalToDouble(const String &separator=':') const
Definition: String.h:11985
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:12052
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:12005
bool TrySexagesimalToDouble(double &value, const String &separator=':') const noexcept
Definition: String.h:12029
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:7321
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