Evo C++ Library v0.5.1
substring.h
Go to the documentation of this file.
1 // Evo C++ Library
2 /* Copyright 2019 Justin Crowell
3 Distributed under the BSD 2-Clause License -- see included file LICENSE.txt for details.
4 */
6 
7 #pragma once
8 #ifndef INCL_evo_substring_h
9 #define INCL_evo_substring_h
10 
11 #include "sublist.h"
12 #include "string.h"
13 #include "strscan.h"
14 
15 namespace evo {
18 
20 
24 
26 
229 struct SubString : public SubList<char,StrSizeT> {
230  typedef SubString ThisType;
232 
235  { }
236 
243  SubString(const ThisType& str) : SubList<char,StrSizeT>(str)
244  { }
245 
252  SubString(const StringBase& str) : SubList<char,StrSizeT>(str)
253  { }
254 
263  SubString(const StringBase& str, Key index, Size size=ALL) : SubList<char,StrSizeT>(str, index, size)
264  { }
265 
272  SubString(const StringBase* str) {
273  if (str != NULL)
274  set(*str);
275  }
276 
281  SubString(const char* data, Size size) : SubList<char,StrSizeT>(data, size)
282  { }
283 
287  SubString(const char* data) : SubList<char,StrSizeT>(data, data?(Size)strlen(data):0)
288  { }
289 
290 #if defined(EVO_CPP11)
291 
295  ::memcpy(this, &src, sizeof(SubString));
296  }
297 
303  ::memcpy(this, &src, sizeof(SubString));
304  return *this;
305  }
306 #endif
307 
313  const SubString& asconst() const {
314  return *this;
315  }
316 
317  // SET
318 
321  { set(src); return *this; }
322 
324  SubString& operator=(const StringBase& data)
325  { set(data); return *this; }
326 
328  SubString& operator=(const StringBase* data)
329  { if (data != NULL) set(*data); else set(); return *this; }
330 
338  SubString& operator=(const char* data) {
339  data_ = (char*)data;
340  size_ = data ? (Size)strlen(data) : 0;
341  return *this;
342  }
343 
344  using SubListType::set;
345 
353  SubString& set(const char* data) {
354  data_ = (char*)data;
355  size_ = data ? (Size)strlen(data) : 0;
356  return *this;
357  }
358 
360  SubString& operator=(const ValNull& val) {
361  EVO_PARAM_UNUSED(val);
362  set(); return *this;
363  }
364 
366  SubString& operator=(const ValEmpty& val) {
367  EVO_PARAM_UNUSED(val);
368  setempty(); return *this;
369  }
370 
382  template<class StringT>
383  bool token(StringT& value, char delim) {
384  if (size_ > 0) {
385  const char* ptr = (char*)memchr(data_, delim, size_);
386  if (ptr != NULL) {
387  Key i = (Key)(ptr - data_);
388  value.set(data_, i);
389  ++i;
390  data_ += i;
391  size_ -= i;
392  return true;
393  }
394  value.set(data_, size_);
395  clear();
396  return true;
397  }
398  value.set();
399  return false;
400  }
401 
413  template<class StringT>
414  bool tokenr(StringT& value, char delim) {
415  if (size_ > 0) {
416  #if defined(EVO_GLIBC_MEMRCHR)
417  const char* ptr = (char*)memrchr(data_, delim, size_);
418  if (ptr != NULL) {
419  const Key i = (Key)(ptr - data_);
420  const Size len = size_ - i;
421  value.set(data_ + i + 1, len - 1);
422  size_ -= len;
423  return true;
424  }
425  #else
426  for (Key i=size_; i > 0; ) {
427  if (data_[--i] == delim) {
428  Size len = size_ - i;
429  value.set(data_ + i + 1, len - 1);
430  size_ -= len;
431  return true;
432  }
433  }
434  #endif
435  value.set(data_, size_);
436  clear();
437  return true;
438  }
439  value.set();
440  return false;
441  }
442 
456  template<class StringT>
457  bool token_any(StringT& value, Char& found_delim, const char* delims, Size count) {
458  assert( count > 0 );
459  if (size_ > 0) {
460  Size j;
461  for (Key i=0; i < size_; ++i) {
462  for (j=0; j < count; ++j) {
463  if (data_[i] == delims[j]) {
464  value.set(data_, i);
465  found_delim = data_[i];
466  ++i;
467  data_ += i;
468  size_ -= i;
469  return true;
470  }
471  }
472  }
473  value.set(data_, size_);
474  found_delim.set();
475  clear();
476  return true;
477  }
478  value.set();
479  found_delim.set();
480  return false;
481  }
482 
496  template<class StringT>
497  bool tokenr_any(StringT& value, Char& found_delim, const char* delims, Size count) {
498  assert( count > 0 );
499  if (size_ > 0) {
500  Size j;
501  for (Key i=size_; i > 0; ) {
502  --i;
503  for (j=0; j < count; ++j) {
504  if (data_[i] == delims[j]) {
505  Size len = size_ - i;
506  value.set(data_ + i + 1, len - 1);
507  found_delim = data_[i];
508  size_ -= len;
509  return true;
510  }
511  }
512  }
513  value.set(data_, size_);
514  found_delim.set();
515  clear();
516  return true;
517  }
518  value.set();
519  found_delim.set();
520  return false;
521  }
522 
532  template<class StringT>
533  bool token_line(StringT& line) {
534  const char* NEWLINE_CHARS = "\n\r";
535  Size i = findany(NEWLINE_CHARS, 2);
536  if (i == END) {
537  if (size_ > 0) {
538  line.set(data_, size_);
539  setempty();
540  return true;
541  }
542  line.set();
543  return false;
544  }
545  line.set(data_, i);
546 
547  if (++i < size_) {
548  char ch1 = data_[i - 1];
549  char ch2 = data_[i];
550  if ((ch1 == '\n' && ch2 == '\r') || (ch1 == '\r' && ch2 == '\n'))
551  ++i;
552  }
553  data_ += i;
554  size_ -= i;
555  return true;
556  }
557 
566  template<class StringT>
567  bool tokenr_line(StringT& line) {
568  const char* NEWLINE_CHARS = "\n\r";
569  Size i = findanyr(NEWLINE_CHARS, 2);
570  if (i == END) {
571  if (size_ > 0) {
572  line.set(data_, size_);
573  setempty();
574  return true;
575  }
576  line.set();
577  return false;
578  }
579  line.set(data_ + i + 1, size_ - i - 1);
580 
581  if (i > 1) {
582  char ch1 = data_[i - 1];
583  char ch2 = data_[i];
584  if ((ch1 == '\n' && ch2 == '\r') || (ch1 == '\r' && ch2 == '\n'))
585  --i;
586  }
587  size_ = i;
588  return true;
589  }
590 
591  // INFO
592 
599  const char* cstr(String& buffer) const
600  { return (size_ > 0 ? buffer.set(data_, size_).cstr() : ""); }
601 
602  // COMPARE
603 
604  using SubListType::compare;
605 
611  template<class T>
612  int compare(const ListBase<wchar16,T>& str) {
613  assert( str.size_ < ULong::MAX );
614  return -utf16_compare8(str.data_, str.size_, data_, size_);
615  }
616 
617  using SubListType::operator==;
618  using SubListType::operator!=;
619 
625  template<class T>
626  bool operator==(const ListBase<wchar16,T>& str) {
627  assert( str.size_ < ULong::MAX );
628  return (utf16_compare8(str.data_, str.size_, data_, size_) == 0);
629  }
630 
632  bool operator==(const char* str) const {
633  return (utf8_compare(data_, size_, str) == 0);
634  }
635 
641  template<class T>
642  bool operator!=(const ListBase<wchar16,T>& str) {
643  assert( str.size_ < ULong::MAX );
644  return (utf16_compare8(str.data_, str.size_, data_, size_) != 0);
645  }
646 
648  bool operator!=(const char* str) const {
649  return (utf8_compare(data_, size_, str) != 0);
650  }
651 
652  using SubListType::starts;
653 
658  bool starts(const char* str) const {
659  if (str == NULL)
660  return false;
661  const SizeT size = (Size)strlen(str);
662  return (size > 0 && size_ >= size && DataEqual<Item>::equal(data_, str, size));
663  }
664 
665  using SubListType::ends;
666 
671  bool ends(const char* str) const {
672  if (str == NULL)
673  return false;
674  const SizeT size = (Size)strlen(str);
675  return (size > 0 && size_ >= size && DataEqual<Item>::equal(data_+size_-size, str, size));
676  }
677 
678  // FIND
679 
681  Key find(char ch) const {
682  if (size_ > 0) {
683  const char* ptr = (char*)memchr(data_, ch, size_);
684  if (ptr != NULL)
685  return (Key)(ptr - data_);
686  }
687  return NONE;
688  }
689 
691  Key find(char ch, Key start, Key end=END) const {
692  if (start < size_) {
693  if (end > size_)
694  end = size_;
695  if (start < end) {
696  const char* ptr = (char*)memchr(data_ + start, ch, end - start);
697  if (ptr != NULL)
698  return (Key)(ptr - data_);
699  }
700  }
701  return NONE;
702  }
703 
705  Key find(const char* pattern, uint pattern_size, Key start=0, Key end=END) const {
706  if (start < size_ && start < end) {
707  assert( pattern != NULL );
708  if (end > size_)
709  end = size_;
710  return impl::string_search(pattern, pattern_size, data_ + start, end - start, start);
711  }
712  return NONE;
713  }
714 
716  Key find(StringSearchAlg alg, const char* pattern, uint pattern_size, Key start=0, Key end=END) const {
717  if (start < size_ && start < end) {
718  assert( pattern != NULL );
719  if (end > size_)
720  end = size_;
721  return impl::string_search(alg, pattern, pattern_size, data_ + start, end - start, start);
722  }
723  return NONE;
724  }
725 
727  Key find(const StringBase& pattern, Key start=0, Key end=END) const {
728  if (start < size_ && start < end) {
729  if (end > size_)
730  end = size_;
731  return impl::string_search(pattern.data_, pattern.size_, data_ + start, end - start, start);
732  }
733  return NONE;
734  }
735 
737  Key find(StringSearchAlg alg, const StringBase& pattern, Key start=0, Key end=END) const {
738  if (start < size_ && start < end) {
739  if (end > size_)
740  end = size_;
741  return impl::string_search(alg, pattern.data_, pattern.size_, data_ + start, end - start, start);
742  }
743  return NONE;
744  }
745 
747  Key findr(char ch) const {
748  #if !defined(EVO_NO_MEMRCHR) && defined(EVO_GLIBC_MEMRCHR)
749  if (size_ > 0) {
750  const char* ptr = (char*)memrchr(data_, ch, size_);
751  if (ptr != NULL)
752  return (Key)(ptr - data_);
753  }
754  #else
755  const char* ptr = data_ + size_;
756  while (ptr > data_)
757  if (*--ptr == ch)
758  return (Key)(ptr - data_);
759  #endif
760  return NONE;
761  }
762 
764  Key findr(char ch, Key start, Key end=END) const {
765  #if !defined(EVO_NO_MEMRCHR) && defined(EVO_GLIBC_MEMRCHR)
766  if (start < size_) {
767  if (end > size_)
768  end = size_;
769  if (start < end) {
770  const char* ptr = (char*)memrchr(data_ + start, ch, end - start);
771  if (ptr != NULL)
772  return (Key)(ptr - data_);
773  }
774  }
775  #else
776  if (end > size_)
777  end = size_;
778  while (end>start)
779  if (data_[--end] == ch)
780  return end;
781  #endif
782  return NONE;
783  }
784 
786  Key findr(const char* pattern, uint pattern_size, Key start=0, Key end=END) const {
787  if (start < size_ && start < end) {
788  assert( pattern != NULL );
789  if (end > size_)
790  end = size_;
791  return impl::string_search_reverse(pattern, pattern_size, data_ + start, end - start, start);
792  }
793  return NONE;
794  }
795 
797  Key findr(StringSearchAlg alg, const char* pattern, uint pattern_size, Key start=0, Key end=END) const {
798  if (start < size_ && start < end) {
799  assert( pattern != NULL );
800  if (end > size_)
801  end = size_;
802  return impl::string_search_reverse(alg, pattern, pattern_size, data_ + start, end - start, start);
803  }
804  return NONE;
805  }
806 
808  Key findr(const StringBase& pattern, Key start=0, Key end=END) const {
809  if (start < size_ && start < end) {
810  if (end > size_)
811  end = size_;
812  return impl::string_search_reverse(pattern.data_, pattern.size_, data_ + start, end - start, start);
813  }
814  return NONE;
815  }
816 
818  Key findr(StringSearchAlg alg, const StringBase& pattern, Key start=0, Key end=END) const {
819  if (start < size_ && start < end) {
820  if (end > size_)
821  end = size_;
822  return impl::string_search_reverse(alg, pattern.data_, pattern.size_, data_ + start, end - start, start);
823  }
824  return NONE;
825  }
826 
828  Key findany(const char* chars, Size count, Key start=0, Key end=END) const {
829  if (start < size_ && start < end && count > 0) {
830  if (end > size_)
831  end = size_;
832  if (count == 1) {
833  // Special case for single char
834  const char* ptr = (char*)memchr(data_ + start, *chars, end - start);
835  if (ptr != NULL)
836  return (Key)(ptr - data_);
837  } else {
838  const char* pend = data_ + end;
839  const char* ptr = data_ + start;
840  for (; ptr < pend; ++ptr)
841  if (memchr(chars, *ptr, count) != NULL)
842  return (Key)(ptr - data_);
843  }
844  }
845  return NONE;
846  }
847 
849  Key findany(const StringBase& chars, Key start=0, Key end=END) const
850  { return findany(chars.data_, chars.size_, start, end); }
851 
853  Key findanyr(const char* chars, Size count, Key start=0, Key end=END) const {
854  if (count == 1)
855  return findr(*chars, start, end);
856  if (start < size_ && start < end && count > 0) {
857  if (end > size_)
858  end = size_;
859  const char* pstart = data_ + start;
860  const char* ptr = data_ + end;
861  while (ptr > pstart)
862  if (memchr(chars, *--ptr, count) != NULL)
863  return (Key)(ptr - data_);
864  }
865  return NONE;
866  }
867 
869  Key findanyr(const StringBase& chars, Key start=0, Key end=END) const
870  { return findanyr(chars.data_, chars.size_, start, end); }
871 
873  Key findanybut(const char* chars, Size count, Key start=0, Key end=END) const {
874  if (start < size_ && start < end) {
875  if (count == 0)
876  return start;
877  if (end > size_)
878  end = size_;
879  const char* pend = data_ + end;
880  const char* ptr = data_ + start;
881  for (; ptr < pend; ++ptr)
882  if (memchr(chars, *ptr, count) == NULL)
883  return (Key)(ptr - data_);
884  }
885  return NONE;
886  }
887 
889  Key findanybut(const StringBase& chars, Key start=0, Key end=END) const
890  { return findanybut(chars.data_, chars.size_, start, end); }
891 
893  Key findanybutr(const char* chars, Size count, Key start=0, Key end=END) const {
894  if (start < size_ && start < end) {
895  if (end > size_)
896  end = size_;
897  if (count == 0)
898  return end - 1;
899  const char* pstart = data_ + start;
900  const char* ptr = data_ + end;
901  while (ptr > pstart)
902  if (memchr(chars, *--ptr, count) == NULL)
903  return (Key)(ptr - data_);
904  }
905  return NONE;
906  }
907 
909  Key findanybutr(const StringBase& chars, Key start=0, Key end=END) const
910  { return findanybutr(chars.data_, chars.size_, start, end); }
911 
913  Key findword(Key start=0, Key end=END) const {
914  if (start < size_ && start < end) {
915  if (end > size_)
916  end = size_;
917  for (; start < end; ++start)
918  if (ascii_breaktype(data_[start]) == cbtWORD)
919  return start;
920  }
921  return NONE;
922  }
923 
925  Key findwordr(Key start=0, Key end=END) const {
926  if (start < size_ && start < end) {
927  if (end > size_)
928  end = size_;
929  while (end > start)
930  if (ascii_breaktype(data_[--end]) == cbtWORD)
931  return end;
932  }
933  return NONE;
934  }
935 
937  Key findnonword(Key start=0, Key end=END) const {
938  if (start < size_ && start < end) {
939  if (end > size_)
940  end = size_;
941  for (; start < end; ++start)
942  if (ascii_breaktype(data_[start]) != cbtWORD)
943  return start;
944  }
945  return NONE;
946  }
947 
949  Key findnonwordr(Key start=0, Key end=END) const {
950  if (start < size_ && start < end) {
951  if (end > size_)
952  end = size_;
953  while (end > start)
954  if (ascii_breaktype(data_[--end]) != cbtWORD)
955  return end;
956  }
957  return NONE;
958  }
959 
961  bool contains(char ch) const
962  { return find(ch) != NONE; }
963 
965  bool contains(const char* str, Size size) const
966  { return find(str, size) != NONE; }
967 
969  bool contains(const StringBase& str) const
970  { return find(str) != NONE; }
971 
972  // SPLIT
973 
975  template<class T1,class T2>
976  bool split(char delim, T1& left, T2& right) const {
977  for (Key i=0; i<size_; ++i) {
978  if (data_[i] == delim) {
979  left.set(*this, 0, i);
980  right.set(*this, i+1, ALL);
981  return true;
982  }
983  }
984  left.set(*this);
985  right.set();
986  return false;
987  }
988 
990  template<class T1>
991  bool split(char delim, T1& left) const {
992  for (Key i=0; i<size_; ++i) {
993  if (data_[i] == delim) {
994  left.set(*this, 0, i);
995  return true;
996  }
997  }
998  left.set(*this);
999  return false;
1000  }
1001 
1003  template<class T2>
1004  bool split(char delim, ValNull left, T2& right) const {
1005  EVO_PARAM_UNUSED(left);
1006  for (Key i=0; i<size_; ++i) {
1007  if (data_[i] == delim) {
1008  right.set(*this, i+1, ALL);
1009  return true;
1010  }
1011  }
1012  right.set();
1013  return false;
1014  }
1015 
1017  template<class T1,class T2>
1018  bool splitr(char delim, T1& left, T2& right) const {
1019  for (Key i=size_; i>0; ) {
1020  if (data_[--i] == delim) {
1021  left.set(*this, 0, i);
1022  right.set(*this, i+1, ALL);
1023  return true;
1024  }
1025  }
1026  left.set(*this);
1027  right.set();
1028  return false;
1029  }
1030 
1032  template<class T1>
1033  bool splitr(char delim, T1& left) const {
1034  for (Key i=size_; i>0; ) {
1035  if (data_[--i] == delim) {
1036  left.set(*this, 0, i);
1037  return true;
1038  }
1039  }
1040  left.set(*this);
1041  return false;
1042  }
1043 
1045  template<class T2>
1046  bool splitr(char delim, ValNull left, T2& right) const {
1047  EVO_PARAM_UNUSED(left);
1048  for (Key i=size_; i>0; ) {
1049  if (data_[--i] == delim) {
1050  right.set(*this, i+1, ALL);
1051  return true;
1052  }
1053  }
1054  right.set();
1055  return false;
1056  }
1057 
1058  // TRIM/STRIP
1059 
1062  char ch;
1063  while ( size_ > 0 && ((ch=data_[size_-1]) == ' ' || ch == '\t') )
1064  --size_;
1065  Size count = 0;
1066  while ( count < size_ && ((ch=data_[count]) == ' ' || ch == '\t') )
1067  ++count;
1068  if (count > 0) {
1069  size_ -= count;
1070  data_ += count;
1071  }
1072  return *this;
1073  }
1074 
1076  SubString& strip(char ch) {
1077  while (size_ > 0 && data_[size_-1] == ch)
1078  --size_;
1079  Size count = 0;
1080  while (count < size_ && data_[count] == ch)
1081  ++count;
1082  if (count > 0) {
1083  size_ -= count;
1084  data_ += count;
1085  }
1086  return *this;
1087  }
1088 
1091  char ch;
1092  Size count = 0;
1093  while ( count < size_ && ((ch=data_[count]) == ' ' || ch == '\t') )
1094  ++count;
1095  if (count > 0) {
1096  size_ -= count;
1097  data_ += count;
1098  }
1099  return *this;
1100  }
1101 
1103  SubString& stripl(char ch, Size max=ALL) {
1104  Size count = 0;
1105  while (count < size_ && data_[count] == ch && count < max)
1106  ++count;
1107  if (count > 0) {
1108  size_ -= count;
1109  data_ += count;
1110  }
1111  return *this;
1112  }
1113 
1115  SubString& stripl(const char* str, Size strsize, Size max=ALL) {
1116  if (strsize > 0 && strsize <= size_ && max > 0) {
1117  Size i, j = 0, count = 0;
1118  do {
1119  for (i=0; i < strsize; ++i, ++j)
1120  if (j >= size_ || str[i] != data_[j])
1121  goto break_all;
1122  ++count;
1123  } while (j < size_ && count < max);
1124  break_all:
1125  if (count > 0) {
1126  count *= strsize;
1127  size_ -= count;
1128  data_ += count;
1129  }
1130  }
1131  return *this;
1132  }
1133 
1136  char ch;
1137  while ( size_ > 0 && ((ch=data_[size_-1]) == ' ' || ch == '\t') )
1138  --size_;
1139  return *this;
1140  }
1141 
1143  SubString& stripr(char ch, Size max=ALL) {
1144  for (Size i=0; size_ > 0 && data_[size_-1] == ch && i < max; ++i)
1145  --size_;
1146  return *this;
1147  }
1148 
1150  SubString& stripr(const char* str, Size strsize, Size max=ALL) {
1151  if (strsize > 0 && strsize <= size_ && max > 0) {
1152  Size i, j = size_, count = 0;
1153  do {
1154  for (i=strsize; i > 0; )
1155  if (j == 0 || str[--i] != data_[--j])
1156  goto break_all;
1157  ++count;
1158  } while (j > 0 && count < max);
1159  break_all:
1160  if (count > 0)
1161  size_ -= (count * strsize);
1162  }
1163  return *this;
1164  }
1165 
1168  if (size_ > 0) {
1169  const char* end = data_ + size_;
1170  data_ = (char*)str_scan_nws(data_, end);
1171  size_ = (Size)(str_scan_nws_r(data_, end) - data_);
1172  }
1173  return *this;
1174  }
1175 
1178  if (size_ > 0) {
1179  const char* end = data_ + size_;
1180  data_ = (char*)str_scan_nws(data_, end);
1181  size_ = (Size)(end - data_);
1182  }
1183  return *this;
1184  }
1185 
1188  if (size_ > 0) {
1189  const char* end = data_ + size_;
1190  size_ = (Size)(str_scan_nws_r(data_, end) - data_);
1191  }
1192  return *this;
1193  }
1194 
1197  char ch;
1198  Size count = 0;
1199  while ( count < size_ && ((ch=data_[count]) == '\n' || ch == '\r') )
1200  ++count;
1201  if (count > 0) {
1202  size_ -= count;
1203  data_ += count;
1204  }
1205  return *this;
1206  }
1207 
1210  char ch;
1211  Size count = 0;
1212  for (; count < size_ && max > 0; --max) {
1213  ch = data_[count];
1214  if (ch == '\n') {
1215  if (count + 1 < size_ && data_[count + 1] == '\r') {
1216  count += 2;
1217  continue;
1218  }
1219  } else if (ch == '\r') {
1220  if (count + 1 < size_ && data_[count + 1] == '\n') {
1221  count += 2;
1222  continue;
1223  }
1224  } else
1225  break;
1226  ++count;
1227  }
1228  if (count > 0) {
1229  size_ -= count;
1230  data_ += count;
1231  }
1232  return *this;
1233  }
1234 
1237  char ch;
1238  while ( size_ > 0 && ((ch=data_[size_-1]) == '\n' || ch == '\r') )
1239  --size_;
1240  return *this;
1241  }
1242 
1245  char ch;
1246  for (; size_ > 0 && max > 0; --max) {
1247  ch = data_[size_ - 1];
1248  if (ch == '\n') {
1249  if (size_ > 1 && data_[size_ - 2] == '\r') {
1250  size_ -= 2;
1251  continue;
1252  }
1253  } else if (ch == '\r') {
1254  if (size_ > 1 && data_[size_ - 2] == '\n') {
1255  size_ -= 2;
1256  continue;
1257  }
1258  } else
1259  break;
1260  --size_;
1261  }
1262  return *this;
1263  }
1264 
1267  stripl_newlines();
1268  stripr_newlines();
1269  return *this;
1270  }
1271 
1272  // OVERRIDES
1273 
1276  { SubListType::clear(); return *this; }
1277 
1279  SubString& set()
1280  { SubListType::set(); return *this; }
1281 
1283  SubString& set(const StringBase& data)
1284  { SubListType::set(data); return *this; }
1285 
1287  SubString& set(const StringBase& data, Key index, Key size=ALL)
1288  { SubListType::set(data, index, size); return *this; }
1289 
1291  SubString& set(const StringBase* data)
1292  { SubListType::set(data); return *this; }
1293 
1295  SubString& set(const char* data, Size size)
1296  { SubListType::set(data, size); return *this; }
1297 
1299  SubString& set2(const StringBase& data, Key index1, Key index2)
1300  { SubListType::set2(data, index1, index2); return *this; }
1301 
1304  { SubListType::setempty(); return *this; }
1305 
1308  { SubListType::triml(size); return *this; }
1309 
1312  { SubListType::trimr(size); return *this; }
1313 
1316  { SubListType::truncate(size); return *this; }
1317 
1320  { SubListType::slice(index); return *this; }
1321 
1323  SubString& slice(Key index, Size size)
1324  { SubListType::slice(index, size); return *this; }
1325 
1327  SubString& slice2(Key index1, Key index2)
1328  { SubListType::slice2(index1, index2); return *this; }
1329 
1332  { return *this; }
1333 
1334  // GETBOOL
1335 
1337  bool getbool(Error& error) const {
1338  assert( data_ > (char*)1 || size_ == 0 );
1339  return impl::tobool(data_, size_, error);
1340  }
1341 
1343  template<class T> T getbool() const {
1344  assert( data_ > (char*)1 || size_ == 0 );
1345  return StaticIf< IsPodType<T>::value, impl::ToBoolPod<T>, impl::ToBool<T> >::Type::getbool(data_, size_);
1346  }
1347 
1348  // GETNUM
1349 
1351  template<class T> T getnum(Error& error, int base=0) const {
1352  STATIC_ASSERT( IsPodType<T>::value, getnum_POD_Type_Required );
1353  assert( data_ > (char*)1 || size_ == 0 );
1354  return impl::tonum<T>(data_, size_, error, base);
1355  }
1356 
1358  template<class T> T getnum(int base=0) const {
1359  assert( data_ > (char*)1 || size_ == 0 );
1360  return StaticIf< IsPodType<T>::value, impl::ToNumPod<T>, impl::ToNum<T> >::Type::getnum(data_, size_, base);
1361  }
1362 
1364  template<class T> T getnumf(Error& error) const {
1365  STATIC_ASSERT( IsPodType<T>::value, getnumf_POD_Type_Required );
1366  assert( data_ > (char*)1 || size_ == 0 );
1367  return impl::tonumf<T>(data_, size_, error);
1368  }
1369 
1371  template<class T> T getnumf() const {
1372  assert( data_ > (char*)1 || size_ == 0 );
1373  return StaticIf< IsPodType<T>::value, impl::ToNumfPod<T>, impl::ToNumf<T> >::Type::getnum(data_, size_);
1374  }
1375 
1376  // BOOLVAL
1377 
1379  Bool boolval() const
1380  { return impl::ToBool<Bool>::getbool(data_, size_); }
1381 
1382  // NUM
1383 
1385  Int num(int base=0) const
1386  { return impl::ToNum<Int>::getnum(data_, size_, base); }
1387 
1389  Long numl(int base=0) const
1390  { return impl::ToNum<Long>::getnum(data_, size_, base); }
1391 
1393  LongL numll(int base=0) const
1394  { return impl::ToNum<LongL>::getnum(data_, size_, base); }
1395 
1396  // NUMU
1397 
1399  UInt numu(int base=0) const
1400  { return impl::ToNum<UInt>::getnum(data_, size_, base); }
1401 
1403  ULong numul(int base=0) const
1404  { return impl::ToNum<ULong>::getnum(data_, size_, base); }
1405 
1407  ULongL numull(int base=0) const
1408  { return impl::ToNum<ULongL>::getnum(data_, size_, base); }
1409 
1410  // NUMF
1411 
1413  Float numf() const
1414  { return impl::ToNumf<Float>::getnum(data_, size_); }
1415 
1417  FloatD numfd() const
1418  { return impl::ToNumf<FloatD>::getnum(data_, size_); }
1419 
1421  FloatL numfl() const
1422  { return impl::ToNumf<FloatL>::getnum(data_, size_); }
1423 
1424  // CONVERT
1425 
1427  template<class C> C convert() const
1428  // An "undefined reference" compiler error pointing here means the given conversion isn't implemented/supported
1429  { return Convert<SubString,C>::value(*this); }
1430 
1432  template<class C> SubString& convert_set(C value)
1433  // An "undefined reference" compiler error pointing here means the given conversion isn't implemented/supported
1434  { Convert<SubString,C>::set(*this, value); return *this; }
1435 
1446  template<class Tok,class C> typename C::Size split(C& items, char delim=',') const {
1447  typename C::Size count = 0;
1448  Tok tok(*this);
1449  for (; tok.next(delim); ++count)
1450  items.add(tok.value().template convert<typename C::Item>());
1451  return count;
1452  }
1453 
1454  // Doxygen: Inherited methods
1455 #ifdef DOXYGEN
1456 
1457  const char* data() const;
1458 
1460  const char& operator[](Key index) const;
1461 
1463  const char& item(Key index) const;
1464 
1466  bool operator==(const StringBase& data) const;
1467 
1469  bool operator!=(const StringBase& data) const;
1470 
1472  bool null() const;
1473 
1475  bool empty() const;
1476 
1478  Size size() const;
1479 
1481  bool shared() const;
1482 
1484  const char* first() const;
1485 
1487  const char* last() const;
1488 
1490  Key iend(Size offset) const;
1491 
1493  ulong hash(ulong seed) const;
1494 
1496  int compare(const StringBase& data) const;
1497 
1499  Key find(ItemVal item,Key start,Key end) const;
1500 
1502  Key findr(ItemVal item,Key start,Key end) const;
1503 
1505  Key findany(const char* items,Size count,Key start,Key end) const;
1506 
1508  Key findanyr(const char* items,Size count,Key start,Key end) const;
1509 
1511  template<class T1,class T2> bool splitat(Key index,T1& left,T2& right) const;
1512 
1514  template<class T1> bool splitat(Key index,T1& left) const;
1515 
1517  template<class T2> bool splitat(Key index,ValNull left,T2& right) const;
1518 
1520  bool splitat_setl(Key index);
1521 
1523  template<class T2> bool splitat_setl(Key index,T2& right);
1524 
1526  bool splitat_setr(Key index);
1527 
1529  template<class T1> bool splitat_setr(Key index,T1& left);
1530 
1532  void swap(StringBase& list);
1533 #endif
1534 
1535 private:
1536  // Doxygen: Hide unused overridden parent members from documentation
1537  #ifdef DOXYGEN
1538  void iterInitMutable();
1539  const char* iterFirst(IterKey& key) const;
1540  const char* iterNext(IterKey& key) const;
1541  const char* iterNext(Size count,IterKey& key) const;
1542  const char* iterLast(IterKey& key) const;
1543  const char* iterPrev(IterKey& key) const;
1544  const char* iterPrev(Size count,IterKey& key) const;
1545  Size iterCount() const;
1546  const char* iterSet(IterKey key) const;
1547  #endif
1548 };
1549 
1550 // SubString comparison
1552 inline bool operator==(const char* str1, const SubString& str2)
1553  { return str2 == str1; }
1554 inline bool operator!=(const char* str1, const SubString& str2)
1555  { return str2 != str1; }
1558 // SubString conversion
1560 // Common base types for string conversion -- used internally
1561 template<class T> struct Convert_SubStringToIntBase {
1562  // Invalid: Converting Num to SubString
1563  template<class U> static void set(U&, const SubString&)
1565  template<class U> static void add(U&, const SubString&)
1567  template<class U> static bool addq(U&, const SubString&, char)
1569  static T value(const SubString& src)
1570  { return src.getnum<T>(); }
1571 };
1572 template<class T> struct Convert_SubStringToFltBase {
1573  // Invalid: Converting Flt to SubString
1574  template<class U> static void set(U&, const SubString&)
1576  template<class U> static void add(U&, const SubString&)
1578  template<class U> static bool addq(U&, const SubString&, char)
1580  static T value(const SubString& src)
1581  { return src.getnumf<T>(); }
1582 };
1583 // Conversion templates
1584 template<> struct Convert<const char*,SubString> {
1585  // Invalid: Converting char* to SubString
1586  template<class U> static void set(U&, const SubString&)
1588  template<class U> static void add(U&, const SubString&)
1590  template<class U> static bool addq(U&, const SubString&, char)
1592  static SubString value(const char* src)
1593  { return src; }
1594 };
1595 template<> struct Convert<char*,SubString> {
1596  // Invalid: Converting char* to SubString
1597  template<class U> static void set(U&, const SubString&)
1599  template<class U> static void add(U&, const SubString&)
1601  template<class U> static bool addq(U&, const SubString&, char)
1603  static SubString value(const char* src)
1604  { return src; }
1605 };
1606 template<> struct Convert<String,SubString> {
1607  static void set(String& dest, const SubString& value)
1608  { dest = value; }
1609  static void add(String& dest, const SubString& value)
1610  { dest.add(value); }
1611  static bool addq(String& dest, const SubString& value, char delim)
1612  { return (value.size() == 0 || dest.writequoted(value.data(), value.size(), delim, true) > 0); }
1613  static SubString value(const String& src)
1614  { return src; }
1615 };
1616 template<> struct Convert<SubString,String> {
1617  static void set(SubString& dest, const String& value)
1618  { dest = value; }
1619  // Invalid: Add String to SubString
1620  template<class U> static void add(U& dest, const String& value)
1622  template<class U> static bool addq(U&, const SubString&, char)
1624  static String value(const SubString& src)
1625  { return src; }
1626 };
1627 template<> struct Convert<SubString,SubString> {
1628  static void set(SubString& dest, const SubString& value)
1629  { dest.set(value); }
1630  // Invalid: Add SubString to SubString
1631  template<class U> static void add(U& dest, const SubString& value)
1633  template<class U> static bool addq(U&, const SubString&, char)
1635  static const SubString& value(const SubString& src)
1636  { return src; }
1637 };
1638 template<> struct Convert<SubString,bool> {
1639  static void set(SubString& dest, bool value) {
1640  if (value) dest.set("true", 4);
1641  else dest.set("false", 5);
1642  }
1643  // Invalid: Add bool to SubString
1644  template<class U> static void add(U& dest, const SubString& value)
1646  template<class U> static bool addq(U&, const SubString&, char)
1648  static bool value(const SubString& src)
1649  { return src.getbool<bool>(); }
1650 };
1651 template<> struct Convert<SubString,short> : public Convert_SubStringToIntBase<short> { };
1652 template<> struct Convert<SubString,int> : public Convert_SubStringToIntBase<int> { };
1653 template<> struct Convert<SubString,long> : public Convert_SubStringToIntBase<long> { };
1654 template<> struct Convert<SubString,longl> : public Convert_SubStringToIntBase<longl> { };
1655 template<> struct Convert<SubString,ushort> : public Convert_SubStringToIntBase<ushort> { };
1656 template<> struct Convert<SubString,uint> : public Convert_SubStringToIntBase<uint> { };
1657 template<> struct Convert<SubString,ulong> : public Convert_SubStringToIntBase<ulong> { };
1658 template<> struct Convert<SubString,ulongl> : public Convert_SubStringToIntBase<ulongl> { };
1659 template<> struct Convert<SubString,float> : public Convert_SubStringToFltBase<float> { };
1660 template<> struct Convert<SubString,double> : public Convert_SubStringToFltBase<double> { };
1661 template<> struct Convert<SubString,ldouble> : public Convert_SubStringToFltBase<ldouble> { };
1662 template<> struct Convert<SubString,Bool> {
1663  static void set(SubString& dest, Bool value) {
1664  if (value.null()) dest.set();
1665  else if (*value) dest.set("true", 4);
1666  else dest.set("false", 5);
1667  }
1668  // Invalid: Add Bool to SubString
1669  template<class U> static void add(U& dest, const SubString& value)
1671  template<class U> static bool addq(U&, const SubString&, char)
1673  static Bool value(const SubString& src)
1674  { return src.getbool<Bool>(); }
1675 };
1676 template<> struct Convert<SubString,Short> : public Convert_SubStringToIntBase<Short> { };
1677 template<> struct Convert<SubString,Int> : public Convert_SubStringToIntBase<Int> { };
1678 template<> struct Convert<SubString,Long> : public Convert_SubStringToIntBase<Long> { };
1679 template<> struct Convert<SubString,LongL> : public Convert_SubStringToIntBase<LongL> { };
1680 template<> struct Convert<SubString,UShort> : public Convert_SubStringToIntBase<UShort> { };
1681 template<> struct Convert<SubString,UInt> : public Convert_SubStringToIntBase<UInt> { };
1682 template<> struct Convert<SubString,ULong> : public Convert_SubStringToIntBase<ULong> { };
1683 template<> struct Convert<SubString,ULongL> : public Convert_SubStringToIntBase<ULongL> { };
1684 template<> struct Convert<SubString,Float> : public Convert_SubStringToFltBase<Float> { };
1685 template<> struct Convert<SubString,FloatD> : public Convert_SubStringToFltBase<FloatD> { };
1686 template<> struct Convert<SubString,FloatL> : public Convert_SubStringToFltBase<FloatL> { };
1687 
1690 
1723 public:
1725  SubStringMapList() : data_(NULL), size_(0) {
1726  }
1727 
1736  SubStringMapList(const SubString* data, SizeT size, bool verify_order=false) : data_((SubString*)data), size_(size) {
1737  if (verify_order && !verify())
1738  EVO_THROW(ExceptionSubStringMapList, "SubStringMapList verify order failed -- the constructor requires ordered input");
1739  }
1740 
1744  const SubString* data() const {
1745  return data_;
1746  }
1747 
1751  SizeT size() const {
1752  return size_;
1753  }
1754 
1758  bool empty() const {
1759  return (size_ == 0);
1760  }
1761 
1765  bool null() const {
1766  return (data_ == NULL);
1767  }
1768 
1777  SizeT find(const SubString& key) const {
1778  int cmp;
1779  SizeT left = 0, right = size_, mid = 0;
1780  while (left < right) {
1781  mid = left + ((right-left) / 2);
1782  cmp = key.compare(data_[mid]);
1783  if (cmp < 0)
1784  right = mid;
1785  else if (cmp == 0)
1786  return mid;
1787  else
1788  left = mid + 1;
1789  }
1790  return NONE;
1791  }
1792 
1831  template<class T>
1832  T find_enum(const SubString& key, T first_enum, T last_enum, T unknown) const {
1833  assert( (SizeT)last_enum >= (SizeT)first_enum );
1834  assert( (SizeT)last_enum - (SizeT)first_enum + 1 == size_ );
1835  SizeT i = find(key);
1836  if (i == NONE || (i += (SizeT)first_enum) > (SizeT)last_enum)
1837  return unknown;
1838  return (T)i;
1839  }
1840 
1886  template<class T>
1887  T find_enum_remap(const T* remap_array, const SubString& key, T first_enum, T last_enum, T unknown) const {
1888  SizeT i = find(key);
1889  if (i == NONE || (SizeT)last_enum < (SizeT)first_enum || i >= ((SizeT)last_enum - (SizeT)first_enum + 1))
1890  return unknown;
1891  return (T)remap_array[i];
1892  }
1893 
1904  template<class T>
1905  SubString get_enum_string(T enum_value, T first_enum, T last_enum) const {
1906  SizeT i;
1907  if ((SizeT)enum_value < (SizeT)first_enum || (SizeT)enum_value > (SizeT)last_enum || (i = (SizeT)enum_value - (SizeT)first_enum) >= size_)
1908  return SubString();
1909  return data_[i];
1910  }
1911 
1923  template<class T>
1924  SubString get_enum_string_remap(const SizeT* reverse_remap_array, T enum_value, T first_enum, T last_enum) const {
1925  SizeT i;
1926  if ((SizeT)enum_value < (SizeT)first_enum || (SizeT)enum_value > (SizeT)last_enum || (i = (SizeT)enum_value - (SizeT)first_enum) >= size_)
1927  return SubString();
1928  return data_[reverse_remap_array[i]];
1929  }
1930 
1931 #if defined(EVO_CPP11)
1932 
1968  template<class T>
1969  T find_enum_class(const SubString& key) const {
1970  return find_enum<T>(key, (T)((SizeT)T::UNKNOWN + 1), (T)((SizeT)T::ENUM_END - 1), T::UNKNOWN);
1971  }
1972 
1982  template<class T>
1983  SubString get_enum_class_string(T enum_value) const {
1984  return get_enum_string(enum_value, (T)((SizeT)T::UNKNOWN + 1), (T)((SizeT)T::ENUM_END - 1));
1985  }
1986 #endif
1987 
1996  bool verify() const {
1997  for (SizeT i = 1; i < size_; ++i)
1998  if (data_[i-1].compare(data_[i]) >= 0)
1999  return false;
2000  return true;
2001  }
2002 
2008  template<class T>
2009  struct ReverseRemap {
2010  typedef typename T::Type EnumType;
2011 
2012  static const int SIZE = (int)T::LAST - (int)T::FIRST + 1;
2013 
2014  SizeT array[SIZE];
2015 
2019  EVO_ONCPP14_FULL(constexpr) ReverseRemap(const EnumType* remap_array) EVO_ONCPP14_FULL(: array()) {
2020  for (SizeT i = 0; i < (uint)SIZE; ++i)
2021  array[(int)remap_array[i] - (int)T::FIRST] = i;
2022  }
2023  };
2024 
2025 private:
2026  SubString* data_;
2027  SizeT size_;
2028 };
2029 
2031 
2032 }
2033 #endif
C convert() const
Convert string to value of given type.
Definition: substring.h:1427
SubString get_enum_string_remap(const SizeT *reverse_remap_array, T enum_value, T first_enum, T last_enum) const
Convert enum value to key string from list, with unsorted enum remapped to sorted values...
Definition: substring.h:1924
SubString(SubString &&src)
Move constructor (C++11).
Definition: substring.h:294
Key find(StringSearchAlg alg, const StringBase &pattern, Key start=0, Key end=END) const
Find first occurrence of pattern string using specified algorithm.
Definition: substring.h:737
CharBreakType ascii_breaktype(char ch)
Get ASCII character word-break type.
Definition: str.h:91
bool operator==(const ListBase< wchar16, T > &str)
Equality operator to compare against UTF-16 string.
Definition: substring.h:626
T & max(T &a, T &b)
Returns highest of given values.
Definition: alg.h:47
Key findr(const char *pattern, uint pattern_size, Key start=0, Key end=END) const
Find last occurrence of pattern string with reverse search.
Definition: substring.h:786
SubString & stripl_newlines()
Strip all left (beginning) newlines from string.
Definition: substring.h:1196
bool getbool(Error &error) const
Convert to bool value for given boolean type.
Definition: substring.h:1337
SubString & stripr_newlines(Size max)
Strip right (ending) newlines from string.
Definition: substring.h:1244
Float numf() const
Convert to number value (floating point).
Definition: substring.h:1413
SubString & stripl2()
Strip left (beginning) whitespace from string, including newlines.
Definition: substring.h:1177
SubString & triml(Size size)
Trim left (beginning) items.
Definition: substring.h:1307
bool contains(const char *str, Size size) const
Check whether this contains given string.
Definition: substring.h:965
Key findanyr(const StringBase &chars, Key start=0, Key end=END) const
Find last occurrence of any given characters with reverse search.
Definition: substring.h:869
#define STATIC_ASSERT_FUNC_UNUSED
Assert a function is unused at compile-time.
Definition: meta.h:80
SubString & operator=(SubString &&src)
Move assignment operator (C++11).
Definition: substring.h:302
Long numl(int base=0) const
Convert to number value (signed long).
Definition: substring.h:1389
Basic boolean type.
Definition: type.h:568
int utf8_compare(const char *str1, ulong len1, const char *str2, ulong len2)
Compare two non-terminated UTF-8 strings.
Definition: str.h:305
Evo String container.
ValEmpty
Special empty value type, pass as vEMPTY.
Definition: sys.h:1101
Static conditional type.
Definition: meta.h:134
bool token(StringT &value, char delim)
Extract next token from string.
Definition: substring.h:383
bool split(char delim, ValNull left, T2 &right) const
Split at first occurrence of delimiter into right substring.
Definition: substring.h:1004
Evo string scanning helpers with SSE optimized code.
FloatL numfl() const
Convert to number value (ldouble floating point).
Definition: substring.h:1421
Key findr(const StringBase &pattern, Key start=0, Key end=END) const
Find last occurrence of pattern string with reverse search.
Definition: substring.h:808
Nullable< T > & set()
Set as null.
Definition: type.h:342
SubString(const char *data)
Constructor to reference terminated string.
Definition: substring.h:287
Key findany(const StringBase &chars, Key start=0, Key end=END) const
Find first occurrence of any given characters with forward search.
Definition: substring.h:849
T find_enum_class(const SubString &key) const
Find key string in list and convert to enum class value (C++11).
Definition: substring.h:1969
bool tokenr_any(StringT &value, Char &found_delim, const char *delims, Size count)
Extract next token from string in reverse (from end of string) using any of given delimiters...
Definition: substring.h:497
bool operator==(const char *str) const
Equality operator.
Definition: substring.h:632
Basic character type (char) – see CharT.
Definition: type.h:775
SubStringMapList input ordering verification failed, see Exception.
Definition: substring.h:22
References a list of sorted substrings for fast lookup.
Definition: substring.h:1722
bool token_line(StringT &line)
Extract next line from string.
Definition: substring.h:533
T first(T val1, T val2)
Definition: alg.h:85
Word character (A-Z, a-z, 0-9, _)
Definition: str.h:65
Size Key
Key type (item index)
Definition: sublist.h:151
SubString(const char *data, Size size)
Constructor to reference string data.
Definition: substring.h:281
SubString get_enum_string(T enum_value, T first_enum, T last_enum) const
Convert enum value to key string from list.
Definition: substring.h:1905
Size writequoted(const char *buf, Size size, char delim, bool optional=false)
Write (append) quoted output to string.
Definition: string.h:4305
ValNull
Unique null value type and value (vNULL).
Definition: sys.h:1096
SubString & stripr2()
Strip right (ending) whitespace (including newlines) from string.
Definition: substring.h:1187
Int num(int base=0) const
Convert to number value (signed).
Definition: substring.h:1385
C::Size split(C &items, char delim=',') const
Split delimited string into item list using given tokenizer.
Definition: substring.h:1446
static const T & value(const T &src)=delete
Convert value to target.
int compare(const ListBase< wchar16, T > &str)
Comparison against UTF-16 string.
Definition: substring.h:612
const SubString & asconst() const
Explicitly use a const reference to this.
Definition: substring.h:313
bool empty() const
Get whether empty.
Definition: substring.h:1758
constexpr ReverseRemap(const EnumType *remap_array)
Constructor.
Definition: substring.h:2019
const char * cstr(String &buffer) const
Get terminated string pointer, using given string buffer if needed (const).
Definition: string.h:1561
FloatD numfd() const
Convert to number value (double floating point).
Definition: substring.h:1417
Key findr(StringSearchAlg alg, const StringBase &pattern, Key start=0, Key end=END) const
Find last occurrence of pattern string with reverse search.
Definition: substring.h:818
#define EVO_CREATE_EXCEPTION_IMPL(NAME, BASE)
Create an Evo exception implementation.
Definition: sys.h:1365
SubString get_enum_class_string(T enum_value) const
Convert enum class value to key string from list (C++11).
Definition: substring.h:1983
bool tokenr_line(StringT &line)
Extract next line from string in reverse (from end of string).
Definition: substring.h:567
static const T MAX
Maximum interger value.
Definition: type.h:996
Key findanybut(const char *chars, Size count, Key start=0, Key end=END) const
Find first occurrence of any character not listed with forward search.
Definition: substring.h:873
void swap(T &a, T &b)
Swap contents of given objects.
Definition: sys.h:1602
SubString & stripr_newlines()
Strip all right (ending) newlines from string.
Definition: substring.h:1236
Generic value conversion template.
Definition: type.h:1757
bool tokenr(StringT &value, char delim)
Extract next token from string in reverse (from end of string).
Definition: substring.h:414
Key findany(const char *chars, Size count, Key start=0, Key end=END) const
Find first occurrence of any given characters with forward search.
Definition: substring.h:828
const char * str_scan_nws(const char *str, const char *end)
Scan string pointer for next non-whitespace character and return stop pointer.
Definition: strscan.h:877
SubString & slice2(Key index1, Key index2)
Slice to given subset using start/end positions.
Definition: substring.h:1327
SubString & clear()
Clear by removing all items.
Definition: substring.h:1275
Basic integer type.
Definition: type.h:980
SubString & slice(Key index, Size size)
Slice to given subset.
Definition: substring.h:1323
SizeT find(const SubString &key) const
Find key string in list.
Definition: substring.h:1777
SubString()
Default constructor sets as null.
Definition: substring.h:234
SubString(const ThisType &str)
Copy constructor.
Definition: substring.h:243
Size size() const
Get size.
Check if type is a Plan Old Data type.
Definition: meta.h:528
bool starts(const char *str) const
Check if starts with given terminated string.
Definition: substring.h:658
Error
General Evo error code stored in exceptions, or used directly when exceptions are disabled...
Definition: sys.h:1113
bool splitr(char delim, ValNull left, T2 &right) const
Split at last occurrence of delimiter into right substring.
Definition: substring.h:1046
Data equality helper.
Definition: container.h:712
StrSizeT Size
List size integer type.
Definition: sublist.h:150
SubStringMapList()
Constructor for null and empty SubString list.
Definition: substring.h:1725
uint32 StrSizeT
Default Evo string size type.
Definition: sys.h:734
bool contains(const StringBase &str) const
Check whether contains given string.
Definition: substring.h:969
String container.
Definition: string.h:674
T getnum(int base=0) const
Convert to number value for given integer type.
Definition: substring.h:1358
T getnum(Error &error, int base=0) const
Convert to number value for given integer type.
Definition: substring.h:1351
SubString & operator=(const SubString &src)
Assignment operator.
Definition: substring.h:320
SubString & operator=(const StringBase *data)
Assignment operator sets as reference to source data from pointer.
Definition: substring.h:328
Key findnonwordr(Key start=0, Key end=END) const
Find last non-word character with reverse search.
Definition: substring.h:949
Key findwordr(Key start=0, Key end=END) const
Find last word character with reverse search.
Definition: substring.h:925
SubStringMapList(const SubString *data, SizeT size, bool verify_order=false)
Constructor for referencing an existing SubString list.
Definition: substring.h:1736
bool operator==(const PtrBase< T > &ptr1, const PtrBase< T, Atomic< T *> > &ptr2)
Equality operator for managed pointer base and atomic pointer base.
Definition: atomic.h:1193
const SubString * data() const
Get pointer to map string values.
Definition: substring.h:1744
SubString & unshare()
Make data unique – no-op.
Definition: substring.h:1331
SubString & stripl()
Strip left (beginning) whitespace (spaces and tabs).
Definition: substring.h:1090
#define STATIC_ASSERT_FUNC_UNUSED_RET(RET)
Assert a function is unused at compile-time (with return value).
Definition: meta.h:96
Key find(char ch) const
Find first occurrence of character with forward search.
Definition: substring.h:681
SubString & stripr()
Strip right (ending) whitespace (spaces and tabs).
Definition: substring.h:1135
T getnumf() const
Convert to floating point number value for given type.
Definition: substring.h:1371
SubString & stripl(char ch, Size max=ALL)
Strip left (beginning) occurrences of character.
Definition: substring.h:1103
static void set(C &dest, T value)=delete
Set target to value (reversed conversion).
static const EndT END
Special integer value for indicating end of items or no item.
Definition: type.h:1846
SubString & strip(char ch)
Strip left (beginning) and right (ending) occurences of character.
Definition: substring.h:1076
static const EndT ALL
Special integer value for indicating all items or all remaining items.
Definition: type.h:1839
T find_enum(const SubString &key, T first_enum, T last_enum, T unknown) const
Find key string in list and convert to enum value.
Definition: substring.h:1832
const char * str_scan_nws_r(const char *str, const char *end)
Scan string pointer for next non-whitespace character in reverse and return new end after stop pointe...
Definition: strscan.h:896
Evo SubList container.
T getbool() const
Convert to bool value for given boolean type.
Definition: substring.h:1343
bool operator!=(const PtrBase< T > &ptr1, const PtrBase< T, Atomic< T *> > &ptr2)
Inequality operator for managed pointer base and atomic pointer base.
Definition: atomic.h:1202
ULong numul(int base=0) const
Convert to number value (unsigned long).
Definition: substring.h:1403
Key findnonword(Key start=0, Key end=END) const
Find first non-word word character.
Definition: substring.h:937
bool operator!=(const ListBase< wchar16, T > &str)
Inequality operator to compare against UTF-16 string.
Definition: substring.h:642
SubString & strip2()
Strip left (beginning) and right (ending) whitespace from string, including newlines.
Definition: substring.h:1167
Evo base exception class.
Definition: sys.h:1214
Key find(StringSearchAlg alg, const char *pattern, uint pattern_size, Key start=0, Key end=END) const
Find first occurrence of pattern string using specified algorithm.
Definition: substring.h:716
SubString & convert_set(C value)
Convert value to string, replacing current string.
Definition: substring.h:1432
SubString(const StringBase &str, Key index, Size size=ALL)
Copy constructor.
Definition: substring.h:263
bool token_any(StringT &value, Char &found_delim, const char *delims, Size count)
Extract next token from string using any of given delimiters.
Definition: substring.h:457
const char * cstr(String &buffer) const
Get terminated string pointer, using given string buffer if needed (const).
Definition: substring.h:599
Key find(const char *pattern, uint pattern_size, Key start=0, Key end=END) const
Find first occurrence of pattern string.
Definition: substring.h:705
ULongL numull(int base=0) const
Convert to number value (unsigned long-long).
Definition: substring.h:1407
LongL numll(int base=0) const
Convert to number value (signed long-long).
Definition: substring.h:1393
Evo C++ Library namespace.
Definition: alg.h:11
Key findr(char ch, Key start, Key end=END) const
Find last occurrence of character with reverse search.
Definition: substring.h:764
bool null() const
Get whether null.
Definition: substring.h:1765
UInt numu(int base=0) const
Convert to number value (unsigned).
Definition: substring.h:1399
StringSearchAlg
String search algorithm selection.
Definition: str.h:1164
static const EndT NONE
Special integer value for indicating no item or unknown item.
Definition: type.h:1832
Key findanybut(const StringBase &chars, Key start=0, Key end=END) const
Find first occurrence of any character not listed with forward search.
Definition: substring.h:889
SubString & truncate(Size size)
Truncate to given size.
Definition: substring.h:1315
DataCopy< char >::PassType ItemVal
Item type as parameter (POD types passed by value, otherwise by const-ref)
Definition: sublist.h:154
SubString & operator=(const char *data)
Assignment operator sets as reference to terminated string.
Definition: substring.h:338
SizeT size() const
Get number of items in map.
Definition: substring.h:1751
SubString & set2(const StringBase &data, Key index1, Key index2)
Set as reference to subset of source data using start/end positions.
Definition: substring.h:1299
ListBaseType StringBase
Alias for ListBaseType.
Definition: substring.h:231
SubString & strip()
Strip left (beginning) and right (ending) whitespace (spaces and tabs).
Definition: substring.h:1061
SubString ThisType
This string type.
Definition: substring.h:230
SubString & operator=(const ValNull &val)
Assignment operator sets as null.
Definition: substring.h:360
SubString & strip_newlines()
Strip left (beginning) and right (ending) newlines from string.
Definition: substring.h:1266
SubString & setempty()
Set as empty but not null.
Definition: substring.h:1303
Key findanybutr(const StringBase &chars, Key start=0, Key end=END) const
Find last occurrence of any character not listed with reverse search.
Definition: substring.h:909
T * data_
Data pointer, NULL if null.
Definition: sys.h:979
String & add(char ch)
Append character (modifier).
Definition: string.h:2741
#define EVO_ONCPP14_FULL(EXPR)
Compile EXPR only if "full" C++14 support is detected, otherwise this is a no-op. ...
Definition: sys.h:292
SubString & stripr(const char *str, Size strsize, Size max=ALL)
Strip right (ending) occurences of string.
Definition: substring.h:1150
bool contains(char ch) const
Check whether this contains given character.
Definition: substring.h:961
T getnumf(Error &error) const
Convert to floating point number value for given type.
Definition: substring.h:1364
Key find(const StringBase &pattern, Key start=0, Key end=END) const
Find first occurrence of pattern string.
Definition: substring.h:727
SubString & trimr(Size size)
Trim right (ending) items.
Definition: substring.h:1311
SubString & operator=(const StringBase &data)
Assignment operator sets as reference to source data.
Definition: substring.h:324
Bool boolval() const
Convert to bool value.
Definition: substring.h:1379
Reference and access existing list data.
Definition: sublist.h:145
Error error() const
Get error code.
Definition: sys.h:1260
bool splitr(char delim, T1 &left) const
Split at last occurrence of delimiter into left substring.
Definition: substring.h:1033
bool operator!=(const char *str) const
Inequality operator.
Definition: substring.h:648
TSize size_
Data size as item count, 0 if empty or null.
Definition: sys.h:980
Nullable basic floating-point base type.
Definition: type.h:1291
Key find(char ch, Key start, Key end=END) const
Find first occurrence of character with forward search.
Definition: substring.h:691
SubString & stripl(const char *str, Size strsize, Size max=ALL)
Strip left (beginning) occurrences of string.
Definition: substring.h:1115
bool split(char delim, T1 &left, T2 &right) const
Split at first occurrence of delimiter into left/right substrings.
Definition: substring.h:976
Key findanybutr(const char *chars, Size count, Key start=0, Key end=END) const
Find last occurrence of any character not listed with reverse search.
Definition: substring.h:893
T find_enum_remap(const T *remap_array, const SubString &key, T first_enum, T last_enum, T unknown) const
Find key string in list and convert to enum value, with unsorted enum remapped to sorted values...
Definition: substring.h:1887
Key findr(char ch) const
Find last occurrence of character with reverse search.
Definition: substring.h:747
String & set()
Set as null and empty.
Definition: string.h:995
SubString(const StringBase &str)
Copy constructor.
Definition: substring.h:252
bool splitr(char delim, T1 &left, T2 &right) const
Split at last occurrence of delimiter into left/right substrings.
Definition: substring.h:1018
uint32 SizeT
Default Evo container size type.
Definition: sys.h:729
bool verify() const
Verify strings are in correct order.
Definition: substring.h:1996
#define EVO_THROW(TYPE, MSG)
Throw an Evo exception.
Definition: sys.h:1446
Reference and access existing string data.
Definition: substring.h:229
SubString(const StringBase *str)
Copy constructor.
Definition: substring.h:272
int utf16_compare8(const wchar16 *str1, ulong len1, const char *str2, ulong len2)
Compare a non-terminated UTF-16 string to a non-terminated UTF-8 string.
Definition: str.h:842
ulong line() const
Get exception line number.
Definition: sys.h:1248
SubString & stripr(char ch, Size max=ALL)
Strip right (ending) occurences of character.
Definition: substring.h:1143
Base for all Evo list types (used internally).
Definition: sys.h:976
SubString & slice(Key index)
Slice beginning items.
Definition: substring.h:1319
#define STATIC_ASSERT(EXP, TOKEN)
Assert compile-time expression is true or trigger compiler error.
Definition: meta.h:54
SubString & operator=(const ValEmpty &val)
Assignment operator sets as null.
Definition: substring.h:366
Key findr(StringSearchAlg alg, const char *pattern, uint pattern_size, Key start=0, Key end=END) const
Find last occurrence of pattern string with reverse search.
Definition: substring.h:797
bool ends(const char *str) const
Check if ends with given terminated string.
Definition: substring.h:671
Key findanyr(const char *chars, Size count, Key start=0, Key end=END) const
Find last occurrence of any given characters with reverse search.
Definition: substring.h:853
#define EVO_PARAM_UNUSED(NAME)
Mark function parameter as unused to suppress "unreferenced parameter" compiler warnings on it...
Definition: sys.h:427
const char * data() const
Get data pointer.
bool split(char delim, T1 &left) const
Split at first occurrence of delimiter into left substring.
Definition: substring.h:991
T::Type EnumType
Alias for enum type used (T::Type)
Definition: substring.h:2010
Builds a reversed enum value remap array for fast reverse lookups.
Definition: substring.h:2009
Key findword(Key start=0, Key end=END) const
Find first word character.
Definition: substring.h:913
SubString & stripl_newlines(Size max)
Strip left (beginning) newlines from string.
Definition: substring.h:1209