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

Last change on this file since 3082 was 3082, checked in by Peter, 8 years ago

new compose functor: compose_f_gx_hx

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.3 KB
Line 
1#ifndef _theplu_yat_utility_stl_utility_
2#define _theplu_yat_utility_stl_utility_
3
4// $Id: stl_utility.h 3082 2013-09-18 23:54:15Z 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
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 "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
64namespace std {
65
66  ///
67  /// Print out a pair
68  ///
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
78namespace theplu {
79namespace yat {
80namespace utility {
81
82  /**
83     Functor class taking absolute value
84  */
85  template<typename T>
86  struct abs : std::unary_function<T, T>
87  {
88    /**
89       \return absolute value
90     */
91    inline T operator()(T x) const
92    { return std::abs(x); }
93  };
94
95
96  /**
97     \brief Adaptor between pointer and pointee interface
98
99     Functor takes a pointer and returns a reference to the instance
100     pointer is pointing to. Return type is decided by <a
101     href=http://www.sgi.com/tech/stl/iterator_traits.html>
102     std::iterator_traits<Pointer>::reference </a>. Pointer must have
103     an \c operator*, i.e., \c Pointer can be a traditional pointer or
104     an \input_iterator.
105
106     The class is designed to be used with boost::transform_iterator
107
108     \code
109     std::vector<MyClass*> vec;
110     ...
111     Dereferencer<MyClass*> dereferencer;
112     std::set<MyClass> s;
113     s.insert(boost::make_transform_iterator(vec.begin(), dereferencer),
114              boost::make_transform_iterator(vec.end(), dereferencer))
115     \endcode
116
117     where elements in vec<MyClass*> are copied in to set<MyClass>.
118
119     \since New in yat 0.7
120   */
121  template<typename Pointer>
122  struct Dereferencer :
123    public std::unary_function<Pointer,
124                               typename std::iterator_traits<Pointer>::reference>
125  {
126    /**
127       \brief constructor
128     */
129    Dereferencer(void)
130    { BOOST_CONCEPT_ASSERT((TrivialIterator<Pointer>)); }
131
132    /**
133       \return * \a ti
134     */
135    typename std::iterator_traits<Pointer>::reference
136    operator()(Pointer ti) const { return *ti; }
137  };
138
139
140  /**
141     See The C++ Standard Library - A Tutorial and Reference by
142     Nicolai M. Josuttis
143
144     If f is a binary functor, both g and h are unary functors, and
145     return type of g (and h) is convertible to F's argument type,
146     then compose_f_gx_hy can be used to create a functor equivalent
147     to \f$ f(g(x), h(y)) \f$
148
149     - F must be an <a
150     href="http://www.sgi.com/tech/stl/AdaptableBinaryFunction.html">
151     AdaptableBinaryFunction</a>
152     - G must be an <a
153     href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">
154     AdaptableUnaryFunction</a>
155     - H must be an <a
156     href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">
157     AdaptableUnaryFunction</a>
158     - \c G::result_type is convertible to \c F::first_argument_type
159     - \c H::result_type is convertible to \c F::second_argument_type
160
161     \see compose_f_gxy, compose_f_gx, and compose_f_gx_hx
162   */
163  template<class F, class G, class H>
164  class compose_f_gx_hy :
165    public std::binary_function<typename G::argument_type,
166                                typename H::argument_type,
167                                typename F::result_type>
168  {
169  public:
170    /**
171       \brief default constructor
172
173       Requires that F, G, and H have default constructors
174    */
175    compose_f_gx_hy(void) {}
176
177    /**
178       \brief Constructor
179     */
180    compose_f_gx_hy(F f, G g, H h)
181      : f_(f), g_(g), h_(h)
182    {
183      BOOST_CONCEPT_ASSERT((boost::Convertible<typename G::result_type
184                            , typename F::first_argument_type>));
185      BOOST_CONCEPT_ASSERT((boost::Convertible<typename H::result_type
186                            , typename F::second_argument_type>));
187
188    }
189
190    /**
191       \brief Does the work
192     */
193    typename F::result_type
194    operator()(typename G::argument_type x,
195               typename H::argument_type y) const
196    {
197      return f_(g_(x), h_(y));
198    }
199
200  private:
201    F f_;
202    G g_;
203    H h_;
204  };
205
206  /**
207     Convenient function to create a compose_f_gx_hy.
208
209     \relates compose_f_gx_hy
210
211     \see std::make_pair
212  */
213  template<class F, class G, class H>
214  compose_f_gx_hy<F, G, H> make_compose_f_gx_hy(F f, G g, H h)
215  {
216    return compose_f_gx_hy<F,G,H>(f,g,h);
217  }
218
219
220  /**
221     See The C++ Standard Library - A Tutorial and Reference by
222     Nicolai M. Josuttis
223
224     If f is a unary functor, g is a binary functor, and return type
225     of g is convertible to F's argument type, then
226     compose_f_gxy can be used to create a functor equivalent to
227     \f$ f(g(x,y)) \f$
228
229     - F must be an <a
230     href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">
231     AdaptableUnaryFunction</a>
232     - G must be an <a
233     href="http://www.sgi.com/tech/stl/AdaptableBinaryFunction.html">
234     AdaptableBinaryFunction</a>
235     - \c G::result_type is convertible to \c F::argument_type
236
237     \see compose_f_gx_hy, compose_f_gx, and compose_f_gx_hx
238
239     \since New in yat 0.7
240   */
241  template<class F, class G>
242  class compose_f_gxy :
243    public std::binary_function<typename G::first_argument_type,
244                                typename G::second_argument_type,
245                                typename F::result_type>
246  {
247  public:
248    /**
249       \brief default constructor
250
251       Requires that F, G, and H have default constructors
252    */
253    compose_f_gxy(void) {}
254
255    /**
256       \brief Constructor
257     */
258    compose_f_gxy(F f, G g)
259      : f_(f), g_(g)
260    {
261      BOOST_CONCEPT_ASSERT((boost::Convertible<typename G::result_type
262                            , typename F::argument_type>));
263    }
264
265    /**
266       \brief Does the work
267     */
268    typename F::result_type
269    operator()(typename G::first_argument_type x,
270               typename G::second_argument_type y) const
271    {
272      return f_(g_(x,y));
273    }
274
275  private:
276    F f_;
277    G g_;
278  };
279
280  /**
281     Convenient function to create a compose_f_gxy.
282
283     \relates compose_f_gxy
284
285     \see std::make_pair
286
287     \since New in yat 0.7
288  */
289  template<class F, class G>
290  compose_f_gxy<F, G> make_compose_f_gxy(F f, G g)
291  {
292    return compose_f_gxy<F,G>(f,g);
293  }
294
295
296  /**
297     See The C++ Standard Library - A Tutorial and Reference by
298     Nicolai M. Josuttis
299
300     If f is a unary functor, g is a unary functor, and return type of
301     g is convertible to F's argument type, then compose_f_gx can be
302     used to create a functor equivalent to \f$ f(g(x)) \f$
303
304     - F must be an <a
305     href="http://www.sgi.com/tech/stl/AdaptableBinaryFunction.html">
306     AdaptableBinaryFunction</a>
307     - G must be an <a
308     href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">
309     AdaptableUnaryFunction</a>
310     - \c G::result_type is convertible to \c F::argument_type
311
312     \see compose_f_gx_hy, compose_f_gxy, and compose_f_gx_hx
313
314     \see <a href="http://www.sgi.com/tech/stl/unary_compose.html">
315     unary_compose</a> (SGI extension)
316
317     \since New in yat 0.7
318   */
319  template<class F, class G>
320  class compose_f_gx : public std::unary_function<typename G::argument_type,
321                                                  typename F::result_type>
322  {
323  public:
324    /**
325       \brief default constructor
326
327       Requires that F and G have default constructors
328    */
329    compose_f_gx(void) {}
330
331    /**
332       \brief Constructor
333     */
334    compose_f_gx(F f, G g)
335      : f_(f), g_(g)
336    {
337      BOOST_CONCEPT_ASSERT((boost::Convertible<typename G::result_type
338                            , typename F::argument_type>));
339    }
340
341    /**
342       \brief Does the work
343     */
344    typename F::result_type
345    operator()(typename G::argument_type x) const
346    {
347      return f_(g_(x));
348    }
349
350  private:
351    F f_;
352    G g_;
353  };
354
355  /**
356     Convenient function to create a compose_f_gx.
357
358     \relates compose_f_gx
359
360     \see std::make_pair
361
362     \since New in yat 0.7
363  */
364  template<class F, class G>
365  compose_f_gx<F, G> make_compose_f_gx(F f, G g)
366  {
367    return compose_f_gx<F,G>(f,g);
368  }
369
370
371  /**
372     If f is a binary functor, g and h a unary functors, and return
373     types of g and h are convertible to F's argument type, then
374     compose_f_gx_hx can be used to create a functor equivalent to \f$
375     f(g(x), h(x)) \f$
376
377     - F must be an <a
378     href="http://www.sgi.com/tech/stl/AdaptableBinaryFunction.html">
379     AdaptableBinaryFunction</a>
380     - G must be an <a
381     href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">
382     AdaptableUnaryFunction</a>
383     - H must be an <a
384     href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">
385     AdaptableUnaryFunction</a>
386     - \c G::result_type is convertible to \c F::first_argument_type
387     - \c H::result_type is convertible to \c F::second_argument_type
388
389     \see compose_f_gx_hy, compose_f_gxy, and compose_f_gx
390
391     \see <a href="http://www.sgi.com/tech/stl/binary_compose.html">
392     binary_compose</a> (SGI extension)
393
394     \since New in yat 0.11
395   */
396  template<class F, class G, class H>
397  class compose_f_gx_hx : public std::unary_function<typename G::argument_type,
398                                                     typename F::result_type>
399  {
400  public:
401    /**
402       \brief default constructor
403
404       Requires that F, G, and H have default constructors
405    */
406    compose_f_gx_hx(void) {}
407
408    /**
409       \brief Constructor
410     */
411    compose_f_gx_hx(F f, G g, H h)
412      : f_(f), g_(g), h_(h)
413    {
414      BOOST_CONCEPT_ASSERT((boost::Convertible<typename G::result_type
415                            , typename F::first_argument_type>));
416      BOOST_CONCEPT_ASSERT((boost::Convertible<typename H::result_type
417                            , typename F::second_argument_type>));
418    }
419
420    /**
421       \brief Does the work
422     */
423    typename F::result_type
424    operator()(typename G::argument_type x) const
425    {
426      return f_(g_(x), h_(x));
427    }
428
429  private:
430    F f_;
431    G g_;
432    H h_;
433  };
434
435  /**
436     Convenient function to create a compose_f_gx_hx.
437
438     \relates compose_f_gx_hx
439
440     \see std::make_pair
441
442     \since New in yat 0.11
443  */
444  template<class F, class G, class H>
445  compose_f_gx_hx<F, G, H> make_compose_f_gx_hx(F f, G g, H h)
446  {
447    return compose_f_gx_hx<F,G,H>(f,g,h);
448  }
449
450
451  /**
452     Functor class to exponentiate values using std::exp
453
454     T should be either \c float, \c double, or \c long \c double
455
456     \since New in yat 0.5
457  */
458  template<typename T>
459  struct Exp : std::unary_function<T, T>
460  {
461    /**
462       \return exponentiated value
463     */
464    inline T operator()(T x) const
465    { return std::exp(x); }
466  };
467
468  /**
469     \brief Identity functor that returns its argument
470
471     \since New in yat 0.7
472   */
473  template<typename T>
474  struct Identity : public std::unary_function<T, T>
475  {
476    /// \return \a arg
477    T operator()(T arg) const { return arg; }
478  };
479
480
481  /**
482     Same functionality as map::operator[] but the function does not
483     modify the map and the function throws if key does not exist in
484     the map.
485
486     \return const reference to m[k]
487
488     \since New in yat 0.7
489   */
490  template <typename Key, typename Tp, typename Compare, typename Alloc>
491  const Tp& get(const std::map<Key, Tp, Compare, Alloc>& m, const Key& k);
492
493
494  /**
495     Creating a map from a range [first, last) such that m[key]
496     returns a vector with indices of which element in [first, last)
497     that is equal to \a key, or more technically: m[element].size()
498     returns number of elements equal to \a element, and
499     m[*element][i] = distance(first, element) for every \a element in
500     [first, last) and \a i smaller than m[element].size().
501
502     Requirement: InputIterator's value type is assignable to Key
503
504     \since New in yat 0.5
505   */
506  template<typename InputIterator, typename Key, typename Comp>
507  void inverse(InputIterator first, InputIterator last,
508               std::map<Key, std::vector<size_t>, Comp >& m)
509  {
510    BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
511    BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
512    m.clear();
513    for (size_t i=0; first!=last; ++i, ++first)
514      m[*first].push_back(i);
515  }
516
517  /**
518     In the created multimap each element e will fulfill: \f$ *(first
519     + e->second) == e->first \f$
520
521     Requirement: InputIterator's value type is assignable to Key
522
523     \since New in yat 0.5
524   */
525  template<typename Key, typename InputIterator, typename Comp>
526  void inverse(InputIterator first, InputIterator last,
527               std::multimap<Key, size_t, Comp>& m)
528  {
529    BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
530    BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
531    m.clear();
532    for (size_t i=0; first!=last; ++i, ++first)
533      m.insert(std::make_pair(*first, i));
534  }
535
536
537  /**
538     Create a map mapping from values in range [first, last) to the
539     distance from first.
540
541     Post-condition: m[first[i]] == i (for all i that correspond to a
542     unique element). For non-unique element behaviour is undefined.
543
544     Requirement: InputIterator's value type is assignable to Key
545
546     \since New in yat 0.10
547   */
548  template<typename InputIterator, typename Key, typename Comp>
549  void inverse(InputIterator first, InputIterator last,
550               std::map<Key, size_t, Comp >& m)
551  {
552    BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
553    BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
554    m.clear();
555    for (size_t i=0; first!=last; ++i, ++first)
556      m[*first] = i;
557  }
558
559  /**
560     \brief Functor that behaves like std::less with the exception
561     that it treates NaN as a number larger than infinity.
562
563     This functor is useful when sorting ranges with NaNs. The problem
564     with NaNs is that std::less always returns \c false when one of
565     the arguments is NaN. That together with the fact that std::sort
566     only guarantees that an element \c i is never less than previous
567     element \c --i. Therefore {10, NaN, 2} is sorted according to
568     this definition, but most often it is desired that the 2 is
569     located before the 10 in the range. Using this functor, less_nan,
570     this can easily be achieved as std::sort(first, last, less_nan)
571
572     The default implementation uses std::isnan(T), which consequently
573     must be supported.
574
575     There is a specialization less_nan<DataWeight>
576
577     \since New in yat 0.6
578  */
579  template<typename T>
580  struct less_nan : std::binary_function<T, T, bool>
581  {
582    /**
583       \return \c true if x is less than y. NaNs are treated as a number
584       larger than infinity, which implies \c true is returned if y is
585       NaN and x is not.
586     */
587    inline bool operator()(T x, T y) const
588    {
589      if (std::isnan(x))
590        return false;
591      if (std::isnan(y))
592        return true;
593      return x<y;
594    }
595  };
596
597
598  /**
599     \brief Specialization for DataWeight.
600   */
601  template<>
602  struct less_nan<DataWeight>
603    : std::binary_function<DataWeight, DataWeight, bool>
604  {
605    /**
606       \return less_nan<double>(x.data(), y.data())
607     */
608    inline bool operator()(const DataWeight& x, const DataWeight& y) const
609    {
610      less_nan<double> compare;
611      return compare(x.data(), y.data());
612    }
613  };
614
615
616  /**
617     Functor class to take logarithm
618
619     T should be either \c float, \c double, or \c long \c double
620
621     \since New in yat 0.5
622  */
623  template<typename T>
624  class Log : std::unary_function<T, T>
625  {
626  public:
627    /**
628       Default constructor using natural base \f$ e \f$
629     */
630    Log(void)
631      : log_base_(1.0) {}
632
633    /**
634       \param base Taking logarithm in which base, e.g. 2 or 10.
635    */
636    explicit Log(double base) : log_base_(std::log(base)) {}
637
638    /**
639       \return logarithm
640     */
641    inline T operator()(T x) const
642    { return std::log(x)/log_base_; }
643
644  private:
645    double log_base_;
646  };
647
648  /**
649     \return max of values
650   */
651  template <typename T>
652  T max(const T& a, const T& b, const T& c)
653  {
654    return std::max(std::max(a,b),c);
655  }
656
657
658  /**
659     \return max of values
660   */
661  template <typename T>
662  T max(const T& a, const T& b, const T& c, const T& d)
663  {
664    return std::max(std::max(a,b), std::max(c,d));
665  }
666
667
668  /**
669     \return max of values
670   */
671  template <typename T>
672  T max(const T& a, const T& b, const T& c, const T& d, const T& e)
673  {
674    return std::max(max(a,b,c,d), e);
675  }
676
677
678  /**
679     \return max of values
680   */
681  template <typename T>
682  T max(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f)
683  {
684    return std::max(max(a,b,c,d), std::max(e,f));
685  }
686
687
688  ///
689  /// @brief Functor comparing pairs using second.
690  ///
691  /// STL provides operator< for the pair.first element, but none for
692  /// pair.second. This template provides this and can be used as the
693  /// comparison object in generic functions such as the STL sort.
694  ///
695  template <class T1,class T2>
696  struct pair_value_compare
697  {
698    ///
699    /// @return true if x.second<y.second or (!(y.second<y.second) and
700    /// x.first<y.first)
701    ///
702    inline bool operator()(const std::pair<T1,T2>& x,
703                           const std::pair<T1,T2>& y) {
704      return ((x.second<y.second) ||
705              (!(y.second<x.second) && (x.first<y.first)));
706    }
707  };
708
709  /**
710     \brief Functor that return std::pair.first
711
712     \see pair_first_iterator
713
714     \since New in yat 0.5
715   */
716  template <class Pair>
717  struct PairFirst
718  {
719    /**
720       The type returned is Pair::first_type& with the exception when
721       Pair is const and Pair::first_type is non-const, in which case
722       const Pair::first_type& is return type.
723     */
724    typedef typename boost::mpl::if_<
725                  typename boost::is_const<Pair>::type,
726                  typename boost::add_const<typename Pair::first_type>::type&,
727                  typename Pair::first_type&>::type result_type;
728
729    /**
730       The argument type is Pair&.
731     */
732    typedef Pair& argument_type;
733
734    /**
735       \return p.first
736     */
737    inline result_type operator()(argument_type p) const
738    { return p.first; }
739
740  };
741
742
743  /**
744     \brief Functor that return std::pair.second
745
746     \see pair_second_iterator
747
748     \since New in yat 0.5
749   */
750  template <class Pair>
751  struct PairSecond
752  {
753    /**
754       The type returned is Pair::second_type& with the exception when
755       Pair is const and Pair::second_type is non-const, in which case
756       const Pair::first_type& is return type.
757     */
758    typedef typename boost::mpl::if_<
759                  typename boost::is_const<Pair>::type,
760                  typename boost::add_const<typename Pair::second_type>::type&,
761                  typename Pair::second_type&>::type result_type;
762
763    /**
764       The argument type is Pair&.
765     */
766    typedef Pair& argument_type;
767
768    /**
769       \return p.first
770     */
771    inline result_type operator()(argument_type p) const
772    { return p.second; }
773
774  };
775
776
777  /**
778     Creates a transform_iterator that transforms an iterator with
779     value type std::pair to an iterator with value type
780     std::pair::first_type. This can be used, for example, to
781     communicate between a std::map and std::vector
782
783     \code
784     std::map<std::string, int> map;
785     ...
786     std::vector<std::string> vec;
787     vec.resize(map.size());
788     std::copy(pair_first_iterator(map.begin()), pair_first_iterator(map.end()),
789               vec.begin());
790     \endcode
791
792     \since New in yat 0.5
793   */
794  template<class Iter>
795  boost::transform_iterator<
796    PairFirst<typename boost::remove_reference<
797                 typename std::iterator_traits<Iter>::reference
798                 >::type>,
799    Iter> pair_first_iterator(Iter i)
800  {
801    // We are going via ::reference in order to remain const info;
802    // ::value_type does not contain const information.
803    typedef typename std::iterator_traits<Iter>::reference ref_type;
804    typedef typename boost::remove_reference<ref_type>::type val_type;
805    typedef PairFirst<val_type> PF;
806    return boost::transform_iterator<PF, Iter>(i, PF());
807  }
808
809
810  /**
811     Creates a transform_iterator that transforms an iterator with
812     value type std::pair to an iterator with value type
813     std::pair::second_type. This can be used, for example, to
814     communicate between a std::map and std::vector
815
816     \code
817     std::map<std::string, int> map;
818     ...
819     std::vector<int> vec(map.size(),0);
820     std::copy(vec.begin(), vec.end(), pair_second_iterator(map.begin()));
821     \endcode
822
823     \since New in yat 0.5
824   */
825  template<class Iter>
826  boost::transform_iterator<
827    PairSecond<typename boost::remove_reference<
828                 typename std::iterator_traits<Iter>::reference
829                 >::type>,
830    Iter> pair_second_iterator(Iter i)
831  {
832    // We are going via ::reference in order to remain const info;
833    // ::value_type does not contain const information.
834    typedef typename std::iterator_traits<Iter>::reference ref_type;
835    typedef typename boost::remove_reference<ref_type>::type val_type;
836    typedef PairSecond<val_type> PS;
837    return boost::transform_iterator<PS, Iter>(i, PS());
838  }
839
840
841  /**
842     Convenient function that creates a binary predicate that can be
843     used to compare pointers when you want to compare them with
844     respect to the objects they point to.
845
846     Example:
847     \code
848     std::vector<MyClass*> vec(18);
849     ...
850     std::sort(vec.begin(), vec.end(),
851               make_ptr_compare(vec[0], std::greater<MyClass>());
852     \endcode
853
854
855     Type Requirement:
856     - \a compare must be a <a
857     href="http://www.sgi.com/tech/stl/AdaptableBinaryPredicate.html">Adaptable
858     Binary Predicate</a>.
859     - value_type of Pointer must be convertible to argument_type of
860       compare
861
862     \return a compose_f_gx_hy in which \c F is defined by \a compare
863     and both \c G and \c H are \c Dereferencer functors.
864
865     \see compose_f_gx_hy
866
867     \since New in yat 0.7
868   */
869  template<typename Pointer, class Compare>
870  compose_f_gx_hy<Compare, Dereferencer<Pointer>, Dereferencer<Pointer> >
871  make_ptr_compare(Pointer p, Compare compare)
872  {
873    return make_compose_f_gx_hy(compare, Dereferencer<Pointer>(),
874                                Dereferencer<Pointer>());
875  }
876
877  /**
878     Same as make_ptr_compare(2) except that std::less is used to
879     compare pointers.
880
881     \since New in yat 0.7
882   */
883  template<typename Pointer>
884  compose_f_gx_hy<std::less<typename std::iterator_traits<Pointer>::value_type>,
885                  Dereferencer<Pointer>, Dereferencer<Pointer> >
886  make_ptr_compare(Pointer p)
887  {
888    typedef typename std::iterator_traits<Pointer>::value_type value_type;
889    BOOST_CONCEPT_ASSERT((boost::LessThanComparable<value_type>));
890    std::less<value_type> compare;
891    return make_ptr_compare(p, compare);
892  }
893
894
895  ///
896  /// @brief Function converting a string to lower case
897  ///
898  std::string& to_lower(std::string& s);
899
900  ///
901  /// @brief Function converting a string to upper case
902  ///
903  std::string& to_upper(std::string& s);
904
905
906  // template implementations
907
908  template <typename Key, typename Tp, typename Compare, typename Alloc>
909  const Tp& get(const std::map<Key, Tp, Compare, Alloc>& m, const Key& key)
910  {
911    typename std::map<Key, Tp, Compare,Alloc>::const_iterator iter(m.find(key));
912    if (iter==m.end()) {
913      std::stringstream ss;
914      ss << "utility::get(const Map&, const Key&): '"
915         << key << "' not found in map\n";
916      throw runtime_error(ss.str());
917    }
918    return iter->second;
919  }
920
921}}} // of namespace utility, yat, and theplu
922#endif
Note: See TracBrowser for help on using the repository browser.