yat  0.10.4pre
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 2940 2013-01-04 05:42:32Z 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 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 
276 // private namespace
277 namespace detail {
278 
288  template<typename T>
289  bool convert(const std::string& s, T& t);
290 
294  template<typename T>
296  {
302  void operator()(const std::string& element, std::vector<T>& vec)
303  {
304  if (!element.size())
305  vec.push_back(std::numeric_limits<T>::quiet_NaN());
306  else {
307  vec.push_back(theplu::yat::utility::convert<T>(element));
308  }
309  }
310  };
311 
317  template<>
318  struct VectorPusher<std::string>
319  {
323  void operator()(const std::string& element, std::vector<std::string>& vec)
324  {
325  vec.push_back(element);
326  }
327  };
328 
329 } // end of namespace detail
330 
331 
339  void mkdir(const std::string& dir, mode_t mode=0777);
340 
346  void mkdir_p(const std::string& dir, mode_t mode=0777);
347 
353  void remove(const std::string& fn);
354 
363  void rename(const std::string& from, const std::string to);
364 
369  void replace(std::string& full_str, std::string old_str, std::string new_str);
370 
371  // template implementations
372 
373  template<typename InputIterator, typename OutputIterator>
374  bool binary_weight(InputIterator first, InputIterator last,
375  OutputIterator result)
376  {
377  bool nan=false;
378  while (first!=last) {
379  if (std::isnan(*first)) {
380  *result=0;
381  nan=true;
382  }
383  else
384  *result = 1.0;
385  ++first;
386  ++result;
387  }
388  return nan;
389  }
390 
391 
392  // template implementations
393  template<typename T>
394  std::string convert(T input)
395  {
396  std::ostringstream ss;
397  ss << input;
398  return ss.str();
399  }
400 
401 
402  template<typename T>
403  T convert(const std::string& s)
404  {
405  T result;
406  if (!detail::convert(s, result))
407  throw runtime_error(std::string("yat::utility::convert(\"")+s+
408  std::string("\")"));
409  return result;
410  }
411 
412 
413  template<typename T>
414  bool is(const std::string& s)
415  {
416  T tmp;
417  return detail::convert(s, tmp);
418  }
419 
420 
421  template<typename T>
422  void load(std::istream& is, std::vector<std::vector<T> >& matrix,
423  char sep, char line_sep, bool ignore_empty,
424  bool rectangle)
425  {
426  size_t nof_columns=0;
427  std::string line;
428  while(getline(is, line, line_sep)){
429  if (line.empty() && ignore_empty)
430  continue;
431  matrix.push_back(std::vector<T>());
432  std::vector<T>& v=matrix.back();
433  v.reserve(nof_columns);
434  std::stringstream ss(line);
435  load(ss, v, sep);
436  // add NaN for final separator (or empty string if T=std::string)
438  if(sep!='\0' && !line.empty() && line[line.size()-1]==sep)
439  pusher("", v);
440 
441  if (rectangle && nof_columns && v.size()!=nof_columns) {
442  std::ostringstream s;
443  s << "load stream error: "
444  << "line " << matrix.size() << " has " << v.size()
445  << " columns; expected " << nof_columns << " columns.";
446  throw utility::IO_error(s.str());
447  }
448  nof_columns = std::max(nof_columns, v.size());
449  }
450 
451  // manipulate the state of the stream to be good
452  is.clear(std::ios::goodbit);
453  }
454 
455  template<typename T>
456  void load(std::istream& is, std::vector<T>& vec, char sep)
457  {
459  std::string element;
460  bool ok=true;
461  while(true) {
462  if(sep=='\0')
463  ok=(is>>element);
464  else
465  ok=getline(is, element, sep);
466  if(!ok)
467  break;
468  pusher(element, vec);
469  }
470  }
471 
472 namespace detail {
473  template<typename T>
474  bool convert(const std::string& s, T& result)
475  {
476  if (!std::numeric_limits<T>::is_signed) {
477  // first non-whitespace character
478  std::string::const_iterator iter = s.begin();
479  while (iter!=s.end() && std::isspace(*iter))
480  ++iter;
481  // unsigned int cannot start with a '-' and with some compilers
482  // operation ss >> result won't fail so catch it like this instead.
483  if (iter==s.end() || *iter=='-')
484  return false;
485  }
486  std::istringstream ss(s);
487  ss >> result;
488  if (ss.fail()) {
489  if (is_nan(s)) {
490  result = std::numeric_limits<T>::quiet_NaN();
491  return true;
492  }
493  if (is_equal(s, "inf")) {
494  result = std::numeric_limits<T>::infinity();
495  return true;
496  }
497  if (is_equal(s, "-inf")) {
498  // unsigned types are caught in prologue
499  YAT_ASSERT(std::numeric_limits<T>::is_signed);
500  result = -std::numeric_limits<T>::infinity();
501  return true;
502  }
503  return false;
504  }
505  // Check that nothing is left on stream
506  std::string b;
507  ss >> b;
508  return b.empty();
509  }
510 } // of namespace detail
511 
512 }}} // of namespace utility, yat, and theplu
513 
514 #endif

Generated on Mon Nov 11 2013 09:41:44 for yat by  doxygen 1.8.1