yat  0.15.2pre
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 3661 2017-07-14 01:10:35Z 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, 2017 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 "config_public.h"
35 
36 #include "concept_check.h"
37 #include "deprecate.h"
38 #include "Exception.h"
39 #include "iterator_traits.h"
40 #include "WeightIterator.h"
41 #include "yat_assert.h"
42 
43 #include <gsl/gsl_math.h>
44 
45 #include <boost/iterator/iterator_concepts.hpp>
46 #include <boost/concept_check.hpp>
47 
48 #include <algorithm>
49 #include <cctype>
50 #include <cmath>
51 #include <cstdlib>
52 #include <functional>
53 #include <limits>
54 #include <locale>
55 #include <istream>
56 #include <numeric>
57 #include <string>
58 #include <stdexcept>
59 #include <sstream>
60 #include <utility>
61 #include <vector>
62 
63 namespace theplu {
64 namespace yat {
65 namespace utility {
66 
77  std::string basename(const std::string& fn);
78 
98  template<typename InputIterator, typename OutputIterator>
99  bool binary_weight(InputIterator first, InputIterator last,
100  OutputIterator result);
101 
112  void chdir(const std::string& dir);
113 
122  void chmod(const std::string& filename, mode_t mode);
123 
131  template<typename T>
132  std::string convert(T input);
133 
139  template<typename T>
140  T convert(const std::string& s);
141 
152  template<typename T>
153  bool convert_try(const std::string& s, T& t);
154 
161  void copy_file(const std::string& source, const std::string& target);
162 
163 
174  std::string dirname(const std::string& fn);
175 
186  bool fnmatch(const std::string& pattern, const std::string& str,
187  int flags=0);
188 
194  template<typename T>
195  bool is(const std::string& s);
196 
203  bool is_double(const std::string&) YAT_DEPRECATE;
204 
213  bool is_equal(std::string s, std::string other);
214 
221  bool is_float(const std::string&) YAT_DEPRECATE;
222 
229  bool is_int(const std::string&) YAT_DEPRECATE;
230 
234  bool is_nan(const std::string& s);
235 
271  template<typename T>
272  void load(std::istream& is, std::vector<std::vector<T> >& vec, char sep='\0',
273  char line_sep='\n', bool ignore_empty=false, bool rectangle=true);
274 
296  template<typename T>
297  void load(std::istream& is, std::vector<T>& vec, char sep='\0');
298 
306  template<typename T>
307 #ifdef YAT_HAVE_LOG2
308  T log2(T x) { return std::log2(x); }
309 #else
310  T log2(T x) { return std::log(x)/M_LN2; }
311 #endif
312 
322  void mkdir(const std::string& dir, mode_t mode=0777);
323 
331  void mkdir_p(const std::string& dir, mode_t mode=0777);
332 
340  void remove(const std::string& fn);
341 
350  void rename(const std::string& from, const std::string& to);
351 
358  void replace(std::string& full_str, std::string old_str, std::string new_str);
359 
360 
373  template<typename Iterator>
374  double sum_weight(Iterator first, Iterator last);
375 
377 
378 // private namespace
379 namespace detail {
380 
384  template<typename T>
385  struct VectorPusher
386  {
392  void operator()(const std::string& element, std::vector<T>& vec)
393  {
394  if (!element.size())
395  vec.push_back(std::numeric_limits<T>::quiet_NaN());
396  else {
397  vec.push_back(theplu::yat::utility::convert<T>(element));
398  }
399  }
400  };
401 
407  template<>
408  struct VectorPusher<std::string>
409  {
413  void operator()(const std::string& element, std::vector<std::string>& vec)
414  {
415  vec.push_back(element);
416  }
417  };
418 
419 
420  template<typename Iterator>
421  double sum_weight(Iterator first, Iterator last, unweighted_iterator_tag tag)
422  {
423  return std::distance(first, last);
424  }
425 
426 
427  template<typename Iterator>
428  double sum_weight(Iterator first, Iterator last, weighted_iterator_tag tag)
429  {
430  return std::accumulate(weight_iterator(first), weight_iterator(last), 0);
431  }
432 
433 
434 } // end of namespace detail
435 
437 
438  // template implementations
439 
440  template<typename InputIterator, typename OutputIterator>
441  bool binary_weight(InputIterator first, InputIterator last,
442  OutputIterator result)
443  {
444  BOOST_CONCEPT_ASSERT((boost_concepts::SinglePassIterator<InputIterator>));
445  BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIterator<InputIterator>));
446  BOOST_CONCEPT_ASSERT((boost_concepts::IncrementableIterator<OutputIterator>));
447  BOOST_CONCEPT_ASSERT((boost_concepts::WritableIterator<OutputIterator, float>));
448 
449  bool nan=false;
450  while (first!=last) {
451  if (std::isnan(*first)) {
452  *result=0;
453  nan=true;
454  }
455  else
456  *result = 1.0;
457  ++first;
458  ++result;
459  }
460  return nan;
461  }
462 
463 
464  template<typename T>
465  std::string convert(T input)
466  {
467  std::ostringstream ss;
468  ss << input;
469  return ss.str();
470  }
471 
472 
473  template<typename T>
474  T convert(const std::string& s)
475  {
476  T result;
477  if (!convert_try(s, result))
478  throw runtime_error(std::string("yat::utility::convert(\"")+s+
479  std::string("\")"));
480  return result;
481  }
482 
483 
484  template<typename T>
485  bool is(const std::string& s)
486  {
487  T tmp;
488  return convert_try(s, tmp);
489  }
490 
491 
492  template<typename T>
493  void load(std::istream& is, std::vector<std::vector<T> >& matrix,
494  char sep, char line_sep, bool ignore_empty,
495  bool rectangle)
496  {
497  size_t nof_columns=0;
498  std::string line;
499  while(getline(is, line, line_sep)){
500  if (line.empty() && ignore_empty)
501  continue;
502  matrix.push_back(std::vector<T>());
503  std::vector<T>& v=matrix.back();
504  v.reserve(nof_columns);
505  std::stringstream ss(line);
506  load(ss, v, sep);
507  // add NaN for final separator (or empty string if T=std::string)
508  detail::VectorPusher<T> pusher;
509  if(sep!='\0' && !line.empty() && line[line.size()-1]==sep)
510  pusher("", v);
511 
512  if (rectangle && nof_columns && v.size()!=nof_columns) {
513  std::ostringstream s;
514  s << "load stream error: "
515  << "line " << matrix.size() << " has " << v.size()
516  << " columns; expected " << nof_columns << " columns.";
517  throw utility::IO_error(s.str());
518  }
519  nof_columns = std::max(nof_columns, v.size());
520  }
521 
522  // manipulate the state of the stream to be good
523  is.clear(std::ios::goodbit);
524  }
525 
526  template<typename T>
527  void load(std::istream& is, std::vector<T>& vec, char sep)
528  {
529  detail::VectorPusher<T> pusher;
530  std::string element;
531  bool ok=true;
532  while(true) {
533  if(sep=='\0')
534  ok=!(is>>element).fail();
535  else
536  ok=!getline(is, element, sep).fail();
537  if(!ok)
538  break;
539  pusher(element, vec);
540  }
541  }
542 
543 
544  template<typename Iterator>
545  double sum_weight(Iterator first, Iterator last)
546  {
547  BOOST_CONCEPT_ASSERT((DataIteratorConcept<Iterator>));
548  BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIterator<Iterator>));
549  BOOST_CONCEPT_ASSERT((boost_concepts::SinglePassIterator<Iterator>));
551  return detail::sum_weight(first, last, tag);
552  }
553 
554 
555 
556  template<typename T>
557  bool convert_try(const std::string& s, T& result)
558  {
559  if (!std::numeric_limits<T>::is_signed) {
560  // first non-whitespace character
561  std::string::const_iterator iter = s.begin();
562  while (iter!=s.end() && std::isspace(*iter))
563  ++iter;
564  // unsigned int cannot start with a '-' and with some compilers
565  // operation ss >> result won't fail so catch it like this instead.
566  if (iter==s.end() || *iter=='-')
567  return false;
568  }
569  std::istringstream ss(s);
570  ss >> result;
571  if (ss.fail()) {
572  if (is_nan(s) || is_equal(s, "-nan")) {
573  result = std::numeric_limits<T>::quiet_NaN();
574  return true;
575  }
576  if (is_equal(s, "inf")) {
577  result = std::numeric_limits<T>::infinity();
578  return true;
579  }
580  if (is_equal(s, "-inf")) {
581  // unsigned types are caught in prologue
582  YAT_ASSERT(std::numeric_limits<T>::is_signed);
583  result = -std::numeric_limits<T>::infinity();
584  return true;
585  }
586  return false;
587  }
588  // Check that nothing is left on stream
589  std::string b;
590  ss >> b;
591  return b.empty();
592  }
593 
594 }}} // of namespace utility, yat, and theplu
595 
596 #endif
bool is(const std::string &s)
check if string is convertible to (numerical) type T
Definition: utility.h:485
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:545
void rename(const std::string &from, const std::string &to)
The Department of Theoretical Physics namespace as we define it.
void copy_file(const std::string &source, const std::string &target)
Copy file source to target.
Definition: iterator_traits.h:47
Definition: stl_utility.h:64
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
Definition: iterator_traits.h:55
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:441
T log2(T x)
Definition: utility.h:310
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:493
bool convert_try(const std::string &s, T &t)
try to convert
Definition: utility.h:557
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:465

Generated on Fri Jul 13 2018 02:33:27 for yat by  doxygen 1.8.11