35 #include <Pt/Locale.h>
69 #if __cplusplus >= 201103L
80 : _value( (
unsigned char)ch )
85 : _value( (unsigned)(val) )
115 return _value > 0xff ? def :
static_cast<char>(_value);
125 #if _LIBCPP_VERSION >= 5000 && __cplusplus < 201103L
130 struct is_trivial<
Pt::Char> {
131 static const bool value =
true;
141 PT_API std::ctype_base::mask ctypeMask(
const Char& ch);
149 return ctypeMask(ch) & std::ctype_base::alpha;
158 return ctypeMask(ch) & std::ctype_base::alnum;
167 return ctypeMask(ch) & std::ctype_base::punct;
176 return ctypeMask(ch) & std::ctype_base::cntrl;
185 return ctypeMask(ch) & std::ctype_base::digit;
194 return ctypeMask(ch) & std::ctype_base::xdigit;
203 return ctypeMask(ch) & std::ctype_base::graph;
212 return ctypeMask(ch) & std::ctype_base::lower;
221 return ctypeMask(ch) & std::ctype_base::upper;
230 return ctypeMask(ch) & std::ctype_base::print;
239 return ctypeMask(ch) & std::ctype_base::space;
274 struct char_traits<
Pt::Char>
278 typedef streamoff off_type;
279 typedef streampos pos_type;
280 typedef Pt::MBState state_type;
282 inline static void assign(char_type& c1,
const char_type& c2)
287 inline static bool eq(
const char_type& c1,
const char_type& c2)
292 inline static bool lt(
const char_type& c1,
const char_type& c2)
297 inline static int compare(
const char_type* s1,
const char_type* s2, std::size_t n)
302 return lt(*s1, *s2) ? -1 : +1;
311 inline static std::size_t length(
const char_type* s)
316 while( ! eq(s[n], term) )
322 inline static const char_type* find(
const char_type* s, std::size_t n,
const char_type& a)
335 inline static char_type* move(char_type* s1,
const char_type* s2, std::size_t n)
337 return (
Pt::Char*) std::memmove(
static_cast<void*
>(s1),
338 static_cast<const void*
>(s2),
342 inline static char_type* copy(char_type* s1,
const char_type* s2, std::size_t n)
344 return (
Pt::Char*) std::memcpy(
static_cast<void*
>(s1),
345 static_cast<const void*
>(s2),
349 inline static char_type* assign(char_type* s, std::size_t n, char_type a)
357 inline static char_type to_char_type(
const int_type& c)
362 inline static int_type to_int_type(
const char_type& c)
367 inline static bool eq_int_type(
const int_type& c1,
const int_type& c2)
372 inline static int_type eof()
377 inline static int_type not_eof(
const int_type& c)
379 return eq_int_type(c, eof()) ? 0 : c;
386 class PT_API basic_string<
Pt::Char>
391 typedef const Pt::Char& const_reference;
393 typedef const Pt::Char* const_pointer;
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;
400 typedef value_type* iterator;
401 typedef const value_type* const_iterator;
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;
408 typedef std::reverse_iterator<iterator,
409 random_access_iterator_tag, value_type>
412 typedef std::reverse_iterator<iterator> reverse_iterator;
413 typedef const std::reverse_iterator<const_iterator> const_reverse_iterator;
416 static const size_type npos =
static_cast<size_type
>(-1);
421 explicit basic_string(
const allocator_type& a = allocator_type());
425 basic_string(
const Pt::Char* str,
const allocator_type& a = allocator_type());
429 basic_string(
const Pt::Char* str, size_type n,
const allocator_type& a = allocator_type());
433 basic_string(
const wchar_t* str,
const allocator_type& a = allocator_type());
437 basic_string(
const wchar_t* str, size_type n,
const allocator_type& a = allocator_type());
441 basic_string(
const char* str,
const allocator_type& a = allocator_type());
445 basic_string(
const char* str, size_type n,
const allocator_type& a = allocator_type());
449 basic_string(size_type n,
Pt::Char c,
const allocator_type& a = allocator_type());
453 basic_string(
const basic_string& str);
457 basic_string(
const basic_string& str,
const allocator_type& a);
461 basic_string(
const basic_string& str, size_type pos, size_type n = npos,
const allocator_type& a = allocator_type());
465 basic_string(
const Pt::Char* begin,
const Pt::Char* end,
const allocator_type& a = allocator_type());
467 template <
typename InputIterator>
468 basic_string(InputIterator begin, InputIterator end,
const allocator_type& a = allocator_type());
478 {
return privdata_rw(); }
483 {
return privdata_rw() + length(); }
487 const_iterator begin()
const
488 {
return privdata_ro(); }
492 const_iterator end()
const
493 {
return privdata_ro() + length(); }
497 reverse_iterator rbegin()
498 {
return reverse_iterator( this->end() ); }
502 reverse_iterator rend()
503 {
return reverse_iterator( this->begin() ); }
507 const_reverse_iterator rbegin()
const
508 {
return const_reverse_iterator( this->end() ); }
512 const_reverse_iterator rend()
const
513 {
return const_reverse_iterator( this->begin() ); }
517 reference operator[](size_type n)
518 {
return privdata_rw()[n]; }
522 const_reference operator[](size_type n)
const
523 {
return privdata_ro()[n]; }
527 reference at(size_type n)
530 throw out_of_range(
"at");
532 return privdata_rw()[n];
537 const_reference at(size_type n)
const
540 throw out_of_range(
"at");
542 return privdata_ro()[n];
553 void resize( std::size_t n,
Pt::Char ch = value_type() );
557 void reserve(std::size_t n = 0);
564 template<
typename Operation>
565 void resize_and_overwrite(size_type n, Operation op);
569 void swap(basic_string& str);
573 allocator_type get_allocator()
const
578 size_type copy(
Pt::Char* a, size_type n, size_type pos = 0)
const;
582 basic_string substr(size_type pos = 0, size_type n = npos)
const
583 {
return basic_string(*
this, pos, n); }
588 size_type length()
const
589 {
return isShortString() ? shortStringLength() : longStringLength(); }
593 size_type size()
const
599 {
return length() == 0; }
603 size_type max_size()
const
604 {
return ( size_type(-1) /
sizeof(
Pt::Char) ) - 1; }
608 size_type capacity()
const
609 {
return isShortString() ? shortStringCapacity() : longStringCapacity(); }
614 {
return privdata_ro(); }
619 {
return privdata_ro(); }
623 basic_string& assign(
const basic_string& str);
627 basic_string& assign(
const basic_string& str, size_type pos, size_type n);
631 basic_string& assign(
const wchar_t* str);
635 basic_string& assign(
const wchar_t* str, size_type n);
639 basic_string& assign(
const Pt::Char* str);
643 basic_string& assign(
const Pt::Char* str, size_type length);
647 basic_string& assign(
const char* str);
651 basic_string& assign(
const char* str, size_type length);
655 basic_string& assign(size_type n,
Pt::Char c);
657 template <
typename InputIterator>
658 basic_string& assign(InputIterator begin, InputIterator end);
662 basic_string& append(
const Pt::Char* str);
666 basic_string& append(
const Pt::Char* str, size_type n);
670 basic_string& append(size_type n,
Pt::Char ch);
674 basic_string& append(
const basic_string& str);
678 basic_string& append(
const basic_string& str, size_type pos, size_type n);
680 template <
typename InputIterator>
681 basic_string& append(InputIterator begin, InputIterator end);
689 basic_string& insert(size_type pos,
const Pt::Char* str);
693 basic_string& insert(size_type pos,
const Pt::Char* str, size_type n);
697 basic_string& insert(size_type pos, size_type n,
Pt::Char ch);
701 basic_string& insert(size_type pos,
const basic_string& str);
705 basic_string& insert(size_type pos,
const basic_string& str, size_type pos2, size_type n);
709 basic_string& insert(iterator p,
Pt::Char ch);
713 basic_string& insert(iterator p, size_type n,
Pt::Char ch);
726 basic_string& erase(size_type pos = 0, size_type n = npos);
730 iterator erase(iterator pos);
734 iterator erase(iterator first, iterator last);
738 basic_string& replace(size_type pos, size_type n,
const Pt::Char* str);
742 basic_string& replace(size_type pos, size_type n,
const Pt::Char* str, size_type n2);
746 basic_string& replace(size_type pos, size_type n, size_type n2,
Pt::Char ch);
750 basic_string& replace(size_type pos, size_type n,
const basic_string& str);
754 basic_string& replace(size_type pos, size_type n,
const basic_string& str, size_type pos2, size_type n2);
758 basic_string& replace(iterator i1, iterator i2,
const Pt::Char* str);
762 basic_string& replace(iterator i1, iterator i2,
const Pt::Char* str, size_type n);
766 basic_string& replace(iterator i1, iterator i2, size_type n,
Pt::Char ch);
770 basic_string& replace(iterator i1, iterator i2,
const basic_string& str);
774 int compare(
const basic_string& str)
const;
778 int compare(
const Pt::Char* str)
const;
782 int compare(
const Pt::Char* str, size_type n)
const;
786 int compare(
const wchar_t* str)
const;
790 int compare(
const wchar_t* str, size_type n)
const;
794 int compare(
const char* str)
const;
798 int compare(
const char* str, size_type n)
const;
802 int compare(size_type pos, size_type n,
const basic_string& str)
const;
806 int compare(size_type pos, size_type n,
const basic_string& str, size_type pos2, size_type n2)
const;
810 int compare(size_type pos, size_type n,
const Pt::Char* str)
const;
814 int compare(size_type pos, size_type n,
const Pt::Char* str, size_type n2)
const;
818 size_type find(
const basic_string& str, size_type pos = 0)
const;
822 size_type find(
const Pt::Char* str, size_type pos, size_type n)
const;
826 size_type find(
const Pt::Char* str, size_type pos = 0)
const;
830 size_type find(
Pt::Char ch, size_type pos = 0)
const;
834 size_type rfind(
const basic_string& str, size_type pos = npos)
const;
838 size_type rfind(
const Pt::Char* str, size_type pos, size_type n)
const;
842 size_type rfind(
const Pt::Char* str, size_type pos = npos)
const;
846 size_type rfind(
Pt::Char ch, size_type pos = npos)
const;
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() ); }
855 size_type find_first_of(
const Pt::Char* s, size_type pos, size_type n)
const;
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) ); }
864 size_type find_first_of(
const Pt::Char ch, size_type pos = 0)
const
865 {
return this->find(ch, pos); }
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() ); }
874 size_type find_last_of(
const Pt::Char* s, size_type pos, size_type n)
const;
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) ); }
883 size_type find_last_of(
const Pt::Char ch, size_type pos = npos)
const
884 {
return this->rfind(ch, pos); }
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() ); }
893 size_type find_first_not_of(
const Pt::Char* s, size_type pos, size_type n)
const;
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) ); }
902 size_type find_first_not_of(
const Pt::Char ch, size_type pos = 0)
const;
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() ); }
911 size_type find_last_not_of(
const Pt::Char* tok, size_type pos, size_type n)
const;
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) ); }
920 size_type find_last_not_of(
Pt::Char ch, size_type pos = npos)
const;
925 std::string
narrow(
char dfault =
'?')
const;
929 static basic_string widen(
const char* str);
933 static basic_string widen(
const std::string& str);
937 template <
typename OutIterT>
938 OutIterT toUtf16(OutIterT to)
const;
942 template <
typename InIterT>
943 static basic_string fromUtf16(InIterT from, InIterT fromEnd);
948 basic_string& operator=(
const basic_string& str)
949 {
return this->assign(str); }
953 basic_string& operator=(
const wchar_t* str)
954 {
return this->assign(str); }
958 basic_string& operator=(
const char* str)
959 {
return this->assign(str); }
963 basic_string& operator=(
const Pt::Char* str)
964 {
return this->assign(str); }
968 basic_string& operator=(
Pt::Char ch)
980 basic_string& operator+=(
const basic_string& str)
981 {
return this->append(str); }
985 basic_string& operator+=(
const Pt::Char* str)
986 {
return this->append(str); }
990 basic_string& operator+=(
Pt::Char c);
1001 static const unsigned _minN = (
sizeof(Ptr) /
sizeof(
Pt::Char)) + 1;
1004 static const unsigned _nN = _minN < 8 ? 8 : _minN;
1007 static const unsigned _nS = _nN *
sizeof(
Pt::Char);
1009 struct Data :
public allocator_type
1011 Data(
const allocator_type& a)
1017 _u._s[_nS - 1] = _nN - 1;
1023 unsigned char _s[_nS];
1028 const Pt::Char* privdata_ro()
const
1029 {
return isShortString() ? shortStringData() : longStringData(); }
1032 {
return isShortString() ? shortStringData() : longStringData(); }
1034 void privreserve(std::size_t n);
1036 bool isShortString()
const
1037 {
return shortStringMagic() != 0xff; }
1039 void markLongString()
1040 { shortStringMagic() = 0xff; }
1042 const Pt::Char* shortStringData()
const
1043 {
return reinterpret_cast<const Pt::Char*
>(&_d._u._s[0]); }
1046 {
return reinterpret_cast<Pt::Char*
>(&_d._u._s[0]); }
1048 unsigned char shortStringMagic()
const
1049 {
return _d._u._s[_nS - 1]; }
1051 unsigned char& shortStringMagic()
1052 {
return _d._u._s[_nS - 1]; }
1054 size_type shortStringLength()
const
1055 {
return _nN - 1 - shortStringMagic(); }
1057 size_type shortStringCapacity()
const
1060 void setShortStringLength(size_type n)
1062 shortStringData()[n] =
Pt::Char(0);
1063 shortStringMagic() =
static_cast<unsigned char>(_nN - n - 1);
1066 void shortStringAssign(
const Pt::Char* str, size_type n)
1068 traits_type::copy(shortStringData(), str, n);
1069 shortStringData()[n] =
Pt::Char(0);
1070 shortStringMagic() =
static_cast<unsigned char>(_nN - n - 1);
1072 void shortStringAssign(
const wchar_t* str, size_type n)
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);
1080 const Pt::Char* longStringData()
const
1081 {
return _d._u._p._begin; }
1084 {
return _d._u._p._begin; }
1086 size_type longStringLength()
const
1087 {
return _d._u._p._end - _d._u._p._begin; }
1089 size_type longStringCapacity()
const
1090 {
return _d._u._p._capacity - _d._u._p._begin; }
1092 void setLength(size_type n)
1094 if (isShortString())
1095 setShortStringLength(n);
1098 _d._u._p._end = _d._u._p._begin + n;
1099 _d._u._p._begin[n] = 0;
1108 inline void swap(basic_string<Pt::Char>& a, basic_string<Pt::Char>& b)
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; }
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; }
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; }
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; }
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; }
1154 inline bool operator==(
const basic_string<Pt::Char>& a,
const basic_string<Pt::Char>& b)
1155 {
return a.compare(b) == 0; }
1161 inline bool operator==(
const Pt::Char* a,
const basic_string<Pt::Char>& b)
1162 {
return b.compare(a) == 0; }
1168 inline bool operator==(
const basic_string<Pt::Char>& a,
const Pt::Char* b)
1169 {
return a.compare(b) == 0; }
1175 inline bool operator==(
const basic_string<Pt::Char>& a,
const wchar_t* b)
1176 {
return a.compare(b) == 0; }
1182 inline bool operator==(
const wchar_t* b,
const basic_string<Pt::Char>& a)
1183 {
return a.compare(b) == 0; }
1189 inline bool operator==(
const basic_string<Pt::Char>& a,
const char* b)
1190 {
return a.compare(b) == 0; }
1196 inline bool operator==(
const char* b,
const basic_string<Pt::Char>& a)
1197 {
return a.compare(b) == 0; }
1205 inline bool operator!=(
const basic_string<Pt::Char>& a,
const basic_string<Pt::Char>& b)
1206 {
return a.compare(b) != 0; }
1212 inline bool operator!=(
const Pt::Char* a,
const basic_string<Pt::Char>& b)
1213 {
return b.compare(a) != 0; }
1219 inline bool operator!=(
const basic_string<Pt::Char>& a,
const Pt::Char* b)
1220 {
return a.compare(b) != 0; }
1226 inline bool operator!=(
const basic_string<Pt::Char>& a,
const wchar_t* b)
1227 {
return a.compare(b) != 0; }
1233 inline bool operator!=(
const wchar_t* b,
const basic_string<Pt::Char>& a)
1234 {
return a.compare(b) != 0; }
1240 inline bool operator!=(
const basic_string<Pt::Char>& a,
const char* b)
1241 {
return a.compare(b) != 0; }
1247 inline bool operator!=(
const char* b,
const basic_string<Pt::Char>& a)
1248 {
return a.compare(b) != 0; }
1256 inline bool operator<(
const basic_string<Pt::Char>& a,
const basic_string<Pt::Char>& b)
1257 {
return a.compare(b) < 0; }
1263 inline bool operator<(
const Pt::Char* a,
const basic_string<Pt::Char>& b)
1264 {
return b.compare(a) > 0; }
1270 inline bool operator<(
const basic_string<Pt::Char>& a,
const Pt::Char* b)
1271 {
return a.compare(b) < 0; }
1277 inline bool operator<(
const basic_string<Pt::Char>& a,
const wchar_t* b)
1278 {
return a.compare(b) < 0; }
1284 inline bool operator<(
const wchar_t* b,
const basic_string<Pt::Char>& a)
1285 {
return a.compare(b) > 0; }
1291 inline bool operator<(
const basic_string<Pt::Char>& a,
const char* b)
1292 {
return a.compare(b) < 0; }
1298 inline bool operator<(
const char* b,
const basic_string<Pt::Char>& a)
1299 {
return a.compare(b) > 0; }
1307 inline bool operator<=(
const basic_string<Pt::Char>& a,
const basic_string<Pt::Char>& b)
1308 {
return a.compare(b) <= 0; }
1314 inline bool operator<=(
const Pt::Char* a,
const basic_string<Pt::Char>& b)
1315 {
return b.compare(a) >= 0; }
1321 inline bool operator<=(
const basic_string<Pt::Char>& a,
const Pt::Char* b)
1322 {
return a.compare(b) <= 0; }
1328 inline bool operator<=(
const basic_string<Pt::Char>& a,
const wchar_t* b)
1329 {
return a.compare(b) <= 0; }
1335 inline bool operator<=(
const wchar_t* b,
const basic_string<Pt::Char>& a)
1336 {
return a.compare(b) >= 0; }
1342 inline bool operator<=(
const basic_string<Pt::Char>& a,
const char* b)
1343 {
return a.compare(b) <= 0; }
1349 inline bool operator<=(
const char* b,
const basic_string<Pt::Char>& a)
1350 {
return a.compare(b) >= 0; }
1358 inline bool operator>(
const basic_string<Pt::Char>& a,
const basic_string<Pt::Char>& b)
1359 {
return a.compare(b) > 0; }
1365 inline bool operator>(
const Pt::Char* a,
const basic_string<Pt::Char>& b)
1366 {
return b.compare(a) < 0; }
1372 inline bool operator>(
const basic_string<Pt::Char>& a,
const Pt::Char* b)
1373 {
return a.compare(b) > 0; }
1379 inline bool operator>(
const basic_string<Pt::Char>& a,
const wchar_t* b)
1380 {
return a.compare(b) > 0; }
1386 inline bool operator>(
const wchar_t* b,
const basic_string<Pt::Char>& a)
1387 {
return a.compare(b) < 0; }
1393 inline bool operator>(
const basic_string<Pt::Char>& a,
const char* b)
1394 {
return a.compare(b) > 0; }
1400 inline bool operator>(
const char* b,
const basic_string<Pt::Char>& a)
1401 {
return a.compare(b) < 0; }
1409 inline bool operator>=(
const basic_string<Pt::Char>& a,
const basic_string<Pt::Char>& b)
1410 {
return a.compare(b) >= 0; }
1416 inline bool operator>=(
const Pt::Char* a,
const basic_string<Pt::Char>& b)
1417 {
return b.compare(a) <= 0; }
1423 inline bool operator>=(
const basic_string<Pt::Char>& a,
const Pt::Char* b)
1424 {
return a.compare(b) >= 0; }
1430 inline bool operator>=(
const basic_string<Pt::Char>& a,
const wchar_t* b)
1431 {
return a.compare(b) >= 0; }
1437 inline bool operator>=(
const wchar_t* b,
const basic_string<Pt::Char>& a)
1438 {
return a.compare(b) <= 0; }
1444 inline bool operator>=(
const basic_string<Pt::Char>& a,
const char* b)
1445 {
return a.compare(b) >= 0; }
1451 inline bool operator>=(
const char* b,
const basic_string<Pt::Char>& a)
1452 {
return a.compare(b) <= 0; }
1465 PT_API ostream& operator<< (ostream& out,
const basic_string<Pt::Char>& str);
1471 typedef std::basic_string<Pt::Char> String;
1475 #ifdef PT_WITH_STD_LOCALE
1476 #include <Pt/Facets.h>
1480 #include <Pt/String.tpp>