yat  0.14.5pre
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 3550 2017-01-03 05:41:02Z 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 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 
514  template <typename Key, typename Tp, typename Compare, typename Alloc,
515  typename Key2>
516  const Tp& get(const std::map<Key, Tp, Compare, Alloc>& m, const Key2& k);
517 
524  template<typename Key>
525  class get_error : public runtime_error
526  {
527  public:
529  get_error(const std::string& msg, const Key& key)
530  : runtime_error(msg), key_(key) {}
532  virtual ~get_error(void) throw () {}
534  const Key& key(void) const { return key_; }
535  private:
536  Key key_;
537  };
538 
551  template<typename InputIterator, typename Key, typename Comp>
552  void inverse(InputIterator first, InputIterator last,
553  std::map<Key, std::vector<size_t>, Comp >& m)
554  {
555  BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
556  BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
557  m.clear();
558  for (size_t i=0; first!=last; ++i, ++first)
559  m[*first].push_back(i);
560  }
561 
570  template<typename Key, typename InputIterator, typename Comp>
571  void inverse(InputIterator first, InputIterator last,
572  std::multimap<Key, size_t, Comp>& m)
573  {
574  BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
575  BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
576  m.clear();
577  for (size_t i=0; first!=last; ++i, ++first)
578  m.insert(std::make_pair(*first, i));
579  }
580 
581 
593  template<typename InputIterator, typename Key, typename Comp>
594  void inverse(InputIterator first, InputIterator last,
595  std::map<Key, size_t, Comp >& m)
596  {
597  BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
598  BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
599  m.clear();
600  for (size_t i=0; first!=last; ++i, ++first)
601  m[*first] = i;
602  }
603 
624  template<typename T>
625  struct less_nan : std::binary_function<T, T, bool>
626  {
632  inline bool operator()(T x, T y) const
633  {
634  if (std::isnan(x))
635  return false;
636  if (std::isnan(y))
637  return true;
638  return x<y;
639  }
640  };
641 
642 
646  template<>
648  : std::binary_function<DataWeight, DataWeight, bool>
649  {
653  inline bool operator()(const DataWeight& x, const DataWeight& y) const
654  {
655  less_nan<double> compare;
656  return compare(x.data(), y.data());
657  }
658  };
659 
660 
668  template<typename T>
669  class Log : std::unary_function<T, T>
670  {
671  public:
675  Log(void)
676  : log_base_(1.0) {}
677 
681  explicit Log(double base) : log_base_(std::log(base)) {}
682 
686  inline T operator()(T x) const
687  { return std::log(x)/log_base_; }
688 
689  private:
690  double log_base_;
691  };
692 
696  template <typename T>
697  T max(const T& a, const T& b, const T& c)
698  {
699  return std::max(std::max(a,b),c);
700  }
701 
702 
706  template <typename T>
707  T max(const T& a, const T& b, const T& c, const T& d)
708  {
709  return std::max(std::max(a,b), std::max(c,d));
710  }
711 
712 
716  template <typename T>
717  T max(const T& a, const T& b, const T& c, const T& d, const T& e)
718  {
719  return std::max(max(a,b,c,d), e);
720  }
721 
722 
726  template <typename T>
727  T max(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f)
728  {
729  return std::max(max(a,b,c,d), std::max(e,f));
730  }
731 
732 
740  template <class T1,class T2>
742  {
747  inline bool operator()(const std::pair<T1,T2>& x,
748  const std::pair<T1,T2>& y) {
749  return ((x.second<y.second) ||
750  (!(y.second<x.second) && (x.first<y.first)));
751  }
752  };
753 
761  template <class Pair>
762  struct PairFirst
763  {
769  typedef typename boost::mpl::if_<
770  typename boost::is_const<Pair>::type,
771  typename boost::add_const<typename Pair::first_type>::type&,
772  typename Pair::first_type&>::type result_type;
773 
777  typedef Pair& argument_type;
778 
783  { return p.first; }
784 
785  };
786 
787 
795  template <class Pair>
796  struct PairSecond
797  {
803  typedef typename boost::mpl::if_<
804  typename boost::is_const<Pair>::type,
805  typename boost::add_const<typename Pair::second_type>::type&,
806  typename Pair::second_type&>::type result_type;
807 
811  typedef Pair& argument_type;
812 
817  { return p.second; }
818 
819  };
820 
821 
839  template<class Iter>
840  boost::transform_iterator<
841  PairFirst<typename boost::remove_reference<
842  typename std::iterator_traits<Iter>::reference
843  >::type>,
844  Iter> pair_first_iterator(Iter i)
845  {
846  // We are going via ::reference in order to remain const info;
847  // ::value_type does not contain const information.
848  typedef typename std::iterator_traits<Iter>::reference ref_type;
849  typedef typename boost::remove_reference<ref_type>::type val_type;
850  typedef PairFirst<val_type> PF;
851  return boost::transform_iterator<PF, Iter>(i, PF());
852  }
853 
854 
870  template<class Iter>
871  boost::transform_iterator<
872  PairSecond<typename boost::remove_reference<
873  typename std::iterator_traits<Iter>::reference
874  >::type>,
875  Iter> pair_second_iterator(Iter i)
876  {
877  // We are going via ::reference in order to remain const info;
878  // ::value_type does not contain const information.
879  typedef typename std::iterator_traits<Iter>::reference ref_type;
880  typedef typename boost::remove_reference<ref_type>::type val_type;
881  typedef PairSecond<val_type> PS;
882  return boost::transform_iterator<PS, Iter>(i, PS());
883  }
884 
885 
914  template<typename Pointer, class Compare>
915  compose_f_gx_hy<Compare, Dereferencer<Pointer>, Dereferencer<Pointer> >
916  make_ptr_compare(Pointer p, Compare compare)
917  {
918  return make_compose_f_gx_hy(compare, Dereferencer<Pointer>(),
920  }
921 
928  template<typename Pointer>
929  compose_f_gx_hy<std::less<typename std::iterator_traits<Pointer>::value_type>,
930  Dereferencer<Pointer>, Dereferencer<Pointer> >
931  make_ptr_compare(Pointer p)
932  {
933  typedef typename std::iterator_traits<Pointer>::value_type value_type;
934  BOOST_CONCEPT_ASSERT((boost::LessThanComparable<value_type>));
935  std::less<value_type> compare;
936  return make_ptr_compare(p, compare);
937  }
938 
939 
943  std::string& to_lower(std::string& s);
944 
948  std::string& to_upper(std::string& s);
949 
950 
951  // template implementations
952 
953  template <typename Key, typename Tp, typename Compare, typename Alloc,
954  typename Key2>
955  const Tp& get(const std::map<Key, Tp, Compare, Alloc>& m, const Key2& key)
956  {
957  BOOST_CONCEPT_ASSERT((boost::Convertible<Key2, Key>));
958  typename std::map<Key, Tp, Compare,Alloc>::const_iterator iter(m.find(key));
959  if (iter==m.end()) {
960  // Avoid throw exception with Key2 because we do not want to
961  // require that Key2 is copy constructible. We know that Key is
962  // copy constructible from std::map requirement.
963  throw
964  get_error<Key>("utility::get(const Map&, const Key&): key not found",
965  key);
966  }
967  return iter->second;
968  }
969 
970 }}} // of namespace utility, yat, and theplu
971 #endif
Functor that behaves like std::less with the exception that it treats NaN as a number larger than inf...
Definition: stl_utility.h:625
Functor that return std::pair.second.
Definition: stl_utility.h:796
void inverse(InputIterator first, InputIterator last, std::map< Key, std::vector< size_t >, Comp > &m)
Definition: stl_utility.h:552
Concept check for Trivial Iterator
Definition: concept_check.h:179
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:747
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:875
compose_f_gxy(F f, G g)
Constructor.
Definition: stl_utility.h:266
Definition: stl_utility.h:326
Definition: stl_utility.h:402
Pair & argument_type
Definition: stl_utility.h:811
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:806
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:532
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:762
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:529
T operator()(T x) const
Definition: stl_utility.h:464
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
T max(const T &a, const T &b, const T &c)
Definition: stl_utility.h:697
Definition: stl_utility.h:250
const Key & key(void) const
access the key object
Definition: stl_utility.h:534
Class used for all runtime error detected within yat library.
Definition: Exception.h:38
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:772
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:844
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:782
compose_f_gxy< F, G > make_compose_f_gxy(F f, G g)
Definition: stl_utility.h:296
Definition: stl_utility.h:669
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:741
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&lt;Key, Tp, Compare, Alloc&gt;&amp; m, const Key&amp; k) ...
Definition: stl_utility.h:525
bool operator()(const DataWeight &x, const DataWeight &y) const
Definition: stl_utility.h:653
T operator()(T x) const
Definition: stl_utility.h:686
bool operator()(T x, T y) const
Definition: stl_utility.h:632
Log(double base)
Definition: stl_utility.h:681
Definition: stl_utility.h:178
Log(void)
Definition: stl_utility.h:675
result_type operator()(argument_type p) const
Definition: stl_utility.h:816
Pair & argument_type
Definition: stl_utility.h:777
std::iterator_traits< Pointer >::reference operator()(Pointer ti) const
Definition: stl_utility.h:136
compose_f_gx_hy< Compare, Dereferencer< Pointer >, Dereferencer< Pointer > > make_ptr_compare(Pointer p, Compare compare)
Definition: stl_utility.h:916

Generated on Tue Sep 26 2017 02:33:29 for yat by  doxygen 1.8.5