yat  0.11.3pre
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 3084 2013-09-19 02:10:18Z 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 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  BOOST_CONCEPT_ASSERT((boost::Convertible<typename G::result_type
184  , typename F::first_argument_type>));
185  BOOST_CONCEPT_ASSERT((boost::Convertible<typename H::result_type
186  , typename F::second_argument_type>));
187 
188  }
189 
193  typename F::result_type operator()(typename G::argument_type x,
194  typename H::argument_type y) const
195  {
196  return f_(g_(x), h_(y));
197  }
198 
199  private:
200  F f_;
201  G g_;
202  H h_;
203  };
204 
212  template<class F, class G, class H>
213  compose_f_gx_hy<F, G, H> make_compose_f_gx_hy(F f, G g, H h)
214  {
215  return compose_f_gx_hy<F,G,H>(f,g,h);
216  }
217 
218 
240  template<class F, class G>
242  public std::binary_function<typename G::first_argument_type,
243  typename G::second_argument_type,
244  typename F::result_type>
245  {
246  public:
252  compose_f_gxy(void) {}
253 
257  compose_f_gxy(F f, G g)
258  : f_(f), g_(g)
259  {
260  BOOST_CONCEPT_ASSERT((boost::Convertible<typename G::result_type
261  , typename F::argument_type>));
262  }
263 
267  typename F::result_type
268  operator()(typename G::first_argument_type x,
269  typename G::second_argument_type y) const
270  {
271  return f_(g_(x,y));
272  }
273 
274  private:
275  F f_;
276  G g_;
277  };
278 
288  template<class F, class G>
289  compose_f_gxy<F, G> make_compose_f_gxy(F f, G g)
290  {
291  return compose_f_gxy<F,G>(f,g);
292  }
293 
294 
318  template<class F, class G>
319  class compose_f_gx : public std::unary_function<typename G::argument_type,
320  typename F::result_type>
321  {
322  public:
328  compose_f_gx(void) {}
329 
333  compose_f_gx(F f, G g)
334  : f_(f), g_(g)
335  {
336  BOOST_CONCEPT_ASSERT((boost::Convertible<typename G::result_type
337  , typename F::argument_type>));
338  }
339 
343  typename F::result_type
344  operator()(typename G::argument_type x) const
345  {
346  return f_(g_(x));
347  }
348 
349  private:
350  F f_;
351  G g_;
352  };
353 
363  template<class F, class G>
364  compose_f_gx<F, G> make_compose_f_gx(F f, G g)
365  {
366  return compose_f_gx<F,G>(f,g);
367  }
368 
369 
396  template<class F, class G, class H>
397  class compose_f_gx_hx : public std::unary_function<typename G::argument_type,
398  typename F::result_type>
399  {
400  public:
407 
411  compose_f_gx_hx(F f, G g, H h)
412  : f_(f), g_(g), h_(h)
413  {
414  BOOST_CONCEPT_ASSERT((boost::Convertible<typename G::result_type
415  , typename F::first_argument_type>));
416  BOOST_CONCEPT_ASSERT((boost::Convertible<typename H::result_type
417  , typename F::second_argument_type>));
418  }
419 
423  typename F::result_type operator()(typename G::argument_type x) const
424  {
425  return f_(g_(x), h_(x));
426  }
427 
428  private:
429  F f_;
430  G g_;
431  H h_;
432  };
433 
443  template<class F, class G, class H>
444  compose_f_gx_hx<F, G, H> make_compose_f_gx_hx(F f, G g, H h)
445  {
446  return compose_f_gx_hx<F,G,H>(f,g,h);
447  }
448 
449 
457  template<typename T>
458  struct Exp : std::unary_function<T, T>
459  {
463  inline T operator()(T x) const
464  { return std::exp(x); }
465  };
466 
472  template<typename T>
473  struct Identity : public std::unary_function<T, T>
474  {
476  T operator()(T arg) const { return arg; }
477  };
478 
479 
489  template <typename Key, typename Tp, typename Compare, typename Alloc>
490  const Tp& get(const std::map<Key, Tp, Compare, Alloc>& m, const Key& k);
491 
492 
505  template<typename InputIterator, typename Key, typename Comp>
506  void inverse(InputIterator first, InputIterator last,
507  std::map<Key, std::vector<size_t>, Comp >& m)
508  {
509  BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
510  BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
511  m.clear();
512  for (size_t i=0; first!=last; ++i, ++first)
513  m[*first].push_back(i);
514  }
515 
524  template<typename Key, typename InputIterator, typename Comp>
525  void inverse(InputIterator first, InputIterator last,
526  std::multimap<Key, size_t, Comp>& m)
527  {
528  BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
529  BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
530  m.clear();
531  for (size_t i=0; first!=last; ++i, ++first)
532  m.insert(std::make_pair(*first, i));
533  }
534 
535 
547  template<typename InputIterator, typename Key, typename Comp>
548  void inverse(InputIterator first, InputIterator last,
549  std::map<Key, size_t, Comp >& m)
550  {
551  BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
552  BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
553  m.clear();
554  for (size_t i=0; first!=last; ++i, ++first)
555  m[*first] = i;
556  }
557 
578  template<typename T>
579  struct less_nan : std::binary_function<T, T, bool>
580  {
586  inline bool operator()(T x, T y) const
587  {
588  if (std::isnan(x))
589  return false;
590  if (std::isnan(y))
591  return true;
592  return x<y;
593  }
594  };
595 
596 
600  template<>
602  : std::binary_function<DataWeight, DataWeight, bool>
603  {
607  inline bool operator()(const DataWeight& x, const DataWeight& y) const
608  {
609  less_nan<double> compare;
610  return compare(x.data(), y.data());
611  }
612  };
613 
614 
622  template<typename T>
623  class Log : std::unary_function<T, T>
624  {
625  public:
629  Log(void)
630  : log_base_(1.0) {}
631 
635  explicit Log(double base) : log_base_(std::log(base)) {}
636 
640  inline T operator()(T x) const
641  { return std::log(x)/log_base_; }
642 
643  private:
644  double log_base_;
645  };
646 
650  template <typename T>
651  T max(const T& a, const T& b, const T& c)
652  {
653  return std::max(std::max(a,b),c);
654  }
655 
656 
660  template <typename T>
661  T max(const T& a, const T& b, const T& c, const T& d)
662  {
663  return std::max(std::max(a,b), std::max(c,d));
664  }
665 
666 
670  template <typename T>
671  T max(const T& a, const T& b, const T& c, const T& d, const T& e)
672  {
673  return std::max(max(a,b,c,d), e);
674  }
675 
676 
680  template <typename T>
681  T max(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f)
682  {
683  return std::max(max(a,b,c,d), std::max(e,f));
684  }
685 
686 
694  template <class T1,class T2>
696  {
701  inline bool operator()(const std::pair<T1,T2>& x,
702  const std::pair<T1,T2>& y) {
703  return ((x.second<y.second) ||
704  (!(y.second<x.second) && (x.first<y.first)));
705  }
706  };
707 
715  template <class Pair>
716  struct PairFirst
717  {
723  typedef typename boost::mpl::if_<
724  typename boost::is_const<Pair>::type,
725  typename boost::add_const<typename Pair::first_type>::type&,
726  typename Pair::first_type&>::type result_type;
727 
731  typedef Pair& argument_type;
732 
737  { return p.first; }
738 
739  };
740 
741 
749  template <class Pair>
750  struct PairSecond
751  {
757  typedef typename boost::mpl::if_<
758  typename boost::is_const<Pair>::type,
759  typename boost::add_const<typename Pair::second_type>::type&,
760  typename Pair::second_type&>::type result_type;
761 
765  typedef Pair& argument_type;
766 
771  { return p.second; }
772 
773  };
774 
775 
793  template<class Iter>
794  boost::transform_iterator<
795  PairFirst<typename boost::remove_reference<
796  typename std::iterator_traits<Iter>::reference
797  >::type>,
798  Iter> pair_first_iterator(Iter i)
799  {
800  // We are going via ::reference in order to remain const info;
801  // ::value_type does not contain const information.
802  typedef typename std::iterator_traits<Iter>::reference ref_type;
803  typedef typename boost::remove_reference<ref_type>::type val_type;
804  typedef PairFirst<val_type> PF;
805  return boost::transform_iterator<PF, Iter>(i, PF());
806  }
807 
808 
824  template<class Iter>
825  boost::transform_iterator<
826  PairSecond<typename boost::remove_reference<
827  typename std::iterator_traits<Iter>::reference
828  >::type>,
829  Iter> pair_second_iterator(Iter i)
830  {
831  // We are going via ::reference in order to remain const info;
832  // ::value_type does not contain const information.
833  typedef typename std::iterator_traits<Iter>::reference ref_type;
834  typedef typename boost::remove_reference<ref_type>::type val_type;
835  typedef PairSecond<val_type> PS;
836  return boost::transform_iterator<PS, Iter>(i, PS());
837  }
838 
839 
868  template<typename Pointer, class Compare>
869  compose_f_gx_hy<Compare, Dereferencer<Pointer>, Dereferencer<Pointer> >
870  make_ptr_compare(Pointer p, Compare compare)
871  {
872  return make_compose_f_gx_hy(compare, Dereferencer<Pointer>(),
874  }
875 
882  template<typename Pointer>
883  compose_f_gx_hy<std::less<typename std::iterator_traits<Pointer>::value_type>,
884  Dereferencer<Pointer>, Dereferencer<Pointer> >
885  make_ptr_compare(Pointer p)
886  {
887  typedef typename std::iterator_traits<Pointer>::value_type value_type;
888  BOOST_CONCEPT_ASSERT((boost::LessThanComparable<value_type>));
889  std::less<value_type> compare;
890  return make_ptr_compare(p, compare);
891  }
892 
893 
897  std::string& to_lower(std::string& s);
898 
902  std::string& to_upper(std::string& s);
903 
904 
905  // template implementations
906 
907  template <typename Key, typename Tp, typename Compare, typename Alloc>
908  const Tp& get(const std::map<Key, Tp, Compare, Alloc>& m, const Key& key)
909  {
910  typename std::map<Key, Tp, Compare,Alloc>::const_iterator iter(m.find(key));
911  if (iter==m.end()) {
912  std::stringstream ss;
913  ss << "utility::get(const Map&, const Key&): '"
914  << key << "' not found in map\n";
915  throw runtime_error(ss.str());
916  }
917  return iter->second;
918  }
919 
920 }}} // of namespace utility, yat, and theplu
921 #endif

Generated on Sat May 24 2014 03:33:05 for yat by  doxygen 1.8.2