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

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

adding functions inverse

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.3 KB
Line 
1#ifndef _theplu_yat_utility_stl_utility_
2#define _theplu_yat_utility_stl_utility_
3
4// $Id: stl_utility.h 1385 2008-07-22 17:32:53Z 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 <algorithm>
39#include <cmath>
40#include <functional>
41#include <map>
42#include <ostream>
43#include <string>
44#include <utility>
45#include <vector>
46
47// debug
48#include <iostream>
49
50namespace std {
51
52  ///
53  /// Print out a pair
54  ///
55  // This is in namespace std because we have not figured out how to have
56  // pair and its operator<< in different namespaces
57  template <class T1, class T2> 
58  std::ostream& operator<<(std::ostream& out, const std::pair<T1,T2>& p) 
59  { out << p.first << "\t" << p.second; return out; }
60
61}
62
63namespace theplu {
64namespace yat {
65namespace utility {
66
67  /**
68     Functor class taking absolute value
69  */
70  template<typename T>
71  struct abs : std::unary_function<T, T>
72  {
73    /**
74       \return absolute value
75     */
76    inline T operator()(T x) const
77    { return std::abs(x); }
78  };
79
80  /**
81     See The C++ Standard Library - A Tutorial and Reference by
82     Nicolai M. Josuttis
83
84     If f is a binary functor, both g and h are unary functors, and
85     return type of g (and h) is convertible to F's argument type,
86     then compose_f_gx_hy can be used to create a functor equivalent
87     to \f$ f(g(x), h(y)) \f$
88   */
89  template<class F, class G, class H>
90  class compose_f_gx_hy
91  {
92  public:
93    /**
94       \brief Constructor
95     */
96    compose_f_gx_hy(F f, G g, H h)
97      : f_(f), g_(g), h_(h) {}
98
99    /**
100       \brief Does the work
101     */
102    bool
103    operator()(double x, 
104               double y) const
105    {
106      return f_(g_(x), h_(y));
107    }
108
109  private:
110    F f_;
111    G g_;
112    H h_;
113  };
114
115  /**
116     Convenient function to create a compose_f_gx_hy.
117
118     \see std::make_pair
119  */
120  template<class F, class G, class H>
121  compose_f_gx_hy<F, G, H> make_compose_f_gx_hy(F f, G g, H h)
122  {
123    return compose_f_gx_hy<F,G,H>(f,g,h);
124  } 
125
126  /**
127     Functor class to exponentiate values using std::exp
128
129     \since New in yat 0.5
130  */
131  template<typename T>
132  struct Exp : std::unary_function<T, T>
133  {
134    /**
135       \return exponentiated value
136     */
137    inline T operator()(T x) const
138    { return std::exp(x); }
139  };
140
141  /**
142     Creating a map from a range [first, last) such that m[key]
143     returns a vector with indices of which element in [first, last)
144     that is equal to \a key, or more technically: m[element].size()
145     returns number of elements equal to \a element, and
146     m[*element][i] = distance(first, element) for every \a element in
147     [first, last) and \a i smaller than m[element].size().
148
149     Requirement: InputIterator's value type is assignable to Key
150
151     \since New in yat 0.5
152   */
153  template<typename InputIterator, typename Key>
154  void inverse(InputIterator first, InputIterator last,
155               std::map<Key, std::vector<size_t> >& m)
156  {
157    m.clear();
158    for (size_t i=0; first!=last; ++i, ++first)
159      m[*first].push_back(i);
160  }
161
162  /**
163     In the created multimap each element e will fulfill: \f$ *(first
164     + e->second) == e->first \f$
165
166     Requirement: InputIterator's value type is assignable to Key
167
168     \since New in yat 0.5
169   */
170  template<typename Key, typename InputIterator>
171  void inverse(InputIterator first, InputIterator last, 
172               std::multimap<Key, size_t>& m)
173  {
174    m.clear();
175    for (size_t i=0; first!=last; ++i, ++first)
176      m.insert(std::make_pair(*first, i));
177  }
178
179
180  /**
181     Functor class to take logarithm
182
183     \since New in yat 0.5
184  */
185  template<typename T>
186  class Log : std::unary_function<T, T>
187  {
188  public:
189    /**
190       Default constructor using natural base \f$ e \f$
191     */
192    Log(void)
193      : log_base_(1.0) {}
194
195    /**
196       \param base Taking logarithm in which base, e.g. 2 or 10.
197    */
198    explicit Log(double base) : log_base_(std::log(base)) {}
199
200    /**
201       \return logarithm
202     */
203    inline T operator()(T x) const
204    { return std::log(x)/log_base_; }
205
206  private:
207    double log_base_;
208  };
209
210  /**
211     \return max of values
212   */
213  template <typename T>
214  T max(const T& a, const T& b, const T& c)
215  {
216    return std::max(std::max(a,b),c);
217  }
218
219
220  /**
221     \return max of values
222   */
223  template <typename T>
224  T max(const T& a, const T& b, const T& c, const T& d)
225  {
226    return std::max(std::max(a,b), std::max(c,d));
227  }
228
229
230  /**
231     \return max of values
232   */
233  template <typename T>
234  T max(const T& a, const T& b, const T& c, const T& d, const T& e)
235  {
236    return std::max(max(a,b,c,d), e);
237  }
238
239
240  /**
241     \return max of values
242   */
243  template <typename T>
244  T max(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f)
245  {
246    return std::max(max(a,b,c,d), std::max(e,f));
247  }
248
249
250  ///
251  /// @brief Functor comparing pairs using second.
252  ///
253  /// STL provides operator< for the pair.first element, but none for
254  /// pair.second. This template provides this and can be used as the
255  /// comparison object in generic functions such as the STL sort.
256  ///
257  template <class T1,class T2>
258  struct pair_value_compare
259  {
260    ///
261    /// @return true if x.second<y.second or (x.second==y.second and
262    /// x.first<y.first)
263    ///
264    inline bool operator()(const std::pair<T1,T2>& x,
265                           const std::pair<T1,T2>& y) {
266      return ((x.second<y.second) ||
267              (!(y.second<x.second) && (x.first<y.first))); 
268    }
269  };
270
271  ///
272  /// @brief Function converting a string to lower case
273  ///
274  std::string& to_lower(std::string& s);
275
276  ///
277  /// @brief Function converting a string to upper case
278  ///
279  std::string& to_upper(std::string& s);
280
281}}} // of namespace utility, yat, and theplu
282
283#endif
Note: See TracBrowser for help on using the repository browser.