rivet is hosted by Hepforge, IPPP Durham
Utils.hh
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #ifndef RIVET_Utils_HH
00003 #define RIVET_Utils_HH
00004 
00005 #include <Rivet/Math/Math.hh>
00006 #include <Rivet/Tools/RivetSTL.hh>
00007 #include <Rivet/Tools/RivetBoost.hh>
00008 #include <cctype>
00009 #include <algorithm>
00010 #include <cerrno>
00011 
00012 namespace Rivet {
00013 
00014 
00015   /// @name String utils
00016   //@{
00017 
00018   /// @brief Convert any object to a string
00019   ///
00020   /// Just a convenience wrapper for the more general Boost lexical_cast
00021   template <typename T>
00022   inline std::string to_str(const T& x) {
00023     return lexical_cast<string>(x);
00024   }
00025 
00026 
00027   /// @brief Convert any object to a string
00028   ///
00029   /// An alias for to_str() with a more "Rivety" mixedCase name.
00030   template <typename T>
00031   inline std::string toString(const T& x) {
00032     return to_str(x);
00033   }
00034 
00035 
00036   /// Case-insensitive string comparison function
00037   ///
00038   /// @todo Replace with something from the Boost string library
00039   inline int nocase_cmp(const std::string& s1, const std::string& s2) {
00040     string::const_iterator it1 = s1.begin();
00041     string::const_iterator it2 = s2.begin();
00042     while ( (it1 != s1.end()) && (it2 != s2.end()) ) {
00043       if(::toupper(*it1) != ::toupper(*it2)) { // < Letters differ?
00044         // Return -1 to indicate smaller than, 1 otherwise
00045         return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1;
00046       }
00047       // Proceed to the next character in each string
00048       ++it1;
00049       ++it2;
00050     }
00051     size_t size1 = s1.size(), size2 = s2.size(); // Cache lengths
00052     // Return -1,0 or 1 according to strings' lengths
00053     if (size1 == size2) return 0;
00054     return (size1 < size2) ? -1 : 1;
00055   }
00056 
00057 
00058   /// Case-insensitive string equality function
00059   inline bool nocase_equals(const std::string& s1, const std::string& s2) {
00060     return nocase_cmp(s1, s2) == 0;
00061   }
00062 
00063 
00064   /// Convert a string to lower-case
00065   ///
00066   /// @todo Replace with something from the Boost string library
00067   inline std::string toLower(const std::string& s) {
00068     string out = s;
00069     transform(out.begin(), out.end(), out.begin(), (int(*)(int)) tolower);
00070     return out;
00071   }
00072 
00073 
00074   /// Convert a string to upper-case
00075   ///
00076   /// @todo Replace with something from the Boost string library
00077   inline std::string toUpper(const std::string& s) {
00078     string out = s;
00079     std::transform(out.begin(), out.end(), out.begin(), (int(*)(int)) toupper);
00080     return out;
00081   }
00082 
00083 
00084   /// Check whether a string @a start is found at the start of @a s
00085   inline bool startsWith(const std::string& s, const std::string& start) {
00086     if (s.length() < start.length()) return false;
00087     return s.substr(0, start.length()) == start;
00088   }
00089 
00090 
00091   /// Check whether a string @a end is found at the end of @a s
00092   inline bool endsWith(const std::string& s, const std::string& end) {
00093     if (s.length() < end.length()) return false;
00094     return s.substr(s.length() - end.length()) == end;
00095   }
00096 
00097 
00098   /// Make a string containing the string representations of each item in v, separated by sep
00099   template <typename T>
00100   inline std::string join(const vector<T>& v, const std::string& sep = " ") {
00101     string rtn;
00102     for (size_t i = 0; i < v.size(); ++i) {
00103       if (i != 0) rtn += sep;
00104       rtn += to_str(v[i]);
00105     }
00106     return rtn;
00107   }
00108 
00109   /// Make a string containing the string representations of each item in s, separated by sep
00110   template <typename T>
00111   inline std::string join(const set<T>& s, const std::string& sep = " ") {
00112     string rtn;
00113     foreach (const T& x, s) {
00114       if (rtn.size() > 0) rtn += sep;
00115       rtn += to_str(x);
00116     }
00117     return rtn;
00118   }
00119 
00120   //@}
00121 
00122 
00123   /// @name Path utils
00124   //@{
00125 
00126   /// @brief Split a path string with colon delimiters
00127   ///
00128   /// Ignores zero-length substrings. Designed for getting elements of filesystem paths, naturally.
00129   inline vector<std::string> pathsplit(const std::string& path) {
00130     const string delim = ":";
00131     vector<string> dirs;
00132     string tmppath = path;
00133     while (true) {
00134       const size_t delim_pos = tmppath.find(delim);
00135       if (delim_pos == string::npos) break;
00136       const string dir = tmppath.substr(0, delim_pos);
00137       if (dir.length()) dirs.push_back(dir); // Don't insert "empties"
00138       tmppath.replace(0, delim_pos+1, "");
00139     }
00140     if (tmppath.length()) dirs.push_back(tmppath); // Don't forget the trailing component!
00141     return dirs;
00142   }
00143 
00144 
00145   /// @brief Join several filesystem paths together with the standard ':' delimiter
00146   ///
00147   /// Note that this does NOT join path elements together with a platform-portable
00148   /// directory delimiter, cf. the Python @c {os.path.join}!
00149   inline std::string pathjoin(const vector<std::string>& paths) {
00150     return join(paths, ":");
00151   }
00152 
00153   //@}
00154 
00155 
00156 }
00157 
00158 #endif