|
Sierra Toolkit
Version of the Day
|
00001 #ifndef STK_UTIL_DIAG_StringUtil_h 00002 #define STK_UTIL_DIAG_StringUtil_h 00003 00004 #include <algorithm> 00005 #include <functional> 00006 #include <string> 00007 #include <cctype> 00008 #include <limits> 00009 00010 #include <stk_util/util/FeatureTest.hpp> 00011 #include <stk_util/diag/String.hpp> 00012 00013 namespace sierra { 00014 00019 00034 int case_strcmp(const char *c1, const char *c2); 00035 00036 int case_strncmp(const char *c1, const char *c2, size_t n); 00037 00052 inline int case_strcmp(const std::string &s1, const std::string &s2) { 00053 return case_strcmp(s1.c_str(), s2.c_str()); 00054 } 00055 00070 inline int case_strcmp(const String &s1, const String &s2) { 00071 return case_strcmp(s1.c_str(), s2.c_str()); 00072 } 00073 00074 const char *case_strstr(const char *t, const char *find); 00075 00076 inline const char *case_strstr(const std::string &s1, const std::string &s2) { 00077 return case_strstr(s1.c_str(), s2.c_str()); 00078 } 00079 00080 inline const char *case_strstr(const String &s1, const String &s2) { 00081 return case_strstr(s1.c_str(), s2.c_str()); 00082 } 00083 00084 00085 /* 00086 * @brief Member function <b>undef_if_empty</b> returns the string value 00087 * "<undefined>" if the string <b>s</b> is empty, otherwise it returns the string. 00088 * 00089 * @param s a <b>String</b> reference to the string to check if empty. 00090 * 00091 * @return a <b>String</b> value of "<undefined>" if the string 00092 * <b>s</b> is empty, otherwise the string. 00093 */ 00094 inline String undef_if_empty(const String &s) { 00095 return s.empty() ? "<undefined>" : s; 00096 } 00097 00105 inline int to_upper(int c) { 00106 return std::toupper(c); 00107 } 00108 00116 inline int to_lower(int c) { 00117 return std::tolower(c); 00118 } 00119 00128 inline int to_identifier_upper(int c) { 00129 return std::isspace(c) ? '_' : std::toupper(c); 00130 } 00131 00140 inline int to_identifier_lower(int c) { 00141 return std::isspace(c) ? '_' : std::tolower(c); 00142 } 00143 00152 template <class T> 00153 inline T &make_upper(T &name) { 00154 std::transform(name.begin(), name.end(), name.begin(), to_upper); 00155 00156 return name; 00157 } 00158 00167 template <class T> 00168 inline T &make_lower(T &name) { 00169 std::transform(name.begin(), name.end(), name.begin(), to_lower); 00170 00171 return name; 00172 } 00173 00182 template <class T> 00183 inline T &make_identifier(T &name) { 00184 std::transform(name.begin(), name.end(), name.begin(), to_identifier_upper); 00185 00186 return name; 00187 } 00188 00198 template <class T> 00199 inline T &make_lower_identifier(T &name) { 00200 std::transform(name.begin(), name.end(), name.begin(), to_identifier_lower); 00201 00202 return name; 00203 } 00204 00213 inline char *make_identifier(char *name) { 00214 for (char *c = name; *c != 0; ++c ) 00215 *c = to_identifier_upper(*c); 00216 00217 return name; 00218 } 00219 00229 inline char *make_lower_identifier(char *name) { 00230 for (char *c = name; *c != 0; ++c ) 00231 *c = to_identifier_lower(*c); 00232 00233 return name; 00234 } 00235 00244 template <class T> 00245 inline T & 00246 trim( 00247 T & name) 00248 { 00249 typename T::iterator it0 = name.begin(); 00250 while (it0 != name.end() && std::isspace(*it0)) 00251 ++it0; 00252 00253 typename T::iterator it1 = name.end(); 00254 while (it1 != it0 && std::isspace(*(it1 - 1))) 00255 --it1; 00256 return name = T(it0, it1); 00257 } 00258 00267 std::string title(const std::string &s); 00268 00269 inline std::string title(const String &s) { 00270 return title(std::string(s.c_str())); 00271 } 00272 00273 00281 inline String lower(const String &s) 00282 { 00283 String t = s; 00284 return make_lower(t); 00285 } 00286 00297 std::string to_string(const double &r, int precision = 4); 00298 00309 std::string to_string(const float &r, int precision = 4); 00310 00320 template <typename T> 00321 std::string to_string(const T &t); 00322 00332 #ifdef SIERRA_USE_PLATFORM_DEMANGLER 00333 // Implement this is Slib_EnvPlatform.C 00334 std::string demangle(const char *symbol); 00335 #else 00336 const char *demangle(const char *symbol); 00337 #endif 00338 00349 std::string format_time(double t, const char *format = "%b %e %Y %H:%M:%S"); 00350 00369 std::string word_wrap(const std::string &s, unsigned int line_length, 00370 const std::string &prefix, const std::string &prefix_first_line); 00371 00386 inline std::string word_wrap(const std::string &s, unsigned int line_length = 72, const std::string &prefix = "") { 00387 return word_wrap(s, line_length, prefix, prefix); 00388 } 00389 00390 00400 class object_phrase 00401 { 00402 public: 00415 object_phrase(int n, const char *noun, const char *singlar = "is", const char *plural = "are") 00416 : m_n(n), 00417 m_noun(noun), 00418 m_singular(singlar), 00419 m_plural(plural) 00420 {} 00421 00429 std::ostream &print(std::ostream &os) const; 00430 00437 operator std::string () const; 00438 00439 private: 00440 int m_n; 00441 const char * m_noun; 00442 const char * m_singular; 00443 const char * m_plural; 00444 }; 00445 00456 inline std::ostream &operator<<(std::ostream &os, const object_phrase &phrase) { 00457 return phrase.print(os); 00458 } 00459 00460 00473 std::istream &getline(std::istream &is, sierra::String &s, char eol = '\n'); 00474 00479 template <class T> 00480 struct less_nocase : public std::binary_function<T, T, bool> 00481 { 00493 bool operator()(const T &lhs, const T &rhs) const { 00494 typename T::const_iterator lhs_it = lhs.begin(); 00495 typename T::const_iterator rhs_it = rhs.begin(); 00496 typename T::const_iterator lhs_it_end = lhs.end(); 00497 typename T::const_iterator rhs_it_end = rhs.end(); 00498 00499 for (; lhs_it != lhs_it_end && rhs_it != rhs_it_end; ++lhs_it, ++rhs_it) { 00500 int i = std::tolower(*lhs_it) - std::tolower(*rhs_it); 00501 if (i != 0) 00502 return i < 0; 00503 } 00504 00505 if (lhs_it == lhs_it_end) 00506 return rhs_it != rhs_it_end; 00507 else 00508 return false; 00509 } 00510 }; 00511 00512 00517 template <> 00518 struct less_nocase<String> : public std::binary_function<String, String, bool> 00519 { 00531 bool operator()(const String &lhs, const String &rhs) const { 00532 const char * lhs_it = lhs.c_str(); 00533 const char * rhs_it = rhs.c_str(); 00534 const char * lhs_it_end = lhs_it + lhs.length(); 00535 const char * rhs_it_end = rhs_it + rhs.length(); 00536 00537 for (; lhs_it != lhs_it_end && rhs_it != rhs_it_end; ++lhs_it, ++rhs_it) { 00538 int i = std::tolower(*lhs_it) - std::tolower(*rhs_it); 00539 if (i != 0) 00540 return i < 0; 00541 } 00542 00543 if (lhs_it == lhs_it_end) 00544 return rhs_it != rhs_it_end; 00545 else 00546 return false; 00547 } 00548 }; 00549 00550 00555 template <> 00556 struct less_nocase<std::string> : public std::binary_function<std::string, std::string, bool> 00557 { 00569 bool operator()(const std::string &lhs, const std::string &rhs) const { 00570 const char * lhs_it = lhs.c_str(); 00571 const char * rhs_it = rhs.c_str(); 00572 const char * lhs_it_end = lhs_it + lhs.length(); 00573 const char * rhs_it_end = rhs_it + rhs.length(); 00574 00575 for (; lhs_it != lhs_it_end && rhs_it != rhs_it_end; ++lhs_it, ++rhs_it) { 00576 int i = std::tolower(*lhs_it) - std::tolower(*rhs_it); 00577 if (i != 0) 00578 return i < 0; 00579 } 00580 00581 if (lhs_it == lhs_it_end) 00582 return rhs_it != rhs_it_end; 00583 else 00584 return false; 00585 } 00586 }; 00587 00588 00593 template<> 00594 struct less_nocase<const char *> : public std::binary_function<const char *, const char *, bool> 00595 { 00607 bool operator()(const char *lhs , const char *rhs) const { 00608 bool result ; 00609 if (NULL == lhs ) 00610 result = NULL != rhs; 00611 else { 00612 for (; *lhs && *rhs && std::tolower(*lhs) == std::tolower(*rhs); ++lhs, ++rhs) 00613 ; 00614 result = std::tolower(*lhs) < std::tolower(*rhs); 00615 } 00616 return result ; 00617 } 00618 }; 00619 00620 00625 template <class T> 00626 struct equal_nocase : public std::binary_function<T, T, bool> 00627 { 00639 bool operator()(const T &lhs, const T &rhs) const { 00640 typename T::const_iterator lhs_it = lhs.begin(); 00641 typename T::const_iterator rhs_it = rhs.begin(); 00642 typename T::const_iterator lhs_it_end = lhs.end(); 00643 typename T::const_iterator rhs_it_end = rhs.end(); 00644 00645 for (; lhs_it != lhs_it_end && rhs_it != rhs_it_end; ++lhs_it, ++rhs_it) { 00646 if (std::tolower(*lhs_it) != std::tolower(*rhs_it)) 00647 return false; 00648 } 00649 00650 return lhs_it == lhs_it_end && rhs_it == rhs_it_end; 00651 } 00652 }; 00653 00658 template <> 00659 struct equal_nocase<String> : public std::binary_function<String, String, bool> 00660 { 00672 bool operator()(const String &lhs, const String &rhs) const { 00673 const char * lhs_it = lhs.c_str(); 00674 const char * rhs_it = rhs.c_str(); 00675 const char * lhs_it_end = lhs_it + lhs.length(); 00676 const char * rhs_it_end = rhs_it + rhs.length(); 00677 00678 for (; lhs_it != lhs_it_end && rhs_it != rhs_it_end; ++lhs_it, ++rhs_it) { 00679 if (std::tolower(*lhs_it) != std::tolower(*rhs_it)) 00680 return false; 00681 } 00682 00683 return lhs_it == lhs_it_end && rhs_it == rhs_it_end; 00684 } 00685 }; 00686 00691 template <> 00692 struct equal_nocase<std::string> : public std::binary_function<std::string, std::string, bool> 00693 { 00705 bool operator()(const std::string &lhs, const std::string &rhs) const { 00706 const char * lhs_it = lhs.c_str(); 00707 const char * rhs_it = rhs.c_str(); 00708 const char * lhs_it_end = lhs_it + lhs.length(); 00709 const char * rhs_it_end = rhs_it + rhs.length(); 00710 00711 for (; lhs_it != lhs_it_end && rhs_it != rhs_it_end; ++lhs_it, ++rhs_it) { 00712 if (std::tolower(*lhs_it) != std::tolower(*rhs_it)) 00713 return false; 00714 } 00715 00716 return lhs_it == lhs_it_end && rhs_it == rhs_it_end; 00717 } 00718 }; 00719 00724 template <> 00725 struct equal_nocase<const char *> : public std::binary_function<const char *, const char *, bool> { 00737 bool operator()(const char *lhs , const char *rhs) const { 00738 bool result = lhs == rhs ; 00739 if ( ! result && NULL != lhs && NULL != rhs ) { 00740 for (; *lhs && *rhs && std::tolower(*lhs) == std::tolower(*rhs) ; ++lhs, ++rhs); 00741 result = 0 == *lhs && 0 == *rhs ; 00742 } 00743 return result ; 00744 } 00745 }; 00746 00751 template <class _Key> struct hash_nocase {}; 00752 00760 inline 00761 size_t hash_string_nocase( 00762 const char * p) 00763 { 00764 size_t h = 0; 00765 const size_t sr = std::numeric_limits<unsigned char>::digits * sizeof(size_t) - 8; 00766 const size_t mask = ((size_t) 0xF) << (sr + 4); 00767 while (*p) { 00768 h = (h << 4) + std::tolower(*p++); 00769 size_t g = h & mask; 00770 h ^= g | (g >> sr); 00771 } 00772 return h; 00773 } 00774 00779 template<> 00780 struct hash_nocase<std::string> 00781 { 00791 size_t operator()(const std::string & __s) const { return hash_string_nocase(__s.c_str()); } 00792 }; 00793 00798 template<> 00799 struct hash_nocase<String> 00800 { 00810 size_t operator()(const String & __s) const { return hash_string_nocase(__s.c_str()); } 00811 }; 00812 00813 // /** 00814 // * @brief Class specialization <b>hash_nocase</b> for <b>std::string</b>. 00815 // * 00816 // */ 00817 // template<> 00818 // struct hash_nocase<const std::string> 00819 // { 00820 // /** 00821 // * @brief Member function <b>operator()</b> returns the hash value of the 00822 // * specified string. 00823 // * 00824 // * @param __s a <b>std::string</const reference to the string to hash. 00825 // * 00826 // * @return a <b>size_t</b> value of the hash value of the specified 00827 // * string. 00828 // */ 00829 // size_t operator()(const std::string & __s) const { return hash_string_nocase(__s.c_str()); } 00830 // }; 00831 00832 // /** 00833 // * @brief Class specialization <b>hash_nocase</b> for <b>std::string</b>. 00834 // * 00835 // */ 00836 // template<> 00837 // struct hash_nocase<const String> 00838 // { 00839 // /** 00840 // * @brief Member function <b>operator()</b> returns the hash value of the 00841 // * specified string. 00842 // * 00843 // * @param __s a <b>std::string</const reference to the string to hash. 00844 // * 00845 // * @return a <b>size_t</b> value of the hash value of the specified 00846 // * string. 00847 // */ 00848 // size_t operator()(const String & __s) const { return hash_string_nocase(__s.c_str()); } 00849 // }; 00850 00854 00855 template <class T> 00856 T convert_cast(const String &s); 00857 00858 } // namespace sierra 00859 00860 #endif // STK_UTIL_DIAG_StringUtil_h