yat  0.16.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 3778 2018-10-31 23:34:00Z 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, 2018 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 <iostream>
57 #include <numeric>
58 #include <string>
59 #include <stdexcept>
60 #include <sstream>
61 #include <utility>
62 #include <vector>
63 
64 namespace theplu {
65 namespace yat {
66 namespace utility {
67 
78  std::string basename(const std::string& fn);
79 
99  template<typename InputIterator, typename OutputIterator>
100  bool binary_weight(InputIterator first, InputIterator last,
101  OutputIterator result);
102 
113  void chdir(const std::string& dir);
114 
123  void chmod(const std::string& filename, mode_t mode);
124 
136  template<typename T>
137  std::string convert(T input);
138 
144  template<typename T>
145  T convert(const std::string& s);
146 
157  template<typename T>
158  bool convert_try(const std::string& s, T& t);
159 
166  void copy_file(const std::string& source, const std::string& target);
167 
168 
179  std::string dirname(const std::string& fn);
180 
191  bool fnmatch(const std::string& pattern, const std::string& str,
192  int flags=0);
193 
199  template<typename T>
200  bool is(const std::string& s);
201 
208  bool is_double(const std::string&) YAT_DEPRECATE;
209 
218  bool is_equal(std::string s, std::string other);
219 
226  bool is_float(const std::string&) YAT_DEPRECATE;
227 
234  bool is_int(const std::string&) YAT_DEPRECATE;
235 
239  bool is_nan(const std::string& s);
240 
276  template<typename T>
277  void load(std::istream& is, std::vector<std::vector<T> >& vec, char sep='\0',
278  char line_sep='\n', bool ignore_empty=false, bool rectangle=true);
279 
301  template<typename T>
302  void load(std::istream& is, std::vector<T>& vec, char sep='\0');
303 
311  template<typename T>
312 #ifdef YAT_HAVE_LOG2
313  T log2(T x) { return std::log2(x); }
314 #else
315  T log2(T x) { return std::log(x)/M_LN2; }
316 #endif
317 
327  void mkdir(const std::string& dir, mode_t mode=0777);
328 
336  void mkdir_p(const std::string& dir, mode_t mode=0777);
337 
344 #if YAT_HAVE_RVALUE
345 #define YAT_MOVE(arg) std::move(arg)
346 #define YAT_MOVE_IF_NOEXCEPT(arg) std::move_if_noexcept(arg)
348 #else
349 #define YAT_MOVE(arg) (arg)
351 #define YAT_MOVE_IF_NOEXCEPT(arg) (arg)
353 #endif
354 
368  void print_what(const std::exception& error, std::ostream& out=std::cerr);
369 
377  void remove(const std::string& fn);
378 
387  void rename(const std::string& from, const std::string& to);
388 
395  void replace(std::string& full_str, std::string old_str, std::string new_str);
396 
397 
410  template<typename Iterator>
411  double sum_weight(Iterator first, Iterator last);
412 
423  void symlink(const std::string& path1, const std::string& path2);
424 
426 
427 // private namespace
428 namespace detail {
429 
433  template<typename T>
434  struct VectorPusher
435  {
441  void operator()(const std::string& element, std::vector<T>& vec)
442  {
443  if (!element.size())
444  vec.push_back(std::numeric_limits<T>::quiet_NaN());
445  else {
446  vec.push_back(theplu::yat::utility::convert<T>(element));
447  }
448  }
449  };
450 
456  template<>
457  struct VectorPusher<std::string>
458  {
462  void operator()(const std::string& element, std::vector<std::string>& vec)
463  {
464  vec.push_back(element);
465  }
466 
467 #ifdef YAT_HAVE_RVALUE
468  void operator()(std::string&& element, std::vector<std::string>& vec)
469  {
470  vec.push_back(std::move(element));
471  }
472 #endif
473  };
474 
475 
476  template<typename Iterator>
477  double sum_weight(Iterator first, Iterator last, unweighted_iterator_tag tag)
478  {
479  return std::distance(first, last);
480  }
481 
482 
483  template<typename Iterator>
484  double sum_weight(Iterator first, Iterator last, weighted_iterator_tag tag)
485  {
486  return std::accumulate(weight_iterator(first), weight_iterator(last), 0);
487  }
488 
489 
490 } // end of namespace detail
491 
493 
494  // template implementations
495 
496  template<typename InputIterator, typename OutputIterator>
497  bool binary_weight(InputIterator first, InputIterator last,
498  OutputIterator result)
499  {
500  BOOST_CONCEPT_ASSERT((boost_concepts::SinglePassIterator<InputIterator>));
501  BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIterator<InputIterator>));
502  BOOST_CONCEPT_ASSERT((boost_concepts::IncrementableIterator<OutputIterator>));
503  BOOST_CONCEPT_ASSERT((boost_concepts::WritableIterator<OutputIterator, float>));
504 
505  bool nan=false;
506  while (first!=last) {
507  if (std::isnan(*first)) {
508  *result=0;
509  nan=true;
510  }
511  else
512  *result = 1.0;
513  ++first;
514  ++result;
515  }
516  return nan;
517  }
518 
519 
520  template<typename T>
521  std::string convert(T input)
522  {
523  std::ostringstream ss;
524  ss << input;
525  return ss.str();
526  }
527 
528 
529  template<typename T>
530  T convert(const std::string& s)
531  {
532  T result;
533  if (!convert_try(s, result))
534  throw runtime_error(std::string("yat::utility::convert(\"")+s+
535  std::string("\")"));
536  return result;
537  }
538 
539 
540  template<typename T>
541  bool is(const std::string& s)
542  {
543  T tmp;
544  return convert_try(s, tmp);
545  }
546 
547 
548  template<typename T>
549  void load(std::istream& is, std::vector<std::vector<T> >& matrix,
550  char sep, char line_sep, bool ignore_empty,
551  bool rectangle)
552  {
553  size_t nof_columns=0;
554  std::string line;
555  while(getline(is, line, line_sep)){
556  if (line.empty() && ignore_empty)
557  continue;
558  matrix.push_back(std::vector<T>());
559  std::vector<T>& v=matrix.back();
560  v.reserve(nof_columns);
561  std::stringstream ss(line);
562  load(ss, v, sep);
563  // add NaN for final separator (or empty string if T=std::string)
564  detail::VectorPusher<T> pusher;
565  if(sep!='\0' && !line.empty() && line[line.size()-1]==sep)
566  pusher("", v);
567 
568  if (rectangle && nof_columns && v.size()!=nof_columns) {
569  std::ostringstream s;
570  s << "load stream error: "
571  << "line " << matrix.size() << " has " << v.size()
572  << " columns; expected " << nof_columns << " columns.";
573  throw utility::IO_error(s.str());
574  }
575  nof_columns = std::max(nof_columns, v.size());
576  }
577 
578  // manipulate the state of the stream to be good
579  is.clear(std::ios::goodbit);
580  }
581 
582  template<typename T>
583  void load(std::istream& is, std::vector<T>& vec, char sep)
584  {
585  detail::VectorPusher<T> pusher;
586  bool ok=true;
587  while(true) {
588  std::string element;
589  if(sep=='\0')
590  ok=!(is>>element).fail();
591  else
592  ok=!getline(is, element, sep).fail();
593  if(!ok)
594  break;
595  pusher(YAT_MOVE(element), vec);
596  }
597  }
598 
599 
600  template<typename Iterator>
601  double sum_weight(Iterator first, Iterator last)
602  {
603  BOOST_CONCEPT_ASSERT((DataIteratorConcept<Iterator>));
604  BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIterator<Iterator>));
605  BOOST_CONCEPT_ASSERT((boost_concepts::SinglePassIterator<Iterator>));
607  return detail::sum_weight(first, last, tag);
608  }
609 
610 
611 
612  template<typename T>
613  bool convert_try(const std::string& s, T& result)
614  {
615  if (!std::numeric_limits<T>::is_signed) {
616  // first non-whitespace character
617  std::string::const_iterator iter = s.begin();
618  while (iter!=s.end() && std::isspace(*iter))
619  ++iter;
620  // unsigned int cannot start with a '-' and with some compilers
621  // operation ss >> result won't fail so catch it like this instead.
622  if (iter==s.end() || *iter=='-')
623  return false;
624  }
625  std::istringstream ss(s);
626  ss >> result;
627  if (ss.fail()) {
628  if (is_nan(s) || is_equal(s, "-nan")) {
629  result = std::numeric_limits<T>::quiet_NaN();
630  return true;
631  }
632  if (is_equal(s, "inf")) {
633  result = std::numeric_limits<T>::infinity();
634  return true;
635  }
636  if (is_equal(s, "-inf")) {
637  // unsigned types are caught in prologue
638  YAT_ASSERT(std::numeric_limits<T>::is_signed);
639  result = -std::numeric_limits<T>::infinity();
640  return true;
641  }
642  return false;
643  }
644  // Check that nothing is left on stream
645  std::string b;
646  ss >> b;
647  return b.empty();
648  }
649 
650 }}} // of namespace utility, yat, and theplu
651 
652 #endif
#define YAT_MOVE(arg)
if rvalue not available, do nothing
Definition: utility.h:350
bool is(const std::string &s)
check if string is convertible to (numerical) type T
Definition: utility.h:541
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)
void symlink(const std::string &path1, const std::string &path2)
Concept check for Data Iterator.
Definition: concept_check.h:240
double sum_weight(Iterator first, Iterator last)
Definition: utility.h:601
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:699
Definition: iterator_traits.h:55
void print_what(const std::exception &error, std::ostream &out=std::cerr)
recursively print exception what
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:497
T log2(T x)
Definition: utility.h:315
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:549
bool convert_try(const std::string &s, T &t)
try to convert
Definition: utility.h:613
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:521

Generated on Thu Dec 12 2019 03:12:08 for yat by  doxygen 1.8.11