00001 #ifndef AGILE_UTILS_HH 00002 #define AGILE_UTILS_HH 00003 00004 #include "AGILe/AGILe.hh" 00005 #include <algorithm> 00006 00007 namespace AGILe { 00008 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)) { // < Letters differ? 00015 // Return -1 to indicate smaller than, 1 otherwise 00016 return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1; 00017 } 00018 // Proceed to the next character in each string 00019 ++it1; 00020 ++it2; 00021 } 00022 size_t size1 = s1.size(), size2 = s2.size(); // Cache lengths 00023 // Return -1,0 or 1 according to strings' lengths 00024 if (size1 == size2) return 0; 00025 return (size1 < size2) ? -1 : 1; 00026 } 00027 00028 00029 inline string toLower(const string& s) { 00030 return boost::to_lower_copy(s); 00031 } 00032 00033 00034 inline string toUpper(const string& s) { 00035 return boost::to_upper_copy(s); 00036 } 00037 00038 00039 template <typename Real> 00040 inline bool fuzzyEquals(Real a, Real b, Real tolerance = 0.001) { 00041 const double absavg = fabs(a + b)/2.0; 00042 const double absdiff = fabs(a - b); 00043 return (absavg == 0.0 && absdiff == 0.0) || absdiff/absavg < tolerance; 00044 } 00045 00046 00049 inline std::vector<std::string> split(string path, const string delim = ":") { 00050 if (delim.length() != 1) { 00051 throw runtime_error("Rivet::split(string): delimiter must be a single character."); 00052 } 00054 std::vector<std::string> dirs; 00055 boost::split(dirs, path, boost::is_any_of(delim)); 00056 return dirs; 00057 } 00058 00059 00060 00061 template <typename T> 00062 inline std::string toString(const T& value) { 00063 std::string strval = lexical_cast<std::string>(value); 00064 //std::cout << "*" << value << "*" << strval << "*" << std::endl; 00065 return strval; 00066 } 00067 00068 template <typename T> 00069 inline T as(const std::string& strvalue) { 00070 T tval = lexical_cast<T>(strvalue); 00071 return tval; 00072 } 00073 00074 template <> 00075 inline bool as<bool>(const std::string& value) { 00076 if (nocase_cmp(value, "true") == 0 || nocase_cmp(value, "yes") == 0 || nocase_cmp(value, "on") == 0) return true; 00077 if (nocase_cmp(value, "false") == 0 || nocase_cmp(value, "no") == 0 || nocase_cmp(value, "off") == 0) return false; 00078 return as<int>(value); 00079 } 00080 00081 inline int asInt(const std::string& value) { return as<int>(value); } 00082 inline double asDouble(const std::string& value) { return as<double>(value); } 00083 inline bool asBool(const std::string& value) { return as<bool>(value); } 00084 00085 00086 } 00087 #endif 00088 00089 00090 #ifndef CEDARSTD 00091 #define CEDARSTD 00092 namespace std { 00093 00094 template <typename T> 00095 inline void operator+=(std::set<T>& s1, const std::set<T>& s2) { 00096 for (typename std::set<T>::const_iterator s = s2.begin(); s != s2.end(); ++s) { 00097 s1.insert(*s); 00098 } 00099 } 00100 00101 template <typename T> 00102 inline void operator+=(std::vector<T>& s1, const std::vector<T>& s2) { 00103 for (typename std::vector<T>::const_iterator s = s2.begin(); s != s2.end(); ++s) { 00104 s1.push_back(*s); 00105 } 00106 } 00107 00108 template <typename T> 00109 inline string join(const std::vector<T>& v, const std::string& sep = " ") { 00110 std::stringstream out; 00111 for (size_t i = 0; i < v.size(); ++i) { 00112 if (i != 0) out << sep; 00113 out << v[i]; 00114 } 00115 return out.str(); 00116 } 00117 00118 } 00119 00120 #endif