Sierra Toolkit  Version of the Day
StringUtil.hpp
1 #ifndef STK_UTIL_DIAG_StringUtil_h
2 #define STK_UTIL_DIAG_StringUtil_h
3 
4 #include <algorithm>
5 #include <functional>
6 #include <string>
7 #include <cctype>
8 #include <limits>
9 
10 #include <stk_util/util/FeatureTest.hpp>
11 #include <stk_util/diag/String.hpp>
12 
13 namespace sierra {
14 
19 
34 int case_strcmp(const char *c1, const char *c2);
35 
36 int case_strncmp(const char *c1, const char *c2, size_t n);
37 
52 inline int case_strcmp(const std::string &s1, const std::string &s2) {
53  return case_strcmp(s1.c_str(), s2.c_str());
54 }
55 
70 inline int case_strcmp(const String &s1, const String &s2) {
71  return case_strcmp(s1.c_str(), s2.c_str());
72 }
73 
74 const char *case_strstr(const char *t, const char *find);
75 
76 inline const char *case_strstr(const std::string &s1, const std::string &s2) {
77  return case_strstr(s1.c_str(), s2.c_str());
78 }
79 
80 inline const char *case_strstr(const String &s1, const String &s2) {
81  return case_strstr(s1.c_str(), s2.c_str());
82 }
83 
84 
85 /*
86  * @brief Member function <b>undef_if_empty</b> returns the string value
87  * "<undefined>" if the string <b>s</b> is empty, otherwise it returns the string.
88  *
89  * @param s a <b>String</b> reference to the string to check if empty.
90  *
91  * @return a <b>String</b> value of "<undefined>" if the string
92  * <b>s</b> is empty, otherwise the string.
93  */
94 inline String undef_if_empty(const String &s) {
95  return s.empty() ? "<undefined>" : s;
96 }
97 
105 inline int to_upper(int c) {
106  return std::toupper(c);
107 }
108 
116 inline int to_lower(int c) {
117  return std::tolower(c);
118 }
119 
128 inline int to_identifier_upper(int c) {
129  return std::isspace(c) ? '_' : std::toupper(c);
130 }
131 
140 inline int to_identifier_lower(int c) {
141  return std::isspace(c) ? '_' : std::tolower(c);
142 }
143 
152 template <class T>
153 inline T &make_upper(T &name) {
154  std::transform(name.begin(), name.end(), name.begin(), to_upper);
155 
156  return name;
157 }
158 
167 template <class T>
168 inline T &make_lower(T &name) {
169  std::transform(name.begin(), name.end(), name.begin(), to_lower);
170 
171  return name;
172 }
173 
182 template <class T>
183 inline T &make_identifier(T &name) {
184  std::transform(name.begin(), name.end(), name.begin(), to_identifier_upper);
185 
186  return name;
187 }
188 
198 template <class T>
199 inline T &make_lower_identifier(T &name) {
200  std::transform(name.begin(), name.end(), name.begin(), to_identifier_lower);
201 
202  return name;
203 }
204 
213 inline char *make_identifier(char *name) {
214  for (char *c = name; *c != 0; ++c )
215  *c = to_identifier_upper(*c);
216 
217  return name;
218 }
219 
229 inline char *make_lower_identifier(char *name) {
230  for (char *c = name; *c != 0; ++c )
231  *c = to_identifier_lower(*c);
232 
233  return name;
234 }
235 
244 template <class T>
245 inline T &
247  T & name)
248 {
249  typename T::iterator it0 = name.begin();
250  while (it0 != name.end() && std::isspace(*it0))
251  ++it0;
252 
253  typename T::iterator it1 = name.end();
254  while (it1 != it0 && std::isspace(*(it1 - 1)))
255  --it1;
256  return name = T(it0, it1);
257 }
258 
267 std::string title(const std::string &s);
268 
269 inline std::string title(const String &s) {
270  return title(std::string(s.c_str()));
271 }
272 
273 
281 inline String lower(const String &s)
282 {
283  String t = s;
284  return make_lower(t);
285 }
286 
297 std::string to_string(const double &r, int precision = 4);
298 
309 std::string to_string(const float &r, int precision = 4);
310 
320 template <typename T>
321 std::string to_string(const T &t);
322 
332 #ifdef SIERRA_USE_PLATFORM_DEMANGLER
333 // Implement this is Slib_EnvPlatform.C
334 std::string demangle(const char *symbol);
335 #else
336 const char *demangle(const char *symbol);
337 #endif
338 
349 std::string format_time(double t, const char *format = "%b %e %Y %H:%M:%S");
350 
369 std::string word_wrap(const std::string &s, unsigned int line_length,
370  const std::string &prefix, const std::string &prefix_first_line);
371 
386 inline std::string word_wrap(const std::string &s, unsigned int line_length = 72, const std::string &prefix = "") {
387  return word_wrap(s, line_length, prefix, prefix);
388 }
389 
390 
401 {
402 public:
415  object_phrase(int n, const char *noun, const char *singlar = "is", const char *plural = "are")
416  : m_n(n),
417  m_noun(noun),
418  m_singular(singlar),
419  m_plural(plural)
420  {}
421 
429  std::ostream &print(std::ostream &os) const;
430 
437  operator std::string () const;
438 
439 private:
440  int m_n;
441  const char * m_noun;
442  const char * m_singular;
443  const char * m_plural;
444 };
445 
456 inline std::ostream &operator<<(std::ostream &os, const object_phrase &phrase) {
457  return phrase.print(os);
458 }
459 
460 
473 std::istream &getline(std::istream &is, sierra::String &s, char eol = '\n');
474 
479 template <class T>
480 struct less_nocase : public std::binary_function<T, T, bool>
481 {
493  bool operator()(const T &lhs, const T &rhs) const {
494  typename T::const_iterator lhs_it = lhs.begin();
495  typename T::const_iterator rhs_it = rhs.begin();
496  typename T::const_iterator lhs_it_end = lhs.end();
497  typename T::const_iterator rhs_it_end = rhs.end();
498 
499  for (; lhs_it != lhs_it_end && rhs_it != rhs_it_end; ++lhs_it, ++rhs_it) {
500  int i = std::tolower(*lhs_it) - std::tolower(*rhs_it);
501  if (i != 0)
502  return i < 0;
503  }
504 
505  if (lhs_it == lhs_it_end)
506  return rhs_it != rhs_it_end;
507  else
508  return false;
509  }
510 };
511 
512 
517 template <>
518 struct less_nocase<String> : public std::binary_function<String, String, bool>
519 {
531  bool operator()(const String &lhs, const String &rhs) const {
532  const char * lhs_it = lhs.c_str();
533  const char * rhs_it = rhs.c_str();
534  const char * lhs_it_end = lhs_it + lhs.length();
535  const char * rhs_it_end = rhs_it + rhs.length();
536 
537  for (; lhs_it != lhs_it_end && rhs_it != rhs_it_end; ++lhs_it, ++rhs_it) {
538  int i = std::tolower(*lhs_it) - std::tolower(*rhs_it);
539  if (i != 0)
540  return i < 0;
541  }
542 
543  if (lhs_it == lhs_it_end)
544  return rhs_it != rhs_it_end;
545  else
546  return false;
547  }
548 };
549 
550 
555 template <>
556 struct less_nocase<std::string> : public std::binary_function<std::string, std::string, bool>
557 {
569  bool operator()(const std::string &lhs, const std::string &rhs) const {
570  const char * lhs_it = lhs.c_str();
571  const char * rhs_it = rhs.c_str();
572  const char * lhs_it_end = lhs_it + lhs.length();
573  const char * rhs_it_end = rhs_it + rhs.length();
574 
575  for (; lhs_it != lhs_it_end && rhs_it != rhs_it_end; ++lhs_it, ++rhs_it) {
576  int i = std::tolower(*lhs_it) - std::tolower(*rhs_it);
577  if (i != 0)
578  return i < 0;
579  }
580 
581  if (lhs_it == lhs_it_end)
582  return rhs_it != rhs_it_end;
583  else
584  return false;
585  }
586 };
587 
588 
593 template<>
594 struct less_nocase<const char *> : public std::binary_function<const char *, const char *, bool>
595 {
607  bool operator()(const char *lhs , const char *rhs) const {
608  bool result ;
609  if (NULL == lhs )
610  result = NULL != rhs;
611  else {
612  for (; *lhs && *rhs && std::tolower(*lhs) == std::tolower(*rhs); ++lhs, ++rhs)
613  ;
614  result = std::tolower(*lhs) < std::tolower(*rhs);
615  }
616  return result ;
617  }
618 };
619 
620 
625 template <class T>
626 struct equal_nocase : public std::binary_function<T, T, bool>
627 {
639  bool operator()(const T &lhs, const T &rhs) const {
640  typename T::const_iterator lhs_it = lhs.begin();
641  typename T::const_iterator rhs_it = rhs.begin();
642  typename T::const_iterator lhs_it_end = lhs.end();
643  typename T::const_iterator rhs_it_end = rhs.end();
644 
645  for (; lhs_it != lhs_it_end && rhs_it != rhs_it_end; ++lhs_it, ++rhs_it) {
646  if (std::tolower(*lhs_it) != std::tolower(*rhs_it))
647  return false;
648  }
649 
650  return lhs_it == lhs_it_end && rhs_it == rhs_it_end;
651  }
652 };
653 
658 template <>
659 struct equal_nocase<String> : public std::binary_function<String, String, bool>
660 {
672  bool operator()(const String &lhs, const String &rhs) const {
673  const char * lhs_it = lhs.c_str();
674  const char * rhs_it = rhs.c_str();
675  const char * lhs_it_end = lhs_it + lhs.length();
676  const char * rhs_it_end = rhs_it + rhs.length();
677 
678  for (; lhs_it != lhs_it_end && rhs_it != rhs_it_end; ++lhs_it, ++rhs_it) {
679  if (std::tolower(*lhs_it) != std::tolower(*rhs_it))
680  return false;
681  }
682 
683  return lhs_it == lhs_it_end && rhs_it == rhs_it_end;
684  }
685 };
686 
691 template <>
692 struct equal_nocase<std::string> : public std::binary_function<std::string, std::string, bool>
693 {
705  bool operator()(const std::string &lhs, const std::string &rhs) const {
706  const char * lhs_it = lhs.c_str();
707  const char * rhs_it = rhs.c_str();
708  const char * lhs_it_end = lhs_it + lhs.length();
709  const char * rhs_it_end = rhs_it + rhs.length();
710 
711  for (; lhs_it != lhs_it_end && rhs_it != rhs_it_end; ++lhs_it, ++rhs_it) {
712  if (std::tolower(*lhs_it) != std::tolower(*rhs_it))
713  return false;
714  }
715 
716  return lhs_it == lhs_it_end && rhs_it == rhs_it_end;
717  }
718 };
719 
724 template <>
725 struct equal_nocase<const char *> : public std::binary_function<const char *, const char *, bool> {
737  bool operator()(const char *lhs , const char *rhs) const {
738  bool result = lhs == rhs ;
739  if ( ! result && NULL != lhs && NULL != rhs ) {
740  for (; *lhs && *rhs && std::tolower(*lhs) == std::tolower(*rhs) ; ++lhs, ++rhs);
741  result = 0 == *lhs && 0 == *rhs ;
742  }
743  return result ;
744  }
745 };
746 
751 template <class _Key> struct hash_nocase {};
752 
760 inline
762  const char * p)
763 {
764  size_t h = 0;
765  const size_t sr = std::numeric_limits<unsigned char>::digits * sizeof(size_t) - 8;
766  const size_t mask = ((size_t) 0xF) << (sr + 4);
767  while (*p) {
768  h = (h << 4) + std::tolower(*p++);
769  size_t g = h & mask;
770  h ^= g | (g >> sr);
771  }
772  return h;
773 }
774 
779 template<>
780 struct hash_nocase<std::string>
781 {
791  size_t operator()(const std::string & __s) const { return hash_string_nocase(__s.c_str()); }
792 };
793 
798 template<>
800 {
810  size_t operator()(const String & __s) const { return hash_string_nocase(__s.c_str()); }
811 };
812 
813 // /**
814 // * @brief Class specialization <b>hash_nocase</b> for <b>std::string</b>.
815 // *
816 // */
817 // template<>
818 // struct hash_nocase<const std::string>
819 // {
820 // /**
821 // * @brief Member function <b>operator()</b> returns the hash value of the
822 // * specified string.
823 // *
824 // * @param __s a <b>std::string</const reference to the string to hash.
825 // *
826 // * @return a <b>size_t</b> value of the hash value of the specified
827 // * string.
828 // */
829 // size_t operator()(const std::string & __s) const { return hash_string_nocase(__s.c_str()); }
830 // };
831 
832 // /**
833 // * @brief Class specialization <b>hash_nocase</b> for <b>std::string</b>.
834 // *
835 // */
836 // template<>
837 // struct hash_nocase<const String>
838 // {
839 // /**
840 // * @brief Member function <b>operator()</b> returns the hash value of the
841 // * specified string.
842 // *
843 // * @param __s a <b>std::string</const reference to the string to hash.
844 // *
845 // * @return a <b>size_t</b> value of the hash value of the specified
846 // * string.
847 // */
848 // size_t operator()(const String & __s) const { return hash_string_nocase(__s.c_str()); }
849 // };
850 
854 
855 template <class T>
856 T convert_cast(const String &s);
857 
858 } // namespace sierra
859 
860 #endif // STK_UTIL_DIAG_StringUtil_h
size_t operator()(const String &__s) const
Member function operator() returns the hash value of the specified string.
Definition: StringUtil.hpp:810
std::string title(const std::string &s)
Function title returns a first letter of each word capitalized of the string.
Definition: StringUtil.cpp:107
int to_lower(int c)
Function to_lower returns the value converted to lower case.
Definition: StringUtil.hpp:116
Definition: Env.cpp:53
std::ostream & print(std::ostream &os) const
Member function print writes the object phrase to the output stream.
Definition: StringUtil.cpp:187
Class hash_nocase is a traits class for hash functions.
Definition: StringUtil.hpp:751
T & trim(T &name)
Function trim trims preceeding and trailing spaces from name. The convertion happens in place...
Definition: StringUtil.hpp:246
object_phrase(int n, const char *noun, const char *singlar="is", const char *plural="are")
Definition: StringUtil.hpp:415
const char * demangle(const char *symbol)
Function demangle returns the demangled C++ symbol from the mangled C++ symbol. The mangled named is ...
Definition: Platform.cpp:210
bool operator()(const std::string &lhs, const std::string &rhs) const
Member function operator() returns true if the lhs is equal to rhs.
Definition: StringUtil.hpp:705
T & make_identifier(T &name)
Function make_identifier converts string name to an identifier case. The convertion happens in place...
Definition: StringUtil.hpp:183
String lower(const String &s)
Function lower returns a lower case version of the string.
Definition: StringUtil.hpp:281
std::istream & getline(std::istream &is, sierra::String &s, char eol)
Function getline returns a string from the input stream which has been terminated by the newline char...
Definition: StringUtil.cpp:33
bool operator()(const T &lhs, const T &rhs) const
Member function operator() returns true if the lhs is equal to rhs.
Definition: StringUtil.hpp:639
int to_identifier_upper(int c)
Function to_identifier_upper returns the value converted to underscore if it is a space or to upper c...
Definition: StringUtil.hpp:128
int to_upper(int c)
Function to_upper returns the value converted to upper case.
Definition: StringUtil.hpp:105
Class less_nocase implements a case insensitive compare functor.
Definition: StringUtil.hpp:480
T & make_upper(T &name)
Function make_upper converts strgin name to upper case. The conversion happens in place...
Definition: StringUtil.hpp:153
T convert_cast(const String &s)
Class specialization hash_nocase for std::string.
Definition: StringUtil.cpp:294
std::string format_time(double t, const char *format)
Function format_time encodes the time using the format specified. The format is described in stdftime...
Definition: StringUtil.cpp:173
Class object_phrase makes a pretty string for those annoying plural or singular noun/verb phrases...
Definition: StringUtil.hpp:400
bool operator()(const T &lhs, const T &rhs) const
Member function operator() returns true if the lhs is less than rhs.
Definition: StringUtil.hpp:493
std::string word_wrap(const std::string &s, unsigned int line_length, const std::string &prefix, const std::string &prefix_first_line)
Function word_wrap reformats a string into multiple lines, none longer that line_length, the first line prefixed with prefix_first_line and the remaining lines prefixed with prefix.
Definition: StringUtil.cpp:249
int to_identifier_lower(int c)
Function to_identifier_lower returns the value converted to underscore if it is a space or to lower c...
Definition: StringUtil.hpp:140
T & make_lower_identifier(T &name)
Function make_lower_identifier converts string name to a lower case identifier case. The convertion happens in place.
Definition: StringUtil.hpp:199
bool operator()(const char *lhs, const char *rhs) const
Member function operator() returns true if the lhs is equal to rhs.
Definition: StringUtil.hpp:737
Class equal_nocase implements a case insensitive compare functor.
Definition: StringUtil.hpp:626
bool operator()(const String &lhs, const String &rhs) const
Member function operator() returns true if the lhs is equal to rhs.
Definition: StringUtil.hpp:672
bool operator()(const String &lhs, const String &rhs) const
Member function operator() returns true if the lhs is less than rhs.
Definition: StringUtil.hpp:531
Part * find(const PartVector &parts, const std::string &name)
Find a part by name in a collection of parts.
Definition: Part.cpp:22
T & make_lower(T &name)
Function make_lower converts string name to lower case. The convertion happens in place...
Definition: StringUtil.hpp:168
int case_strcmp(const char *c1, const char *c2)
Function case_strcmp compares two null terminated strings case insenstively. It returns zero if they ...
Definition: StringUtil.cpp:47
size_t hash_string_nocase(const char *p)
Function hash_string_nocase hash a character string case insensitively.
Definition: StringUtil.hpp:761
bool operator()(const char *lhs, const char *rhs) const
Member function operator() returns true if the lhs is less than rhs.
Definition: StringUtil.hpp:607
bool operator()(const std::string &lhs, const std::string &rhs) const
Member function operator() returns true if the lhs is less than rhs.
Definition: StringUtil.hpp:569
size_t operator()(const std::string &__s) const
Member function operator() returns the hash value of the specified string.
Definition: StringUtil.hpp:791
std::string to_string(const T &t)
Definition: StringUtil.cpp:135