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/Rivet.hh>
00006 #include <Rivet/Math/Math.hh>
00007 #include <cctype>
00008 #include <algorithm>
00009 #include <cerrno>
00010 
00011 
00012 namespace Rivet {
00013 
00014 
00015   inline int nocase_cmp(const string& s1, const string& s2) {
00016     string::const_iterator it1 = s1.begin();
00017     string::const_iterator it2 = s2.begin();
00018     while ( (it1 != s1.end()) && (it2 != s2.end()) ) {
00019       if(::toupper(*it1) != ::toupper(*it2)) { // < Letters differ?
00020         // Return -1 to indicate smaller than, 1 otherwise
00021         return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1;
00022       }
00023       // Proceed to the next character in each string
00024       ++it1;
00025       ++it2;
00026     }
00027     size_t size1 = s1.size(), size2 = s2.size(); // Cache lengths
00028     // Return -1,0 or 1 according to strings' lengths
00029     if (size1 == size2) return 0;
00030     return (size1 < size2) ? -1 : 1;
00031   }
00032 
00033 
00034   inline string toLower(const string& s) {
00035     string out = s;
00036     transform(out.begin(), out.end(), out.begin(), (int(*)(int)) tolower);
00037     return out;
00038   }
00039 
00040 
00041   inline string toUpper(const string& s) {
00042     string out = s;
00043     std::transform(out.begin(), out.end(), out.begin(), (int(*)(int)) toupper);
00044     return out;
00045   }
00046 
00047 
00048   inline bool startsWith(const string& s, const string& start) {
00049     if (s.length() < start.length()) return false;
00050     return s.substr(0, start.length()) == start;
00051   }
00052 
00053 
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   /// Split a string with single-character delimiters, ignoring zero-length
00060   /// substrings. Designed for getting elements of filesystem paths, naturally.
00061   inline vector<string> split(string path, const string delim = ":") {
00062     vector<string> dirs;
00063     if (delim.length() != 1) {
00064       throw Error("Rivet::split(string): delimiter must be a single character.");
00065     }
00066     while (true) {
00067       const size_t delim_pos = path.find(delim);
00068       if (delim_pos == string::npos) break;
00069       const string dir = path.substr(0, delim_pos);
00070       if (dir.length()) dirs.push_back(dir); // Don't insert "empties"
00071       path.replace(0, delim_pos+1, "");
00072     }
00073     if (path.length()) dirs.push_back(path); // Don't forget the trailing component!
00074     return dirs;
00075   }
00076 
00077   /// Get library install path
00078   const string getLibPath();
00079 
00080   /// Get data install path
00081   const string getDataPath();
00082 
00083   /// Get Rivet data install path
00084   const string getRivetDataPath();
00085 
00086 
00087 }
00088 #endif
00089 
00090 
00091 #ifndef CEDARSTD
00092 #define CEDARSTD
00093 namespace std {
00094 
00095   template <typename T>
00096   inline void operator+=(set<T>& s1, const set<T>& s2) {
00097     for (typename set<T>::const_iterator s = s2.begin(); s != s2.end(); ++s) {
00098       s1.insert(*s);
00099     }
00100   }
00101 
00102   template <typename T>
00103   inline void operator+=(vector<T>& s1, const vector<T>& s2) {
00104     for (typename vector<T>::const_iterator s = s2.begin(); s != s2.end(); ++s) {
00105       s1.push_back(*s);
00106     }
00107   }
00108 
00109   template <typename T>
00110   inline string join(const vector<T>& v, const string& sep = " ") {
00111     stringstream out;
00112     for (size_t i = 0; i < v.size(); ++i) {
00113       if (i != 0) out << sep;
00114       out << v[i];
00115     }
00116     return out.str();
00117   }
00118 
00119 }
00120 #endif