yat  0.12.3pre
utility.h
Go to the documentation of this file.
1 #ifndef _theplu_yat_utility_utility_
2 #define _theplu_yat_utility_utility_
3 
4 // $Id: utility.h 3284 2014-07-09 05:38:58Z peter $
5 
6 /*
7  Copyright (C) 2005 Jari Häkkinen, Peter Johansson, Markus Ringnér
8  Copyright (C) 2006 Jari Häkkinen
9  Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson
10  Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Peter Johansson
11 
12  This file is part of the yat library, http://dev.thep.lu.se/yat
13 
14  The yat library is free software; you can redistribute it and/or
15  modify it under the terms of the GNU General Public License as
16  published by the Free Software Foundation; either version 3 of the
17  License, or (at your option) any later version.
18 
19  The yat library is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with yat. If not, see <http://www.gnu.org/licenses/>.
26 */
27 
33 
34 #include "deprecate.h"
35 #include "Exception.h"
36 #include "yat_assert.h"
37 
38 #include <gsl/gsl_math.h>
39 
40 #include <algorithm>
41 #include <cctype>
42 #include <cmath>
43 #include <functional>
44 #include <limits>
45 #include <locale>
46 #include <istream>
47 #include <string>
48 #include <stdexcept>
49 #include <sstream>
50 #include <utility>
51 #include <vector>
52 
53 namespace theplu {
54 namespace yat {
55 namespace utility {
56 
67  std::string basename(const std::string& fn);
68 
79  template<typename InputIterator, typename OutputIterator>
80  bool binary_weight(InputIterator first, InputIterator last,
81  OutputIterator result);
82 
93  void chdir(const std::string& dir);
94 
103  void chmod(const std::string& filename, mode_t mode);
104 
112  template<typename T>
113  std::string convert(T input);
114 
120  template<typename T>
121  T convert(const std::string& s);
122 
129  void copy_file(const std::string& source, const std::string& target);
130 
141  std::string dirname(const std::string& fn);
142 
153  bool fnmatch(const std::string& pattern, const std::string& str,
154  int flags=0);
155 
161  template<typename T>
162  bool is(const std::string& s);
163 
170  bool is_double(const std::string&) YAT_DEPRECATE;
171 
180  bool is_equal(std::string s, std::string other);
181 
188  bool is_float(const std::string&) YAT_DEPRECATE;
189 
196  bool is_int(const std::string&) YAT_DEPRECATE;
197 
201  bool is_nan(const std::string& s);
202 
238  template<typename T>
239  void load(std::istream& is, std::vector<std::vector<T> >& vec, char sep='\0',
240  char line_sep='\n', bool ignore_empty=false, bool rectangle=true);
241 
263  template<typename T>
264  void load(std::istream& is, std::vector<T>& vec, char sep='\0');
265 
271  // c++11 provides std::log2 so perhaps we should call that one if
272  // availalable (but a bit tricky since this is a public header)
273  template<typename T>
274  T log2(T x) { return std::log(x)/M_LN2; }
275 
277 
278 // private namespace
279 namespace detail {
280 
292  template<typename T>
293  bool convert(const std::string& s, T& t);
294 
298  template<typename T>
299  struct VectorPusher
300  {
306  void operator()(const std::string& element, std::vector<T>& vec)
307  {
308  if (!element.size())
309  vec.push_back(std::numeric_limits<T>::quiet_NaN());
310  else {
311  vec.push_back(theplu::yat::utility::convert<T>(element));
312  }
313  }
314  };
315 
321  template<>
322  struct VectorPusher<std::string>
323  {
327  void operator()(const std::string& element, std::vector<std::string>& vec)
328  {
329  vec.push_back(element);
330  }
331  };
332 
333 } // end of namespace detail
334 
336 
337 
347  void mkdir(const std::string& dir, mode_t mode=0777);
348 
356  void mkdir_p(const std::string& dir, mode_t mode=0777);
357 
365  void remove(const std::string& fn);
366 
375  void rename(const std::string& from, const std::string& to);
376 
383  void replace(std::string& full_str, std::string old_str, std::string new_str);
384 
385  // template implementations
386 
387  template<typename InputIterator, typename OutputIterator>
388  bool binary_weight(InputIterator first, InputIterator last,
389  OutputIterator result)
390  {
391  bool nan=false;
392  while (first!=last) {
393  if (std::isnan(*first)) {
394  *result=0;
395  nan=true;
396  }
397  else
398  *result = 1.0;
399  ++first;
400  ++result;
401  }
402  return nan;
403  }
404 
405 
406  // template implementations
407  template<typename T>
408  std::string convert(T input)
409  {
410  std::ostringstream ss;
411  ss << input;
412  return ss.str();
413  }
414 
415 
416  template<typename T>
417  T convert(const std::string& s)
418  {
419  T result;
420  if (!detail::convert(s, result))
421  throw runtime_error(std::string("yat::utility::convert(\"")+s+
422  std::string("\")"));
423  return result;
424  }
425 
426 
427  template<typename T>
428  bool is(const std::string& s)
429  {
430  T tmp;
431  return detail::convert(s, tmp);
432  }
433 
434 
435  template<typename T>
436  void load(std::istream& is, std::vector<std::vector<T> >& matrix,
437  char sep, char line_sep, bool ignore_empty,
438  bool rectangle)
439  {
440  size_t nof_columns=0;
441  std::string line;
442  while(getline(is, line, line_sep)){
443  if (line.empty() && ignore_empty)
444  continue;
445  matrix.push_back(std::vector<T>());
446  std::vector<T>& v=matrix.back();
447  v.reserve(nof_columns);
448  std::stringstream ss(line);
449  load(ss, v, sep);
450  // add NaN for final separator (or empty string if T=std::string)
451  detail::VectorPusher<T> pusher;
452  if(sep!='\0' && !line.empty() && line[line.size()-1]==sep)
453  pusher("", v);
454 
455  if (rectangle && nof_columns && v.size()!=nof_columns) {
456  std::ostringstream s;
457  s << "load stream error: "
458  << "line " << matrix.size() << " has " << v.size()
459  << " columns; expected " << nof_columns << " columns.";
460  throw utility::IO_error(s.str());
461  }
462  nof_columns = std::max(nof_columns, v.size());
463  }
464 
465  // manipulate the state of the stream to be good
466  is.clear(std::ios::goodbit);
467  }
468 
469  template<typename T>
470  void load(std::istream& is, std::vector<T>& vec, char sep)
471  {
472  detail::VectorPusher<T> pusher;
473  std::string element;
474  bool ok=true;
475  while(true) {
476  if(sep=='\0')
477  ok=(is>>element);
478  else
479  ok=getline(is, element, sep);
480  if(!ok)
481  break;
482  pusher(element, vec);
483  }
484  }
485 
487 namespace detail {
488  template<typename T>
489  bool convert(const std::string& s, T& result)
490  {
491  if (!std::numeric_limits<T>::is_signed) {
492  // first non-whitespace character
493  std::string::const_iterator iter = s.begin();
494  while (iter!=s.end() && std::isspace(*iter))
495  ++iter;
496  // unsigned int cannot start with a '-' and with some compilers
497  // operation ss >> result won't fail so catch it like this instead.
498  if (iter==s.end() || *iter=='-')
499  return false;
500  }
501  std::istringstream ss(s);
502  ss >> result;
503  if (ss.fail()) {
504  if (is_nan(s) || is_equal(s, "-nan")) {
505  result = std::numeric_limits<T>::quiet_NaN();
506  return true;
507  }
508  if (is_equal(s, "inf")) {
509  result = std::numeric_limits<T>::infinity();
510  return true;
511  }
512  if (is_equal(s, "-inf")) {
513  // unsigned types are caught in prologue
514  YAT_ASSERT(std::numeric_limits<T>::is_signed);
515  result = -std::numeric_limits<T>::infinity();
516  return true;
517  }
518  return false;
519  }
520  // Check that nothing is left on stream
521  std::string b;
522  ss >> b;
523  return b.empty();
524  }
525 } // of namespace detail
526 
528 
529 }}} // of namespace utility, yat, and theplu
530 
531 #endif
bool is(const std::string &s)
check if string is convertible to (numerical) type T
Definition: utility.h:428
bool is_int(const std::string &)
void chdir(const std::string &dir)
std::string dirname(const std::string &fn)
void rename(const std::string &from, const std::string &to)
void copy_file(const std::string &source, const std::string &target)
Copy file source to target.
void replace(std::string &full_str, std::string old_str, std::string new_str)
bool is_double(const std::string &)
bool is_float(const std::string &)
void mkdir_p(const std::string &dir, mode_t mode=0777)
T max(const T &a, const T &b, const T &c)
Definition: stl_utility.h:638
Class used for all runtime error detected within yat library.
Definition: Exception.h:38
void chmod(const std::string &filename, mode_t mode)
bool is_nan(const std::string &s)
bool is_equal(std::string s, std::string other)
bool fnmatch(const std::string &pattern, const std::string &str, int flags=0)
Class to report errors associated with IO operations.
Definition: Exception.h:109
bool binary_weight(InputIterator first, InputIterator last, OutputIterator result)
Definition: utility.h:388
T log2(T x)
Definition: utility.h:274
void load(std::istream &is, std::vector< std::vector< T > > &vec, char sep='\0', char line_sep='\n', bool ignore_empty=false, bool rectangle=true)
Definition: utility.h:436
std::string basename(const std::string &fn)
void mkdir(const std::string &dir, mode_t mode=0777)
create a directory dir
std::string convert(T input)
convert T to a string
Definition: utility.h:408

Generated on Mon Jun 1 2015 12:29:51 for yat by  doxygen 1.8.5