yat  0.17.3pre
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 3855 2020-01-02 01:11:34Z 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 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 
201  std::string getcwd(void);
202 
208  template<typename T>
209  bool is(const std::string& s);
210 
217  bool is_double(const std::string&) YAT_DEPRECATE;
218 
227  bool is_equal(std::string s, std::string other);
228 
235  bool is_float(const std::string&) YAT_DEPRECATE;
236 
243  bool is_int(const std::string&) YAT_DEPRECATE;
244 
248  bool is_nan(const std::string& s);
249 
285  template<typename T>
286  void load(std::istream& is, std::vector<std::vector<T> >& vec, char sep='\0',
287  char line_sep='\n', bool ignore_empty=false, bool rectangle=true);
288 
310  template<typename T>
311  void load(std::istream& is, std::vector<T>& vec, char sep='\0');
312 
320  template<typename T>
321 #ifdef YAT_HAVE_LOG2
322  T log2(T x) { return std::log2(x); }
323 #else
324  T log2(T x) { return std::log(x)/M_LN2; }
325 #endif
326 
336  void mkdir(const std::string& dir, mode_t mode=0777);
337 
345  void mkdir_p(const std::string& dir, mode_t mode=0777);
346 
353 #if YAT_HAVE_RVALUE
354 #define YAT_MOVE(arg) std::move(arg)
355 #define YAT_MOVE_IF_NOEXCEPT(arg) std::move_if_noexcept(arg)
357 #else
358 #define YAT_MOVE(arg) (arg)
360 #define YAT_MOVE_IF_NOEXCEPT(arg) (arg)
362 #endif
363 
377  void print_what(const std::exception& error, std::ostream& out=std::cerr);
378 
386  void remove(const std::string& fn);
387 
396  void rename(const std::string& from, const std::string& to);
397 
404  void replace(std::string& full_str, std::string old_str, std::string new_str);
405 
406 
419  template<typename Iterator>
420  double sum_weight(Iterator first, Iterator last);
421 
432  void symlink(const std::string& path1, const std::string& path2);
433 
435 
436 // private namespace
437 namespace detail {
438 
442  template<typename T>
443  struct VectorPusher
444  {
450  void operator()(const std::string& element, std::vector<T>& vec)
451  {
452  if (!element.size())
453  vec.push_back(std::numeric_limits<T>::quiet_NaN());
454  else {
455  vec.push_back(theplu::yat::utility::convert<T>(element));
456  }
457  }
458  };
459 
465  template<>
466  struct VectorPusher<std::string>
467  {
471  void operator()(const std::string& element, std::vector<std::string>& vec)
472  {
473  vec.push_back(element);
474  }
475 
476 #ifdef YAT_HAVE_RVALUE
477  void operator()(std::string&& element, std::vector<std::string>& vec)
478  {
479  vec.push_back(std::move(element));
480  }
481 #endif
482  };
483 
484 
485  template<typename Iterator>
486  double sum_weight(Iterator first, Iterator last, unweighted_iterator_tag tag)
487  {
488  return std::distance(first, last);
489  }
490 
491 
492  template<typename Iterator>
493  double sum_weight(Iterator first, Iterator last, weighted_iterator_tag tag)
494  {
495  return std::accumulate(weight_iterator(first), weight_iterator(last), 0);
496  }
497 
498 
499 } // end of namespace detail
500 
502 
503  // template implementations
504 
505  template<typename InputIterator, typename OutputIterator>
506  bool binary_weight(InputIterator first, InputIterator last,
507  OutputIterator result)
508  {
509  BOOST_CONCEPT_ASSERT((boost_concepts::SinglePassIterator<InputIterator>));
510  BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIterator<InputIterator>));
511  BOOST_CONCEPT_ASSERT((boost_concepts::IncrementableIterator<OutputIterator>));
512  BOOST_CONCEPT_ASSERT((boost_concepts::WritableIterator<OutputIterator, float>));
513 
514  bool nan=false;
515  while (first!=last) {
516  if (std::isnan(*first)) {
517  *result=0;
518  nan=true;
519  }
520  else
521  *result = 1.0;
522  ++first;
523  ++result;
524  }
525  return nan;
526  }
527 
528 
529  template<typename T>
530  std::string convert(T input)
531  {
532  std::ostringstream ss;
533  ss << input;
534  return ss.str();
535  }
536 
537 
538  template<typename T>
539  T convert(const std::string& s)
540  {
541  T result;
542  if (!convert_try(s, result))
543  throw runtime_error(std::string("yat::utility::convert(\"")+s+
544  std::string("\")"));
545  return result;
546  }
547 
548 
549  template<typename T>
550  bool is(const std::string& s)
551  {
552  T tmp;
553  return convert_try(s, tmp);
554  }
555 
556 
557  template<typename T>
558  void load(std::istream& is, std::vector<std::vector<T> >& matrix,
559  char sep, char line_sep, bool ignore_empty,
560  bool rectangle)
561  {
562  size_t nof_columns=0;
563  std::string line;
564  while(getline(is, line, line_sep)){
565  if (line.empty() && ignore_empty)
566  continue;
567  matrix.push_back(std::vector<T>());
568  std::vector<T>& v=matrix.back();
569  v.reserve(nof_columns);
570  std::stringstream ss(line);
571  load(ss, v, sep);
572  // add NaN for final separator (or empty string if T=std::string)
573  detail::VectorPusher<T> pusher;
574  if(sep!='\0' && !line.empty() && line[line.size()-1]==sep)
575  pusher("", v);
576 
577  if (rectangle && nof_columns && v.size()!=nof_columns) {
578  std::ostringstream s;
579  s << "load stream error: "
580  << "line " << matrix.size() << " has " << v.size()
581  << " columns; expected " << nof_columns << " columns.";
582  throw utility::IO_error(s.str());
583  }
584  nof_columns = std::max(nof_columns, v.size());
585  }
586 
587  // manipulate the state of the stream to be good
588  is.clear(std::ios::goodbit);
589  }
590 
591  template<typename T>
592  void load(std::istream& is, std::vector<T>& vec, char sep)
593  {
594  detail::VectorPusher<T> pusher;
595  bool ok=true;
596  while(true) {
597  std::string element;
598  if(sep=='\0')
599  ok=!(is>>element).fail();
600  else
601  ok=!getline(is, element, sep).fail();
602  if(!ok)
603  break;
604  pusher(YAT_MOVE(element), vec);
605  }
606  }
607 
608 
609  template<typename Iterator>
610  double sum_weight(Iterator first, Iterator last)
611  {
612  BOOST_CONCEPT_ASSERT((DataIteratorConcept<Iterator>));
613  BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIterator<Iterator>));
614  BOOST_CONCEPT_ASSERT((boost_concepts::SinglePassIterator<Iterator>));
616  return detail::sum_weight(first, last, tag);
617  }
618 
619 
620 
621  template<typename T>
622  bool convert_try(const std::string& s, T& result)
623  {
624  if (!std::numeric_limits<T>::is_signed) {
625  // first non-whitespace character
626  std::string::const_iterator iter = s.begin();
627  while (iter!=s.end() && std::isspace(*iter))
628  ++iter;
629  // unsigned int cannot start with a '-' and with some compilers
630  // operation ss >> result won't fail so catch it like this instead.
631  if (iter==s.end() || *iter=='-')
632  return false;
633  }
634  std::istringstream ss(s);
635  ss >> result;
636  if (ss.fail()) {
637  if (is_nan(s) || is_equal(s, "-nan")) {
638  result = std::numeric_limits<T>::quiet_NaN();
639  return true;
640  }
641  if (is_equal(s, "inf")) {
642  result = std::numeric_limits<T>::infinity();
643  return true;
644  }
645  if (is_equal(s, "-inf")) {
646  // unsigned types are caught in prologue
647  YAT_ASSERT(std::numeric_limits<T>::is_signed);
648  result = -std::numeric_limits<T>::infinity();
649  return true;
650  }
651  return false;
652  }
653  // Check that nothing is left on stream
654  std::string b;
655  ss >> b;
656  return b.empty();
657  }
658 
659 }}} // of namespace utility, yat, and theplu
660 
661 #endif
#define YAT_MOVE(arg)
Definition: utility.h:354
bool is(const std::string &s)
check if string is convertible to (numerical) type T
Definition: utility.h:550
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:610
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
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:506
T log2(T x)
Definition: utility.h:322
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:558
bool convert_try(const std::string &s, T &t)
try to convert
Definition: utility.h:622
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:530

Generated on Thu Aug 27 2020 03:33:18 for yat by  doxygen 1.8.11