yat  0.10.4pre
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 2857 2012-09-27 23:17:17Z 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 
444  template<typename InputIterator, typename Key, typename Comp>
445  void inverse(InputIterator first, InputIterator last,
446  std::map<Key, size_t, Comp >& m)
447  {
448  BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
449  BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
450  m.clear();
451  for (size_t i=0; first!=last; ++i, ++first)
452  m[*first] = i;
453  }
454 
475  template<typename T>
476  struct less_nan : std::binary_function<T, T, bool>
477  {
483  inline bool operator()(T x, T y) const
484  {
485  if (std::isnan(x))
486  return false;
487  if (std::isnan(y))
488  return true;
489  return x<y;
490  }
491  };
492 
493 
497  template<>
499  : std::binary_function<DataWeight, DataWeight, bool>
500  {
504  inline bool operator()(const DataWeight& x, const DataWeight& y) const
505  {
506  less_nan<double> compare;
507  return compare(x.data(), y.data());
508  }
509  };
510 
511 
519  template<typename T>
520  class Log : std::unary_function<T, T>
521  {
522  public:
526  Log(void)
527  : log_base_(1.0) {}
528 
532  explicit Log(double base) : log_base_(std::log(base)) {}
533 
537  inline T operator()(T x) const
538  { return std::log(x)/log_base_; }
539 
540  private:
541  double log_base_;
542  };
543 
547  template <typename T>
548  T max(const T& a, const T& b, const T& c)
549  {
550  return std::max(std::max(a,b),c);
551  }
552 
553 
557  template <typename T>
558  T max(const T& a, const T& b, const T& c, const T& d)
559  {
560  return std::max(std::max(a,b), std::max(c,d));
561  }
562 
563 
567  template <typename T>
568  T max(const T& a, const T& b, const T& c, const T& d, const T& e)
569  {
570  return std::max(max(a,b,c,d), e);
571  }
572 
573 
577  template <typename T>
578  T max(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f)
579  {
580  return std::max(max(a,b,c,d), std::max(e,f));
581  }
582 
583 
591  template <class T1,class T2>
593  {
598  inline bool operator()(const std::pair<T1,T2>& x,
599  const std::pair<T1,T2>& y) {
600  return ((x.second<y.second) ||
601  (!(y.second<x.second) && (x.first<y.first)));
602  }
603  };
604 
612  template <class Pair>
613  struct PairFirst
614  {
620  typedef typename boost::mpl::if_<
621  typename boost::is_const<Pair>::type,
622  typename boost::add_const<typename Pair::first_type>::type&,
623  typename Pair::first_type&>::type result_type;
624 
628  typedef Pair& argument_type;
629 
634  { return p.first; }
635 
636  };
637 
638 
646  template <class Pair>
647  struct PairSecond
648  {
654  typedef typename boost::mpl::if_<
655  typename boost::is_const<Pair>::type,
656  typename boost::add_const<typename Pair::second_type>::type&,
657  typename Pair::second_type&>::type result_type;
658 
662  typedef Pair& argument_type;
663 
668  { return p.second; }
669 
670  };
671 
672 
690  template<class Iter>
691  boost::transform_iterator<
692  PairFirst<typename boost::remove_reference<
693  typename std::iterator_traits<Iter>::reference
694  >::type>,
695  Iter> pair_first_iterator(Iter i)
696  {
697  // We are going via ::reference in order to remain const info;
698  // ::value_type does not contain const information.
699  typedef typename std::iterator_traits<Iter>::reference ref_type;
700  typedef typename boost::remove_reference<ref_type>::type val_type;
701  typedef PairFirst<val_type> PF;
702  return boost::transform_iterator<PF, Iter>(i, PF());
703  }
704 
705 
721  template<class Iter>
722  boost::transform_iterator<
723  PairSecond<typename boost::remove_reference<
724  typename std::iterator_traits<Iter>::reference
725  >::type>,
726  Iter> pair_second_iterator(Iter i)
727  {
728  // We are going via ::reference in order to remain const info;
729  // ::value_type does not contain const information.
730  typedef typename std::iterator_traits<Iter>::reference ref_type;
731  typedef typename boost::remove_reference<ref_type>::type val_type;
732  typedef PairSecond<val_type> PS;
733  return boost::transform_iterator<PS, Iter>(i, PS());
734  }
735 
736 
765  template<typename Pointer, class Compare>
766  compose_f_gx_hy<Compare, Dereferencer<Pointer>, Dereferencer<Pointer> >
767  make_ptr_compare(Pointer p, Compare compare)
768  {
769  return make_compose_f_gx_hy(compare, Dereferencer<Pointer>(),
771  }
772 
779  template<typename Pointer>
780  compose_f_gx_hy<std::less<typename std::iterator_traits<Pointer>::value_type>,
781  Dereferencer<Pointer>, Dereferencer<Pointer> >
782  make_ptr_compare(Pointer p)
783  {
784  typedef typename std::iterator_traits<Pointer>::value_type value_type;
785  BOOST_CONCEPT_ASSERT((boost::LessThanComparable<value_type>));
786  std::less<value_type> compare;
787  return make_ptr_compare(p, compare);
788  }
789 
790 
794  std::string& to_lower(std::string& s);
795 
799  std::string& to_upper(std::string& s);
800 
801 
802  // template implementations
803 
804  template <typename Key, typename Tp, typename Compare, typename Alloc>
805  const Tp& get(const std::map<Key, Tp, Compare, Alloc>& m, const Key& key)
806  {
807  typename std::map<Key, Tp, Compare,Alloc>::const_iterator iter(m.find(key));
808  if (iter==m.end()) {
809  std::stringstream ss;
810  ss << "utility::get(const Map&, const Key&): `"
811  << key << "' not found in map\n";
812  throw runtime_error(ss.str());
813  }
814  return iter->second;
815  }
816 
817 }}} // of namespace utility, yat, and theplu
818 #endif

Generated on Mon Nov 11 2013 09:41:44 for yat by  doxygen 1.8.1