String.h
1 /*
2  * Copyright (C) 2004-2007 Marc Boris Duerner
3  * Copyright (C) 2011 Tommi Maekitalo
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * As a special exception, you may use this file as part of a free
11  * software library without restriction. Specifically, if other files
12  * instantiate templates or use macros or inline functions from this
13  * file, or you compile this file and link it with other files to
14  * produce an executable, this file does not by itself cause the
15  * resulting executable to be covered by the GNU General Public
16  * License. This exception does not however invalidate any other
17  * reasons why the executable file might be covered by the GNU Library
18  * General Public License.
19  *
20  * This library is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23  * Lesser General Public License for more details.
24  *
25  * You should have received a copy of the GNU Lesser General Public
26  * License along with this library; if not, write to the Free Software
27  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28  */
29 
30 #ifndef PT_STRING_H
31 #define PT_STRING_H
32 
33 #include <Pt/Api.h>
34 #include <Pt/Types.h>
35 #include <Pt/Locale.h>
36 #include <string>
37 #include <iterator>
38 #include <stdexcept>
39 #include <cstring>
40 #include <cctype>
41 #include <cstddef>
42 
43 namespace Pt {
44 
66 struct Char
67 {
68  public:
69 #if __cplusplus >= 201103L
70  Char() = default;
72 #else
73  Char()
75  : _value()
76  {}
77 #endif
78  Char(char ch)
80  : _value( (unsigned char)ch )
81  {}
82 
84  Char(int val)
85  : _value( (unsigned)(val) )
86  {}
87 
90  : _value(val)
91  {}
92 
94  uint32_t value() const
95  { return _value; }
96 
98  operator uint32_t() const
99  { return _value; }
100 
102  /*Char& operator=(const Char& ch)
103  {
104  _value = ch._value;
105  return *this;
106  }*/
107 
113  char narrow(char def = '?') const
114  {
115  return _value > 0xff ? def : static_cast<char>(_value);
116  }
117 
118  private:
119  Pt::uint32_t _value ;
120 };
121 
122 } // namespace Pt
123 
124 // workaround for partial c++11 implementations like macOS
125 #if _LIBCPP_VERSION >= 5000 && __cplusplus < 201103L
126 
127 namespace std {
128 
129 template <>
130 struct is_trivial<Pt::Char> {
131  static const bool value = true;
132 };
133 
134 } // namespace
135 
136 #endif
137 
138 namespace Pt {
139 
141 PT_API std::ctype_base::mask ctypeMask(const Char& ch);
142 
147 inline int isalpha(const Char& ch)
148 {
149  return ctypeMask(ch) & std::ctype_base::alpha;
150 }
151 
156 inline int isalnum(const Char& ch)
157 {
158  return ctypeMask(ch) & std::ctype_base::alnum;
159 }
160 
165 inline int ispunct(const Char& ch)
166 {
167  return ctypeMask(ch) & std::ctype_base::punct;
168 }
169 
174 inline int iscntrl(const Char& ch)
175 {
176  return ctypeMask(ch) & std::ctype_base::cntrl;
177 }
178 
183 inline int isdigit(const Char& ch)
184 {
185  return ctypeMask(ch) & std::ctype_base::digit;
186 }
187 
192 inline int isxdigit(const Char& ch)
193 {
194  return ctypeMask(ch) & std::ctype_base::xdigit;
195 }
196 
201 inline int isgraph(const Char& ch)
202 {
203  return ctypeMask(ch) & std::ctype_base::graph;
204 }
205 
210 inline int islower(const Char& ch)
211 {
212  return ctypeMask(ch) & std::ctype_base::lower;
213 }
214 
219 inline int isupper(const Char& ch)
220 {
221  return ctypeMask(ch) & std::ctype_base::upper;
222 }
223 
228 inline int isprint(const Char& ch)
229 {
230  return ctypeMask(ch) & std::ctype_base::print;
231 }
232 
237 inline int isspace(const Char& ch)
238 {
239  return ctypeMask(ch) & std::ctype_base::space;
240 }
241 
246 PT_API Char tolower(const Char& ch);
247 
252 PT_API Char toupper(const Char& ch);
253 
254 
255 struct MBState
256 {
257  MBState()
258  : n(0)
259  , value()
260  {}
261 
262  int n;
263  union {
264  Pt::uint32_t wchars[4];
265  char mbytes[16];
266  } value;
267 };
268 
269 } // namespace Pt
270 
271 namespace std {
272 
273 template<>
274 struct char_traits<Pt::Char>
275 {
276  typedef Pt::Char char_type;
277  typedef Pt::uint32_t int_type;
278  typedef streamoff off_type;
279  typedef streampos pos_type;
280  typedef Pt::MBState state_type;
281 
282  inline static void assign(char_type& c1, const char_type& c2)
283  {
284  c1 = c2;
285  }
286 
287  inline static bool eq(const char_type& c1, const char_type& c2)
288  {
289  return c1 == c2;
290  }
291 
292  inline static bool lt(const char_type& c1, const char_type& c2)
293  {
294  return c1 < c2;
295  }
296 
297  inline static int compare(const char_type* s1, const char_type* s2, std::size_t n)
298  {
299  while(n-- > 0)
300  {
301  if( ! eq(*s1, *s2) )
302  return lt(*s1, *s2) ? -1 : +1;
303 
304  ++s1;
305  ++s2;
306  }
307 
308  return 0;
309  }
310 
311  inline static std::size_t length(const char_type* s)
312  {
313  const Pt::Char term(0);
314 
315  std::size_t n = 0;
316  while( ! eq(s[n], term) )
317  ++n;
318 
319  return n;
320  }
321 
322  inline static const char_type* find(const char_type* s, std::size_t n, const char_type& a)
323  {
324  while(n-- > 0)
325  {
326  if (*s == a)
327  return s;
328 
329  ++s;
330  }
331 
332  return 0;
333  }
334 
335  inline static char_type* move(char_type* s1, const char_type* s2, std::size_t n)
336  {
337  return (Pt::Char*) std::memmove( static_cast<void*>(s1),
338  static_cast<const void*>(s2),
339  n * sizeof(Pt::Char) );
340  }
341 
342  inline static char_type* copy(char_type* s1, const char_type* s2, std::size_t n)
343  {
344  return (Pt::Char*) std::memcpy( static_cast<void*>(s1),
345  static_cast<const void*>(s2),
346  n * sizeof(Pt::Char) );
347  }
348 
349  inline static char_type* assign(char_type* s, std::size_t n, char_type a)
350  {
351  while(n-- > 0)
352  *(s++) = a;
353 
354  return s;
355  }
356 
357  inline static char_type to_char_type(const int_type& c)
358  {
359  return char_type(c);
360  }
361 
362  inline static int_type to_int_type(const char_type& c)
363  {
364  return c.value();
365  }
366 
367  inline static bool eq_int_type(const int_type& c1, const int_type& c2)
368  {
369  return c1 == c2;
370  }
371 
372  inline static int_type eof()
373  {
374  return Pt::uint32_t(-1);
375  }
376 
377  inline static int_type not_eof(const int_type& c)
378  {
379  return eq_int_type(c, eof()) ? 0 : c;
380  }
381 };
382 
385 template <>
386 class PT_API basic_string<Pt::Char>
387 {
388  public:
389  typedef Pt::Char value_type;
390  typedef Pt::Char& reference;
391  typedef const Pt::Char& const_reference;
392  typedef Pt::Char* pointer;
393  typedef const Pt::Char* const_pointer;
394 
395  typedef std::size_t size_type;
396  typedef char_traits<Pt::Char> traits_type;
397  typedef std::allocator<Pt::Char> allocator_type;
398  typedef allocator_type::difference_type difference_type;
399 
400  typedef value_type* iterator;
401  typedef const value_type* const_iterator;
402 
403 #ifdef _RWSTD_NO_CLASS_PARTIAL_SPEC
404  typedef std::reverse_iterator<const_iterator,
405  random_access_iterator_tag, value_type>
406  const_reverse_iterator;
407 
408  typedef std::reverse_iterator<iterator,
409  random_access_iterator_tag, value_type>
410  reverse_iterator;
411 #else
412  typedef std::reverse_iterator<iterator> reverse_iterator;
413  typedef const std::reverse_iterator<const_iterator> const_reverse_iterator;
414 #endif
415 
416  static const size_type npos = static_cast<size_type>(-1);
417 
418  public:
421  explicit basic_string(const allocator_type& a = allocator_type());
422 
425  basic_string(const Pt::Char* str, const allocator_type& a = allocator_type());
426 
429  basic_string(const Pt::Char* str, size_type n, const allocator_type& a = allocator_type());
430 
433  basic_string(const wchar_t* str, const allocator_type& a = allocator_type());
434 
437  basic_string(const wchar_t* str, size_type n, const allocator_type& a = allocator_type());
438 
441  basic_string(const char* str, const allocator_type& a = allocator_type());
442 
445  basic_string(const char* str, size_type n, const allocator_type& a = allocator_type());
446 
449  basic_string(size_type n, Pt::Char c, const allocator_type& a = allocator_type());
450 
453  basic_string(const basic_string& str);
454 
457  basic_string(const basic_string& str, const allocator_type& a);
458 
461  basic_string(const basic_string& str, size_type pos, size_type n = npos, const allocator_type& a = allocator_type());
462 
465  basic_string(const Pt::Char* begin, const Pt::Char* end, const allocator_type& a = allocator_type());
466 
467  template <typename InputIterator>
468  basic_string(InputIterator begin, InputIterator end, const allocator_type& a = allocator_type());
469 
472  ~basic_string();
473 
474  public:
477  iterator begin()
478  { return privdata_rw(); }
479 
482  iterator end()
483  { return privdata_rw() + length(); }
484 
487  const_iterator begin() const
488  { return privdata_ro(); }
489 
492  const_iterator end() const
493  { return privdata_ro() + length(); }
494 
497  reverse_iterator rbegin()
498  { return reverse_iterator( this->end() ); }
499 
502  reverse_iterator rend()
503  { return reverse_iterator( this->begin() ); }
504 
507  const_reverse_iterator rbegin() const
508  { return const_reverse_iterator( this->end() ); }
509 
512  const_reverse_iterator rend() const
513  { return const_reverse_iterator( this->begin() ); }
514 
517  reference operator[](size_type n)
518  { return privdata_rw()[n]; }
519 
522  const_reference operator[](size_type n) const
523  { return privdata_ro()[n]; }
524 
527  reference at(size_type n)
528  {
529  if( n >= size() )
530  throw out_of_range("at");
531 
532  return privdata_rw()[n];
533  }
534 
537  const_reference at(size_type n) const
538  {
539  if( n >= size() )
540  throw out_of_range("at");
541 
542  return privdata_ro()[n];
543  }
544 
545  public:
548  void push_back(Pt::Char ch)
549  { (*this) += ch; }
550 
553  void resize( std::size_t n, Pt::Char ch = value_type() );
554 
557  void reserve(std::size_t n = 0);
558 
564  template<typename Operation>
565  void resize_and_overwrite(size_type n, Operation op);
566 
569  void swap(basic_string& str);
570 
573  allocator_type get_allocator() const
574  { return _d; }
575 
578  size_type copy(Pt::Char* a, size_type n, size_type pos = 0) const;
579 
582  basic_string substr(size_type pos = 0, size_type n = npos) const
583  { return basic_string(*this, pos, n); }
584 
585  public:
588  size_type length() const
589  { return isShortString() ? shortStringLength() : longStringLength(); }
590 
593  size_type size() const
594  { return length(); }
595 
598  bool empty() const
599  { return length() == 0; }
600 
603  size_type max_size() const
604  { return ( size_type(-1) / sizeof(Pt::Char) ) - 1; }
605 
608  size_type capacity() const
609  { return isShortString() ? shortStringCapacity() : longStringCapacity(); }
610 
613  const Pt::Char* data() const
614  { return privdata_ro(); }
615 
618  const Pt::Char* c_str() const
619  { return privdata_ro(); }
620 
623  basic_string& assign(const basic_string& str);
624 
627  basic_string& assign(const basic_string& str, size_type pos, size_type n);
628 
631  basic_string& assign(const wchar_t* str);
632 
635  basic_string& assign(const wchar_t* str, size_type n);
636 
639  basic_string& assign(const Pt::Char* str);
640 
643  basic_string& assign(const Pt::Char* str, size_type length);
644 
647  basic_string& assign(const char* str);
648 
651  basic_string& assign(const char* str, size_type length);
652 
655  basic_string& assign(size_type n, Pt::Char c);
656 
657  template <typename InputIterator>
658  basic_string& assign(InputIterator begin, InputIterator end);
659 
662  basic_string& append(const Pt::Char* str);
663 
666  basic_string& append(const Pt::Char* str, size_type n);
667 
670  basic_string& append(size_type n, Pt::Char ch);
671 
674  basic_string& append(const basic_string& str);
675 
678  basic_string& append(const basic_string& str, size_type pos, size_type n);
679 
680  template <typename InputIterator>
681  basic_string& append(InputIterator begin, InputIterator end);
682 
685  basic_string& append(const Pt::Char* begin, const Pt::Char* end);
686 
689  basic_string& insert(size_type pos, const Pt::Char* str);
690 
693  basic_string& insert(size_type pos, const Pt::Char* str, size_type n);
694 
697  basic_string& insert(size_type pos, size_type n, Pt::Char ch);
698 
701  basic_string& insert(size_type pos, const basic_string& str);
702 
705  basic_string& insert(size_type pos, const basic_string& str, size_type pos2, size_type n);
706 
709  basic_string& insert(iterator p, Pt::Char ch);
710 
713  basic_string& insert(iterator p, size_type n, Pt::Char ch);
714 
715  // unimplemented
716  //template <typename InputIterator>
717  //basic_string& insert(iterator p, InputIterator first, InputIterator last);
718 
721  void clear()
722  { setLength(0); }
723 
726  basic_string& erase(size_type pos = 0, size_type n = npos);
727 
730  iterator erase(iterator pos);
731 
734  iterator erase(iterator first, iterator last);
735 
738  basic_string& replace(size_type pos, size_type n, const Pt::Char* str);
739 
742  basic_string& replace(size_type pos, size_type n, const Pt::Char* str, size_type n2);
743 
746  basic_string& replace(size_type pos, size_type n, size_type n2, Pt::Char ch);
747 
750  basic_string& replace(size_type pos, size_type n, const basic_string& str);
751 
754  basic_string& replace(size_type pos, size_type n, const basic_string& str, size_type pos2, size_type n2);
755 
758  basic_string& replace(iterator i1, iterator i2, const Pt::Char* str);
759 
762  basic_string& replace(iterator i1, iterator i2, const Pt::Char* str, size_type n);
763 
766  basic_string& replace(iterator i1, iterator i2, size_type n, Pt::Char ch);
767 
770  basic_string& replace(iterator i1, iterator i2, const basic_string& str);
771 
774  int compare(const basic_string& str) const;
775 
778  int compare(const Pt::Char* str) const;
779 
782  int compare(const Pt::Char* str, size_type n) const;
783 
786  int compare(const wchar_t* str) const;
787 
790  int compare(const wchar_t* str, size_type n) const;
791 
794  int compare(const char* str) const;
795 
798  int compare(const char* str, size_type n) const;
799 
802  int compare(size_type pos, size_type n, const basic_string& str) const;
803 
806  int compare(size_type pos, size_type n, const basic_string& str, size_type pos2, size_type n2) const;
807 
810  int compare(size_type pos, size_type n, const Pt::Char* str) const;
811 
814  int compare(size_type pos, size_type n, const Pt::Char* str, size_type n2) const;
815 
818  size_type find(const basic_string& str, size_type pos = 0) const;
819 
822  size_type find(const Pt::Char* str, size_type pos, size_type n) const;
823 
826  size_type find(const Pt::Char* str, size_type pos = 0) const;
827 
830  size_type find(Pt::Char ch, size_type pos = 0) const;
831 
834  size_type rfind(const basic_string& str, size_type pos = npos) const;
835 
838  size_type rfind(const Pt::Char* str, size_type pos, size_type n) const;
839 
842  size_type rfind(const Pt::Char* str, size_type pos = npos) const;
843 
846  size_type rfind(Pt::Char ch, size_type pos = npos) const;
847 
850  size_type find_first_of(const basic_string& str, size_type pos = 0) const
851  { return this->find_first_of( str.data(), pos, str.size() ); }
852 
855  size_type find_first_of(const Pt::Char* s, size_type pos, size_type n) const;
856 
859  size_type find_first_of(const Pt::Char* str, size_type pos = 0) const
860  { return this->find_first_of( str, pos, traits_type::length(str) ); }
861 
864  size_type find_first_of(const Pt::Char ch, size_type pos = 0) const
865  { return this->find(ch, pos); }
866 
869  size_type find_last_of(const basic_string& str, size_type pos = npos) const
870  { return this->find_last_of( str.data(), pos, str.size() ); }
871 
874  size_type find_last_of(const Pt::Char* s, size_type pos, size_type n) const;
875 
878  size_type find_last_of(const Pt::Char* str, size_type pos = npos) const
879  { return this->find_last_of( str, pos, traits_type::length(str) ); }
880 
883  size_type find_last_of(const Pt::Char ch, size_type pos = npos) const
884  { return this->rfind(ch, pos); }
885 
888  size_type find_first_not_of(const basic_string& str, size_type pos = 0) const
889  { return this->find_first_not_of( str.data(), pos, str.size() ); }
890 
893  size_type find_first_not_of(const Pt::Char* s, size_type pos, size_type n) const;
894 
897  size_type find_first_not_of(const Pt::Char* str, size_type pos = 0) const
898  { return this->find_first_not_of( str, pos, traits_type::length(str) ); }
899 
902  size_type find_first_not_of(const Pt::Char ch, size_type pos = 0) const;
903 
906  size_type find_last_not_of(const basic_string& str, size_type pos = npos) const
907  { return this->find_last_not_of( str.data(), pos, str.size() ); }
908 
911  size_type find_last_not_of(const Pt::Char* tok, size_type pos, size_type n) const;
912 
915  size_type find_last_not_of(const Pt::Char* str, size_type pos = npos) const
916  { return this->find_last_not_of( str, pos, traits_type::length(str) ); }
917 
920  size_type find_last_not_of(Pt::Char ch, size_type pos = npos) const;
921 
922  public:
925  std::string narrow(char dfault = '?') const;
926 
929  static basic_string widen(const char* str);
930 
933  static basic_string widen(const std::string& str);
934 
937  template <typename OutIterT>
938  OutIterT toUtf16(OutIterT to) const;
939 
942  template <typename InIterT>
943  static basic_string fromUtf16(InIterT from, InIterT fromEnd);
944 
945  public:
948  basic_string& operator=(const basic_string& str)
949  { return this->assign(str); }
950 
953  basic_string& operator=(const wchar_t* str)
954  { return this->assign(str); }
955 
958  basic_string& operator=(const char* str)
959  { return this->assign(str); }
960 
963  basic_string& operator=(const Pt::Char* str)
964  { return this->assign(str); }
965 
968  basic_string& operator=(Pt::Char ch)
969  {
970  // no privreserve(1), short string capacity is large enough
971 
972  Pt::Char* p = privdata_rw();
973  p[0] = ch;
974  setLength(1);
975  return *this;
976  }
977 
980  basic_string& operator+=(const basic_string& str)
981  { return this->append(str); }
982 
985  basic_string& operator+=(const Pt::Char* str)
986  { return this->append(str); }
987 
990  basic_string& operator+=(Pt::Char c);
991 
992  private:
993  struct Ptr
994  {
995  Pt::Char* _begin;
996  Pt::Char* _end;
997  Pt::Char* _capacity;
998  };
999 
1000  // minimum possible short string character count
1001  static const unsigned _minN = (sizeof(Ptr) / sizeof(Pt::Char)) + 1;
1002 
1003  // short string character count
1004  static const unsigned _nN = _minN < 8 ? 8 : _minN;
1005 
1006  // short string raw storage size in bytes
1007  static const unsigned _nS = _nN * sizeof(Pt::Char);
1008 
1009  struct Data : public allocator_type
1010  {
1011  Data(const allocator_type& a)
1012  : allocator_type(a)
1013  {
1014  Pt::Char* str = reinterpret_cast<Pt::Char*>(&_u._s[0]);
1015  *str = 0;
1016 
1017  _u._s[_nS - 1] = _nN - 1;
1018  }
1019 
1020  union
1021  {
1022  Ptr _p;
1023  unsigned char _s[_nS];
1024  } _u;
1025  } _d;
1026 
1027  private:
1028  const Pt::Char* privdata_ro() const
1029  { return isShortString() ? shortStringData() : longStringData(); }
1030 
1031  Pt::Char* privdata_rw()
1032  { return isShortString() ? shortStringData() : longStringData(); }
1033 
1034  void privreserve(std::size_t n);
1035 
1036  bool isShortString() const
1037  { return shortStringMagic() != 0xff; }
1038 
1039  void markLongString()
1040  { shortStringMagic() = 0xff; }
1041 
1042  const Pt::Char* shortStringData() const
1043  { return reinterpret_cast<const Pt::Char*>(&_d._u._s[0]); }
1044 
1045  Pt::Char* shortStringData()
1046  { return reinterpret_cast<Pt::Char*>(&_d._u._s[0]); }
1047 
1048  unsigned char shortStringMagic() const
1049  { return _d._u._s[_nS - 1]; }
1050 
1051  unsigned char& shortStringMagic()
1052  { return _d._u._s[_nS - 1]; }
1053 
1054  size_type shortStringLength() const
1055  { return _nN - 1 - shortStringMagic(); }
1056 
1057  size_type shortStringCapacity() const
1058  { return _nN - 1; }
1059 
1060  void setShortStringLength(size_type n)
1061  {
1062  shortStringData()[n] = Pt::Char(0);
1063  shortStringMagic() = static_cast<unsigned char>(_nN - n - 1);
1064  }
1065 
1066  void shortStringAssign(const Pt::Char* str, size_type n)
1067  {
1068  traits_type::copy(shortStringData(), str, n);
1069  shortStringData()[n] = Pt::Char(0);
1070  shortStringMagic() = static_cast<unsigned char>(_nN - n - 1);
1071  }
1072  void shortStringAssign(const wchar_t* str, size_type n)
1073  {
1074  for (size_type nn = 0; nn < n; ++nn)
1075  shortStringData()[nn] = str[nn];
1076  shortStringData()[n] = Pt::Char(0);
1077  shortStringMagic() = static_cast<unsigned char>(_nN - n - 1);
1078  }
1079 
1080  const Pt::Char* longStringData() const
1081  { return _d._u._p._begin; }
1082 
1083  Pt::Char* longStringData()
1084  { return _d._u._p._begin; }
1085 
1086  size_type longStringLength() const
1087  { return _d._u._p._end - _d._u._p._begin; }
1088 
1089  size_type longStringCapacity() const
1090  { return _d._u._p._capacity - _d._u._p._begin; }
1091 
1092  void setLength(size_type n)
1093  {
1094  if (isShortString())
1095  setShortStringLength(n);
1096  else
1097  {
1098  _d._u._p._end = _d._u._p._begin + n;
1099  _d._u._p._begin[n] = 0;
1100  }
1101  }
1102 };
1103 
1108 inline void swap(basic_string<Pt::Char>& a, basic_string<Pt::Char>& b)
1109 { a.swap(b); }
1110 
1111 // operator +
1112 
1117 inline basic_string<Pt::Char> operator+(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1118 { basic_string<Pt::Char> temp; temp += a; temp += b; return temp; }
1119 
1124 inline basic_string<Pt::Char> operator+(const basic_string<Pt::Char>& a, const Pt::Char* b)
1125 { basic_string<Pt::Char> temp; temp += a; temp += b; return temp; }
1126 
1131 inline basic_string<Pt::Char> operator+(const Pt::Char* a, const basic_string<Pt::Char>& b)
1132 { basic_string<Pt::Char> temp; temp += a; temp += b; return temp; }
1133 
1138 inline basic_string<Pt::Char> operator+(const basic_string<Pt::Char>& a, Pt::Char b)
1139 { basic_string<Pt::Char> temp; temp += a; temp += b; return temp; }
1140 
1145 inline basic_string<Pt::Char> operator+(Pt::Char a, const basic_string<Pt::Char>& b)
1146 { basic_string<Pt::Char> temp; temp += a; temp += b; return temp; }
1147 
1148 // operator ==
1149 
1154 inline bool operator==(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1155 { return a.compare(b) == 0; }
1156 
1161 inline bool operator==(const Pt::Char* a, const basic_string<Pt::Char>& b)
1162 { return b.compare(a) == 0; }
1163 
1168 inline bool operator==(const basic_string<Pt::Char>& a, const Pt::Char* b)
1169 { return a.compare(b) == 0; }
1170 
1175 inline bool operator==(const basic_string<Pt::Char>& a, const wchar_t* b)
1176 { return a.compare(b) == 0; }
1177 
1182 inline bool operator==(const wchar_t* b, const basic_string<Pt::Char>& a)
1183 { return a.compare(b) == 0; }
1184 
1189 inline bool operator==(const basic_string<Pt::Char>& a, const char* b)
1190 { return a.compare(b) == 0; }
1191 
1196 inline bool operator==(const char* b, const basic_string<Pt::Char>& a)
1197 { return a.compare(b) == 0; }
1198 
1199 // operator !=
1200 
1205 inline bool operator!=(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1206 { return a.compare(b) != 0; }
1207 
1212 inline bool operator!=(const Pt::Char* a, const basic_string<Pt::Char>& b)
1213 { return b.compare(a) != 0; }
1214 
1219 inline bool operator!=(const basic_string<Pt::Char>& a, const Pt::Char* b)
1220 { return a.compare(b) != 0; }
1221 
1226 inline bool operator!=(const basic_string<Pt::Char>& a, const wchar_t* b)
1227 { return a.compare(b) != 0; }
1228 
1233 inline bool operator!=(const wchar_t* b, const basic_string<Pt::Char>& a)
1234 { return a.compare(b) != 0; }
1235 
1240 inline bool operator!=(const basic_string<Pt::Char>& a, const char* b)
1241 { return a.compare(b) != 0; }
1242 
1247 inline bool operator!=(const char* b, const basic_string<Pt::Char>& a)
1248 { return a.compare(b) != 0; }
1249 
1250 // operator <
1251 
1256 inline bool operator<(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1257 { return a.compare(b) < 0; }
1258 
1263 inline bool operator<(const Pt::Char* a, const basic_string<Pt::Char>& b)
1264 { return b.compare(a) > 0; }
1265 
1270 inline bool operator<(const basic_string<Pt::Char>& a, const Pt::Char* b)
1271 { return a.compare(b) < 0; }
1272 
1277 inline bool operator<(const basic_string<Pt::Char>& a, const wchar_t* b)
1278 { return a.compare(b) < 0; }
1279 
1284 inline bool operator<(const wchar_t* b, const basic_string<Pt::Char>& a)
1285 { return a.compare(b) > 0; }
1286 
1291 inline bool operator<(const basic_string<Pt::Char>& a, const char* b)
1292 { return a.compare(b) < 0; }
1293 
1298 inline bool operator<(const char* b, const basic_string<Pt::Char>& a)
1299 { return a.compare(b) > 0; }
1300 
1301 // operator <=
1302 
1307 inline bool operator<=(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1308 { return a.compare(b) <= 0; }
1309 
1314 inline bool operator<=(const Pt::Char* a, const basic_string<Pt::Char>& b)
1315 { return b.compare(a) >= 0; }
1316 
1321 inline bool operator<=(const basic_string<Pt::Char>& a, const Pt::Char* b)
1322 { return a.compare(b) <= 0; }
1323 
1328 inline bool operator<=(const basic_string<Pt::Char>& a, const wchar_t* b)
1329 { return a.compare(b) <= 0; }
1330 
1335 inline bool operator<=(const wchar_t* b, const basic_string<Pt::Char>& a)
1336 { return a.compare(b) >= 0; }
1337 
1342 inline bool operator<=(const basic_string<Pt::Char>& a, const char* b)
1343 { return a.compare(b) <= 0; }
1344 
1349 inline bool operator<=(const char* b, const basic_string<Pt::Char>& a)
1350 { return a.compare(b) >= 0; }
1351 
1352 // operator >
1353 
1358 inline bool operator>(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1359 { return a.compare(b) > 0; }
1360 
1365 inline bool operator>(const Pt::Char* a, const basic_string<Pt::Char>& b)
1366 { return b.compare(a) < 0; }
1367 
1372 inline bool operator>(const basic_string<Pt::Char>& a, const Pt::Char* b)
1373 { return a.compare(b) > 0; }
1374 
1379 inline bool operator>(const basic_string<Pt::Char>& a, const wchar_t* b)
1380 { return a.compare(b) > 0; }
1381 
1386 inline bool operator>(const wchar_t* b, const basic_string<Pt::Char>& a)
1387 { return a.compare(b) < 0; }
1388 
1393 inline bool operator>(const basic_string<Pt::Char>& a, const char* b)
1394 { return a.compare(b) > 0; }
1395 
1400 inline bool operator>(const char* b, const basic_string<Pt::Char>& a)
1401 { return a.compare(b) < 0; }
1402 
1403 // operator >=
1404 
1409 inline bool operator>=(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1410 { return a.compare(b) >= 0; }
1411 
1416 inline bool operator>=(const Pt::Char* a, const basic_string<Pt::Char>& b)
1417 { return b.compare(a) <= 0; }
1418 
1423 inline bool operator>=(const basic_string<Pt::Char>& a, const Pt::Char* b)
1424 { return a.compare(b) >= 0; }
1425 
1430 inline bool operator>=(const basic_string<Pt::Char>& a, const wchar_t* b)
1431 { return a.compare(b) >= 0; }
1432 
1437 inline bool operator>=(const wchar_t* b, const basic_string<Pt::Char>& a)
1438 { return a.compare(b) <= 0; }
1439 
1444 inline bool operator>=(const basic_string<Pt::Char>& a, const char* b)
1445 { return a.compare(b) >= 0; }
1446 
1451 inline bool operator>=(const char* b, const basic_string<Pt::Char>& a)
1452 { return a.compare(b) <= 0; }
1453 
1458 //PT_API basic_istream<Pt::Char>& operator>>(basic_istream<Pt::Char>& is,
1459 // basic_string<Pt::Char>& str);
1460 
1465 PT_API ostream& operator<< (ostream& out, const basic_string<Pt::Char>& str);
1466 
1467 } // namespace std
1468 
1469 namespace Pt {
1470 
1471 typedef std::basic_string<Pt::Char> String;
1472 
1473 }
1474 
1475 #ifdef PT_WITH_STD_LOCALE
1476 #include <Pt/Facets.h>
1477 #endif
1478 
1479 // Include the implementation header
1480 #include <Pt/String.tpp>
1481 
1482 #endif
Core module.
Definition: Allocator.h:33
Char()
Default Constructor.
Definition: String.h:74
int isprint(const Char &ch)
Checks whether ch is a printable character.
Definition: String.h:228
int isgraph(const Char &ch)
Checks whether ch is a graphical character.
Definition: String.h:201
int isalpha(const Char &ch)
Checks whether ch is a alphabetic character.
Definition: String.h:147
R narrow(T from)
Checked numeric conversion.
Definition: Convert.h:112
Char toupper(const Char &ch)
Convert a character to upper case.
uint32_t value() const
Returns the unicode value.
Definition: String.h:94
Char tolower(const Char &ch)
Convert a character to lower case.
int isupper(const Char &ch)
Checks whether ch is upper case.
Definition: String.h:219
int isxdigit(const Char &ch)
Checks whether ch is a hexadecimal digit.
Definition: String.h:192
Unicode character type.
Definition: String.h:67
int isdigit(const Char &ch)
Checks whether ch is a decimal digit.
Definition: String.h:183
int isalnum(const Char &ch)
Checks whether ch is a alphanumeric character.
Definition: String.h:156
Char(int val)
Construct from int.
Definition: String.h:84
int ispunct(const Char &ch)
Checks whether ch is a punctuation character.
Definition: String.h:165
uint_type uint32_t
Unsigned 32-bit integer type.
Definition: Api-Types.h:48
Char(uint32_t val)
Construct from unsigned 32-bit integer.
Definition: String.h:89
int isspace(const Char &ch)
Checks whether ch is a whitespace character.
Definition: String.h:237
char narrow(char def='?') const
Assignment operator.
Definition: String.h:113
int iscntrl(const Char &ch)
Checks whether ch is a control character.
Definition: String.h:174
int islower(const Char &ch)
Checks whether ch is lower case.
Definition: String.h:210