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
43namespace Pt {
44
66struct Char
67{
68 public:
69#if __cplusplus >= 201103L
71 Char() = default;
72#else
74 Char()
75 : _value()
76 {}
77#endif
79 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
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
127namespace std {
128
129template <>
130struct is_trivial<Pt::Char> {
131 static const bool value = true;
132};
133
134} // namespace
135
136#endif
137
138namespace Pt {
139
141PT_API std::ctype_base::mask ctypeMask(const Char& ch);
142
147inline int isalpha(const Char& ch)
148{
149 return ctypeMask(ch) & std::ctype_base::alpha;
150}
151
156inline int isalnum(const Char& ch)
157{
158 return ctypeMask(ch) & std::ctype_base::alnum;
159}
160
165inline int ispunct(const Char& ch)
166{
167 return ctypeMask(ch) & std::ctype_base::punct;
168}
169
174inline int iscntrl(const Char& ch)
175{
176 return ctypeMask(ch) & std::ctype_base::cntrl;
177}
178
183inline int isdigit(const Char& ch)
184{
185 return ctypeMask(ch) & std::ctype_base::digit;
186}
187
192inline int isxdigit(const Char& ch)
193{
194 return ctypeMask(ch) & std::ctype_base::xdigit;
195}
196
201inline int isgraph(const Char& ch)
202{
203 return ctypeMask(ch) & std::ctype_base::graph;
204}
205
210inline int islower(const Char& ch)
211{
212 return ctypeMask(ch) & std::ctype_base::lower;
213}
214
219inline int isupper(const Char& ch)
220{
221 return ctypeMask(ch) & std::ctype_base::upper;
222}
223
228inline int isprint(const Char& ch)
229{
230 return ctypeMask(ch) & std::ctype_base::print;
231}
232
237inline int isspace(const Char& ch)
238{
239 return ctypeMask(ch) & std::ctype_base::space;
240}
241
246PT_API Char tolower(const Char& ch);
247
252PT_API Char toupper(const Char& ch);
253
254
255struct 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
271namespace std {
272
273template<>
274struct 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
385template <>
386class 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
1108inline void swap(basic_string<Pt::Char>& a, basic_string<Pt::Char>& b)
1109{ a.swap(b); }
1110
1111// operator +
1112
1117inline 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
1124inline 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
1131inline 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
1138inline 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
1145inline 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
1154inline bool operator==(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1155{ return a.compare(b) == 0; }
1156
1161inline bool operator==(const Pt::Char* a, const basic_string<Pt::Char>& b)
1162{ return b.compare(a) == 0; }
1163
1168inline bool operator==(const basic_string<Pt::Char>& a, const Pt::Char* b)
1169{ return a.compare(b) == 0; }
1170
1175inline bool operator==(const basic_string<Pt::Char>& a, const wchar_t* b)
1176{ return a.compare(b) == 0; }
1177
1182inline bool operator==(const wchar_t* b, const basic_string<Pt::Char>& a)
1183{ return a.compare(b) == 0; }
1184
1189inline bool operator==(const basic_string<Pt::Char>& a, const char* b)
1190{ return a.compare(b) == 0; }
1191
1196inline bool operator==(const char* b, const basic_string<Pt::Char>& a)
1197{ return a.compare(b) == 0; }
1198
1199// operator !=
1200
1205inline bool operator!=(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1206{ return a.compare(b) != 0; }
1207
1212inline bool operator!=(const Pt::Char* a, const basic_string<Pt::Char>& b)
1213{ return b.compare(a) != 0; }
1214
1219inline bool operator!=(const basic_string<Pt::Char>& a, const Pt::Char* b)
1220{ return a.compare(b) != 0; }
1221
1226inline bool operator!=(const basic_string<Pt::Char>& a, const wchar_t* b)
1227{ return a.compare(b) != 0; }
1228
1233inline bool operator!=(const wchar_t* b, const basic_string<Pt::Char>& a)
1234{ return a.compare(b) != 0; }
1235
1240inline bool operator!=(const basic_string<Pt::Char>& a, const char* b)
1241{ return a.compare(b) != 0; }
1242
1247inline bool operator!=(const char* b, const basic_string<Pt::Char>& a)
1248{ return a.compare(b) != 0; }
1249
1250// operator <
1251
1256inline bool operator<(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1257{ return a.compare(b) < 0; }
1258
1263inline bool operator<(const Pt::Char* a, const basic_string<Pt::Char>& b)
1264{ return b.compare(a) > 0; }
1265
1270inline bool operator<(const basic_string<Pt::Char>& a, const Pt::Char* b)
1271{ return a.compare(b) < 0; }
1272
1277inline bool operator<(const basic_string<Pt::Char>& a, const wchar_t* b)
1278{ return a.compare(b) < 0; }
1279
1284inline bool operator<(const wchar_t* b, const basic_string<Pt::Char>& a)
1285{ return a.compare(b) > 0; }
1286
1291inline bool operator<(const basic_string<Pt::Char>& a, const char* b)
1292{ return a.compare(b) < 0; }
1293
1298inline bool operator<(const char* b, const basic_string<Pt::Char>& a)
1299{ return a.compare(b) > 0; }
1300
1301// operator <=
1302
1307inline bool operator<=(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1308{ return a.compare(b) <= 0; }
1309
1314inline bool operator<=(const Pt::Char* a, const basic_string<Pt::Char>& b)
1315{ return b.compare(a) >= 0; }
1316
1321inline bool operator<=(const basic_string<Pt::Char>& a, const Pt::Char* b)
1322{ return a.compare(b) <= 0; }
1323
1328inline bool operator<=(const basic_string<Pt::Char>& a, const wchar_t* b)
1329{ return a.compare(b) <= 0; }
1330
1335inline bool operator<=(const wchar_t* b, const basic_string<Pt::Char>& a)
1336{ return a.compare(b) >= 0; }
1337
1342inline bool operator<=(const basic_string<Pt::Char>& a, const char* b)
1343{ return a.compare(b) <= 0; }
1344
1349inline bool operator<=(const char* b, const basic_string<Pt::Char>& a)
1350{ return a.compare(b) >= 0; }
1351
1352// operator >
1353
1358inline bool operator>(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1359{ return a.compare(b) > 0; }
1360
1365inline bool operator>(const Pt::Char* a, const basic_string<Pt::Char>& b)
1366{ return b.compare(a) < 0; }
1367
1372inline bool operator>(const basic_string<Pt::Char>& a, const Pt::Char* b)
1373{ return a.compare(b) > 0; }
1374
1379inline bool operator>(const basic_string<Pt::Char>& a, const wchar_t* b)
1380{ return a.compare(b) > 0; }
1381
1386inline bool operator>(const wchar_t* b, const basic_string<Pt::Char>& a)
1387{ return a.compare(b) < 0; }
1388
1393inline bool operator>(const basic_string<Pt::Char>& a, const char* b)
1394{ return a.compare(b) > 0; }
1395
1400inline bool operator>(const char* b, const basic_string<Pt::Char>& a)
1401{ return a.compare(b) < 0; }
1402
1403// operator >=
1404
1409inline bool operator>=(const basic_string<Pt::Char>& a, const basic_string<Pt::Char>& b)
1410{ return a.compare(b) >= 0; }
1411
1416inline bool operator>=(const Pt::Char* a, const basic_string<Pt::Char>& b)
1417{ return b.compare(a) <= 0; }
1418
1423inline bool operator>=(const basic_string<Pt::Char>& a, const Pt::Char* b)
1424{ return a.compare(b) >= 0; }
1425
1430inline bool operator>=(const basic_string<Pt::Char>& a, const wchar_t* b)
1431{ return a.compare(b) >= 0; }
1432
1437inline bool operator>=(const wchar_t* b, const basic_string<Pt::Char>& a)
1438{ return a.compare(b) <= 0; }
1439
1444inline bool operator>=(const basic_string<Pt::Char>& a, const char* b)
1445{ return a.compare(b) >= 0; }
1446
1451inline 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
1465PT_API ostream& operator<< (ostream& out, const basic_string<Pt::Char>& str);
1466
1467} // namespace std
1468
1469namespace Pt {
1470
1471typedef 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
Unicode capable basic_string.
Definition Api-String.h:67
void swap(String &a, String &b)
Swaps two strings.
Definition Api-String.h:778
bool operator<=(const String &a, const String &b)
Compares two strings.
Definition Api-String.h:977
bool operator>(const String &a, const String &b)
Compares two strings.
Definition Api-String.h:1028
String operator+(const String &a, const String &b)
Concatenates two strings.
Definition Api-String.h:787
bool operator>=(const String &a, const String &b)
Compares two strings.
Definition Api-String.h:1079
R narrow(T from)
Checked numeric conversion.
Definition Convert.h:112
uint_type uint32_t
Unsigned 32-bit integer type.
Definition Api-Types.h:52
Core module.
Definition Allocator.h:33
Unicode character type.
Definition String.h:67
int isalnum(const Char &ch)
Checks whether ch is a alphanumeric character.
Definition String.h:156
int ispunct(const Char &ch)
Checks whether ch is a punctuation character.
Definition String.h:165
int isgraph(const Char &ch)
Checks whether ch is a graphical character.
Definition String.h:201
Char(char ch)
Construct from char.
Definition String.h:79
int isdigit(const Char &ch)
Checks whether ch is a decimal digit.
Definition String.h:183
char narrow(char def='?') const
Assignment operator.
Definition String.h:113
Char()=default
Default Constructor.
Char toupper(const Char &ch)
Convert a character to upper case.
Char tolower(const Char &ch)
Convert a character to lower case.
int isxdigit(const Char &ch)
Checks whether ch is a hexadecimal digit.
Definition String.h:192
int islower(const Char &ch)
Checks whether ch is lower case.
Definition String.h:210
uint32_t value() const
Returns the unicode value.
Definition String.h:94
int iscntrl(const Char &ch)
Checks whether ch is a control character.
Definition String.h:174
Char(int val)
Construct from int.
Definition String.h:84
int isalpha(const Char &ch)
Checks whether ch is a alphabetic character.
Definition String.h:147
int isspace(const Char &ch)
Checks whether ch is a whitespace character.
Definition String.h:237
int isprint(const Char &ch)
Checks whether ch is a printable character.
Definition String.h:228
int isupper(const Char &ch)
Checks whether ch is upper case.
Definition String.h:219
Char(uint32_t val)
Construct from unsigned 32-bit integer.
Definition String.h:89