yat  0.14.5pre
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 3575 2017-01-12 23:10:47Z 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, 2015, 2016 Peter Johansson
11  Copyright (C) 2017 Jari Häkkinen
12 
13  This file is part of the yat library, http://dev.thep.lu.se/yat
14 
15  The yat library is free software; you can redistribute it and/or
16  modify it under the terms of the GNU General Public License as
17  published by the Free Software Foundation; either version 3 of the
18  License, or (at your option) any later version.
19 
20  The yat library is distributed in the hope that it will be useful,
21  but WITHOUT ANY WARRANTY; without even the implied warranty of
22  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23  General Public License for more details.
24 
25  You should have received a copy of the GNU General Public License
26  along with yat. If not, see <http://www.gnu.org/licenses/>.
27 */
28 
34 
35 #include "concept_check.h"
36 #include "deprecate.h"
37 #include "Exception.h"
38 #include "iterator_traits.h"
39 #include "WeightIterator.h"
40 #include "yat_assert.h"
41 
42 #include <gsl/gsl_math.h>
43 
44 #include <boost/iterator/iterator_concepts.hpp>
45 #include <boost/concept_check.hpp>
46 
47 #include <algorithm>
48 #include <cctype>
49 #include <cmath>
50 #include <cstdlib>
51 #include <functional>
52 #include <limits>
53 #include <locale>
54 #include <istream>
55 #include <numeric>
56 #include <string>
57 #include <stdexcept>
58 #include <sstream>
59 #include <utility>
60 #include <vector>
61 
62 namespace theplu {
63 namespace yat {
64 namespace utility {
65 
76  std::string basename(const std::string& fn);
77 
97  template<typename InputIterator, typename OutputIterator>
98  bool binary_weight(InputIterator first, InputIterator last,
99  OutputIterator result);
100 
111  void chdir(const std::string& dir);
112 
121  void chmod(const std::string& filename, mode_t mode);
122 
130  template<typename T>
131  std::string convert(T input);
132 
138  template<typename T>
139  T convert(const std::string& s);
140 
147  void copy_file(const std::string& source, const std::string& target);
148 
149 
160  std::string dirname(const std::string& fn);
161 
172  bool fnmatch(const std::string& pattern, const std::string& str,
173  int flags=0);
174 
180  template<typename T>
181  bool is(const std::string& s);
182 
189  bool is_double(const std::string&) YAT_DEPRECATE;
190 
199  bool is_equal(std::string s, std::string other);
200 
207  bool is_float(const std::string&) YAT_DEPRECATE;
208 
215  bool is_int(const std::string&) YAT_DEPRECATE;
216 
220  bool is_nan(const std::string& s);
221 
257  template<typename T>
258  void load(std::istream& is, std::vector<std::vector<T> >& vec, char sep='\0',
259  char line_sep='\n', bool ignore_empty=false, bool rectangle=true);
260 
282  template<typename T>
283  void load(std::istream& is, std::vector<T>& vec, char sep='\0');
284 
292  // c++11 provides std::log2 so perhaps we should call that one if
293  // availalable (but a bit tricky since this is a public header)
294  template<typename T>
295  T log2(T x) { return std::log(x)/M_LN2; }
296 
306  void mkdir(const std::string& dir, mode_t mode=0777);
307 
315  void mkdir_p(const std::string& dir, mode_t mode=0777);
316 
324  void remove(const std::string& fn);
325 
334  void rename(const std::string& from, const std::string& to);
335 
342  void replace(std::string& full_str, std::string old_str, std::string new_str);
343 
344 
357  template<typename Iterator>
358  double sum_weight(Iterator first, Iterator last);
359 
361 
362 // private namespace
363 namespace detail {
364 
376  template<typename T>
377  bool convert(const std::string& s, T& t);
378 
382  template<typename T>
383  struct VectorPusher
384  {
390  void operator()(const std::string& element, std::vector<T>& vec)
391  {
392  if (!element.size())
393  vec.push_back(std::numeric_limits<T>::quiet_NaN());
394  else {
395  vec.push_back(theplu::yat::utility::convert<T>(element));
396  }
397  }
398  };
399 
405  template<>
406  struct VectorPusher<std::string>
407  {
411  void operator()(const std::string& element, std::vector<std::string>& vec)
412  {
413  vec.push_back(element);
414  }
415  };
416 
417 
418  template<typename Iterator>
419  double sum_weight(Iterator first, Iterator last, unweighted_iterator_tag tag)
420  {
421  return std::distance(first, last);
422  }
423 
424 
425  template<typename Iterator>
426  double sum_weight(Iterator first, Iterator last, weighted_iterator_tag tag)
427  {
428  return std::accumulate(weight_iterator(first), weight_iterator(last), 0);
429  }
430 
431 
432 } // end of namespace detail
433 
435 
436  // template implementations
437 
438  template<typename InputIterator, typename OutputIterator>
439  bool binary_weight(InputIterator first, InputIterator last,
440  OutputIterator result)
441  {
442  BOOST_CONCEPT_ASSERT((boost_concepts::SinglePassIterator<InputIterator>));
443  BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIterator<InputIterator>));
444  BOOST_CONCEPT_ASSERT((boost_concepts::IncrementableIterator<OutputIterator>));
445  BOOST_CONCEPT_ASSERT((boost_concepts::WritableIterator<OutputIterator, float>));
446 
447  bool nan=false;
448  while (first!=last) {
449  if (std::isnan(*first)) {
450  *result=0;
451  nan=true;
452  }
453  else
454  *result = 1.0;
455  ++first;
456  ++result;
457  }
458  return nan;
459  }
460 
461 
462  template<typename T>
463  std::string convert(T input)
464  {
465  std::ostringstream ss;
466  ss << input;
467  return ss.str();
468  }
469 
470 
471  template<typename T>
472  T convert(const std::string& s)
473  {
474  T result;
475  if (!detail::convert(s, result))
476  throw runtime_error(std::string("yat::utility::convert(\"")+s+
477  std::string("\")"));
478  return result;
479  }
480 
481 
482  template<typename T>
483  bool is(const std::string& s)
484  {
485  T tmp;
486  return detail::convert(s, tmp);
487  }
488 
489 
490  template<typename T>
491  void load(std::istream& is, std::vector<std::vector<T> >& matrix,
492  char sep, char line_sep, bool ignore_empty,
493  bool rectangle)
494  {
495  size_t nof_columns=0;
496  std::string line;
497  while(getline(is, line, line_sep)){
498  if (line.empty() && ignore_empty)
499  continue;
500  matrix.push_back(std::vector<T>());
501  std::vector<T>& v=matrix.back();
502  v.reserve(nof_columns);
503  std::stringstream ss(line);
504  load(ss, v, sep);
505  // add NaN for final separator (or empty string if T=std::string)
506  detail::VectorPusher<T> pusher;
507  if(sep!='\0' && !line.empty() && line[line.size()-1]==sep)
508  pusher("", v);
509 
510  if (rectangle && nof_columns && v.size()!=nof_columns) {
511  std::ostringstream s;
512  s << "load stream error: "
513  << "line " << matrix.size() << " has " << v.size()
514  << " columns; expected " << nof_columns << " columns.";
515  throw utility::IO_error(s.str());
516  }
517  nof_columns = std::max(nof_columns, v.size());
518  }
519 
520  // manipulate the state of the stream to be good
521  is.clear(std::ios::goodbit);
522  }
523 
524  template<typename T>
525  void load(std::istream& is, std::vector<T>& vec, char sep)
526  {
527  detail::VectorPusher<T> pusher;
528  std::string element;
529  bool ok=true;
530  while(true) {
531  if(sep=='\0')
532  ok=!(is>>element).fail();
533  else
534  ok=!getline(is, element, sep).fail();
535  if(!ok)
536  break;
537  pusher(element, vec);
538  }
539  }
540 
541 
542  template<typename Iterator>
543  double sum_weight(Iterator first, Iterator last)
544  {
545  BOOST_CONCEPT_ASSERT((DataIteratorConcept<Iterator>));
546  BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIterator<Iterator>));
547  BOOST_CONCEPT_ASSERT((boost_concepts::SinglePassIterator<Iterator>));
549  return detail::sum_weight(first, last, tag);
550  }
551 
552 
554 namespace detail {
555  template<typename T>
556  bool convert(const std::string& s, T& result)
557  {
558  if (!std::numeric_limits<T>::is_signed) {
559  // first non-whitespace character
560  std::string::const_iterator iter = s.begin();
561  while (iter!=s.end() && std::isspace(*iter))
562  ++iter;
563  // unsigned int cannot start with a '-' and with some compilers
564  // operation ss >> result won't fail so catch it like this instead.
565  if (iter==s.end() || *iter=='-')
566  return false;
567  }
568  std::istringstream ss(s);
569  ss >> result;
570  if (ss.fail()) {
571  if (is_nan(s) || is_equal(s, "-nan")) {
572  result = std::numeric_limits<T>::quiet_NaN();
573  return true;
574  }
575  if (is_equal(s, "inf")) {
576  result = std::numeric_limits<T>::infinity();
577  return true;
578  }
579  if (is_equal(s, "-inf")) {
580  // unsigned types are caught in prologue
581  YAT_ASSERT(std::numeric_limits<T>::is_signed);
582  result = -std::numeric_limits<T>::infinity();
583  return true;
584  }
585  return false;
586  }
587  // Check that nothing is left on stream
588  std::string b;
589  ss >> b;
590  return b.empty();
591  }
592 } // of namespace detail
593 
595 
596 }}} // of namespace utility, yat, and theplu
597 
598 #endif
bool is(const std::string &s)
check if string is convertible to (numerical) type T
Definition: utility.h:483
bool is_int(const std::string &)
detail::weighted_iterator_traits_detail< value >::type type
Definition: iterator_traits.h:114
void chdir(const std::string &dir)
std::string dirname(const std::string &fn)
Concept check for Data Iterator.
Definition: concept_check.h:228
double sum_weight(Iterator first, Iterator last)
Definition: utility.h:543
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:697
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:439
T log2(T x)
Definition: utility.h:295
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:491
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:463

Generated on Tue Sep 26 2017 02:33:29 for yat by  doxygen 1.8.5