source: trunk/yat/utility/stl_utility.h @ 1789

Last change on this file since 1789 was 1789, checked in by Peter, 12 years ago

Speeding up copying from Matrix to MatrixWeighted? using
BinaryWeight?. Moving BinaryWeight? from stl_utility.h to
utility.h. Improved docs in MatrixWeighted?.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.4 KB
Line 
1#ifndef _theplu_yat_utility_stl_utility_
2#define _theplu_yat_utility_stl_utility_
3
4// $Id: stl_utility.h 1789 2009-02-10 16:11:04Z 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 Jari Häkkinen, Peter Johansson
11  Copyright (C) 2008 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
29///
30/// \file stl_utility.h
31///
32/// There are a number of useful functionality missing in the Standard
33/// Template Library, STL. This file is an effort to provide
34/// extensions to STL functionality.
35///
36
37#include <boost/iterator/transform_iterator.hpp>
38#include <boost/mpl/if.hpp>
39#include <boost/type_traits/is_const.hpp>
40#include <boost/type_traits/add_const.hpp>
41
42#include <algorithm>
43#include <cmath>
44#include <functional>
45#include <map>
46#include <ostream>
47#include <string>
48#include <utility>
49#include <vector>
50
51namespace std {
52
53  ///
54  /// Print out a pair
55  ///
56  // This is in namespace std because we have not figured out how to have
57  // pair and its operator<< in different namespaces
58  template <class T1, class T2> 
59  std::ostream& operator<<(std::ostream& out, const std::pair<T1,T2>& p) 
60  { out << p.first << "\t" << p.second; return out; }
61
62}
63
64namespace theplu {
65namespace yat {
66namespace utility {
67
68  /**
69     Functor class taking absolute value
70  */
71  template<typename T>
72  struct abs : std::unary_function<T, T>
73  {
74    /**
75       \return absolute value
76     */
77    inline T operator()(T x) const
78    { return std::abs(x); }
79  };
80
81
82  /**
83     See The C++ Standard Library - A Tutorial and Reference by
84     Nicolai M. Josuttis
85
86     If f is a binary functor, both g and h are unary functors, and
87     return type of g (and h) is convertible to F's argument type,
88     then compose_f_gx_hy can be used to create a functor equivalent
89     to \f$ f(g(x), h(y)) \f$
90   */
91  template<class F, class G, class H>
92  class compose_f_gx_hy
93  {
94  public:
95    /**
96       \brief Constructor
97     */
98    compose_f_gx_hy(F f, G g, H h)
99      : f_(f), g_(g), h_(h) {}
100
101    /**
102       \brief Does the work
103     */
104    bool
105    operator()(double x, 
106               double y) const
107    {
108      return f_(g_(x), h_(y));
109    }
110
111  private:
112    F f_;
113    G g_;
114    H h_;
115  };
116
117  /**
118     Convenient function to create a compose_f_gx_hy.
119
120     \see std::make_pair
121  */
122  template<class F, class G, class H>
123  compose_f_gx_hy<F, G, H> make_compose_f_gx_hy(F f, G g, H h)
124  {
125    return compose_f_gx_hy<F,G,H>(f,g,h);
126  } 
127
128  /**
129     Functor class to exponentiate values using std::exp
130
131     \since New in yat 0.5
132  */
133  template<typename T>
134  struct Exp : std::unary_function<T, T>
135  {
136    /**
137       \return exponentiated value
138     */
139    inline T operator()(T x) const
140    { return std::exp(x); }
141  };
142
143  /**
144     Creating a map from a range [first, last) such that m[key]
145     returns a vector with indices of which element in [first, last)
146     that is equal to \a key, or more technically: m[element].size()
147     returns number of elements equal to \a element, and
148     m[*element][i] = distance(first, element) for every \a element in
149     [first, last) and \a i smaller than m[element].size().
150
151     Requirement: InputIterator's value type is assignable to Key
152
153     \since New in yat 0.5
154   */
155  template<typename InputIterator, typename Key>
156  void inverse(InputIterator first, InputIterator last,
157               std::map<Key, std::vector<size_t> >& m)
158  {
159    m.clear();
160    for (size_t i=0; first!=last; ++i, ++first)
161      m[*first].push_back(i);
162  }
163
164  /**
165     In the created multimap each element e will fulfill: \f$ *(first
166     + e->second) == e->first \f$
167
168     Requirement: InputIterator's value type is assignable to Key
169
170     \since New in yat 0.5
171   */
172  template<typename Key, typename InputIterator>
173  void inverse(InputIterator first, InputIterator last, 
174               std::multimap<Key, size_t>& m)
175  {
176    m.clear();
177    for (size_t i=0; first!=last; ++i, ++first)
178      m.insert(std::make_pair(*first, i));
179  }
180
181
182  /**
183     Functor class to take logarithm
184
185     \since New in yat 0.5
186  */
187  template<typename T>
188  class Log : std::unary_function<T, T>
189  {
190  public:
191    /**
192       Default constructor using natural base \f$ e \f$
193     */
194    Log(void)
195      : log_base_(1.0) {}
196
197    /**
198       \param base Taking logarithm in which base, e.g. 2 or 10.
199    */
200    explicit Log(double base) : log_base_(std::log(base)) {}
201
202    /**
203       \return logarithm
204     */
205    inline T operator()(T x) const
206    { return std::log(x)/log_base_; }
207
208  private:
209    double log_base_;
210  };
211
212  /**
213     \return max of values
214   */
215  template <typename T>
216  T max(const T& a, const T& b, const T& c)
217  {
218    return std::max(std::max(a,b),c);
219  }
220
221
222  /**
223     \return max of values
224   */
225  template <typename T>
226  T max(const T& a, const T& b, const T& c, const T& d)
227  {
228    return std::max(std::max(a,b), std::max(c,d));
229  }
230
231
232  /**
233     \return max of values
234   */
235  template <typename T>
236  T max(const T& a, const T& b, const T& c, const T& d, const T& e)
237  {
238    return std::max(max(a,b,c,d), e);
239  }
240
241
242  /**
243     \return max of values
244   */
245  template <typename T>
246  T max(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f)
247  {
248    return std::max(max(a,b,c,d), std::max(e,f));
249  }
250
251
252  ///
253  /// @brief Functor comparing pairs using second.
254  ///
255  /// STL provides operator< for the pair.first element, but none for
256  /// pair.second. This template provides this and can be used as the
257  /// comparison object in generic functions such as the STL sort.
258  ///
259  template <class T1,class T2>
260  struct pair_value_compare
261  {
262    ///
263    /// @return true if x.second<y.second or (x.second==y.second and
264    /// x.first<y.first)
265    ///
266    inline bool operator()(const std::pair<T1,T2>& x,
267                           const std::pair<T1,T2>& y) {
268      return ((x.second<y.second) ||
269              (!(y.second<x.second) && (x.first<y.first))); 
270    }
271  };
272
273  /**
274     \brief Functor that return std::pair.first
275
276     \see pair_first_iterator
277
278     \since New in yat 0.5
279   */
280  template <class Pair>
281  struct PairFirst
282  {
283    /**
284       The type returned is Pair::first_type& with the exception when
285       Pair is const and Pair::first_type is non-const, in which case
286       const Pair::first_type& is return type.
287     */
288    typedef typename boost::mpl::if_<
289                  typename boost::is_const<Pair>::type, 
290                  typename boost::add_const<typename Pair::first_type>::type&,
291                  typename Pair::first_type&>::type result_type;
292   
293    /**
294       The argument type is Pair&.
295     */
296    typedef Pair& argument_type;
297
298    /**
299       \return p.first
300     */
301    inline result_type operator()(argument_type p) const
302    { return p.first; }
303
304  };
305
306
307  /**
308     \brief Functor that return std::pair.second
309
310     \see pair_second_iterator
311
312     \since New in yat 0.5
313   */
314  template <class Pair>
315  struct PairSecond
316  {
317    /**
318       The type returned is Pair::second_type& with the exception when
319       Pair is const and Pair::second_type is non-const, in which case
320       const Pair::first_type& is return type.
321     */
322    typedef typename boost::mpl::if_<
323                  typename boost::is_const<Pair>::type, 
324                  typename boost::add_const<typename Pair::second_type>::type&,
325                  typename Pair::second_type&>::type result_type;
326   
327    /**
328       The argument type is Pair&.
329     */
330    typedef Pair& argument_type;
331
332    /**
333       \return p.first
334     */
335    inline result_type operator()(argument_type p) const
336    { return p.second; }
337
338  };
339
340
341  /**
342     Creates a transform_iterator that transforms an iterator with
343     value type std::pair to an iterator with value type
344     std::pair::first_type. This can be used, for example, to
345     communicate between a std::map and std::vector
346
347     \code
348     std::map<std::string, int> map;
349     ...
350     std::vector<std::string> vec;
351     vec.resize(map.size());
352     std::copy(pair_first_iterator(map.begin()), pair_first_iterator(map.end()),
353               vec.begin());
354     \endcode
355
356     \since New in yat 0.5
357   */
358  template<class Iter>
359  boost::transform_iterator<
360    PairFirst<typename std::iterator_traits<Iter>::value_type>, 
361    Iter> pair_first_iterator(Iter i)
362  {
363    typedef PairFirst<typename std::iterator_traits<Iter>::value_type> PF; 
364    return boost::transform_iterator<PF, Iter>(i, PF());
365  }
366
367
368  /**
369     Creates a transform_iterator that transforms an iterator with
370     value type std::pair to an iterator with value type
371     std::pair::second_type. This can be used, for example, to
372     communicate between a std::map and std::vector
373
374     \code
375     std::map<std::string, int> map;
376     ...
377     std::vector<int> vec(map.size(),0);
378     std::copy(vec.begin(), vec.end(), pair_second_iterator(map.begin()));
379     \endcode
380
381     \since New in yat 0.5
382   */
383  template<class Iter>
384  boost::transform_iterator<
385    PairSecond<typename std::iterator_traits<Iter>::value_type>, 
386    Iter> pair_second_iterator(Iter i)
387  {
388    typedef PairSecond<typename std::iterator_traits<Iter>::value_type> PF; 
389    return boost::transform_iterator<PF, Iter>(i, PF());
390  }
391
392
393
394
395  ///
396  /// @brief Function converting a string to lower case
397  ///
398  std::string& to_lower(std::string& s);
399
400  ///
401  /// @brief Function converting a string to upper case
402  ///
403  std::string& to_upper(std::string& s);
404
405}}} // of namespace utility, yat, and theplu
406
407#endif
Note: See TracBrowser for help on using the repository browser.