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

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

updating copyright statements

  • 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 1797 2009-02-12 18:07:10Z 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 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.