00001
00002 #ifndef RIVET_Utils_HH
00003 #define RIVET_Utils_HH 1
00004
00005 #include <cctype>
00006 #include <algorithm>
00007
00008 namespace Rivet {
00009
00010 inline int nocase_cmp(const string& s1, const string& s2) {
00011 string::const_iterator it1 = s1.begin();
00012 string::const_iterator it2 = s2.begin();
00013 while ( (it1 != s1.end()) && (it2 != s2.end()) ) {
00014 if(::toupper(*it1) != ::toupper(*it2)) {
00015
00016 return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1;
00017 }
00018
00019 ++it1;
00020 ++it2;
00021 }
00022 size_t size1 = s1.size(), size2 = s2.size();
00023
00024 if (size1 == size2) return 0;
00025 return (size1 < size2) ? -1 : 1;
00026 }
00027
00028
00029 inline string toLower(const string& s) {
00030 string out = s;
00031 transform(out.begin(), out.end(), out.begin(), (int(*)(int)) tolower);
00032 return out;
00033 }
00034
00035
00036 inline string toUpper(const string& s) {
00037 string out = s;
00038 std::transform(out.begin(), out.end(), out.begin(), (int(*)(int)) toupper);
00039 return out;
00040 }
00041
00042
00043 template <typename Real>
00044 inline bool fuzzyEquals(Real a, Real b, Real tolerance = 0.001) {
00045 const double absavg = fabs(a + b)/2.0;
00046 const double absdiff = fabs(a - b);
00047 return (absavg == 0.0 && absdiff == 0.0) || absdiff/absavg < tolerance;
00048 }
00049
00050
00051
00052
00053 inline vector<string> split(const string& s, const string delim = ":") {
00054 string path = s;
00055 vector<string> dirs;
00056 if (delim.length() != 1) {
00057 throw runtime_error("Rivet::split(string): delimiter must be a single character.");
00058 }
00059 while (size_t delim_pos = path.find(delim) != string::npos) {
00060 string dir = path.substr(0, delim_pos);
00061 if (dir.length()) dirs.push_back(dir);
00062 path.replace(0, delim_pos+1, "");
00063 }
00064 if (path.length()) dirs.push_back(path);
00065 return dirs;
00066 }
00067
00068
00069
00070 const string getInstalledDataPath();
00071
00072
00073 const string getInstalledLibPath();
00074
00075 }
00076
00077
00078 namespace std {
00079
00080 template <typename T>
00081 inline void operator+=(set<T>& s1, const set<T>& s2) {
00082 for (typename set<T>::const_iterator s = s2.begin(); s != s2.end(); ++s) {
00083 s1.insert(*s);
00084 }
00085 }
00086
00087 template <typename T>
00088 inline void operator+=(vector<T>& s1, const vector<T>& s2) {
00089 for (typename vector<T>::const_iterator s = s2.begin(); s != s2.end(); ++s) {
00090 s1.push_back(*s);
00091 }
00092 }
00093
00094 }
00095
00096 #endif