Gorgon Game Engine
String.h
Go to the documentation of this file.
1 
4 #pragma once
5 
6 #include <string>
7 #include <cstring>
8 #include <string>
9 #include <sstream>
10 #include <iostream>
11 #include <iomanip>
12 #include <stdexcept>
13 #include <algorithm>
14 #include "String/Exceptions.h"
15 #include "Enum.h"
16 #include "Types.h"
17 
18 #undef decltype
19 
20 namespace Gorgon {
21 
23  namespace String {
24 
26  bool operator()(const std::string &left, const std::string &right) const {
27  unsigned len=(unsigned int)std::min(left.length(), right.length());
28 
29  auto l=left.begin();
30  auto r=right.begin();
31  for(unsigned i=0; i<len; i++) {
32  auto lc=tolower(*l);
33  auto rc=tolower(*r);
34  if(lc<rc) {
35  return true;
36  }
37  else if(lc>rc) {
38  return false;
39  }
40  ++l;
41  ++r;
42  }
43 
44  return left.length()<right.length();
45  }
46  };
47 
49  inline int CaseInsensitiveCompare(const std::string &left, const std::string &right) {
50  unsigned len=(unsigned int)std::min(left.length(), right.length());
51 
52  auto l=left.begin();
53  auto r=right.begin();
54  for(unsigned i=0; i<len; i++) {
55  auto lc=tolower(*l);
56  auto rc=tolower(*r);
57  if(lc<rc) {
58  return -1;
59  }
60  else if(lc>rc) {
61  return 1;
62  }
63  ++l;
64  ++r;
65  }
66 
67  return left.length()<right.length() ? -1 : (left.length()==right.length() ? 0 : 1);
68  }
69 
70 
71 #ifdef DOXYGEN
72  template <class T_>
77  T_ To(const std::string &value) {
78  return T_();
79  }
80 #endif
81 
83 
84 
85 # define ISENUMUPGRADED decltype(gorgon__enum_tr_loc(T_()))::isupgradedenum
86 
87  template <class T_>
88  typename std::enable_if<std::is_constructible<T_, std::string>::value, T_>::type
89  To(const std::string &value) {
90  return T_(value);
91  }
92 
93  template <class T_>
94  typename std::enable_if<!std::is_constructible<T_, std::string>::value && !ISENUMUPGRADED, T_>::type
95  To(const std::string &value) {
96  std::stringstream ss(value);
97 
98  T_ ret;
99  ss>>ret;
100 
101  return ret;
102  }
103 
104  template <class T_>
105  typename std::enable_if<std::is_constructible<T_, const char*>::value, T_>::type
106  To(const char *value) {
107  return T_(value);
108  }
109 
110  template <class T_>
111  typename std::enable_if<!std::is_constructible<T_, const char*>::value && std::is_constructible<T_, std::string>::value, T_>::type
112  To(const char *value) {
113  return T_(value);
114  }
115 
116  template <class T_>
117  typename std::enable_if<!std::is_constructible<T_, const char*>::value &&
118  !std::is_constructible<T_, std::string>::value &&
119  !ISENUMUPGRADED,
120  T_>::type
121  To(const char *value) {
122  std::stringstream ss(value);
123 
124  T_ ret;
125  ss>>ret;
126 
127  return ret;
128  }
129 
130  template <>
131  inline char To<char>(const std::string &value) {
132  char *n;
133  return (char)std::strtol(value.c_str(), &n, 10);
134  }
135 
136  template <>
137  inline unsigned char To<unsigned char>(const std::string &value) {
138  char *n;
139  return (unsigned char)std::strtol(value.c_str(), &n, 10);
140  }
141 
142  template <>
143  inline short To<short>(const std::string &value) {
144  char *n;
145  return (short)std::strtol(value.c_str(), &n, 10);
146  }
147 
148  template <>
149  inline unsigned short To<unsigned short>(const std::string &value) {
150  char *n;
151  return (unsigned short)std::strtol(value.c_str(), &n, 10);
152  }
153 
154  template <>
155  inline int To<int>(const std::string &value) {
156  char *n;
157  return (int)std::strtol(value.c_str(), &n, 10);
158  }
159 
160  template <>
161  inline unsigned To<unsigned>(const std::string &value) {
162  char *n;
163  return (unsigned)std::strtol(value.c_str(), &n, 10);
164  }
165 
166  template <>
167  inline long To<long>(const std::string &value) {
168  char *n;
169  return (long)std::strtol(value.c_str(), &n, 10);
170  }
171 
172  template <>
173  inline unsigned long To<unsigned long>(const std::string &value) {
174  char *n;
175  return (unsigned long)std::strtol(value.c_str(), &n, 10);
176  }
177 
178  template <>
179  inline long long To<long long>(const std::string &value) {
180  char *n;
181  return (long long)std::strtol(value.c_str(), &n, 10);
182  }
183 
184  template <>
185  inline unsigned long long To<unsigned long long>(const std::string &value) {
186  char *n;
187  return (unsigned long long)std::strtol(value.c_str(), &n, 10);
188  }
189 
190  template <>
191  inline float To<float>(const std::string &value) {
192  if(value=="") return 0;
193 
194  return (float)std::strtof(value.c_str(), nullptr);
195  }
196 
197  template <>
198  inline double To<double>(const std::string &value) {
199  if(value=="") return 0;
200 
201  return std::strtod(value.c_str(), nullptr);
202  }
203 
204  template <>
205  inline long double To<long double>(const std::string &value) {
206  if(value=="") return 0;
207 
208  return std::strtold(value.c_str(), nullptr);
209  }
210 
211  template <>
212  inline bool To<bool>(const std::string &value) {
213  if(value=="false" || value=="no" || value=="" || To<int>(value)==0)
214  return false;
215  else
216  return true;
217  }
218 
219  template <>
220  inline char To<char>(const char *value) {
221  return (char)std::strtol(value, nullptr, 10);
222  }
223 
224  template <>
225  inline unsigned char To<unsigned char>(const char *value) {
226  return (unsigned char)std::strtol(value, nullptr, 10);
227  }
228 
229  template <>
230  inline short To<short>(const char *value) {
231  return (short)std::strtol(value, nullptr, 10);
232  }
233 
234  template <>
235  inline unsigned short To<unsigned short>(const char *value) {
236  return (unsigned short)std::strtol(value, nullptr, 10);
237  }
238 
239  template <>
240  inline int To<int>(const char *value) {
241  return (int)std::strtol(value, nullptr, 10);
242  }
243 
244  template <>
245  inline unsigned To<unsigned>(const char *value) {
246  return (unsigned)std::strtol(value, nullptr, 10);
247  }
248 
249  template <>
250  inline long To<long>(const char *value) {
251  return (long)std::strtol(value, nullptr, 10);
252  }
253 
254  template <>
255  inline unsigned long To<unsigned long>(const char *value) {
256  return (unsigned long)std::strtol(value, nullptr, 10);
257  }
258 
259  template <>
260  inline long long To<long long>(const char *value) {
261  return (long long)std::strtol(value, nullptr, 10);
262  }
263 
264  template <>
265  inline unsigned long long To<unsigned long long>(const char *value) {
266  return (unsigned long long)std::strtol(value, nullptr, 10);
267  }
268 
269  template <>
270  inline float To<float>(const char *value) {
271  return (float)std::atof(value);
272  }
273 
274  template <>
275  inline double To<double>(const char *value) {
276  return std::atof(value);
277  }
278 
279  template <>
280  inline long double To<long double>(const char *value) {
281  return std::atof(value);
282  }
283 
284  template <>
285  inline bool To<bool>(const char *value) {
286  return To<bool>(std::string(value));
287  }
288 
292  template <class T_>
293  T_ HexTo(const std::string &value);
294 
295  template <>
296  inline int HexTo<int>(const std::string &value) {
297  return std::stoi(value, nullptr, 16);
298  }
299 
300  template <>
301  inline long HexTo<long>(const std::string &value) {
302  return std::stol(value, nullptr, 16);
303  }
304 
305  template <>
306  inline long long HexTo<long long>(const std::string &value) {
307  return std::stoll(value, nullptr, 16);
308  }
309 
310  template <>
311  inline unsigned int HexTo<unsigned int>(const std::string &value) {
312  return (unsigned int)std::stoul(value, nullptr, 16);
313  }
314 
315  template <>
316  inline unsigned long HexTo<unsigned long>(const std::string &value) {
317  return std::stoul(value, nullptr, 16);
318  }
319 
320  template <>
321  inline unsigned long long HexTo<unsigned long long>(const std::string &value) {
322  return std::stoull(value, nullptr, 16);
323  }
325 
328  inline std::string PadStart(std::string str, std::size_t len, char pad = ' ') {
329  if(len > str.size())
330  str.insert(0, len - str.size(), pad);
331 
332  return str;
333  }
334 
337  inline std::string PadEnd(std::string str, std::size_t len, char pad = ' ') {
338  if(len > str.size())
339  str.insert(str.end(), len - str.size(), pad);
340 
341  return str;
342  }
343 
349  inline std::string Replace(std::string str, const std::string &find, const std::string &replace) {
350  std::string::size_type l=0;
351 
352  auto flen=find.length();
353  auto rlen=replace.length();
354 
355  if(!find.length()) return str;
356 
357  while( (l=str.find(find, l)) != str.npos ) {
358  str.erase(l, flen);
359  str.insert(l, replace);
360  l+=rlen;
361  }
362 
363  return str;
364  }
365 
370  inline std::string Trim(std::string str, const std::string &chars=" \t\n\r") {
371  if(!str.length()) return "";
372 
373  const char *ptr=str.c_str();
374  while(*ptr && chars.find_first_of(*ptr)!=chars.npos) {
375  ptr++;
376  }
377  str=str.substr(ptr-str.c_str());
378 
379  while(str.length() && chars.find_first_of(str[str.length()-1])!=chars.npos) {
380  str.resize(str.length()-1);
381  }
382 
383  return str;
384  }
385 
390  inline std::string TrimStart(std::string str, const std::string &chars=" \t\n\r") {
391  if(!str.length()) return "";
392 
393  const char *ptr=str.c_str();
394  while(*ptr && chars.find_first_of(*ptr)!=chars.npos) {
395  ptr++;
396  }
397  str=str.substr(ptr-str.c_str());
398 
399  return str;
400  }
401 
406  inline std::string TrimEnd(std::string str, const std::string &chars=" \t\n\r") {
407  while(str.length() && chars.find_first_of(str[str.length()-1])!=chars.npos) {
408  str.resize(str.length()-1);
409  }
410 
411  return str;
412  }
413 
416  inline std::string ToLower(std::string str) {
417  for(auto it=str.begin();it!=str.end();++it) {
418  *it=tolower(*it);
419  }
420 
421  return str;
422  }
423 
426  inline std::string ToUpper(std::string str) {
427  for(auto it=str.begin();it!=str.end();++it) {
428  *it=toupper(*it);
429  }
430 
431  return str;
432  }
433 
434 
436  inline std::string From(const char &value) {
437  return std::to_string(value);
438  }
439 
440  inline std::string From(const unsigned char &value) {
441  return std::to_string(value);
442  }
443 
444  inline std::string From(const int &value) {
445  return std::to_string(value);
446  }
447 
448  inline std::string From(const unsigned &value) {
449  return std::to_string(value);
450  }
451 
452  inline std::string From(const long &value) {
453  return std::to_string(value);
454  }
455 
456  inline std::string From(const unsigned long &value) {
457  return std::to_string(value);
458  }
459 
460  inline std::string From(const long long &value) {
461  return std::to_string(value);
462  }
463 
464  inline std::string From(const unsigned long long &value) {
465  return std::to_string(value);
466  }
467 
468  inline std::string From(const float &value) {
469  std::stringstream ss;
470  if(value > 1e7) {
471  ss<<std::fixed<<std::setprecision(0)<<value;
472  }
473  else {
474  ss<<std::setprecision(7)<<value;
475  }
476 
477  return ss.str();
478  }
479 
480  inline std::string From(const double &value) {
481  std::stringstream ss;
482  if(value > 1e14) {
483  ss<<std::fixed<<std::setprecision(0)<<value;
484  }
485  else {
486  ss<<std::setprecision(14)<<value;
487  }
488  return ss.str();
489  }
490 
491  inline std::string From(const long double &value) {
492  std::stringstream ss;
493  if(value > 1e28l) {
494  ss<<std::fixed<<std::setprecision(0)<<value;
495  }
496  else {
497  ss<<std::setprecision(28)<<value;
498  }
499  return ss.str();
500  }
501 
502  inline std::string From(const std::string &value) {
503  return value;
504  }
505 
506  template<class T_>
507  typename std::enable_if<std::is_convertible<T_, std::string>::value, std::string>::type
508  From(const T_ &item) {
509  return (std::string)item;
510  }
511 
512  template<class T_>
513  typename std::enable_if<!std::is_convertible<T_, std::string>::value && !decltype(gorgon__enum_tr_loc((*(T_*)nullptr)))::isupgradedenum, std::string>::type
514  From(const T_ &item) {
515  std::stringstream ss;
516  ss<<item;
517 
518  return ss.str();
519  }
520 
521  template<typename T>
522  class IsStreamable
523  {
524  using one = char;
525  struct two {
526  char dummy[2];
527  };
528 
529  template<class TT>
530  static one test(decltype(((std::ostream*)nullptr)->operator<<((TT*)nullptr))) { return one(); }
531 
532  static two test(...) { return two(); }
533 
534  public:
535  static const bool Value = sizeof( test(*(std::ostream*)nullptr) )==1;
536  };
537 
538  inline void streamthis(std::stringstream &stream) {
539  }
540 
541  template<class T_, class ...P_>
542  void streamthis(std::stringstream &stream, const T_ &first, const P_&... rest) {
543  stream<<first;
544 
545  streamthis(stream, rest...);
546  }
548 
549  template<class T_>
551  static const bool Value =
552  IsStreamable<T_>::Value ||
553  std::is_convertible<T_, std::string>::value ||
554  decltype(gorgon__enum_tr_loc(*((typename std::decay<T_>::type*)nullptr)))::isupgradedenum;
555  };
556 
559  template<class ...P_>
560  std::string Concat(const P_&... rest) {
561  std::stringstream ss;
562  streamthis(ss, rest...);
563 
564 
565  return ss.str();
566  }
567 
569  inline int UTF8Bytes(char c) {
570  if((c & 0b10000000) == 0b00000000) return 1;
571 
572  if((c & 0b11100000) == 0b11000000) return 2;
573 
574  if((c & 0b11110000) == 0b11100000) return 3;
575 
576  if((c & 0b11111000) == 0b11110000) return 4;
577 
578  //we are probably at the middle of a code point, just return
579  // 1 so that the stream can sync.
580  return 1;
581  }
582 
583  inline int UnicodeUTF8Bytes(Char c) {
584  if(c < 0x80) return 1;
585 
586  if(c < 0x800) return 2;
587 
588  if(c < 0x10000) return 3;
589 
590  if(c < 0x0010FFFF) return 4;
591 
592  return 3; //replacement: 0xfffd
593  }
594 
595  inline int UnicodeGlyphCount(const std::string &s) {
596  int i = 0;
597  int count = 0;
598  while(i < s.length()) {
599  count++;
600  i += UTF8Bytes(s[i]);
601  }
602 
603  return count;
604  }
605 
609  inline bool AppendUnicode(std::string &s, Char c) {
610  if(c > 0x10FFFF) {
611  s += "\xEF\xBF\xBD";
612  return false;
613  }
614 
615  int bytes = UnicodeUTF8Bytes(c);
616  s.resize(s.size() + bytes);
617 
618  auto it = s.rbegin();
619  int cur = 0;
620 
621  while(cur < bytes-1) {
622  *it = (c & 0b00111111) | 0b10000000;
623  it++;
624  cur++;
625  c = c >> 6;
626  }
627 
628  if(bytes == 1) {
629  *it = c;
630  }
631  else if(bytes == 2) {
632  *it = c | 0b11000000;
633  }
634  else if(bytes == 3) {
635  *it = c | 0b11100000;
636  }
637  else if(bytes == 4) {
638  *it = c | 0b11110000;
639  }
640  else
641  return false; // future proofing
642 
643  return true;
644  }
645 
650  inline bool InsertUnicode(std::string &s, std::size_t pos, Char c) {
651  if(c > 0x10FFFF) {
652  s += "\xEF\xBF\xBD";
653  return false;
654  }
655 
656  char data[4] = {};
657 
658  int bytes = UnicodeUTF8Bytes(c);
659 
660  auto it = data + 3;
661  int cur = 0;
662 
663  while(cur < bytes-1) {
664  *it = (c & 0b00111111) | 0b10000000;
665  it--;
666  cur++;
667  c = c >> 6;
668  }
669 
670  if(bytes == 1) {
671  *it = c;
672  }
673  else if(bytes == 2) {
674  *it = c | 0b11000000;
675  }
676  else if(bytes == 3) {
677  *it = c | 0b11100000;
678  }
679  else if(bytes == 4) {
680  *it = c | 0b11110000;
681  }
682  else
683  return false; // future proofing
684 
685  s.insert(pos, it, bytes);
686 
687  return true;
688  }
689 
691  enum class LineEnding {
693  None = 0,
694 
696  LF = 1,
697 
699  Unix = 1,
700 
702  CR = 2,
703 
705  Mac = 2,
706 
708  CRLF = 3,
709 
711  Standard = 3,
712 
714  Windows = 3,
715 
717  Mixed = 4,
718  };
719 
722  std::string FixLineEndings(const std::string &in, LineEnding type = LineEnding::Standard);
723 
724  //for pretty documentation
725 #ifdef DOXYGEN
726  template<class T_>
730  std::string From(const T_ &item) { return ""; }
731 #endif
732 
734  template<class T_>
735  std::string Join(const T_ &vec, const std::string &glue = ", ") {
736  int totalsize = 0;
737  int gluesize = (int)glue.size();
738 
739  for(const std::string &s : vec) {
740  if(totalsize)
741  totalsize += gluesize;
742 
743  totalsize += (int)s.size();
744  }
745 
746  std::string ret;
747  ret.resize(totalsize);
748  bool first = true;
749 
750  char *data = &ret[0];
751  const char *gluedata = glue.data();
752 
753  for(const std::string &s : vec) {
754  if(!first) {
755  std::memcpy(data, gluedata, gluesize);
756  data += gluesize;
757  }
758 
759  std::memcpy(data, s.data(), s.size());
760 
761  data += s.size();
762 
763  first = false;
764  }
765 
766  return ret;
767  }
768 
779  inline std::string Extract(std::string &original, const std::string &marker, bool trim = false) {
780  auto pos=original.find(marker);
781 
782  if(pos==original.npos) {
783  std::string ret;
784  std::swap(ret, original);
785 
786  return ret;
787  }
788 
789  std::string ret=original.substr(0, pos);
790  original=original.substr(pos+marker.length());
791 
792  if(trim) {
793  ret = TrimEnd(ret);
794  original = TrimStart(original);
795  }
796 
797  return ret;
798  }
799 
800 
811  inline std::string Extract(std::string &original, char marker, bool trim = false) {
812  auto pos=original.find_first_of(marker);
813 
814  if(pos==original.npos) {
815  std::string ret;
816  std::swap(ret, original);
817 
818  return ret;
819  }
820 
821  std::string ret=original.substr(0, pos);
822  original=original.substr(pos+1);
823 
824  if(trim) {
825  ret = TrimEnd(ret);
826  original = TrimStart(original);
827  }
828 
829  return ret;
830  }
831 
832  enum class QuoteType {
833  None,
834  Single,
835  Double,
836  Both
837  };
838 
854  inline std::string Extract_UseQuotes(std::string &original, char marker, QuoteType quotetype=QuoteType::Both) {
855  int inquotes=0;
856  std::size_t pos=0;
857 
858  for(auto &c : original) {
859  if(inquotes==1) {
860  if(c=='\'') {
861  inquotes=0;
862  }
863  }
864  else if(inquotes==2) {
865  if(c=='"') {
866  inquotes=0;
867  }
868  }
869  else if(c==marker) {
870  std::string temp=original.substr(0, pos);
871  original=original.substr(pos+1);
872 
873  return temp;
874  }
875  else if(c=='\'' && (quotetype==QuoteType::Single || quotetype==QuoteType::Both)) {
876  inquotes=1;
877  }
878  else if(c=='"' && (quotetype==QuoteType::Double || quotetype==QuoteType::Both)) {
879  inquotes=2;
880  }
881 
882  pos++;
883  }
884 
885  std::string temp;
886  std::swap(temp, original);
887 
888  return temp;
889  }
890 
891  }
892 }
893 
894 # undef ISENUMUPGRADED
Gorgon::String::UTF8Bytes
int UTF8Bytes(char c)
Returns the number of bytes used by the next UTF8 codepoint.
Definition: String.h:569
Gorgon::swap
void swap(Event< Source_, Args_... > &l, Event< Source_, Args_... > &r)
Swaps two events.
Definition: Event.h:351
Gorgon::String::From
std::enable_if< decltype(gorgon__enum_tr_loc(T_()))::isupgradedenum, std::string >::type From(const T_ &e)
Definition: Enum.h:303
Gorgon::String::TrimStart
std::string TrimStart(std::string str, const std::string &chars=" \t\n\r")
Strips the whitespace from the start of a string.
Definition: String.h:390
Gorgon::String::Replace
std::string Replace(std::string str, const std::string &find, const std::string &replace)
String replace that does not use regex.
Definition: String.h:349
Gorgon::String::CanBeStringified
Definition: String.h:550
Gorgon::String::QuoteType::None
@ None
Enum.h
contains Enum class that allows C++ enums to have string capabilities.
Gorgon::String::PadEnd
std::string PadEnd(std::string str, std::size_t len, char pad=' ')
Pads the string to the given number of characters from the start.
Definition: String.h:337
gorgon__enum_tr_loc
gorgon__no_enum_trait gorgon__enum_tr_loc(T_)
Gorgon::String::FixLineEndings
std::string FixLineEndings(const std::string &in, LineEnding type=LineEnding::Standard)
Fixes/changes line endings.
Definition: String.cpp:8
Gorgon::String::CanBeStringified::Value
static const bool Value
Definition: String.h:551
Gorgon::String::Join
std::string Join(const T_ &vec, const std::string &glue=", ")
Joins a list of strings to a single string using the given glue text.
Definition: String.h:735
Gorgon::String::Extract_UseQuotes
std::string Extract_UseQuotes(std::string &original, char marker, QuoteType quotetype=QuoteType::Both)
Extracts the part of the string up to the given marker.
Definition: String.h:854
Gorgon::String::ToUpper
std::string ToUpper(std::string str)
Converts the given string to uppercase.
Definition: String.h:426
Gorgon
Root namespace for Gorgon Game Engine.
Definition: Any.h:19
Gorgon::Char
uint32_t Char
Definition: Types.h:46
Gorgon::String::ToLower
std::string ToLower(std::string str)
Converts the given string to lowercase.
Definition: String.h:416
Gorgon::String::Trim
std::string Trim(std::string str, const std::string &chars=" \t\n\r")
Strips whitespace around the given string both from start and end.
Definition: String.h:370
Gorgon::String::LineEnding::Windows
@ Windows
\x0d\x0a
Gorgon::String::To
std::enable_if< decltype(gorgon__enum_tr_loc(T_()))::isupgradedenum, T_ >::type To(const std::string &text)
Definition: Enum.h:295
Gorgon::String::UnicodeGlyphCount
int UnicodeGlyphCount(const std::string &s)
Definition: String.h:595
Gorgon::String::UnicodeUTF8Bytes
int UnicodeUTF8Bytes(Char c)
Definition: String.h:583
Gorgon::String::TrimEnd
std::string TrimEnd(std::string str, const std::string &chars=" \t\n\r")
Strips the whitespace at the end of a string.
Definition: String.h:406
Gorgon::String::LineEnding
LineEnding
Line ending types.
Definition: String.h:691
Gorgon::String::Extract
std::string Extract(std::string &original, const std::string &marker, bool trim=false)
Extracts the part of the string up to the given marker.
Definition: String.h:779
Gorgon::String::LineEnding::None
@ None
None, no line endings.
Types.h
contains type definitions for Gorgon system
Gorgon::String::InsertUnicode
bool InsertUnicode(std::string &s, std::size_t pos, Char c)
Appends a unicode code point to the string.
Definition: String.h:650
Gorgon::String::QuoteType::Single
@ Single
Gorgon::String::CaseInsensitiveLess
Definition: String.h:25
Gorgon::String::Concat
std::string Concat(const P_ &... rest)
Streams the given parameters into a stringstream and returns the result, effectively concatinating al...
Definition: String.h:560
Exceptions.h
Exceptions This file contains string related exceptions.
Gorgon::String::PadStart
std::string PadStart(std::string str, std::size_t len, char pad=' ')
Pads the string to the given number of characters from the start.
Definition: String.h:328
Gorgon::String::CaseInsensitiveLess::operator()
bool operator()(const std::string &left, const std::string &right) const
Definition: String.h:26
Gorgon::String::CaseInsensitiveCompare
int CaseInsensitiveCompare(const std::string &left, const std::string &right)
Compares two strings case insensitive. Works similar to strcmp.
Definition: String.h:49
Gorgon::String::AppendUnicode
bool AppendUnicode(std::string &s, Char c)
Appends a unicode code point to the string.
Definition: String.h:609
Gorgon::String::QuoteType
QuoteType
Definition: String.h:832