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 class Char
67 {
68  public:
70  Char()
71  : _value(0)
72  {}
73 
75  Char(char ch)
76  : _value( (unsigned char)ch )
77  {}
78 
80  Char(int val)
81  : _value( (unsigned)(val) )
82  {}
83 
86  : _value(val)
87  {}
88 
90  uint32_t value() const
91  { return _value; }
92 
94  operator uint32_t() const
95  { return _value; }
96 
98  Char& operator=(const Char& ch)
99  {
100  _value = ch._value;
101  return *this;
102  }
103 
109  char narrow(char def = '?') const
110  {
111  return _value > 0xff ? def : static_cast<char>(_value);
112  }
113 
114  private:
115  Pt::uint32_t _value;
116 };
117 
119 PT_API std::ctype_base::mask ctypeMask(const Char& ch);
120 
125 inline int isalpha(const Char& ch)
126 {
127  return ctypeMask(ch) & std::ctype_base::alpha;
128 }
129 
134 inline int isalnum(const Char& ch)
135 {
136  return ctypeMask(ch) & std::ctype_base::alnum;
137 }
138 
143 inline int ispunct(const Char& ch)
144 {
145  return ctypeMask(ch) & std::ctype_base::punct;
146 }
147 
152 inline int iscntrl(const Char& ch)
153 {
154  return ctypeMask(ch) & std::ctype_base::cntrl;
155 }
161 inline int isdigit(const Char& ch)
162 {
163  return ctypeMask(ch) & std::ctype_base::digit;
164 }
165 
170 inline int isxdigit(const Char& ch)
171 {
172  return ctypeMask(ch) & std::ctype_base::xdigit;
173 }
174 
179 inline int isgraph(const Char& ch)
180 {
181  return ctypeMask(ch) & std::ctype_base::graph;
182 }
183 
188 inline int islower(const Char& ch)
189 {
190  return ctypeMask(ch) & std::ctype_base::lower;
191 }
192 
197 inline int isupper(const Char& ch)
198 {
199  return ctypeMask(ch) & std::ctype_base::upper;
200 }
201 
206 inline int isprint(const Char& ch)
207 {
208  return ctypeMask(ch) & std::ctype_base::print;
209 }
210 
215 inline int isspace(const Char& ch)
216 {
217  return ctypeMask(ch) & std::ctype_base::space;
218 }
224 PT_API Char tolower(const Char& ch);
225 
230 PT_API Char toupper(const Char& ch);
231 
232 
233 struct MBState
234 {
235  MBState()
236  : n(0)
237  , value()
238  {}
240  int n;
241  union {
242  Pt::uint32_t wchars[4];
243  char mbytes[16];
244  } value;
245 };
246 
247 } // namespace Pt
248 
249 namespace std {
250 
251 template<>
252 struct char_traits<Pt::Char>
253 {
254  typedef Pt::Char char_type;
255  typedef Pt::uint32_t int_type;
256  typedef streamoff off_type;
257  typedef streampos pos_type;
258  typedef Pt::MBState state_type;
260  inline static void assign(char_type& c1, const char_type& c2)
261  {
262  c1 = c2;
263  }
265  inline static bool eq(const char_type& c1, const char_type& c2)
266  {
267  return c1 == c2;
268  }
269 
270  inline static bool lt(const char_type& c1, const char_type& c2)
271  {
272  return c1 < c2;
273  }
274 
275  inline static int compare(const char_type* s1, const char_type* s2, std::size_t n)
276  {
277  while(n-- > 0)
278  {
279  if( ! eq(*s1, *s2) )
280  return lt(*s1, *s2) ? -1 : +1;
281 
282  ++s1;
283  ++s2;
284  }
285 
286  return 0;
287  }
288 
289  inline static std::size_t length(const char_type* s)
290  {
291  const Pt::Char term(0);
292 
293  std::size_t n = 0;
294  while( ! eq(s[n], term) )
295  ++n;
296 
297  return n;
298  }
299 
300  inline static const char_type* find(const char_type* s, std::size_t n, const char_type& a)
301  {
302  while(n-- > 0)
303  {
304  if (*s == a)
305  return s;
306 
307  ++s;
308  }
309 
310  return 0;
311  }
312 
313  inline static char_type* move(char_type* s1, const char_type* s2, std::size_t n)
314  {
315  return (Pt::Char*) std::memmove(s1, s2, n * sizeof(Pt::Char));
316  }
317 
318  inline static char_type* copy(char_type* s1, const char_type* s2, std::size_t n)
319  {
320  return (Pt::Char*) std::memcpy(s1, s2, n * sizeof(Pt::Char));
321  }
322 
323  inline static char_type* assign(char_type* s, std::size_t n, char_type a)
324  {
325  while(n-- > 0)
326  *(s++) = a;
327 
328  return s;
329  }
330 
331  inline static char_type to_char_type(const int_type& c)
332  {
333  return char_type(c);
334  }
335 
336  inline static int_type to_int_type(const char_type& c)
337  {
338  return c.value();
339  }
340 
341  inline static bool eq_int_type(const int_type& c1, const int_type& c2)
342  {
343  return c1 == c2;
344  }
345 
346  inline static int_type eof()
347  {
348  return Pt::uint32_t(-1);
349  }
350 
351  inline static int_type not_eof(const int_type& c)
352  {
353  return eq_int_type(c, eof()) ? 0 : c;
354  }
355 };
356 
359 template <>
360 class PT_API basic_string<Pt::Char>
361 {
362  public:
363  typedef Pt::Char value_type;
364  typedef std::size_t size_type;
365  typedef char_traits< Pt::Char > traits_type;
366  typedef std::allocator<Pt::Char> allocator_type;
367  typedef allocator_type::difference_type difference_type;
368  typedef allocator_type::reference reference;
369  typedef allocator_type::const_reference const_reference;
370  typedef allocator_type::pointer pointer;
371  typedef allocator_type::const_pointer const_pointer;
372  typedef value_type* iterator;
373  typedef const value_type* const_iterator;
374 
375 #ifdef _RWSTD_NO_CLASS_PARTIAL_SPEC
376  typedef std::reverse_iterator<const_iterator,
377  random_access_iterator_tag, value_type>
378  const_reverse_iterator;
379 
380  typedef std::reverse_iterator<iterator,
381  random_access_iterator_tag, value_type>
382  reverse_iterator;
383 #else
384  typedef std::reverse_iterator<iterator> reverse_iterator;
385  typedef const std::reverse_iterator<const_iterator> const_reverse_iterator;
386 #endif
387 
388  static const size_type npos = static_cast<size_type>(-1);
389 
390  public:
393  explicit basic_string( const allocator_type& a = allocator_type());
394 
397  basic_string(const Pt::Char* str, const allocator_type& a = allocator_type());
398 
401  basic_string(const Pt::Char* str, size_type n, const allocator_type& a = allocator_type());
402 
405  basic_string(const wchar_t* str, const allocator_type& a = allocator_type());
406 
409  basic_string(const wchar_t* str, size_type n, const allocator_type& a = allocator_type());
410 
413  basic_string(const char* str, const allocator_type& a = allocator_type());
414 
417  basic_string(const char* str, size_type n, const allocator_type& a = allocator_type());
418 
421  basic_string(size_type n, Pt::Char c, const allocator_type& a = allocator_type());
422 
425  basic_string(const basic_string& str);
426 
429  basic_string(const basic_string& str, const allocator_type& a);
430 
433  basic_string(const basic_string& str, size_type pos, size_type n = npos, const allocator_type& a = allocator_type());
434 
437  basic_string(const Pt::Char* begin, const Pt::Char* end, const allocator_type& a = allocator_type());
438 
439  template <typename InputIterator>
440  basic_string(InputIterator begin, InputIterator end, const allocator_type& a = allocator_type());
441 
444  ~basic_string();
445 
446  public:
449  iterator begin()
450  { return privdata_rw(); }
451 
454  iterator end()
455  { return privdata_rw() + length(); }
456 
459  const_iterator begin() const
460  { return privdata_ro(); }
461 
464  const_iterator end() const
465  { return privdata_ro() + length(); }
466 
469  reverse_iterator rbegin()
470  { return reverse_iterator( this->end() ); }
471 
474  reverse_iterator rend()
475  { return reverse_iterator( this->begin() ); }
476 
479  const_reverse_iterator rbegin() const
480  { return const_reverse_iterator( this->end() ); }
481 
484  const_reverse_iterator rend() const
485  { return const_reverse_iterator( this->begin() ); }
486 
489  reference operator[](size_type n)
490  { return privdata_rw()[n]; }
491 
494  const_reference operator[](size_type n) const
495  { return privdata_ro()[n]; }
499  reference at(size_type n)
500  {
501  if( n >= size() )
502  throw out_of_range("at");
503 
504  return privdata_rw()[n];
505  }
506 
509  const_reference at(size_type n) const
510  {
511  if( n >= size() )
512  throw out_of_range("at");
513 
514  return privdata_ro()[n];
515  }
516 
517  public:
520  void push_back(Pt::Char ch)
521  { (*this) += ch; }
522 
525  void resize( std::size_t n, Pt::Char ch = value_type() );
526 
529  void reserve(std::size_t n = 0);
530 
533  void swap(basic_string& str);
537  allocator_type get_allocator() const
538  { return _d; }
539 
542  size_type copy(Pt::Char* a, size_type n, size_type pos = 0) const;
546  basic_string substr(size_type pos = 0, size_type n = npos) const
547  { return basic_string(*this, pos, n); }
548 
549  public:
552  size_type length() const
553  { return isShortString() ? shortStringLength() : longStringLength(); }
554 
557  size_type size() const
558  { return length(); }
559 
562  bool empty() const
563  { return length() == 0; }
564 
567  size_type max_size() const
568  { return ( size_type(-1) / sizeof(Pt::Char) ) - 1; }
569 
572  size_type capacity() const
573  { return isShortString() ? shortStringCapacity() : longStringCapacity(); }
574 
577  const Pt::Char* data() const
578  { return privdata_ro(); }
579 
582  const Pt::Char* c_str() const
583  { return privdata_ro(); }
584 
587  basic_string& assign(const basic_string& str);
588 
591  basic_string& assign(const basic_string& str, size_type pos, size_type n);
592 
595  basic_string& assign(const wchar_t* str);
596 
599  basic_string& assign(const wchar_t* str, size_type n);
600 
603  basic_string& assign(const Pt::Char* str);
607  basic_string& assign(const Pt::Char* str, size_type length);
608 
611  basic_string& assign(const char* str);
612 
615  basic_string& assign(const char* str, size_type length);
616 
619  basic_string& assign(size_type n, Pt::Char c);
620 
621  template <typename InputIterator>
622  basic_string& assign(InputIterator begin, InputIterator end);
623 
626  basic_string& append(const Pt::Char* str);
627 
630  basic_string& append(const Pt::Char* str, size_type n);
634  basic_string& append(size_type n, Pt::Char ch);
635 
638  basic_string& append(const basic_string& str);
639 
642  basic_string& append(const basic_string& str, size_type pos, size_type n);
643 
644  template <typename InputIterator>
645  basic_string& append(InputIterator begin, InputIterator end);
646 
649  basic_string& append(const Pt::Char* begin, const Pt::Char* end);
650 
653  basic_string& insert(size_type pos, const Pt::Char* str);
654 
657  basic_string& insert(size_type pos, const Pt::Char* str, size_type n);
658 
661  basic_string& insert(size_type pos, size_type n, Pt::Char ch);
662 
665  basic_string& insert(size_type pos, const basic_string& str);
666 
669  basic_string& insert(size_type pos, const basic_string& str, size_type pos2, size_type n);
670 
673  basic_string& insert(iterator p, Pt::Char ch);
674 
677  basic_string& insert(iterator p, size_type n, Pt::Char ch);
678 
679  // unimplemented
680  //template <typename InputIterator>
681  //basic_string& insert(iterator p, InputIterator first, InputIterator last);
682 
685  void clear()
686  { setLength(0); }
687 
690  basic_string& erase(size_type pos = 0, size_type n = npos);
691 
694  iterator erase(iterator pos);
695 
698  iterator erase(iterator first, iterator last);
699 
702  basic_string& replace(size_type pos, size_type n, const Pt::Char* str);
703 
706  basic_string& replace(size_type pos, size_type n, const Pt::Char* str, size_type n2);
707 
710  basic_string& replace(size_type pos, size_type n, size_type n2, Pt::Char ch);
711 
714  basic_string& replace(size_type pos, size_type n, const basic_string& str);
715 
718  basic_string& replace(size_type pos, size_type n, const basic_string& str, size_type pos2, size_type n2);
719 
722  basic_string& replace(iterator i1, iterator i2, const Pt::Char* str);
723 
726  basic_string& replace(iterator i1, iterator i2, const Pt::Char* str, size_type n);
727 
730  basic_string& replace(iterator i1, iterator i2, size_type n, Pt::Char ch);
731 
734  basic_string& replace(iterator i1, iterator i2, const basic_string& str);
735 
738  int compare(const basic_string& str) const;
739 
742  int compare(const Pt::Char* str) const;
743 
746  int compare(const Pt::Char* str, size_type n) const;
747 
750  int compare(const wchar_t* str) const;
751 
754  int compare(const wchar_t* str, size_type n) const;
755 
758  int compare(const char* str) const;
759 
762  int compare(const char* str, size_type n) const;
766  int compare(size_type pos, size_type n, const basic_string& str) const;
767 
770  int compare(size_type pos, size_type n, const basic_string& str, size_type pos2, size_type n2) const;
771 
774  int compare(size_type pos, size_type n, const Pt::Char* str) const;
775 
778  int compare(size_type pos, size_type n, const Pt::Char* str, size_type n2) const;
779 
782  size_type find(const basic_string& str, size_type pos = 0) const;
783 
786  size_type find(const Pt::Char* str, size_type pos, size_type n) const;
787 
790  size_type find(const Pt::Char* str, size_type pos = 0) const;
794  size_type find(Pt::Char ch, size_type pos = 0) const;
795 
798  size_type rfind(const basic_string& str, size_type pos = npos) const;
799 
802  size_type rfind(const Pt::Char* str, size_type pos, size_type n) const;
803 
806  size_type rfind(const Pt::Char* str, size_type pos = npos) const;
810  size_type rfind(Pt::Char ch, size_type pos = npos) const;
811 
814  size_type find_first_of(const basic_string& str, size_type pos = 0) const
815  { return this->find_first_of( str.data(), pos, str.size() ); }
816 
819  size_type find_first_of(const Pt::Char* s, size_type pos, size_type n) const;
820 
823  size_type find_first_of(const Pt::Char* str, size_type pos = 0) const
824  { return this->find_first_of( str, pos, traits_type::length(str) ); }
825 
828  size_type find_first_of(const Pt::Char ch, size_type pos = 0) const
829  { return this->find(ch, pos); }
830 
833  size_type find_last_of(const basic_string& str, size_type pos = npos) const
834  { return this->find_last_of( str.data(), pos, str.size() ); }
838  size_type find_last_of(const Pt::Char* s, size_type pos, size_type n) const;
839 
842  size_type find_last_of(const Pt::Char* str, size_type pos = npos) const
843  { return this->find_last_of( str, pos, traits_type::length(str) ); }
844 
847  size_type find_last_of(const Pt::Char ch, size_type pos = npos) const
848  { return this->rfind(ch, pos); }
849 
852  size_type find_first_not_of(const basic_string& str, size_type pos = 0) const
853  { return this->find_first_not_of( str.data(), pos, str.size() ); }
854 
857  size_type find_first_not_of(const Pt::Char* s, size_type pos, size_type n) const;
861  size_type find_first_not_of(const Pt::Char* str, size_type pos = 0) const
862  { return this->find_first_not_of( str, pos, traits_type::length(str) ); }
863 
866  size_type find_first_not_of(const Pt::Char ch, size_type pos = 0) const;
867 
870  size_type find_last_not_of(const basic_string& str, size_type pos = npos) const
871  { return this->find_last_not_of( str.data(), pos, str.size() ); }
875  size_type find_last_not_of(const Pt::Char* tok, size_type pos, size_type n) const;
876 
879  size_type find_last_not_of(const Pt::Char* str, size_type pos = npos) const
880  { return this->find_last_not_of( str, pos, traits_type::length(str) ); }
881 
884  size_type find_last_not_of(Pt::Char ch, size_type pos = npos) const;
885 
886  public:
889  std::string narrow(char dfault = '?') const;
890 
893  static basic_string widen(const char* str);
894 
897  static basic_string widen(const std::string& str);
898 
901  template <typename OutIterT>
902  OutIterT toUtf16(OutIterT to) const;
903 
906  template <typename InIterT>
907  static basic_string fromUtf16(InIterT from, InIterT fromEnd);
908 
909  public:
912  basic_string& operator=(const basic_string& str)
913  { return this->assign(str); }
914 
917  basic_string& operator=(const wchar_t* str)
918  { return this->assign(str); }
919 
922  basic_string& operator=(const char* str)
923  { return this->assign(str); }
924 
927  basic_string& operator=(const Pt::Char* str)
928  { return this->assign(str); }
929 
932  basic_string& operator=(Pt::Char ch)
933  {
934  // no privreserve(1), short string capacity is large enough
935 
936  Pt::Char* p = privdata_rw();
937  p[0] = ch;
938  setLength(1);
939  return *this;
940  }
941 
944  basic_string& operator+=(const basic_string& str)
945  { return this->append(str); }
946 
949  basic_string& operator+=(const Pt::Char* str)
950  { return this->append(str); }
951 
954  basic_string& operator+=(Pt::Char c);
955 
956  private:
957  struct Ptr
958  {
959  Pt::Char* _begin;
960  Pt::Char* _end;
961  Pt::Char* _capacity;
962  };
963 
964  // minimum possible short string character count
965  static const unsigned _minN = (sizeof(Ptr) / sizeof(Pt::Char)) + 1;
966 
967  // short string character count
968  static const unsigned _nN = _minN < 8 ? 8 : _minN;
969 
970  // short string raw storage size in bytes
971  static const unsigned _nS = _nN * sizeof(Pt::Char);
972 
973  struct Data : public allocator_type
974  {
975  Data(const allocator_type& a)
976  : allocator_type(a)
977  {
978  Pt::Char* str = reinterpret_cast<Pt::Char*>(&_u._s[0]);
979  *str = 0;
980 
981  _u._s[_nS - 1] = _nN - 1;
982  }
983 
984  union
985  {
986  Ptr _p;
987  unsigned char _s[_nS];
988  } _u;
989  } _d;
990 
991  private:
992  const Pt::Char* privdata_ro() const
993  { return isShortString() ? shortStringData() : longStringData(); }
994 
995  Pt::Char* privdata_rw()
996  { return isShortString() ? shortStringData() : longStringData(); }
997 
998  void privreserve(std::size_t n);
999 
1000  bool isShortString() const
1001  { return shortStringMagic() != 0xff; }
1002 
1003  void markLongString()
1004  { shortStringMagic() = 0xff; }
1005 
1006  const Pt::Char* shortStringData() const
1007  { return reinterpret_cast<const Pt::Char*>(&_d._u._s[0]); }
1008 
1009  Pt::Char* shortStringData()
1010  { return reinterpret_cast<Pt::Char*>(&_d._u._s[0]); }
1012  unsigned char shortStringMagic() const
1013  { return _d._u._s[_nS - 1]; }
1014 
1015  unsigned char& shortStringMagic()
1016  { return _d._u._s[_nS - 1]; }
1017 
1018  size_type shortStringLength() const
1019  { return _nN - 1 - shortStringMagic(); }
1020 
1021  size_type shortStringCapacity() const
1022  { return _nN - 1; }
1023 
1024  void setShortStringLength(size_type n)
1025  {
1026  shortStringData()[n] = Pt::Char(0);
1027  shortStringMagic() = static_cast<unsigned char>(_nN - n - 1);
1028  }
1029 
1030  void shortStringAssign(const Pt::Char* str, size_type n)
1031  {
1032  traits_type::copy(shortStringData(), str, n);
1033  shortStringData()[n] = Pt::Char(0);
1034  shortStringMagic() = static_cast<unsigned char>(_nN - n - 1);
1035  }
1036  void shortStringAssign(const wchar_t* str, size_type n)
1037  {
1038  for (size_type nn = 0; nn < n; ++nn)
1039  shortStringData()[nn] = str[nn];
1040  shortStringData()[n] = Pt::Char(0);
1041  shortStringMagic() = static_cast<unsigned char>(_nN - n - 1);
1042  }
1043 
1044  const Pt::Char* longStringData() const
1045  { return _d._u._p._begin; }
1047  Pt::Char* longStringData()
1048  { return _d._u._p._begin; }
1049 
1050  size_type longStringLength() const
1051  { return _d._u._p._end - _d._u._p._begin; }
1052 
1053  size_type longStringCapacity() const
1054  { return _d._u._p._capacity - _d._u._p._begin; }
1056  void setLength(size_type n)
1057  {
1058  if (isShortString())
1059  setShortStringLength(n);
1060  else
1061  {
1062  _d._u._p._end = _d._u._p._begin + n;
1063  _d._u._p._begin[n] = 0;
1064  }
1065  }
1066 };
1067 
1072 inline void swap(basic_string<Pt::Char>& a, basic_string<Pt::Char>& b)
1073 { a.swap(b); }
1074 
1075 // operator +
1081 inline basic_string<Pt::Char> operator+(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1082 { basic_string<Pt::Char> temp; temp += a; temp += b; return temp; }
1088 inline basic_string<Pt::Char> operator+(const basic_string<Pt::Char>& a, const Pt::Char* b)
1089 { basic_string<Pt::Char> temp; temp += a; temp += b; return temp; }
1095 inline basic_string<Pt::Char> operator+(const Pt::Char* a, const basic_string<Pt::Char>& b)
1096 { basic_string<Pt::Char> temp; temp += a; temp += b; return temp; }
1102 inline basic_string<Pt::Char> operator+(const basic_string<Pt::Char>& a, Pt::Char b)
1103 { basic_string<Pt::Char> temp; temp += a; temp += b; return temp; }
1104 
1109 inline basic_string<Pt::Char> operator+(Pt::Char a, const basic_string<Pt::Char>& b)
1110 { basic_string<Pt::Char> temp; temp += a; temp += b; return temp; }
1111 
1112 // operator ==
1113 
1118 inline bool operator==(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1119 { return a.compare(b) == 0; }
1120 
1125 inline bool operator==(const Pt::Char* a, const basic_string<Pt::Char>& b)
1126 { return b.compare(a) == 0; }
1127 
1132 inline bool operator==(const basic_string<Pt::Char>& a, const Pt::Char* b)
1133 { return a.compare(b) == 0; }
1134 
1139 inline bool operator==(const basic_string<Pt::Char>& a, const wchar_t* b)
1140 { return a.compare(b) == 0; }
1141 
1146 inline bool operator==(const wchar_t* b, const basic_string<Pt::Char>& a)
1147 { return a.compare(b) == 0; }
1148 
1153 inline bool operator==(const basic_string<Pt::Char>& a, const char* b)
1154 { return a.compare(b) == 0; }
1155 
1160 inline bool operator==(const char* b, const basic_string<Pt::Char>& a)
1161 { return a.compare(b) == 0; }
1162 
1163 // operator !=
1164 
1169 inline bool operator!=(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1170 { return a.compare(b) != 0; }
1171 
1176 inline bool operator!=(const Pt::Char* a, const basic_string<Pt::Char>& b)
1177 { return b.compare(a) != 0; }
1178 
1183 inline bool operator!=(const basic_string<Pt::Char>& a, const Pt::Char* b)
1184 { return a.compare(b) != 0; }
1185 
1190 inline bool operator!=(const basic_string<Pt::Char>& a, const wchar_t* b)
1191 { return a.compare(b) != 0; }
1192 
1197 inline bool operator!=(const wchar_t* b, const basic_string<Pt::Char>& a)
1198 { return a.compare(b) != 0; }
1199 
1204 inline bool operator!=(const basic_string<Pt::Char>& a, const char* b)
1205 { return a.compare(b) != 0; }
1206 
1211 inline bool operator!=(const char* b, const basic_string<Pt::Char>& a)
1212 { return a.compare(b) != 0; }
1213 
1214 // operator <
1215 
1220 inline bool operator<(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1221 { return a.compare(b) < 0; }
1222 
1227 inline bool operator<(const Pt::Char* a, const basic_string<Pt::Char>& b)
1228 { return b.compare(a) > 0; }
1229 
1234 inline bool operator<(const basic_string<Pt::Char>& a, const Pt::Char* b)
1235 { return a.compare(b) < 0; }
1236 
1241 inline bool operator<(const basic_string<Pt::Char>& a, const wchar_t* b)
1242 { return a.compare(b) < 0; }
1243 
1248 inline bool operator<(const wchar_t* b, const basic_string<Pt::Char>& a)
1249 { return a.compare(b) > 0; }
1250 
1255 inline bool operator<(const basic_string<Pt::Char>& a, const char* b)
1256 { return a.compare(b) < 0; }
1257 
1262 inline bool operator<(const char* b, const basic_string<Pt::Char>& a)
1263 { return a.compare(b) > 0; }
1264 
1265 // operator <=
1266 
1271 inline bool operator<=(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1272 { return a.compare(b) <= 0; }
1273 
1278 inline bool operator<=(const Pt::Char* a, const basic_string<Pt::Char>& b)
1279 { return b.compare(a) >= 0; }
1280 
1285 inline bool operator<=(const basic_string<Pt::Char>& a, const Pt::Char* b)
1286 { return a.compare(b) <= 0; }
1287 
1292 inline bool operator<=(const basic_string<Pt::Char>& a, const wchar_t* b)
1293 { return a.compare(b) <= 0; }
1294 
1299 inline bool operator<=(const wchar_t* b, const basic_string<Pt::Char>& a)
1300 { return a.compare(b) >= 0; }
1301 
1306 inline bool operator<=(const basic_string<Pt::Char>& a, const char* b)
1307 { return a.compare(b) <= 0; }
1308 
1313 inline bool operator<=(const char* b, const basic_string<Pt::Char>& a)
1314 { return a.compare(b) >= 0; }
1315 
1316 // operator >
1317 
1322 inline bool operator>(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1323 { return a.compare(b) > 0; }
1324 
1329 inline bool operator>(const Pt::Char* a, const basic_string<Pt::Char>& b)
1330 { return b.compare(a) < 0; }
1331 
1336 inline bool operator>(const basic_string<Pt::Char>& a, const Pt::Char* b)
1337 { return a.compare(b) > 0; }
1338 
1343 inline bool operator>(const basic_string<Pt::Char>& a, const wchar_t* b)
1344 { return a.compare(b) > 0; }
1345 
1350 inline bool operator>(const wchar_t* b, const basic_string<Pt::Char>& a)
1351 { return a.compare(b) < 0; }
1352 
1357 inline bool operator>(const basic_string<Pt::Char>& a, const char* b)
1358 { return a.compare(b) > 0; }
1359 
1364 inline bool operator>(const char* b, const basic_string<Pt::Char>& a)
1365 { return a.compare(b) < 0; }
1366 
1367 // operator >=
1368 
1373 inline bool operator>=(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1374 { return a.compare(b) >= 0; }
1375 
1380 inline bool operator>=(const Pt::Char* a, const basic_string<Pt::Char>& b)
1381 { return b.compare(a) <= 0; }
1382 
1387 inline bool operator>=(const basic_string<Pt::Char>& a, const Pt::Char* b)
1388 { return a.compare(b) >= 0; }
1389 
1394 inline bool operator>=(const basic_string<Pt::Char>& a, const wchar_t* b)
1395 { return a.compare(b) >= 0; }
1396 
1401 inline bool operator>=(const wchar_t* b, const basic_string<Pt::Char>& a)
1402 { return a.compare(b) <= 0; }
1403 
1408 inline bool operator>=(const basic_string<Pt::Char>& a, const char* b)
1409 { return a.compare(b) >= 0; }
1410 
1415 inline bool operator>=(const char* b, const basic_string<Pt::Char>& a)
1416 { return a.compare(b) <= 0; }
1417 
1422 PT_API ostream& operator<< (ostream& out, const basic_string<Pt::Char>& str);
1423 
1424 } // namespace std
1425 
1426 namespace Pt {
1427 
1428 typedef std::basic_string<Pt::Char> String;
1429 
1430 }
1431 
1432 #ifdef PT_WITH_STD_LOCALE
1433 #include <Pt/Facets.h>
1434 #endif
1435 
1436 // Include the implementation header
1437 #include <Pt/String.tpp>
1438 
1439 #endif
int isgraph(const Char &ch)
Checks whether ch is a graphical character.
Definition: String.h:179
int islower(const Char &ch)
Checks whether ch is lower case.
Definition: String.h:188
int isspace(const Char &ch)
Checks whether ch is a whitespace character.
Definition: String.h:215
R narrow(T from)
Checked numeric conversion.
Definition: Convert.h:112
int isalnum(const Char &ch)
Checks whether ch is a alphanumeric character.
Definition: String.h:134
uint32_t value() const
Returns the unicode value.
Definition: String.h:90
Char(int val)
Construct from int.
Definition: String.h:80
Char & operator=(const Char &ch)
Assignment operator.
Definition: String.h:98
Unicode character type.
Definition: String.h:66
int iscntrl(const Char &ch)
Checks whether ch is a control character.
Definition: String.h:152
char narrow(char def= '?') const
Narrows the character to 8-bit.
Definition: String.h:109
int isalpha(const Char &ch)
Checks whether ch is a alphabetic character.
Definition: String.h:125
int ispunct(const Char &ch)
Checks whether ch is a punctuation character.
Definition: String.h:143
uint_type uint32_t
Unsigned 32-bit integer type.
Definition: Types.h:42
int isupper(const Char &ch)
Checks whether ch is upper case.
Definition: String.h:197
int isxdigit(const Char &ch)
Checks whether ch is a hexadecimal digit.
Definition: String.h:170
Char(uint32_t val)
Construct from unsigned 32-bit integer.
Definition: String.h:85
int isprint(const Char &ch)
Checks whether ch is a printable character.
Definition: String.h:206
Char(char ch)
Construct from char.
Definition: String.h:75
Char()
Default Constructor.
Definition: String.h:70