yat  0.9.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 2731 2012-04-30 05:58:27Z 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 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:
173  compose_f_gx_hy(F f, G g, H h)
174  : f_(f), g_(g), h_(h)
175  {
176  BOOST_CONCEPT_ASSERT((boost::Convertible<typename G::result_type
177  , typename F::first_argument_type>));
178  BOOST_CONCEPT_ASSERT((boost::Convertible<typename H::result_type
179  , typename F::second_argument_type>));
180 
181  }
182 
186  typename F::result_type
187  operator()(typename G::argument_type x,
188  typename H::argument_type y) const
189  {
190  return f_(g_(x), h_(y));
191  }
192 
193  private:
194  F f_;
195  G g_;
196  H h_;
197  };
198 
206  template<class F, class G, class H>
207  compose_f_gx_hy<F, G, H> make_compose_f_gx_hy(F f, G g, H h)
208  {
209  return compose_f_gx_hy<F,G,H>(f,g,h);
210  }
211 
212 
234  template<class F, class G>
236  public std::binary_function<typename G::first_argument_type,
237  typename G::second_argument_type,
238  typename F::result_type>
239  {
240  public:
244  compose_f_gxy(F f, G g)
245  : f_(f), g_(g)
246  {
247  BOOST_CONCEPT_ASSERT((boost::Convertible<typename G::result_type
248  , typename F::argument_type>));
249  }
250 
254  typename F::result_type
255  operator()(typename G::first_argument_type x,
256  typename G::second_argument_type y) const
257  {
258  return f_(g_(x,y));
259  }
260 
261  private:
262  F f_;
263  G g_;
264  };
265 
275  template<class F, class G>
276  compose_f_gxy<F, G> make_compose_f_gxy(F f, G g)
277  {
278  return compose_f_gxy<F,G>(f,g);
279  }
280 
281 
302  template<class F, class G>
303  class compose_f_gx : public std::unary_function<typename G::argument_type,
304  typename F::result_type>
305  {
306  public:
310  compose_f_gx(F f, G g)
311  : f_(f), g_(g)
312  {
313  BOOST_CONCEPT_ASSERT((boost::Convertible<typename G::result_type
314  , typename F::argument_type>));
315  }
316 
320  typename F::result_type
321  operator()(typename G::argument_type x) const
322  {
323  return f_(g_(x));
324  }
325 
326  private:
327  F f_;
328  G g_;
329  };
330 
340  template<class F, class G>
341  compose_f_gx<F, G> make_compose_f_gx(F f, G g)
342  {
343  return compose_f_gx<F,G>(f,g);
344  }
345 
346 
354  template<typename T>
355  struct Exp : std::unary_function<T, T>
356  {
360  inline T operator()(T x) const
361  { return std::exp(x); }
362  };
363 
369  template<typename T>
370  struct Identity : public std::unary_function<T, T>
371  {
373  T operator()(T arg) const { return arg; }
374  };
375 
376 
386  template <typename Key, typename Tp, typename Compare, typename Alloc>
387  const Tp& get(const std::map<Key, Tp, Compare, Alloc>& m, const Key& k);
388 
389 
402  template<typename InputIterator, typename Key, typename Comp>
403  void inverse(InputIterator first, InputIterator last,
404  std::map<Key, std::vector<size_t>, Comp >& m)
405  {
406  BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
407  BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
408  m.clear();
409  for (size_t i=0; first!=last; ++i, ++first)
410  m[*first].push_back(i);
411  }
412 
421  template<typename Key, typename InputIterator, typename Comp>
422  void inverse(InputIterator first, InputIterator last,
423  std::multimap<Key, size_t, Comp>& m)
424  {
425  BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
426  BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
427  m.clear();
428  for (size_t i=0; first!=last; ++i, ++first)
429  m.insert(std::make_pair(*first, i));
430  }
431 
432 
453  template<typename T>
454  struct less_nan : std::binary_function<T, T, bool>
455  {
461  inline bool operator()(T x, T y) const
462  {
463  if (std::isnan(x))
464  return false;
465  if (std::isnan(y))
466  return true;
467  return x<y;
468  }
469  };
470 
471 
475  template<>
477  : std::binary_function<DataWeight, DataWeight, bool>
478  {
482  inline bool operator()(const DataWeight& x, const DataWeight& y) const
483  {
484  less_nan<double> compare;
485  return compare(x.data(), y.data());
486  }
487  };
488 
489 
497  template<typename T>
498  class Log : std::unary_function<T, T>
499  {
500  public:
504  Log(void)
505  : log_base_(1.0) {}
506 
510  explicit Log(double base) : log_base_(std::log(base)) {}
511 
515  inline T operator()(T x) const
516  { return std::log(x)/log_base_; }
517 
518  private:
519  double log_base_;
520  };
521 
525  template <typename T>
526  T max(const T& a, const T& b, const T& c)
527  {
528  return std::max(std::max(a,b),c);
529  }
530 
531 
535  template <typename T>
536  T max(const T& a, const T& b, const T& c, const T& d)
537  {
538  return std::max(std::max(a,b), std::max(c,d));
539  }
540 
541 
545  template <typename T>
546  T max(const T& a, const T& b, const T& c, const T& d, const T& e)
547  {
548  return std::max(max(a,b,c,d), e);
549  }
550 
551 
555  template <typename T>
556  T max(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f)
557  {
558  return std::max(max(a,b,c,d), std::max(e,f));
559  }
560 
561 
569  template <class T1,class T2>
571  {
576  inline bool operator()(const std::pair<T1,T2>& x,
577  const std::pair<T1,T2>& y) {
578  return ((x.second<y.second) ||
579  (!(y.second<x.second) && (x.first<y.first)));
580  }
581  };
582 
590  template <class Pair>
591  struct PairFirst
592  {
598  typedef typename boost::mpl::if_<
599  typename boost::is_const<Pair>::type,
600  typename boost::add_const<typename Pair::first_type>::type&,
601  typename Pair::first_type&>::type result_type;
602 
606  typedef Pair& argument_type;
607 
612  { return p.first; }
613 
614  };
615 
616 
624  template <class Pair>
625  struct PairSecond
626  {
632  typedef typename boost::mpl::if_<
633  typename boost::is_const<Pair>::type,
634  typename boost::add_const<typename Pair::second_type>::type&,
635  typename Pair::second_type&>::type result_type;
636 
640  typedef Pair& argument_type;
641 
646  { return p.second; }
647 
648  };
649 
650 
668  template<class Iter>
669  boost::transform_iterator<
670  PairFirst<typename boost::remove_reference<
671  typename std::iterator_traits<Iter>::reference
672  >::type>,
673  Iter> pair_first_iterator(Iter i)
674  {
675  // We are going via ::reference in order to remain const info;
676  // ::value_type does not contain const information.
677  typedef typename std::iterator_traits<Iter>::reference ref_type;
678  typedef typename boost::remove_reference<ref_type>::type val_type;
679  typedef PairFirst<val_type> PF;
680  return boost::transform_iterator<PF, Iter>(i, PF());
681  }
682 
683 
699  template<class Iter>
700  boost::transform_iterator<
701  PairSecond<typename boost::remove_reference<
702  typename std::iterator_traits<Iter>::reference
703  >::type>,
704  Iter> pair_second_iterator(Iter i)
705  {
706  // We are going via ::reference in order to remain const info;
707  // ::value_type does not contain const information.
708  typedef typename std::iterator_traits<Iter>::reference ref_type;
709  typedef typename boost::remove_reference<ref_type>::type val_type;
710  typedef PairSecond<val_type> PS;
711  return boost::transform_iterator<PS, Iter>(i, PS());
712  }
713 
714 
743  template<typename Pointer, class Compare>
744  compose_f_gx_hy<Compare, Dereferencer<Pointer>, Dereferencer<Pointer> >
745  make_ptr_compare(Pointer p, Compare compare)
746  {
747  return make_compose_f_gx_hy(compare, Dereferencer<Pointer>(),
749  }
750 
757  template<typename Pointer>
758  compose_f_gx_hy<std::less<typename std::iterator_traits<Pointer>::value_type>,
759  Dereferencer<Pointer>, Dereferencer<Pointer> >
760  make_ptr_compare(Pointer p)
761  {
762  typedef typename std::iterator_traits<Pointer>::value_type value_type;
763  BOOST_CONCEPT_ASSERT((boost::LessThanComparable<value_type>));
764  std::less<value_type> compare;
765  return make_ptr_compare(p, compare);
766  }
767 
768 
772  std::string& to_lower(std::string& s);
773 
777  std::string& to_upper(std::string& s);
778 
779 
780  // template implementations
781 
782  template <typename Key, typename Tp, typename Compare, typename Alloc>
783  const Tp& get(const std::map<Key, Tp, Compare, Alloc>& m, const Key& key)
784  {
785  typename std::map<Key, Tp, Compare,Alloc>::const_iterator iter(m.find(key));
786  if (iter==m.end()) {
787  std::stringstream ss;
788  ss << "utility::get(const Map&, const Key&): `"
789  << key << "' not found in map\n";
790  throw runtime_error(ss.str());
791  }
792  return iter->second;
793  }
794 
795 }}} // of namespace utility, yat, and theplu
796 #endif

Generated on Tue Jan 29 2013 02:33:39 for yat by  doxygen 1.8.1