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 <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 
00078   /// @brief Join several filesystem paths together with a delimiter character.
00079   /// Note that this does NOT join path elements together with a platform-portable
00080   /// directory delimiter, cf. the Python @c {os.path.join}!
00081   inline string pathjoin(const vector<string>& paths) {
00082     const string delim = ":";
00083     string rtn;
00084     for (vector<string>::const_iterator is = paths.begin(); is != paths.end(); ++is) {
00085       if (rtn.size() > 0) rtn += delim;
00086       rtn += *is;
00087     }
00088     return rtn;
00089   }
00090 
00091 
00092 }
00093 #endif
00094 
00095 
00096 #ifndef CEDARSTD
00097 #define CEDARSTD
00098 namespace std {
00099 
00100   template <typename T>
00101   inline void operator+=(set<T>& s1, const set<T>& s2) {
00102     for (typename set<T>::const_iterator s = s2.begin(); s != s2.end(); ++s) {
00103       s1.insert(*s);
00104     }
00105   }
00106 
00107   template <typename T>
00108   inline set<T> operator+(const set<T>& s1, const set<T>& s2) {
00109     set<T> rtn(s1);
00110     rtn += s2;
00111     return rtn;
00112   }
00113 
00114   template <typename T>
00115   inline string join(const set<T>& s, const string& sep = " ") {
00116     stringstream out;
00117     bool first = false;
00118     for (typename set<T>::const_iterator it = s.begin(); it != s.end(); ++it) {
00119       if (first) {
00120         first = false;
00121       } else {
00122         out << sep;
00123       }
00124       out << *it;
00125     }
00126     return out.str();
00127   }
00128 
00129 
00130   template <typename T>
00131   inline void operator+=(vector<T>& v1, const vector<T>& v2) {
00132     for (typename vector<T>::const_iterator s = v2.begin(); s != v2.end(); ++s) {
00133       v1.push_back(*s);
00134     }
00135   }
00136 
00137   template <typename T>
00138   inline vector<T> operator+(const vector<T>& v1, const vector<T>& v2) {
00139     vector<T> rtn(v1);
00140     rtn += v2;
00141     return rtn;
00142   }
00143 
00144   template <typename T>
00145   inline string join(const vector<T>& v, const string& sep = " ") {
00146     stringstream out;
00147     for (size_t i = 0; i < v.size(); ++i) {
00148       if (i != 0) out << sep;
00149       out << v[i];
00150     }
00151     return out.str();
00152   }
00153 
00154 }
00155 #endif