yat  0.18.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 3999 2020-10-08 23:22: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, 2014, 2015, 2016, 2017, 2018, 2019, 2020 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 <boost/iterator/iterator_concepts.hpp>
44 #include <boost/concept_check.hpp>
45 
46 #include <algorithm>
47 #include <cctype>
48 #include <cmath>
49 #include <cstdlib>
50 #include <cstring>
51 #include <functional>
52 #include <limits>
53 #include <locale>
54 #include <istream>
55 #include <iostream>
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 
89  template<typename T>
90  std::istream& binary_read(std::istream& is, T& x)
91  {
92  const unsigned char type_size=sizeof(T);
93  YAT_ASSERT(type_size <= 16);
94  char buffer[16];
95  is.read(buffer, type_size);
96  memcpy(&x, buffer, type_size);
97  return is;
98  }
99 
100 
112  template<typename T>
113  void binary_write(std::ostream& os, T x)
114  {
115  const unsigned char type_size=sizeof(T);
116  YAT_ASSERT(type_size <= 16);
117  char buffer[16];
118  memcpy(buffer, &x, type_size);
119  os.write(buffer, type_size);
120  }
121 
141  template<typename InputIterator, typename OutputIterator>
142  bool binary_weight(InputIterator first, InputIterator last,
143  OutputIterator result);
144 
155  void chdir(const std::string& dir);
156 
165  void chmod(const std::string& filename, mode_t mode);
166 
178  template<typename T>
179  std::string convert(T input);
180 
186  template<typename T>
187  T convert(const std::string& s);
188 
199  template<typename T>
200  bool convert_try(const std::string& s, T& t);
201 
208  void copy_file(const std::string& source, const std::string& target);
209 
210 
221  std::string dirname(const std::string& fn);
222 
233  bool fnmatch(const std::string& pattern, const std::string& str,
234  int flags=0);
235 
243  std::string getcwd(void);
244 
254  void gsl_error_handler(const char* reason, const char* file,
255  int line, int gsl_errno);
256 
262  template<typename T>
263  bool is(const std::string& s);
264 
271  bool is_double(const std::string&) YAT_DEPRECATE;
272 
281  bool is_equal(std::string s, std::string other);
282 
289  bool is_float(const std::string&) YAT_DEPRECATE;
290 
297  bool is_int(const std::string&) YAT_DEPRECATE;
298 
302  bool is_nan(const std::string& s);
303 
339  template<typename T>
340  void load(std::istream& is, std::vector<std::vector<T> >& vec, char sep='\0',
341  char line_sep='\n', bool ignore_empty=false, bool rectangle=true);
342 
364  template<typename T>
365  void load(std::istream& is, std::vector<T>& vec, char sep='\0');
366 
374  template<typename T>
375  T log2(T x) { return std::log2(x); }
376 
386  void mkdir(const std::string& dir, mode_t mode=0777);
387 
395  void mkdir_p(const std::string& dir, mode_t mode=0777);
396 
403 #define YAT_MOVE(arg) std::move(arg)
404 #define YAT_MOVE_IF_NOEXCEPT(arg) std::move_if_noexcept(arg)
406 
418  void print_what(const std::exception& error, std::ostream& out=std::cerr);
419 
427  void remove(const std::string& fn);
428 
437  void rename(const std::string& from, const std::string& to);
438 
445  void replace(std::string& full_str, std::string old_str, std::string new_str);
446 
447 
460  template<typename Iterator>
461  double sum_weight(Iterator first, Iterator last);
462 
473  void symlink(const std::string& path1, const std::string& path2);
474 
476 
477 // private namespace
478 namespace detail {
479 
483  template<typename T>
484  struct VectorPusher
485  {
491  void operator()(const std::string& element, std::vector<T>& vec)
492  {
493  if (!element.size())
494  vec.push_back(std::numeric_limits<T>::quiet_NaN());
495  else {
496  vec.push_back(theplu::yat::utility::convert<T>(element));
497  }
498  }
499  };
500 
506  template<>
507  struct VectorPusher<std::string>
508  {
512  void operator()(const std::string& element, std::vector<std::string>& vec)
513  {
514  vec.push_back(element);
515  }
516 
517  void operator()(std::string&& element, std::vector<std::string>& vec)
518  {
519  vec.push_back(std::move(element));
520  }
521  };
522 
523 
524  template<typename Iterator>
525  double sum_weight(Iterator first, Iterator last, unweighted_iterator_tag tag)
526  {
527  return std::distance(first, last);
528  }
529 
530 
531  template<typename Iterator>
532  double sum_weight(Iterator first, Iterator last, weighted_iterator_tag tag)
533  {
534  return std::accumulate(weight_iterator(first), weight_iterator(last), 0);
535  }
536 
537 
538 } // end of namespace detail
539 
541 
542  // template implementations
543 
544  template<typename InputIterator, typename OutputIterator>
545  bool binary_weight(InputIterator first, InputIterator last,
546  OutputIterator result)
547  {
548  BOOST_CONCEPT_ASSERT((boost_concepts::SinglePassIterator<InputIterator>));
549  BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIterator<InputIterator>));
550  BOOST_CONCEPT_ASSERT((boost_concepts::IncrementableIterator<OutputIterator>));
551  BOOST_CONCEPT_ASSERT((boost_concepts::WritableIterator<OutputIterator, float>));
552 
553  bool nan=false;
554  while (first!=last) {
555  if (std::isnan(*first)) {
556  *result=0;
557  nan=true;
558  }
559  else
560  *result = 1.0;
561  ++first;
562  ++result;
563  }
564  return nan;
565  }
566 
567 
568  template<typename T>
569  std::string convert(T input)
570  {
571  std::ostringstream ss;
572  ss << input;
573  return ss.str();
574  }
575 
576 
577  template<typename T>
578  T convert(const std::string& s)
579  {
580  T result;
581  if (!convert_try(s, result))
582  throw runtime_error(std::string("yat::utility::convert(\"")+s+
583  std::string("\")"));
584  return result;
585  }
586 
587 
588  template<typename T>
589  bool is(const std::string& s)
590  {
591  T tmp;
592  return convert_try(s, tmp);
593  }
594 
595 
596  template<typename T>
597  void load(std::istream& is, std::vector<std::vector<T> >& matrix,
598  char sep, char line_sep, bool ignore_empty,
599  bool rectangle)
600  {
601  size_t nof_columns=0;
602  std::string line;
603  while(getline(is, line, line_sep)){
604  if (line.empty() && ignore_empty)
605  continue;
606  std::vector<T> v;
607  v.reserve(nof_columns);
608  bool empty_last_element = !line.empty() && line.back()==sep;
609  std::stringstream ss(std::move(line));
610  load(ss, v, sep);
611  // add NaN for final separator (or empty string if T=std::string)
612  detail::VectorPusher<T> pusher;
613  if (empty_last_element && sep!='\0')
614  pusher("", v);
615 
616  if (rectangle && nof_columns && v.size()!=nof_columns) {
617  std::ostringstream s;
618  s << "load stream error: "
619  << "line " << matrix.size() << " has " << v.size()
620  << " columns; expected " << nof_columns << " columns.";
621  throw utility::IO_error(s.str());
622  }
623  nof_columns = std::max(nof_columns, v.size());
624  matrix.push_back(std::move(v));
625  }
626 
627  // manipulate the state of the stream to be good
628  is.clear(std::ios::goodbit);
629  }
630 
631  template<typename T>
632  void load(std::istream& is, std::vector<T>& vec, char sep)
633  {
634  detail::VectorPusher<T> pusher;
635  while(true) {
636  std::string element;
637  if(sep=='\0')
638  is>>element;
639  else
640  getline(is, element, sep);
641  if(is.fail())
642  break;
643  pusher(std::move(element), vec);
644  }
645  }
646 
647 
648  template<typename Iterator>
649  double sum_weight(Iterator first, Iterator last)
650  {
651  BOOST_CONCEPT_ASSERT((DataIteratorConcept<Iterator>));
652  BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIterator<Iterator>));
653  BOOST_CONCEPT_ASSERT((boost_concepts::SinglePassIterator<Iterator>));
655  return detail::sum_weight(first, last, tag);
656  }
657 
658 
659 
660  template<typename T>
661  bool convert_try(const std::string& s, T& result)
662  {
663  if (!std::numeric_limits<T>::is_signed) {
664  // first non-whitespace character
665  std::string::const_iterator iter = s.begin();
666  while (iter!=s.end() && std::isspace(*iter))
667  ++iter;
668  // unsigned int cannot start with a '-' and with some compilers
669  // operation ss >> result won't fail so catch it like this instead.
670  if (iter==s.end() || *iter=='-')
671  return false;
672  }
673  std::istringstream ss(s);
674  ss >> result;
675  if (ss.fail()) {
676  if (is_nan(s) || is_equal(s, "-nan")) {
677  result = std::numeric_limits<T>::quiet_NaN();
678  return true;
679  }
680  if (is_equal(s, "inf")) {
681  result = std::numeric_limits<T>::infinity();
682  return true;
683  }
684  if (is_equal(s, "-inf")) {
685  // unsigned types are caught in prologue
686  YAT_ASSERT(std::numeric_limits<T>::is_signed);
687  result = -std::numeric_limits<T>::infinity();
688  return true;
689  }
690  return false;
691  }
692  // Check that nothing is left on stream
693  std::string b;
694  ss >> b;
695  return b.empty();
696  }
697 
698 }}} // of namespace utility, yat, and theplu
699 
700 #endif
bool is(const std::string &s)
check if string is convertible to (numerical) type T
Definition: utility.h:589
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:649
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: 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
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)
std::string getcwd(void)
current directory
void gsl_error_handler(const char *reason, const char *file, int line, int gsl_errno)
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:545
T log2(T x)
Definition: utility.h:375
void binary_write(std::ostream &os, T x)
Definition: utility.h:113
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:597
bool convert_try(const std::string &s, T &t)
try to convert
Definition: utility.h:661
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:569
std::istream & binary_read(std::istream &is, T &x)
Definition: utility.h:90

Generated on Tue Sep 7 2021 17:32:32 for yat by  doxygen 1.8.14