Sierra Toolkit Version of the Day
StringUtil.hpp
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines