cphot 0.1
A C++ tool for computing photometry from spectra.
helpers.hpp
Go to the documentation of this file.
1 /**
2  * @file helpers.hpp
3  * @brief Some random tools to ease the project
4  * @version 0.1
5  * @date 2021-12-01
6  *
7  */
8 #ifndef Helpers_HH
9 #define Helpers_HH
10 #include <algorithm>
11 #include <cassert>
12 #include <cstdio>
13 #include <dirent.h>
14 #include <iostream>
15 #include <regex>
16 #include <sstream>
17 #include <string>
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 #include <vector>
21 
22 
23 // for windows mkdir
24 #ifdef _WIN32
25 #include <direct.h>
26 #endif
27 
28 /**
29  * Display an `std::vector` object
30  */
31 template <typename T>
32 std::ostream & operator<<(std::ostream &os,
33  const std::vector<T> &v)
34 {
35  os << "[ ";
36  for (const T &p : v){ os << p << " ";}
37  os << "]\n";
38  return os;
39 }
40 
41 
42 /**
43  * Check if a vector contains an item
44  */
45 bool contains(const std::vector<std::string>& v, const std::string& other){
46  for (const auto& entry: v){
47  if (entry.compare(other) == 0){
48  return true;
49  }
50  }
51  return false;
52 }
53 
54 
55 namespace utils
56 {
57 
58  /**
59  * Check if a file exists regardless of types.
60  * @param name filename and path to check
61  * @return whether the file exists
62  */
63  inline bool file_exists (const std::string& name) {
64  struct stat buffer;
65  return (stat (name.c_str(), &buffer) == 0);
66  }
67 
68  /**
69  * Checks if a folder exists
70  * @param foldername path to the folder to check.
71  * @return true if the folder exists, false otherwise.
72  */
73  bool folder_exists(std::string foldername)
74  {
75  struct stat st;
76  stat(foldername.c_str(), &st);
77  return st.st_mode & S_IFDIR;
78  }
79 
80  /**
81  * Portable wrapper for mkdir. Internally used by mkdir()
82  * @param[in] path the full path of the directory to create.
83  * @return zero on success, otherwise -1.
84  */
85  int _mkdir(const char *path)
86  {
87  #ifdef _WIN32
88  return ::_mkdir(path);
89  #else
90  #if _POSIX_C_SOURCE
91  return ::mkdir(path, 0755);
92  #else
93  return ::mkdir(path, 0755); // not sure if this works on mac
94  #endif
95  #endif
96  }
97 
98  /**
99  * Recursive, portable wrapper for mkdir.
100  * @param[in] path the full path of the directory to create.
101  * @return zero on success, otherwise -1.
102  */
103  int mkdir(const char *path)
104  {
105  std::string current_level = "";
106  std::string level;
107  std::stringstream ss(path);
108 
109  // split path using slash as a separator
110  while (std::getline(ss, level, '/'))
111  {
112  current_level += level; // append folder to the current level
113 
114  // create current level
115  if (!folder_exists(current_level) && _mkdir(current_level.c_str()) != 0)
116  return -1;
117 
118  current_level += "/"; // don't forget to append a slash
119  }
120 
121  return 0;
122  }
123 }
124 
125 
126 /**
127  * Return the list of files matching a pattern from a given directory
128  *
129  * @param path where to look for files
130  * @param pattern which pattern to match (regex needed)
131  */
132 std::vector<std::string> list_dir(const std::string& path,
133  const std::string& pattern = ".*") {
134 
135  struct dirent *entry;
136  DIR *dir = opendir(path.c_str());
137  const std::regex txt_regex(pattern);
138 
139  std::vector<std::string> results;
140  if (dir == NULL) {
141  return results;
142  }
143  while ((entry = readdir(dir)) != NULL) {
144  if (std::regex_match(entry->d_name, txt_regex)){
145  results.push_back(path + "/" + entry->d_name);
146  }
147  }
148  closedir(dir);
149  return results;
150 }
151 
152 
153 /**
154  * Split string into bits according to a given delimiter.
155  *
156  * @param text original string
157  * @param delimiter string to cut on
158  *
159  * @return a vector of strings
160  * */
161 std::vector<std::string> split_string(const std::string & text,
162  const std::string & delimiter){
163  size_t pos;
164  std::string token;
165  std::string s(text);
166  std::vector<std::string> tokens;
167  while ((pos = s.find(delimiter)) != std::string::npos) {
168  token = s.substr(0, pos);
169  tokens.push_back(token);
170  s.erase(0, pos + delimiter.length());
171  }
172  tokens.push_back(s);
173  return tokens;
174 }
175 
176 
177 /**
178  * Returns the upper case of a string
179  */
180 std::string toupper(std::string s) {
181  std::transform(s.begin(), s.end(), s.begin(),
182  [](unsigned char c){ return std::toupper(c); }
183  );
184  return s;
185 }
186 
187 /**
188  * Returns the lower case of a string
189  */
190 std::string tolower(std::string s) {
191  std::transform(s.begin(), s.end(), s.begin(),
192  [](unsigned char c){ return std::tolower(c); }
193  );
194  return s;
195 }
196 
197 /**
198  * Helper to make a string with formatting options.
199  * Note that c++20 has std::format in the <format> library
200  *
201  * @param format formatting string similar to printf
202  * @param args formatting arguments
203  *
204  * @return the formatted string
205  */
206 template< typename... Args >
207 std::string string_sprintf( const char* format, Args... args ) {
208  int length = std::snprintf( nullptr, 0, format, args... );
209  assert( length >= 0 );
210 
211  char* buf = new char[length + 1];
212  std::snprintf( buf, length + 1, format, args... );
213 
214  std::string str( buf );
215  delete[] buf;
216  return str;
217 }
218 
219 /**
220 * @brief Parse a char* into a numeric value.
221 *
222 * @tparam T the output type
223 * @param txt the string to parse
224 * @return T the value as a T type
225 */
226 template <typename T>
227 T parseString(const char * txt){
228  T d = std::atof(txt);
229  return d;
230 }
231 
232 /**
233 * @brief Parse a std::string into a numeric value.
234 *
235 * @tparam T the output type
236 * @param txt the string to parse
237 * @return T the value as a T type
238 */
239 template <typename T>
240 T parseString(const std::string& txt){
241  T d = std::atof(txt.c_str());
242  return d;
243 }
244 
245 #endif // Helpers_HH
246 // vim: expandtab:ts=4:softtabstop=4:shiftwidth=4
contains
bool contains(const std::vector< std::string > &v, const std::string &other)
Check if a vector contains an item.
Definition: helpers.hpp:45
parseString
T parseString(const char *txt)
Parse a char* into a numeric value.
Definition: helpers.hpp:227
split_string
std::vector< std::string > split_string(const std::string &text, const std::string &delimiter)
Split string into bits according to a given delimiter.
Definition: helpers.hpp:161
operator<<
std::ostream & operator<<(std::ostream &os, const std::vector< T > &v)
Display an std::vector object.
Definition: helpers.hpp:32
list_dir
std::vector< std::string > list_dir(const std::string &path, const std::string &pattern=".*")
Return the list of files matching a pattern from a given directory.
Definition: helpers.hpp:132
c
constexpr QSpeed c
Definition: rquantities.hpp:351
utils::folder_exists
bool folder_exists(std::string foldername)
Checks if a folder exists.
Definition: helpers.hpp:73
tolower
std::string tolower(std::string s)
Returns the lower case of a string.
Definition: helpers.hpp:190
utils
Definition: helpers.hpp:55
toupper
std::string toupper(std::string s)
Returns the upper case of a string.
Definition: helpers.hpp:180
utils::_mkdir
int _mkdir(const char *path)
Portable wrapper for mkdir.
Definition: helpers.hpp:85
utils::file_exists
bool file_exists(const std::string &name)
Check if a file exists regardless of types.
Definition: helpers.hpp:63
string_sprintf
std::string string_sprintf(const char *format, Args... args)
Helper to make a string with formatting options.
Definition: helpers.hpp:207
utils::mkdir
int mkdir(const char *path)
Recursive, portable wrapper for mkdir.
Definition: helpers.hpp:103