Rivet  1.8.0
Utils.hh
1 // -*- C++ -*-
2 #ifndef RIVET_Utils_HH
3 #define RIVET_Utils_HH
4 
5 #include <Rivet/Math/Math.hh>
6 #include <cctype>
7 #include <algorithm>
8 #include <cerrno>
9 
10 
11 namespace Rivet {
12 
13 
14  inline int nocase_cmp(const string& s1, const string& s2) {
15  string::const_iterator it1 = s1.begin();
16  string::const_iterator it2 = s2.begin();
17  while ( (it1 != s1.end()) && (it2 != s2.end()) ) {
18  if(::toupper(*it1) != ::toupper(*it2)) { // < Letters differ?
19  // Return -1 to indicate smaller than, 1 otherwise
20  return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1;
21  }
22  // Proceed to the next character in each string
23  ++it1;
24  ++it2;
25  }
26  size_t size1 = s1.size(), size2 = s2.size(); // Cache lengths
27  // Return -1,0 or 1 according to strings' lengths
28  if (size1 == size2) return 0;
29  return (size1 < size2) ? -1 : 1;
30  }
31 
32 
33  inline string toLower(const string& s) {
34  string out = s;
35  transform(out.begin(), out.end(), out.begin(), (int(*)(int)) tolower);
36  return out;
37  }
38 
39 
40  inline string toUpper(const string& s) {
41  string out = s;
42  std::transform(out.begin(), out.end(), out.begin(), (int(*)(int)) toupper);
43  return out;
44  }
45 
46 
47  inline bool startsWith(const string& s, const string& start) {
48  if (s.length() < start.length()) return false;
49  return s.substr(0, start.length()) == start;
50  }
51 
52 
54  inline bool endsWith(const string& s, const string& end) {
55  if (s.length() < end.length()) return false;
56  return s.substr(s.length() - end.length()) == end;
57  }
58 
59 
62  inline vector<string> pathsplit(const string& path) {
63  const string delim = ":";
64  vector<string> dirs;
65  string tmppath = path;
66  while (true) {
67  const size_t delim_pos = tmppath.find(delim);
68  if (delim_pos == string::npos) break;
69  const string dir = tmppath.substr(0, delim_pos);
70  if (dir.length()) dirs.push_back(dir); // Don't insert "empties"
71  tmppath.replace(0, delim_pos+1, "");
72  }
73  if (tmppath.length()) dirs.push_back(tmppath); // Don't forget the trailing component!
74  return dirs;
75  }
76 
78  inline vector<string> split(const string& path, const string& UNUSED(delim) = ":") {
79  return pathsplit(path);
80  }
81 
85  inline string pathjoin(const vector<string>& paths) {
86  const string delim = ":";
87  string rtn;
88  for (vector<string>::const_iterator is = paths.begin(); is != paths.end(); ++is) {
89  if (rtn.size() > 0) rtn += delim;
90  rtn += *is;
91  }
92  return rtn;
93  }
94 
95 
96 }
97 #endif
98 
99 
100 #ifndef CEDARSTD
101 #define CEDARSTD
102 namespace std {
103 
104  template <typename T>
105  inline void operator+=(set<T>& s1, const set<T>& s2) {
106  for (typename set<T>::const_iterator s = s2.begin(); s != s2.end(); ++s) {
107  s1.insert(*s);
108  }
109  }
110 
111  template <typename T>
112  inline set<T> operator+(const set<T>& s1, const set<T>& s2) {
113  set<T> rtn(s1);
114  rtn += s2;
115  return rtn;
116  }
117 
118  template <typename T>
119  inline string join(const set<T>& s, const string& sep = " ") {
120  stringstream out;
121  bool first = false;
122  for (typename set<T>::const_iterator it = s.begin(); it != s.end(); ++it) {
123  if (first) {
124  first = false;
125  } else {
126  out << sep;
127  }
128  out << *it;
129  }
130  return out.str();
131  }
132 
133 
134  template <typename T>
135  inline void operator+=(vector<T>& v1, const vector<T>& v2) {
136  for (typename vector<T>::const_iterator s = v2.begin(); s != v2.end(); ++s) {
137  v1.push_back(*s);
138  }
139  }
140 
141  template <typename T>
142  inline vector<T> operator+(const vector<T>& v1, const vector<T>& v2) {
143  vector<T> rtn(v1);
144  rtn += v2;
145  return rtn;
146  }
147 
148  template <typename T>
149  inline string join(const vector<T>& v, const string& sep = " ") {
150  stringstream out;
151  for (size_t i = 0; i < v.size(); ++i) {
152  if (i != 0) out << sep;
153  out << v[i];
154  }
155  return out.str();
156  }
157 
158 }
159 #endif