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 <cctype>
00007 #include <algorithm>
00008 #include <cerrno>
00009 
00010 
00011 namespace Rivet {
00012 
00013 
00014   inline int nocase_cmp(const string& s1, const string& s2) {
00015     string::const_iterator it1 = s1.begin();
00016     string::const_iterator it2 = s2.begin();
00017     while ( (it1 != s1.end()) && (it2 != s2.end()) ) {
00018       if(::toupper(*it1) != ::toupper(*it2)) { // < Letters differ?
00019         // Return -1 to indicate smaller than, 1 otherwise
00020         return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1;
00021       }
00022       // Proceed to the next character in each string
00023       ++it1;
00024       ++it2;
00025     }
00026     size_t size1 = s1.size(), size2 = s2.size(); // Cache lengths
00027     // Return -1,0 or 1 according to strings' lengths
00028     if (size1 == size2) return 0;
00029     return (size1 < size2) ? -1 : 1;
00030   }
00031 
00032 
00033   inline string toLower(const string& s) {
00034     string out = s;
00035     transform(out.begin(), out.end(), out.begin(), (int(*)(int)) tolower);
00036     return out;
00037   }
00038 
00039 
00040   inline string toUpper(const string& s) {
00041     string out = s;
00042     std::transform(out.begin(), out.end(), out.begin(), (int(*)(int)) toupper);
00043     return out;
00044   }
00045 
00046 
00047   inline bool startsWith(const string& s, const string& start) {
00048     if (s.length() < start.length()) return false;
00049     return s.substr(0, start.length()) == start;
00050   }
00051 
00052 
00053   /// Check whether a string @a end is found at the end of @a s
00054   inline bool endsWith(const string& s, const string& end) {
00055     if (s.length() < end.length()) return false;
00056     return s.substr(s.length() - end.length()) == end;
00057   }
00058 
00059 
00060   /// @brief Split a path string with colon delimiters.
00061   /// Ignores zero-length substrings. Designed for getting elements of filesystem paths, naturally.
00062   inline vector<string> pathsplit(const string& path) {
00063     const string delim = ":";
00064     vector<string> dirs;
00065     string tmppath = path;
00066     while (true) {
00067       const size_t delim_pos = tmppath.find(delim);
00068       if (delim_pos == string::npos) break;
00069       const string dir = tmppath.substr(0, delim_pos);
00070       if (dir.length()) dirs.push_back(dir); // Don't insert "empties"
00071       tmppath.replace(0, delim_pos+1, "");
00072     }
00073     if (tmppath.length()) dirs.push_back(tmppath); // Don't forget the trailing component!
00074     return dirs;
00075   }
00076 
00077   /// @deprecated Use @c pathsplit instead.
00078   inline vector<string> split(const string& path, const string& UNUSED(delim) = ":") {
00079     return pathsplit(path);
00080   }
00081 
00082   /// @brief Join several filesystem paths together with a delimiter character.
00083   /// Note that this does NOT join path elements together with a platform-portable
00084   /// directory delimiter, cf. the Python @c {os.path.join}!
00085   inline string pathjoin(const vector<string>& paths) {
00086     const string delim = ":";
00087     string rtn;
00088     for (vector<string>::const_iterator is = paths.begin(); is != paths.end(); ++is) {
00089       if (rtn.size() > 0) rtn += delim;
00090       rtn += *is;
00091     }
00092     return rtn;
00093   }
00094 
00095 
00096 }
00097 #endif
00098 
00099 
00100 #ifndef CEDARSTD
00101 #define CEDARSTD
00102 namespace std {
00103 
00104   template <typename T>
00105   inline void operator+=(set<T>& s1, const set<T>& s2) {
00106     for (typename set<T>::const_iterator s = s2.begin(); s != s2.end(); ++s) {
00107       s1.insert(*s);
00108     }
00109   }
00110 
00111   template <typename T>
00112   inline set<T> operator+(const set<T>& s1, const set<T>& s2) {
00113     set<T> rtn(s1);
00114     rtn += s2;
00115     return rtn;
00116   }
00117 
00118   template <typename T>
00119   inline string join(const set<T>& s, const string& sep = " ") {
00120     stringstream out;
00121     bool first = false;
00122     for (typename set<T>::const_iterator it = s.begin(); it != s.end(); ++it) {
00123       if (first) {
00124         first = false;
00125       } else {
00126         out << sep;
00127       }
00128       out << *it;
00129     }
00130     return out.str();
00131   }
00132 
00133 
00134   template <typename T>
00135   inline void operator+=(vector<T>& v1, const vector<T>& v2) {
00136     for (typename vector<T>::const_iterator s = v2.begin(); s != v2.end(); ++s) {
00137       v1.push_back(*s);
00138     }
00139   }
00140 
00141   template <typename T>
00142   inline vector<T> operator+(const vector<T>& v1, const vector<T>& v2) {
00143     vector<T> rtn(v1);
00144     rtn += v2;
00145     return rtn;
00146   }
00147 
00148   template <typename T>
00149   inline string join(const vector<T>& v, const string& sep = " ") {
00150     stringstream out;
00151     for (size_t i = 0; i < v.size(); ++i) {
00152       if (i != 0) out << sep;
00153       out << v[i];
00154     }
00155     return out.str();
00156   }
00157 
00158 }
00159 #endif