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

Last change on this file since 1399 was 1399, checked in by Peter, 13 years ago

refs #369 added a function to create a boost::transform_iterator that was mentioned in ticket:369 - should probably add the corresponding for pair::second too.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.0 KB
Line 
1#ifndef _theplu_yat_utility_stl_utility_
2#define _theplu_yat_utility_stl_utility_
3
4// $Id: stl_utility.h 1399 2008-08-06 22:52:39Z 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, 2007 Jari Häkkinen, Peter Johansson
10  Copyright (C) 2008 Peter Johansson
11
12  This file is part of the yat library, http://trac.thep.lu.se/yat
13
14  The yat library is free software; you can redistribute it and/or
15  modify it under the terms of the GNU General Public License as
16  published by the Free Software Foundation; either version 2 of the
17  License, or (at your option) any later version.
18
19  The yat library is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22  General Public License for more details.
23
24  You should have received a copy of the GNU General Public License
25  along with this program; if not, write to the Free Software
26  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27  02111-1307, USA.
28*/
29
30///
31/// \file stl_utility.h
32///
33/// There are a number of useful functionality missing in the Standard
34/// Template Library, STL. This file is an effort to provide
35/// extensions to STL functionality.
36///
37
38#include <boost/iterator/transform_iterator.hpp>
39#include <boost/mpl/if.hpp>
40#include <boost/type_traits/is_const.hpp>
41#include <boost/type_traits/add_const.hpp>
42
43#include <algorithm>
44#include <cmath>
45#include <functional>
46#include <map>
47#include <ostream>
48#include <string>
49#include <utility>
50#include <vector>
51
52namespace std {
53
54  ///
55  /// Print out a pair
56  ///
57  // This is in namespace std because we have not figured out how to have
58  // pair and its operator<< in different namespaces
59  template <class T1, class T2> 
60  std::ostream& operator<<(std::ostream& out, const std::pair<T1,T2>& p) 
61  { out << p.first << "\t" << p.second; return out; }
62
63}
64
65namespace theplu {
66namespace yat {
67namespace utility {
68
69  /**
70     Functor class taking absolute value
71  */
72  template<typename T>
73  struct abs : std::unary_function<T, T>
74  {
75    /**
76       \return absolute value
77     */
78    inline T operator()(T x) const
79    { return std::abs(x); }
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     Creates a transform_iterator that transforms an iterator with
309     value type std::pair to an iterator with value type
310     std::pair::first_type. This can be used, for example, to
311     communicate between a std::map and std::vector
312
313     \code
314     std::map<std::string, int> map;
315     ...
316     std::vector<std::string> vec;
317     vec.resize(map.size());
318     std::copy(pair_first_iterator(map.begin()), pair_first_iterator(map.end()),
319               vec.begin());
320     \endcode
321
322     \since New in yat 0.5
323   */
324  template<class Iter>
325  boost::transform_iterator<
326    PairFirst<typename std::iterator_traits<Iter>::value_type>, 
327    Iter> pair_first_iterator(Iter i)
328  {
329    typedef PairFirst<typename std::iterator_traits<Iter>::value_type> PF; 
330    return boost::transform_iterator<PF, Iter>(i, PF());
331  }
332
333
334
335
336  ///
337  /// @brief Function converting a string to lower case
338  ///
339  std::string& to_lower(std::string& s);
340
341  ///
342  /// @brief Function converting a string to upper case
343  ///
344  std::string& to_upper(std::string& s);
345
346}}} // of namespace utility, yat, and theplu
347
348#endif
Note: See TracBrowser for help on using the repository browser.