yat  0.19pre
stl_utility.h
Go to the documentation of this file.
1 #ifndef _theplu_yat_utility_stl_utility_
2 #define _theplu_yat_utility_stl_utility_
3 
4 // $Id: stl_utility.h 3792 2019-04-12 07:15:09Z peter $
5 
6 /*
7  Copyright (C) 2004 Jari Häkkinen
8  Copyright (C) 2005 Jari Häkkinen, Peter Johansson, Markus Ringnér
9  Copyright (C) 2006 Jari Häkkinen
10  Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson
11  Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018 Peter Johansson
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 
36 
37 #include "concept_check.h"
38 #include "DataWeight.h"
39 #include "Exception.h"
40 
41 #include <boost/concept_check.hpp>
42 #include <boost/iterator/transform_iterator.hpp>
43 #include <boost/mpl/if.hpp>
44 #include <boost/type_traits/add_const.hpp>
45 #include <boost/type_traits/is_const.hpp>
46 #include <boost/type_traits/remove_reference.hpp>
47 
48 #include <algorithm>
49 #include <cmath>
50 #include <exception>
51 #include <functional>
52 #include <iterator>
53 #include <map>
54 #include <ostream>
55 #include <sstream>
56 #include <string>
57 #include <utility>
58 #include <vector>
59 
60 // We are intruding standard namespace, which might cause
61 // conflicts. Let the user turn off these declarations by defining
62 // YAT_STD_DISABE
63 #ifndef YAT_STD_DISABLE
64 namespace std {
65 
69  // This is in namespace std because we have not figured out how to have
70  // pair and its operator<< in different namespaces
71  template <class T1, class T2>
72  std::ostream& operator<<(std::ostream& out, const std::pair<T1,T2>& p)
73  { out << p.first << "\t" << p.second; return out; }
74 
75 }
76 #endif
77 
78 namespace theplu {
79 namespace yat {
80 namespace utility {
81 
85  template<typename T>
86  struct abs : std::unary_function<T, T>
87  {
91  inline T operator()(T x) const
92  { return std::abs(x); }
93  };
94 
95 
121  template<typename Pointer>
122  struct Dereferencer :
123  public std::unary_function<Pointer,
124  typename std::iterator_traits<Pointer>::reference>
125  {
130  { BOOST_CONCEPT_ASSERT((TrivialIterator<Pointer>)); }
131 
135  typename std::iterator_traits<Pointer>::reference
136  operator()(Pointer ti) const { return *ti; }
137  };
138 
139 
177  template<class F, class G, class H>
179  public std::binary_function<typename G::argument_type,
180  typename H::argument_type,
181  typename F::result_type>
182  {
183  public:
190 
194  compose_f_gx_hy(F f, G g, H h)
195  : f_(f), g_(g), h_(h)
196  {
197  }
198 
202  typename F::result_type operator()(typename G::argument_type x,
203  typename H::argument_type y) const
204  {
205  return f_(g_(x), h_(y));
206  }
207 
208  private:
209  F f_;
210  G g_;
211  H h_;
212  };
213 
221  template<class F, class G, class H>
223  {
224  return compose_f_gx_hy<F,G,H>(f,g,h);
225  }
226 
227 
249  template<class F, class G>
251  public std::binary_function<typename G::first_argument_type,
252  typename G::second_argument_type,
253  typename F::result_type>
254  {
255  public:
261  compose_f_gxy(void) {}
262 
266  compose_f_gxy(F f, G g)
267  : f_(f), g_(g)
268  {
269  }
270 
274  typename F::result_type
275  operator()(typename G::first_argument_type x,
276  typename G::second_argument_type y) const
277  {
278  return f_(g_(x,y));
279  }
280 
281  private:
282  F f_;
283  G g_;
284  };
285 
295  template<class F, class G>
297  {
298  return compose_f_gxy<F,G>(f,g);
299  }
300 
301 
325  template<class F, class G>
326  class compose_f_gx : public std::unary_function<typename G::argument_type,
327  typename F::result_type>
328  {
329  public:
335  compose_f_gx(void) {}
336 
340  compose_f_gx(F f, G g)
341  : f_(f), g_(g)
342  {
343  }
344 
348  typename F::result_type
349  operator()(typename G::argument_type x) const
350  {
351  return f_(g_(x));
352  }
353 
354  private:
355  F f_;
356  G g_;
357  };
358 
368  template<class F, class G>
370  {
371  return compose_f_gx<F,G>(f,g);
372  }
373 
374 
401  template<class F, class G, class H>
402  class compose_f_gx_hx : public std::unary_function<typename G::argument_type,
403  typename F::result_type>
404  {
405  public:
412 
416  compose_f_gx_hx(F f, G g, H h)
417  : f_(f), g_(g), h_(h)
418  {
419  }
420 
424  typename F::result_type operator()(typename G::argument_type x) const
425  {
426  return f_(g_(x), h_(x));
427  }
428 
429  private:
430  F f_;
431  G g_;
432  H h_;
433  };
434 
444  template<class F, class G, class H>
446  {
447  return compose_f_gx_hx<F,G,H>(f,g,h);
448  }
449 
450 
458  template<typename T>
459  struct Exp : std::unary_function<T, T>
460  {
464  inline T operator()(T x) const
465  { return std::exp(x); }
466  };
467 
473  template<typename T>
474  struct Identity : public std::unary_function<T, T>
475  {
477  T operator()(T arg) const { return arg; }
478  };
479 
480 
492  template<typename T>
493  void clear(std::vector<T>& vec)
494  {
495  std::vector<T> other;
496  vec.swap(other);
497  }
498 
499 
516  template <typename Key, typename Tp, typename Compare, typename Alloc,
517  typename Key2>
518  const Tp& get(const std::map<Key, Tp, Compare, Alloc>& m, const Key2& k);
519 
526  template<typename Key>
527  class get_error : public runtime_error
528  {
529  public:
531  get_error(const std::string& msg, const Key& key)
532  : runtime_error(msg), key_(key) {}
534  virtual ~get_error(void) throw () {}
536  const Key& key(void) const { return key_; }
537  private:
538  Key key_;
539  };
540 
553  template<typename InputIterator, typename Key, typename Comp>
554  void inverse(InputIterator first, InputIterator last,
555  std::map<Key, std::vector<size_t>, Comp >& m)
556  {
557  BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
558  BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
559  m.clear();
560  for (size_t i=0; first!=last; ++i, ++first)
561  m[*first].push_back(i);
562  }
563 
572  template<typename Key, typename InputIterator, typename Comp>
573  void inverse(InputIterator first, InputIterator last,
574  std::multimap<Key, size_t, Comp>& m)
575  {
576  BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
577  BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
578  m.clear();
579  for (size_t i=0; first!=last; ++i, ++first)
580  m.insert(std::make_pair(*first, i));
581  }
582 
583 
595  template<typename InputIterator, typename Key, typename Comp>
596  void inverse(InputIterator first, InputIterator last,
597  std::map<Key, size_t, Comp >& m)
598  {
599  BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
600  BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
601  m.clear();
602  for (size_t i=0; first!=last; ++i, ++first)
603  m[*first] = i;
604  }
605 
626  template<typename T>
627  struct less_nan : std::binary_function<T, T, bool>
628  {
634  inline bool operator()(T x, T y) const
635  {
636  if (std::isnan(x))
637  return false;
638  if (std::isnan(y))
639  return true;
640  return x<y;
641  }
642  };
643 
644 
648  template<>
650  : std::binary_function<DataWeight, DataWeight, bool>
651  {
655  inline bool operator()(const DataWeight& x, const DataWeight& y) const
656  {
657  less_nan<double> compare;
658  return compare(x.data(), y.data());
659  }
660  };
661 
662 
670  template<typename T>
671  class Log : std::unary_function<T, T>
672  {
673  public:
677  Log(void)
678  : log_base_(1.0) {}
679 
683  explicit Log(double base) : log_base_(std::log(base)) {}
684 
688  inline T operator()(T x) const
689  { return std::log(x)/log_base_; }
690 
691  private:
692  double log_base_;
693  };
694 
698  template <typename T>
699  T max(const T& a, const T& b, const T& c)
700  {
701  return std::max(std::max(a,b),c);
702  }
703 
704 
708  template <typename T>
709  T max(const T& a, const T& b, const T& c, const T& d)
710  {
711  return std::max(std::max(a,b), std::max(c,d));
712  }
713 
714 
718  template <typename T>
719  T max(const T& a, const T& b, const T& c, const T& d, const T& e)
720  {
721  return std::max(max(a,b,c,d), e);
722  }
723 
724 
728  template <typename T>
729  T max(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f)
730  {
731  return std::max(max(a,b,c,d), std::max(e,f));
732  }
733 
734 
742  template <class T1,class T2>
744  {
749  inline bool operator()(const std::pair<T1,T2>& x,
750  const std::pair<T1,T2>& y) {
751  return ((x.second<y.second) ||
752  (!(y.second<x.second) && (x.first<y.first)));
753  }
754  };
755 
763  template <class Pair>
764  struct PairFirst
765  {
771  typedef typename boost::mpl::if_<
772  typename boost::is_const<Pair>::type,
773  typename boost::add_const<typename Pair::first_type>::type&,
774  typename Pair::first_type&>::type result_type;
775 
779  typedef Pair& argument_type;
780 
784  inline result_type operator()(argument_type p) const
785  { return p.first; }
786 
787  };
788 
789 
797  template <class Pair>
798  struct PairSecond
799  {
805  typedef typename boost::mpl::if_<
806  typename boost::is_const<Pair>::type,
807  typename boost::add_const<typename Pair::second_type>::type&,
808  typename Pair::second_type&>::type result_type;
809 
813  typedef Pair& argument_type;
814 
818  inline result_type operator()(argument_type p) const
819  { return p.second; }
820 
821  };
822 
823 
841  template<class Iter>
842  boost::transform_iterator<
843  PairFirst<typename boost::remove_reference<
844  typename std::iterator_traits<Iter>::reference
845  >::type>,
846  Iter> pair_first_iterator(Iter i)
847  {
848  // We are going via ::reference in order to remain const info;
849  // ::value_type does not contain const information.
850  typedef typename std::iterator_traits<Iter>::reference ref_type;
851  typedef typename boost::remove_reference<ref_type>::type val_type;
852  typedef PairFirst<val_type> PF;
853  return boost::transform_iterator<PF, Iter>(i, PF());
854  }
855 
856 
872  template<class Iter>
873  boost::transform_iterator<
874  PairSecond<typename boost::remove_reference<
875  typename std::iterator_traits<Iter>::reference
876  >::type>,
877  Iter> pair_second_iterator(Iter i)
878  {
879  // We are going via ::reference in order to remain const info;
880  // ::value_type does not contain const information.
881  typedef typename std::iterator_traits<Iter>::reference ref_type;
882  typedef typename boost::remove_reference<ref_type>::type val_type;
883  typedef PairSecond<val_type> PS;
884  return boost::transform_iterator<PS, Iter>(i, PS());
885  }
886 
887 
916  template<typename Pointer, class Compare>
918  make_ptr_compare(Pointer p, Compare compare)
919  {
920  return make_compose_f_gx_hy(compare, Dereferencer<Pointer>(),
922  }
923 
930  template<typename Pointer>
932  Dereferencer<Pointer>, Dereferencer<Pointer> >
933  make_ptr_compare(Pointer p)
934  {
935  typedef typename std::iterator_traits<Pointer>::value_type value_type;
936  BOOST_CONCEPT_ASSERT((boost::LessThanComparable<value_type>));
937  std::less<value_type> compare;
938  return make_ptr_compare(p, compare);
939  }
940 
941 
945  std::string& to_lower(std::string& s);
946 
950  std::string& to_upper(std::string& s);
951 
952 
953  // template implementations
954 
955  template <typename Key, typename Tp, typename Compare, typename Alloc,
956  typename Key2>
957  const Tp& get(const std::map<Key, Tp, Compare, Alloc>& m, const Key2& key)
958  {
959  BOOST_CONCEPT_ASSERT((boost::Convertible<Key2, Key>));
960  typename std::map<Key, Tp, Compare,Alloc>::const_iterator iter(m.find(key));
961  if (iter==m.end()) {
962  // Avoid throw exception with Key2 because we do not want to
963  // require that Key2 is copy constructible. We know that Key is
964  // copy constructible from std::map requirement.
965  throw
966  get_error<Key>("utility::get(const Map&, const Key&): key not found",
967  key);
968  }
969  return iter->second;
970  }
971 
972 }}} // of namespace utility, yat, and theplu
973 #endif
Functor that behaves like std::less with the exception that it treats NaN as a number larger than inf...
Definition: stl_utility.h:627
Functor that return std::pair.second.
Definition: stl_utility.h:798
Concept check for Trivial Iterator.
Definition: concept_check.h:191
compose_f_gx_hx< F, G, H > make_compose_f_gx_hx(F f, G g, H h)
Definition: stl_utility.h:445
F::result_type operator()(typename G::first_argument_type x, typename G::second_argument_type y) const
Does the work.
Definition: stl_utility.h:275
bool operator()(const std::pair< T1, T2 > &x, const std::pair< T1, T2 > &y)
Definition: stl_utility.h:749
F::result_type operator()(typename G::argument_type x, typename H::argument_type y) const
Does the work.
Definition: stl_utility.h:202
boost::transform_iterator< PairSecond< typename boost::remove_reference< typename std::iterator_traits< Iter >::reference >::type >, Iter > pair_second_iterator(Iter i)
Definition: stl_utility.h:877
compose_f_gxy(F f, G g)
Constructor.
Definition: stl_utility.h:266
The Department of Theoretical Physics namespace as we define it.
Definition: stl_utility.h:326
T max(const T &a, const T &b, const T &c, const T &d, const T &e, const T &f)
Definition: stl_utility.h:729
Definition: stl_utility.h:402
Pair & argument_type
Definition: stl_utility.h:813
boost::mpl::if_< typename boost::is_const< Pair >::type, typename boost::add_const< typename Pair::second_type >::type &, typename Pair::second_type & >::type result_type
Definition: stl_utility.h:808
Definition: stl_utility.h:64
void clear(std::vector< T > &vec)
reduce size and capacity to zero
Definition: stl_utility.h:493
virtual ~get_error(void)
destructor
Definition: stl_utility.h:534
compose_f_gx_hx(F f, G g, H h)
Constructor.
Definition: stl_utility.h:416
Functor that return std::pair.first.
Definition: stl_utility.h:764
compose_f_gx_hy(F f, G g, H h)
Constructor.
Definition: stl_utility.h:194
get_error(const std::string &msg, const Key &key)
constructor
Definition: stl_utility.h:531
T operator()(T x) const
Definition: stl_utility.h:464
compose_f_gx_hy< std::less< typename std::iterator_traits< Pointer >::value_type >, Dereferencer< Pointer >, Dereferencer< Pointer > > make_ptr_compare(Pointer p)
Definition: stl_utility.h:933
void inverse(InputIterator first, InputIterator last, std::map< Key, size_t, Comp > &m)
Definition: stl_utility.h:596
compose_f_gx_hx(void)
default constructor
Definition: stl_utility.h:411
std::string & to_lower(std::string &s)
Function converting a string to lower case.
Holds a pair of data and associated weight.
Definition: DataWeight.h:39
compose_f_gx(F f, G g)
Constructor.
Definition: stl_utility.h:340
F::result_type operator()(typename G::argument_type x) const
Does the work.
Definition: stl_utility.h:424
Definition: stl_utility.h:250
const Key & key(void) const
access the key object
Definition: stl_utility.h:536
Class used for all runtime error detected within yat library.
Definition: Exception.h:53
boost::mpl::if_< typename boost::is_const< Pair >::type, typename boost::add_const< typename Pair::first_type >::type &, typename Pair::first_type & >::type result_type
Definition: stl_utility.h:774
compose_f_gx_hy< F, G, H > make_compose_f_gx_hy(F f, G g, H h)
Definition: stl_utility.h:222
boost::transform_iterator< PairFirst< typename boost::remove_reference< typename std::iterator_traits< Iter >::reference >::type >, Iter > pair_first_iterator(Iter i)
Definition: stl_utility.h:846
Adaptor between pointer and pointee interface.
Definition: stl_utility.h:122
T operator()(T arg) const
Definition: stl_utility.h:477
result_type operator()(argument_type p) const
Definition: stl_utility.h:784
compose_f_gxy< F, G > make_compose_f_gxy(F f, G g)
Definition: stl_utility.h:296
Definition: stl_utility.h:671
Dereferencer(void)
constructor
Definition: stl_utility.h:129
std::string & to_upper(std::string &s)
Function converting a string to upper case.
Definition: stl_utility.h:86
compose_f_gx(void)
default constructor
Definition: stl_utility.h:335
Identity functor that returns its argument.
Definition: stl_utility.h:474
F::result_type operator()(typename G::argument_type x) const
Does the work.
Definition: stl_utility.h:349
compose_f_gxy(void)
default constructor
Definition: stl_utility.h:261
Functor comparing pairs using second.
Definition: stl_utility.h:743
T operator()(T x) const
Definition: stl_utility.h:91
compose_f_gx< F, G > make_compose_f_gx(F f, G g)
Definition: stl_utility.h:369
Definition: stl_utility.h:459
compose_f_gx_hy(void)
default constructor
Definition: stl_utility.h:189
error class used in get(const std::map<Key, Tp, Compare, Alloc>& m, const Key& k) ...
Definition: stl_utility.h:527
bool operator()(const DataWeight &x, const DataWeight &y) const
Definition: stl_utility.h:655
T operator()(T x) const
Definition: stl_utility.h:688
bool operator()(T x, T y) const
Definition: stl_utility.h:634
Log(double base)
Definition: stl_utility.h:683
Definition: stl_utility.h:178
Log(void)
Definition: stl_utility.h:677
result_type operator()(argument_type p) const
Definition: stl_utility.h:818
Pair & argument_type
Definition: stl_utility.h:779
std::iterator_traits< Pointer >::reference operator()(Pointer ti) const
Definition: stl_utility.h:136

Generated on Mon Feb 22 2021 02:26:03 for yat by  doxygen 1.8.11