yat  0.13.2pre
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 3417 2015-05-25 01:35:59Z 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 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 
163  template<class F, class G, class H>
165  public std::binary_function<typename G::argument_type,
166  typename H::argument_type,
167  typename F::result_type>
168  {
169  public:
176 
180  compose_f_gx_hy(F f, G g, H h)
181  : f_(f), g_(g), h_(h)
182  {
183  }
184 
188  typename F::result_type operator()(typename G::argument_type x,
189  typename H::argument_type y) const
190  {
191  return f_(g_(x), h_(y));
192  }
193 
194  private:
195  F f_;
196  G g_;
197  H h_;
198  };
199 
207  template<class F, class G, class H>
209  {
210  return compose_f_gx_hy<F,G,H>(f,g,h);
211  }
212 
213 
235  template<class F, class G>
237  public std::binary_function<typename G::first_argument_type,
238  typename G::second_argument_type,
239  typename F::result_type>
240  {
241  public:
247  compose_f_gxy(void) {}
248 
252  compose_f_gxy(F f, G g)
253  : f_(f), g_(g)
254  {
255  }
256 
260  typename F::result_type
261  operator()(typename G::first_argument_type x,
262  typename G::second_argument_type y) const
263  {
264  return f_(g_(x,y));
265  }
266 
267  private:
268  F f_;
269  G g_;
270  };
271 
281  template<class F, class G>
283  {
284  return compose_f_gxy<F,G>(f,g);
285  }
286 
287 
311  template<class F, class G>
312  class compose_f_gx : public std::unary_function<typename G::argument_type,
313  typename F::result_type>
314  {
315  public:
321  compose_f_gx(void) {}
322 
326  compose_f_gx(F f, G g)
327  : f_(f), g_(g)
328  {
329  }
330 
334  typename F::result_type
335  operator()(typename G::argument_type x) const
336  {
337  return f_(g_(x));
338  }
339 
340  private:
341  F f_;
342  G g_;
343  };
344 
354  template<class F, class G>
356  {
357  return compose_f_gx<F,G>(f,g);
358  }
359 
360 
387  template<class F, class G, class H>
388  class compose_f_gx_hx : public std::unary_function<typename G::argument_type,
389  typename F::result_type>
390  {
391  public:
398 
402  compose_f_gx_hx(F f, G g, H h)
403  : f_(f), g_(g), h_(h)
404  {
405  }
406 
410  typename F::result_type operator()(typename G::argument_type x) const
411  {
412  return f_(g_(x), h_(x));
413  }
414 
415  private:
416  F f_;
417  G g_;
418  H h_;
419  };
420 
430  template<class F, class G, class H>
432  {
433  return compose_f_gx_hx<F,G,H>(f,g,h);
434  }
435 
436 
444  template<typename T>
445  struct Exp : std::unary_function<T, T>
446  {
450  inline T operator()(T x) const
451  { return std::exp(x); }
452  };
453 
459  template<typename T>
460  struct Identity : public std::unary_function<T, T>
461  {
463  T operator()(T arg) const { return arg; }
464  };
465 
466 
478  template<typename T>
479  void clear(std::vector<T>& vec)
480  {
481  std::vector<T> other;
482  vec.swap(other);
483  }
484 
485 
500  template <typename Key, typename Tp, typename Compare, typename Alloc,
501  typename Key2>
502  const Tp& get(const std::map<Key, Tp, Compare, Alloc>& m, const Key2& k);
503 
510  template<typename Key>
511  class get_error : public runtime_error
512  {
513  public:
515  get_error(const std::string& msg, const Key& key)
516  : runtime_error(msg), key_(key) {}
518  virtual ~get_error(void) throw () {}
520  const Key& key(void) const { return key_; }
521  private:
522  Key key_;
523  };
524 
537  template<typename InputIterator, typename Key, typename Comp>
538  void inverse(InputIterator first, InputIterator last,
539  std::map<Key, std::vector<size_t>, Comp >& m)
540  {
541  BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
542  BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
543  m.clear();
544  for (size_t i=0; first!=last; ++i, ++first)
545  m[*first].push_back(i);
546  }
547 
556  template<typename Key, typename InputIterator, typename Comp>
557  void inverse(InputIterator first, InputIterator last,
558  std::multimap<Key, size_t, Comp>& m)
559  {
560  BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
561  BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
562  m.clear();
563  for (size_t i=0; first!=last; ++i, ++first)
564  m.insert(std::make_pair(*first, i));
565  }
566 
567 
579  template<typename InputIterator, typename Key, typename Comp>
580  void inverse(InputIterator first, InputIterator last,
581  std::map<Key, size_t, Comp >& m)
582  {
583  BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
584  BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
585  m.clear();
586  for (size_t i=0; first!=last; ++i, ++first)
587  m[*first] = i;
588  }
589 
610  template<typename T>
611  struct less_nan : std::binary_function<T, T, bool>
612  {
618  inline bool operator()(T x, T y) const
619  {
620  if (std::isnan(x))
621  return false;
622  if (std::isnan(y))
623  return true;
624  return x<y;
625  }
626  };
627 
628 
632  template<>
634  : std::binary_function<DataWeight, DataWeight, bool>
635  {
639  inline bool operator()(const DataWeight& x, const DataWeight& y) const
640  {
641  less_nan<double> compare;
642  return compare(x.data(), y.data());
643  }
644  };
645 
646 
654  template<typename T>
655  class Log : std::unary_function<T, T>
656  {
657  public:
661  Log(void)
662  : log_base_(1.0) {}
663 
667  explicit Log(double base) : log_base_(std::log(base)) {}
668 
672  inline T operator()(T x) const
673  { return std::log(x)/log_base_; }
674 
675  private:
676  double log_base_;
677  };
678 
682  template <typename T>
683  T max(const T& a, const T& b, const T& c)
684  {
685  return std::max(std::max(a,b),c);
686  }
687 
688 
692  template <typename T>
693  T max(const T& a, const T& b, const T& c, const T& d)
694  {
695  return std::max(std::max(a,b), std::max(c,d));
696  }
697 
698 
702  template <typename T>
703  T max(const T& a, const T& b, const T& c, const T& d, const T& e)
704  {
705  return std::max(max(a,b,c,d), e);
706  }
707 
708 
712  template <typename T>
713  T max(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f)
714  {
715  return std::max(max(a,b,c,d), std::max(e,f));
716  }
717 
718 
726  template <class T1,class T2>
728  {
733  inline bool operator()(const std::pair<T1,T2>& x,
734  const std::pair<T1,T2>& y) {
735  return ((x.second<y.second) ||
736  (!(y.second<x.second) && (x.first<y.first)));
737  }
738  };
739 
747  template <class Pair>
748  struct PairFirst
749  {
755  typedef typename boost::mpl::if_<
756  typename boost::is_const<Pair>::type,
757  typename boost::add_const<typename Pair::first_type>::type&,
758  typename Pair::first_type&>::type result_type;
759 
763  typedef Pair& argument_type;
764 
769  { return p.first; }
770 
771  };
772 
773 
781  template <class Pair>
782  struct PairSecond
783  {
789  typedef typename boost::mpl::if_<
790  typename boost::is_const<Pair>::type,
791  typename boost::add_const<typename Pair::second_type>::type&,
792  typename Pair::second_type&>::type result_type;
793 
797  typedef Pair& argument_type;
798 
803  { return p.second; }
804 
805  };
806 
807 
825  template<class Iter>
826  boost::transform_iterator<
827  PairFirst<typename boost::remove_reference<
828  typename std::iterator_traits<Iter>::reference
829  >::type>,
830  Iter> pair_first_iterator(Iter i)
831  {
832  // We are going via ::reference in order to remain const info;
833  // ::value_type does not contain const information.
834  typedef typename std::iterator_traits<Iter>::reference ref_type;
835  typedef typename boost::remove_reference<ref_type>::type val_type;
836  typedef PairFirst<val_type> PF;
837  return boost::transform_iterator<PF, Iter>(i, PF());
838  }
839 
840 
856  template<class Iter>
857  boost::transform_iterator<
858  PairSecond<typename boost::remove_reference<
859  typename std::iterator_traits<Iter>::reference
860  >::type>,
861  Iter> pair_second_iterator(Iter i)
862  {
863  // We are going via ::reference in order to remain const info;
864  // ::value_type does not contain const information.
865  typedef typename std::iterator_traits<Iter>::reference ref_type;
866  typedef typename boost::remove_reference<ref_type>::type val_type;
867  typedef PairSecond<val_type> PS;
868  return boost::transform_iterator<PS, Iter>(i, PS());
869  }
870 
871 
900  template<typename Pointer, class Compare>
901  compose_f_gx_hy<Compare, Dereferencer<Pointer>, Dereferencer<Pointer> >
902  make_ptr_compare(Pointer p, Compare compare)
903  {
904  return make_compose_f_gx_hy(compare, Dereferencer<Pointer>(),
906  }
907 
914  template<typename Pointer>
915  compose_f_gx_hy<std::less<typename std::iterator_traits<Pointer>::value_type>,
916  Dereferencer<Pointer>, Dereferencer<Pointer> >
917  make_ptr_compare(Pointer p)
918  {
919  typedef typename std::iterator_traits<Pointer>::value_type value_type;
920  BOOST_CONCEPT_ASSERT((boost::LessThanComparable<value_type>));
921  std::less<value_type> compare;
922  return make_ptr_compare(p, compare);
923  }
924 
925 
929  std::string& to_lower(std::string& s);
930 
934  std::string& to_upper(std::string& s);
935 
936 
937  // template implementations
938 
939  template <typename Key, typename Tp, typename Compare, typename Alloc,
940  typename Key2>
941  const Tp& get(const std::map<Key, Tp, Compare, Alloc>& m, const Key2& key)
942  {
943  BOOST_CONCEPT_ASSERT((boost::Convertible<Key2, Key>));
944  typename std::map<Key, Tp, Compare,Alloc>::const_iterator iter(m.find(key));
945  if (iter==m.end()) {
946  // Avoid throw exception with Key2 because we do not want to
947  // require that Key2 is copy constructible. We know that Key is
948  // copy constructible from std::map requirement.
949  throw
950  get_error<Key>("utility::get(const Map&, const Key&): key not found",
951  key);
952  }
953  return iter->second;
954  }
955 
956 }}} // of namespace utility, yat, and theplu
957 #endif
Functor that behaves like std::less with the exception that it treats NaN as a number larger than inf...
Definition: stl_utility.h:611
Functor that return std::pair.second.
Definition: stl_utility.h:782
void inverse(InputIterator first, InputIterator last, std::map< Key, std::vector< size_t >, Comp > &m)
Definition: stl_utility.h:538
Concept check for Trivial Iterator
Definition: concept_check.h:177
compose_f_gx_hx< F, G, H > make_compose_f_gx_hx(F f, G g, H h)
Definition: stl_utility.h:431
F::result_type operator()(typename G::first_argument_type x, typename G::second_argument_type y) const
Does the work.
Definition: stl_utility.h:261
bool operator()(const std::pair< T1, T2 > &x, const std::pair< T1, T2 > &y)
Definition: stl_utility.h:733
F::result_type operator()(typename G::argument_type x, typename H::argument_type y) const
Does the work.
Definition: stl_utility.h:188
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:861
compose_f_gxy(F f, G g)
Constructor.
Definition: stl_utility.h:252
Definition: stl_utility.h:312
Definition: stl_utility.h:388
Pair & argument_type
Definition: stl_utility.h:797
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:792
void clear(std::vector< T > &vec)
reduce size and capacity to zero
Definition: stl_utility.h:479
virtual ~get_error(void)
destructor
Definition: stl_utility.h:518
compose_f_gx_hx(F f, G g, H h)
Constructor.
Definition: stl_utility.h:402
Functor that return std::pair.first.
Definition: stl_utility.h:748
compose_f_gx_hy(F f, G g, H h)
Constructor.
Definition: stl_utility.h:180
get_error(const std::string &msg, const Key &key)
constructor
Definition: stl_utility.h:515
T operator()(T x) const
Definition: stl_utility.h:450
compose_f_gx_hx(void)
default constructor
Definition: stl_utility.h:397
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:326
F::result_type operator()(typename G::argument_type x) const
Does the work.
Definition: stl_utility.h:410
T max(const T &a, const T &b, const T &c)
Definition: stl_utility.h:683
Definition: stl_utility.h:236
const Key & key(void) const
access the key object
Definition: stl_utility.h:520
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:758
compose_f_gx_hy< F, G, H > make_compose_f_gx_hy(F f, G g, H h)
Definition: stl_utility.h:208
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:830
Adaptor between pointer and pointee interface.
Definition: stl_utility.h:122
T operator()(T arg) const
Definition: stl_utility.h:463
result_type operator()(argument_type p) const
Definition: stl_utility.h:768
compose_f_gxy< F, G > make_compose_f_gxy(F f, G g)
Definition: stl_utility.h:282
Definition: stl_utility.h:655
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:321
Identity functor that returns its argument.
Definition: stl_utility.h:460
F::result_type operator()(typename G::argument_type x) const
Does the work.
Definition: stl_utility.h:335
compose_f_gxy(void)
default constructor
Definition: stl_utility.h:247
Functor comparing pairs using second.
Definition: stl_utility.h:727
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:355
Definition: stl_utility.h:445
compose_f_gx_hy(void)
default constructor
Definition: stl_utility.h:175
error class used in get(const std::map&lt;Key, Tp, Compare, Alloc&gt;&amp; m, const Key&amp; k) ...
Definition: stl_utility.h:511
bool operator()(const DataWeight &x, const DataWeight &y) const
Definition: stl_utility.h:639
T operator()(T x) const
Definition: stl_utility.h:672
bool operator()(T x, T y) const
Definition: stl_utility.h:618
Log(double base)
Definition: stl_utility.h:667
Definition: stl_utility.h:164
Log(void)
Definition: stl_utility.h:661
result_type operator()(argument_type p) const
Definition: stl_utility.h:802
Pair & argument_type
Definition: stl_utility.h:763
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:902

Generated on Wed Jan 4 2017 02:23:07 for yat by  doxygen 1.8.5