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 
561  void swap(basic_string& str);
562 
565  allocator_type get_allocator() const
566  { return _d; }
567 
570  size_type copy(Pt::Char* a, size_type n, size_type pos = 0) const;
571 
574  basic_string substr(size_type pos = 0, size_type n = npos) const
575  { return basic_string(*this, pos, n); }
576 
577  public:
580  size_type length() const
581  { return isShortString() ? shortStringLength() : longStringLength(); }
582 
585  size_type size() const
586  { return length(); }
587 
590  bool empty() const
591  { return length() == 0; }
592 
595  size_type max_size() const
596  { return ( size_type(-1) / sizeof(Pt::Char) ) - 1; }
597 
600  size_type capacity() const
601  { return isShortString() ? shortStringCapacity() : longStringCapacity(); }
602 
605  const Pt::Char* data() const
606  { return privdata_ro(); }
607 
610  const Pt::Char* c_str() const
611  { return privdata_ro(); }
612 
615  basic_string& assign(const basic_string& str);
616 
619  basic_string& assign(const basic_string& str, size_type pos, size_type n);
620 
623  basic_string& assign(const wchar_t* str);
624 
627  basic_string& assign(const wchar_t* str, size_type n);
628 
631  basic_string& assign(const Pt::Char* str);
632 
635  basic_string& assign(const Pt::Char* str, size_type length);
636 
639  basic_string& assign(const char* str);
640 
643  basic_string& assign(const char* str, size_type length);
644 
647  basic_string& assign(size_type n, Pt::Char c);
648 
649  template <typename InputIterator>
650  basic_string& assign(InputIterator begin, InputIterator end);
651 
654  basic_string& append(const Pt::Char* str);
655 
658  basic_string& append(const Pt::Char* str, size_type n);
659 
662  basic_string& append(size_type n, Pt::Char ch);
663 
666  basic_string& append(const basic_string& str);
667 
670  basic_string& append(const basic_string& str, size_type pos, size_type n);
671 
672  template <typename InputIterator>
673  basic_string& append(InputIterator begin, InputIterator end);
674 
677  basic_string& append(const Pt::Char* begin, const Pt::Char* end);
678 
681  basic_string& insert(size_type pos, const Pt::Char* str);
682 
685  basic_string& insert(size_type pos, const Pt::Char* str, size_type n);
686 
689  basic_string& insert(size_type pos, size_type n, Pt::Char ch);
690 
693  basic_string& insert(size_type pos, const basic_string& str);
694 
697  basic_string& insert(size_type pos, const basic_string& str, size_type pos2, size_type n);
698 
701  basic_string& insert(iterator p, Pt::Char ch);
702 
705  basic_string& insert(iterator p, size_type n, Pt::Char ch);
706 
707  // unimplemented
708  //template <typename InputIterator>
709  //basic_string& insert(iterator p, InputIterator first, InputIterator last);
710 
713  void clear()
714  { setLength(0); }
715 
718  basic_string& erase(size_type pos = 0, size_type n = npos);
719 
722  iterator erase(iterator pos);
723 
726  iterator erase(iterator first, iterator last);
727 
730  basic_string& replace(size_type pos, size_type n, const Pt::Char* str);
731 
734  basic_string& replace(size_type pos, size_type n, const Pt::Char* str, size_type n2);
735 
738  basic_string& replace(size_type pos, size_type n, size_type n2, Pt::Char ch);
739 
742  basic_string& replace(size_type pos, size_type n, const basic_string& str);
743 
746  basic_string& replace(size_type pos, size_type n, const basic_string& str, size_type pos2, size_type n2);
747 
750  basic_string& replace(iterator i1, iterator i2, const Pt::Char* str);
751 
754  basic_string& replace(iterator i1, iterator i2, const Pt::Char* str, size_type n);
755 
758  basic_string& replace(iterator i1, iterator i2, size_type n, Pt::Char ch);
759 
762  basic_string& replace(iterator i1, iterator i2, const basic_string& str);
763 
766  int compare(const basic_string& str) const;
767 
770  int compare(const Pt::Char* str) const;
771 
774  int compare(const Pt::Char* str, size_type n) const;
775 
778  int compare(const wchar_t* str) const;
779 
782  int compare(const wchar_t* str, size_type n) const;
783 
786  int compare(const char* str) const;
787 
790  int compare(const char* str, size_type n) const;
791 
794  int compare(size_type pos, size_type n, const basic_string& str) const;
795 
798  int compare(size_type pos, size_type n, const basic_string& str, size_type pos2, size_type n2) const;
799 
802  int compare(size_type pos, size_type n, const Pt::Char* str) const;
803 
806  int compare(size_type pos, size_type n, const Pt::Char* str, size_type n2) const;
807 
810  size_type find(const basic_string& str, size_type pos = 0) const;
811 
814  size_type find(const Pt::Char* str, size_type pos, size_type n) const;
815 
818  size_type find(const Pt::Char* str, size_type pos = 0) const;
819 
822  size_type find(Pt::Char ch, size_type pos = 0) const;
823 
826  size_type rfind(const basic_string& str, size_type pos = npos) const;
827 
830  size_type rfind(const Pt::Char* str, size_type pos, size_type n) const;
831 
834  size_type rfind(const Pt::Char* str, size_type pos = npos) const;
835 
838  size_type rfind(Pt::Char ch, size_type pos = npos) const;
839 
842  size_type find_first_of(const basic_string& str, size_type pos = 0) const
843  { return this->find_first_of( str.data(), pos, str.size() ); }
844 
847  size_type find_first_of(const Pt::Char* s, size_type pos, size_type n) const;
848 
851  size_type find_first_of(const Pt::Char* str, size_type pos = 0) const
852  { return this->find_first_of( str, pos, traits_type::length(str) ); }
853 
856  size_type find_first_of(const Pt::Char ch, size_type pos = 0) const
857  { return this->find(ch, pos); }
858 
861  size_type find_last_of(const basic_string& str, size_type pos = npos) const
862  { return this->find_last_of( str.data(), pos, str.size() ); }
863 
866  size_type find_last_of(const Pt::Char* s, size_type pos, size_type n) const;
867 
870  size_type find_last_of(const Pt::Char* str, size_type pos = npos) const
871  { return this->find_last_of( str, pos, traits_type::length(str) ); }
872 
875  size_type find_last_of(const Pt::Char ch, size_type pos = npos) const
876  { return this->rfind(ch, pos); }
877 
880  size_type find_first_not_of(const basic_string& str, size_type pos = 0) const
881  { return this->find_first_not_of( str.data(), pos, str.size() ); }
882 
885  size_type find_first_not_of(const Pt::Char* s, size_type pos, size_type n) const;
886 
889  size_type find_first_not_of(const Pt::Char* str, size_type pos = 0) const
890  { return this->find_first_not_of( str, pos, traits_type::length(str) ); }
891 
894  size_type find_first_not_of(const Pt::Char ch, size_type pos = 0) const;
895 
898  size_type find_last_not_of(const basic_string& str, size_type pos = npos) const
899  { return this->find_last_not_of( str.data(), pos, str.size() ); }
900 
903  size_type find_last_not_of(const Pt::Char* tok, size_type pos, size_type n) const;
904 
907  size_type find_last_not_of(const Pt::Char* str, size_type pos = npos) const
908  { return this->find_last_not_of( str, pos, traits_type::length(str) ); }
909 
912  size_type find_last_not_of(Pt::Char ch, size_type pos = npos) const;
913 
914  public:
917  std::string narrow(char dfault = '?') const;
918 
921  static basic_string widen(const char* str);
922 
925  static basic_string widen(const std::string& str);
926 
929  template <typename OutIterT>
930  OutIterT toUtf16(OutIterT to) const;
931 
934  template <typename InIterT>
935  static basic_string fromUtf16(InIterT from, InIterT fromEnd);
936 
937  public:
940  basic_string& operator=(const basic_string& str)
941  { return this->assign(str); }
942 
945  basic_string& operator=(const wchar_t* str)
946  { return this->assign(str); }
947 
950  basic_string& operator=(const char* str)
951  { return this->assign(str); }
952 
955  basic_string& operator=(const Pt::Char* str)
956  { return this->assign(str); }
957 
960  basic_string& operator=(Pt::Char ch)
961  {
962  // no privreserve(1), short string capacity is large enough
963 
964  Pt::Char* p = privdata_rw();
965  p[0] = ch;
966  setLength(1);
967  return *this;
968  }
969 
972  basic_string& operator+=(const basic_string& str)
973  { return this->append(str); }
974 
977  basic_string& operator+=(const Pt::Char* str)
978  { return this->append(str); }
979 
982  basic_string& operator+=(Pt::Char c);
983 
984  private:
985  struct Ptr
986  {
987  Pt::Char* _begin;
988  Pt::Char* _end;
989  Pt::Char* _capacity;
990  };
991 
992  // minimum possible short string character count
993  static const unsigned _minN = (sizeof(Ptr) / sizeof(Pt::Char)) + 1;
994 
995  // short string character count
996  static const unsigned _nN = _minN < 8 ? 8 : _minN;
997 
998  // short string raw storage size in bytes
999  static const unsigned _nS = _nN * sizeof(Pt::Char);
1000 
1001  struct Data : public allocator_type
1002  {
1003  Data(const allocator_type& a)
1004  : allocator_type(a)
1005  {
1006  Pt::Char* str = reinterpret_cast<Pt::Char*>(&_u._s[0]);
1007  *str = 0;
1008 
1009  _u._s[_nS - 1] = _nN - 1;
1010  }
1011 
1012  union
1013  {
1014  Ptr _p;
1015  unsigned char _s[_nS];
1016  } _u;
1017  } _d;
1018 
1019  private:
1020  const Pt::Char* privdata_ro() const
1021  { return isShortString() ? shortStringData() : longStringData(); }
1022 
1023  Pt::Char* privdata_rw()
1024  { return isShortString() ? shortStringData() : longStringData(); }
1025 
1026  void privreserve(std::size_t n);
1027 
1028  bool isShortString() const
1029  { return shortStringMagic() != 0xff; }
1030 
1031  void markLongString()
1032  { shortStringMagic() = 0xff; }
1033 
1034  const Pt::Char* shortStringData() const
1035  { return reinterpret_cast<const Pt::Char*>(&_d._u._s[0]); }
1036 
1037  Pt::Char* shortStringData()
1038  { return reinterpret_cast<Pt::Char*>(&_d._u._s[0]); }
1039 
1040  unsigned char shortStringMagic() const
1041  { return _d._u._s[_nS - 1]; }
1042 
1043  unsigned char& shortStringMagic()
1044  { return _d._u._s[_nS - 1]; }
1045 
1046  size_type shortStringLength() const
1047  { return _nN - 1 - shortStringMagic(); }
1048 
1049  size_type shortStringCapacity() const
1050  { return _nN - 1; }
1051 
1052  void setShortStringLength(size_type n)
1053  {
1054  shortStringData()[n] = Pt::Char(0);
1055  shortStringMagic() = static_cast<unsigned char>(_nN - n - 1);
1056  }
1057 
1058  void shortStringAssign(const Pt::Char* str, size_type n)
1059  {
1060  traits_type::copy(shortStringData(), str, n);
1061  shortStringData()[n] = Pt::Char(0);
1062  shortStringMagic() = static_cast<unsigned char>(_nN - n - 1);
1063  }
1064  void shortStringAssign(const wchar_t* str, size_type n)
1065  {
1066  for (size_type nn = 0; nn < n; ++nn)
1067  shortStringData()[nn] = str[nn];
1068  shortStringData()[n] = Pt::Char(0);
1069  shortStringMagic() = static_cast<unsigned char>(_nN - n - 1);
1070  }
1071 
1072  const Pt::Char* longStringData() const
1073  { return _d._u._p._begin; }
1074 
1075  Pt::Char* longStringData()
1076  { return _d._u._p._begin; }
1077 
1078  size_type longStringLength() const
1079  { return _d._u._p._end - _d._u._p._begin; }
1080 
1081  size_type longStringCapacity() const
1082  { return _d._u._p._capacity - _d._u._p._begin; }
1083 
1084  void setLength(size_type n)
1085  {
1086  if (isShortString())
1087  setShortStringLength(n);
1088  else
1089  {
1090  _d._u._p._end = _d._u._p._begin + n;
1091  _d._u._p._begin[n] = 0;
1092  }
1093  }
1094 };
1095 
1100 inline void swap(basic_string<Pt::Char>& a, basic_string<Pt::Char>& b)
1101 { a.swap(b); }
1102 
1103 // operator +
1104 
1109 inline basic_string<Pt::Char> operator+(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1110 { basic_string<Pt::Char> temp; temp += a; temp += b; return temp; }
1111 
1116 inline basic_string<Pt::Char> operator+(const basic_string<Pt::Char>& a, const Pt::Char* b)
1117 { basic_string<Pt::Char> temp; temp += a; temp += b; return temp; }
1118 
1123 inline basic_string<Pt::Char> operator+(const Pt::Char* a, const basic_string<Pt::Char>& b)
1124 { basic_string<Pt::Char> temp; temp += a; temp += b; return temp; }
1125 
1130 inline basic_string<Pt::Char> operator+(const basic_string<Pt::Char>& a, Pt::Char b)
1131 { basic_string<Pt::Char> temp; temp += a; temp += b; return temp; }
1132 
1137 inline basic_string<Pt::Char> operator+(Pt::Char a, const basic_string<Pt::Char>& b)
1138 { basic_string<Pt::Char> temp; temp += a; temp += b; return temp; }
1139 
1140 // operator ==
1141 
1146 inline bool operator==(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1147 { return a.compare(b) == 0; }
1148 
1153 inline bool operator==(const Pt::Char* a, const basic_string<Pt::Char>& b)
1154 { return b.compare(a) == 0; }
1155 
1160 inline bool operator==(const basic_string<Pt::Char>& a, const Pt::Char* b)
1161 { return a.compare(b) == 0; }
1162 
1167 inline bool operator==(const basic_string<Pt::Char>& a, const wchar_t* b)
1168 { return a.compare(b) == 0; }
1169 
1174 inline bool operator==(const wchar_t* b, const basic_string<Pt::Char>& a)
1175 { return a.compare(b) == 0; }
1176 
1181 inline bool operator==(const basic_string<Pt::Char>& a, const char* b)
1182 { return a.compare(b) == 0; }
1183 
1188 inline bool operator==(const char* b, const basic_string<Pt::Char>& a)
1189 { return a.compare(b) == 0; }
1190 
1191 // operator !=
1192 
1197 inline bool operator!=(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1198 { return a.compare(b) != 0; }
1199 
1204 inline bool operator!=(const Pt::Char* a, const basic_string<Pt::Char>& b)
1205 { return b.compare(a) != 0; }
1206 
1211 inline bool operator!=(const basic_string<Pt::Char>& a, const Pt::Char* b)
1212 { return a.compare(b) != 0; }
1213 
1218 inline bool operator!=(const basic_string<Pt::Char>& a, const wchar_t* b)
1219 { return a.compare(b) != 0; }
1220 
1225 inline bool operator!=(const wchar_t* b, const basic_string<Pt::Char>& a)
1226 { return a.compare(b) != 0; }
1227 
1232 inline bool operator!=(const basic_string<Pt::Char>& a, const char* b)
1233 { return a.compare(b) != 0; }
1234 
1239 inline bool operator!=(const char* b, const basic_string<Pt::Char>& a)
1240 { return a.compare(b) != 0; }
1241 
1242 // operator <
1243 
1248 inline bool operator<(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1249 { return a.compare(b) < 0; }
1250 
1255 inline bool operator<(const Pt::Char* a, const basic_string<Pt::Char>& b)
1256 { return b.compare(a) > 0; }
1257 
1262 inline bool operator<(const basic_string<Pt::Char>& a, const Pt::Char* b)
1263 { return a.compare(b) < 0; }
1264 
1269 inline bool operator<(const basic_string<Pt::Char>& a, const wchar_t* b)
1270 { return a.compare(b) < 0; }
1271 
1276 inline bool operator<(const wchar_t* b, const basic_string<Pt::Char>& a)
1277 { return a.compare(b) > 0; }
1278 
1283 inline bool operator<(const basic_string<Pt::Char>& a, const char* b)
1284 { return a.compare(b) < 0; }
1285 
1290 inline bool operator<(const char* b, const basic_string<Pt::Char>& a)
1291 { return a.compare(b) > 0; }
1292 
1293 // operator <=
1294 
1299 inline bool operator<=(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1300 { return a.compare(b) <= 0; }
1301 
1306 inline bool operator<=(const Pt::Char* a, const basic_string<Pt::Char>& b)
1307 { return b.compare(a) >= 0; }
1308 
1313 inline bool operator<=(const basic_string<Pt::Char>& a, const Pt::Char* b)
1314 { return a.compare(b) <= 0; }
1315 
1320 inline bool operator<=(const basic_string<Pt::Char>& a, const wchar_t* b)
1321 { return a.compare(b) <= 0; }
1322 
1327 inline bool operator<=(const wchar_t* b, const basic_string<Pt::Char>& a)
1328 { return a.compare(b) >= 0; }
1329 
1334 inline bool operator<=(const basic_string<Pt::Char>& a, const char* b)
1335 { return a.compare(b) <= 0; }
1336 
1341 inline bool operator<=(const char* b, const basic_string<Pt::Char>& a)
1342 { return a.compare(b) >= 0; }
1343 
1344 // operator >
1345 
1350 inline bool operator>(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1351 { return a.compare(b) > 0; }
1352 
1357 inline bool operator>(const Pt::Char* a, const basic_string<Pt::Char>& b)
1358 { return b.compare(a) < 0; }
1359 
1364 inline bool operator>(const basic_string<Pt::Char>& a, const Pt::Char* b)
1365 { return a.compare(b) > 0; }
1366 
1371 inline bool operator>(const basic_string<Pt::Char>& a, const wchar_t* b)
1372 { return a.compare(b) > 0; }
1373 
1378 inline bool operator>(const wchar_t* b, const basic_string<Pt::Char>& a)
1379 { return a.compare(b) < 0; }
1380 
1385 inline bool operator>(const basic_string<Pt::Char>& a, const char* b)
1386 { return a.compare(b) > 0; }
1387 
1392 inline bool operator>(const char* b, const basic_string<Pt::Char>& a)
1393 { return a.compare(b) < 0; }
1394 
1395 // operator >=
1396 
1401 inline bool operator>=(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1402 { return a.compare(b) >= 0; }
1403 
1408 inline bool operator>=(const Pt::Char* a, const basic_string<Pt::Char>& b)
1409 { return b.compare(a) <= 0; }
1410 
1415 inline bool operator>=(const basic_string<Pt::Char>& a, const Pt::Char* b)
1416 { return a.compare(b) >= 0; }
1417 
1422 inline bool operator>=(const basic_string<Pt::Char>& a, const wchar_t* b)
1423 { return a.compare(b) >= 0; }
1424 
1429 inline bool operator>=(const wchar_t* b, const basic_string<Pt::Char>& a)
1430 { return a.compare(b) <= 0; }
1431 
1436 inline bool operator>=(const basic_string<Pt::Char>& a, const char* b)
1437 { return a.compare(b) >= 0; }
1438 
1443 inline bool operator>=(const char* b, const basic_string<Pt::Char>& a)
1444 { return a.compare(b) <= 0; }
1445 
1450 //PT_API basic_istream<Pt::Char>& operator>>(basic_istream<Pt::Char>& is,
1451 // basic_string<Pt::Char>& str);
1452 
1457 PT_API ostream& operator<< (ostream& out, const basic_string<Pt::Char>& str);
1458 
1459 } // namespace std
1460 
1461 namespace Pt {
1462 
1463 typedef std::basic_string<Pt::Char> String;
1464 
1465 }
1466 
1467 #ifdef PT_WITH_STD_LOCALE
1468 #include <Pt/Facets.h>
1469 #endif
1470 
1471 // Include the implementation header
1472 #include <Pt/String.tpp>
1473 
1474 #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
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
uint_type uint32_t
Unsigned 32-bit integer type.
Definition: Api-Types.h:48
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