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

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

improve docs

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