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

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

avoid extra newlines

  • 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 3083 2013-09-19 01:22:29Z 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, and return
372     types of g and h are convertible to F's argument type, then
373     compose_f_gx_hx can be used to create a functor equivalent to \f$
374     f(g(x), h(x)) \f$
375
376     - F must be an <a
377     href="http://www.sgi.com/tech/stl/AdaptableBinaryFunction.html">
378     AdaptableBinaryFunction</a>
379     - G must be an <a
380     href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">
381     AdaptableUnaryFunction</a>
382     - H must be an <a
383     href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">
384     AdaptableUnaryFunction</a>
385     - \c G::result_type is convertible to \c F::first_argument_type
386     - \c H::result_type is convertible to \c F::second_argument_type
387
388     \see compose_f_gx_hy, compose_f_gxy, and compose_f_gx
389
390     \see <a href="http://www.sgi.com/tech/stl/binary_compose.html">
391     binary_compose</a> (SGI extension)
392
393     \since New in yat 0.11
394   */
395  template<class F, class G, class H>
396  class compose_f_gx_hx : public std::unary_function<typename G::argument_type,
397                                                     typename F::result_type>
398  {
399  public:
400    /**
401       \brief default constructor
402
403       Requires that F, G, and H have default constructors
404    */
405    compose_f_gx_hx(void) {}
406
407    /**
408       \brief Constructor
409     */
410    compose_f_gx_hx(F f, G g, H h)
411      : f_(f), g_(g), h_(h)
412    {
413      BOOST_CONCEPT_ASSERT((boost::Convertible<typename G::result_type
414                            , typename F::first_argument_type>));
415      BOOST_CONCEPT_ASSERT((boost::Convertible<typename H::result_type
416                            , typename F::second_argument_type>));
417    }
418
419    /**
420       \brief Does the work
421     */
422    typename F::result_type operator()(typename G::argument_type x) const
423    {
424      return f_(g_(x), h_(x));
425    }
426
427  private:
428    F f_;
429    G g_;
430    H h_;
431  };
432
433  /**
434     Convenient function to create a compose_f_gx_hx.
435
436     \relates compose_f_gx_hx
437
438     \see std::make_pair
439
440     \since New in yat 0.11
441  */
442  template<class F, class G, class H>
443  compose_f_gx_hx<F, G, H> make_compose_f_gx_hx(F f, G g, H h)
444  {
445    return compose_f_gx_hx<F,G,H>(f,g,h);
446  }
447
448
449  /**
450     Functor class to exponentiate values using std::exp
451
452     T should be either \c float, \c double, or \c long \c double
453
454     \since New in yat 0.5
455  */
456  template<typename T>
457  struct Exp : std::unary_function<T, T>
458  {
459    /**
460       \return exponentiated value
461     */
462    inline T operator()(T x) const
463    { return std::exp(x); }
464  };
465
466  /**
467     \brief Identity functor that returns its argument
468
469     \since New in yat 0.7
470   */
471  template<typename T>
472  struct Identity : public std::unary_function<T, T>
473  {
474    /// \return \a arg
475    T operator()(T arg) const { return arg; }
476  };
477
478
479  /**
480     Same functionality as map::operator[] but the function does not
481     modify the map and the function throws if key does not exist in
482     the map.
483
484     \return const reference to m[k]
485
486     \since New in yat 0.7
487   */
488  template <typename Key, typename Tp, typename Compare, typename Alloc>
489  const Tp& get(const std::map<Key, Tp, Compare, Alloc>& m, const Key& k);
490
491
492  /**
493     Creating a map from a range [first, last) such that m[key]
494     returns a vector with indices of which element in [first, last)
495     that is equal to \a key, or more technically: m[element].size()
496     returns number of elements equal to \a element, and
497     m[*element][i] = distance(first, element) for every \a element in
498     [first, last) and \a i smaller than m[element].size().
499
500     Requirement: InputIterator's value type is assignable to Key
501
502     \since New in yat 0.5
503   */
504  template<typename InputIterator, typename Key, typename Comp>
505  void inverse(InputIterator first, InputIterator last,
506               std::map<Key, std::vector<size_t>, Comp >& m)
507  {
508    BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
509    BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
510    m.clear();
511    for (size_t i=0; first!=last; ++i, ++first)
512      m[*first].push_back(i);
513  }
514
515  /**
516     In the created multimap each element e will fulfill: \f$ *(first
517     + e->second) == e->first \f$
518
519     Requirement: InputIterator's value type is assignable to Key
520
521     \since New in yat 0.5
522   */
523  template<typename Key, typename InputIterator, typename Comp>
524  void inverse(InputIterator first, InputIterator last,
525               std::multimap<Key, size_t, Comp>& m)
526  {
527    BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
528    BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
529    m.clear();
530    for (size_t i=0; first!=last; ++i, ++first)
531      m.insert(std::make_pair(*first, i));
532  }
533
534
535  /**
536     Create a map mapping from values in range [first, last) to the
537     distance from first.
538
539     Post-condition: m[first[i]] == i (for all i that correspond to a
540     unique element). For non-unique element behaviour is undefined.
541
542     Requirement: InputIterator's value type is assignable to Key
543
544     \since New in yat 0.10
545   */
546  template<typename InputIterator, typename Key, typename Comp>
547  void inverse(InputIterator first, InputIterator last,
548               std::map<Key, size_t, Comp >& m)
549  {
550    BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
551    BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
552    m.clear();
553    for (size_t i=0; first!=last; ++i, ++first)
554      m[*first] = i;
555  }
556
557  /**
558     \brief Functor that behaves like std::less with the exception
559     that it treates NaN as a number larger than infinity.
560
561     This functor is useful when sorting ranges with NaNs. The problem
562     with NaNs is that std::less always returns \c false when one of
563     the arguments is NaN. That together with the fact that std::sort
564     only guarantees that an element \c i is never less than previous
565     element \c --i. Therefore {10, NaN, 2} is sorted according to
566     this definition, but most often it is desired that the 2 is
567     located before the 10 in the range. Using this functor, less_nan,
568     this can easily be achieved as std::sort(first, last, less_nan)
569
570     The default implementation uses std::isnan(T), which consequently
571     must be supported.
572
573     There is a specialization less_nan<DataWeight>
574
575     \since New in yat 0.6
576  */
577  template<typename T>
578  struct less_nan : std::binary_function<T, T, bool>
579  {
580    /**
581       \return \c true if x is less than y. NaNs are treated as a number
582       larger than infinity, which implies \c true is returned if y is
583       NaN and x is not.
584     */
585    inline bool operator()(T x, T y) const
586    {
587      if (std::isnan(x))
588        return false;
589      if (std::isnan(y))
590        return true;
591      return x<y;
592    }
593  };
594
595
596  /**
597     \brief Specialization for DataWeight.
598   */
599  template<>
600  struct less_nan<DataWeight>
601    : std::binary_function<DataWeight, DataWeight, bool>
602  {
603    /**
604       \return less_nan<double>(x.data(), y.data())
605     */
606    inline bool operator()(const DataWeight& x, const DataWeight& y) const
607    {
608      less_nan<double> compare;
609      return compare(x.data(), y.data());
610    }
611  };
612
613
614  /**
615     Functor class to take logarithm
616
617     T should be either \c float, \c double, or \c long \c double
618
619     \since New in yat 0.5
620  */
621  template<typename T>
622  class Log : std::unary_function<T, T>
623  {
624  public:
625    /**
626       Default constructor using natural base \f$ e \f$
627     */
628    Log(void)
629      : log_base_(1.0) {}
630
631    /**
632       \param base Taking logarithm in which base, e.g. 2 or 10.
633    */
634    explicit Log(double base) : log_base_(std::log(base)) {}
635
636    /**
637       \return logarithm
638     */
639    inline T operator()(T x) const
640    { return std::log(x)/log_base_; }
641
642  private:
643    double log_base_;
644  };
645
646  /**
647     \return max of values
648   */
649  template <typename T>
650  T max(const T& a, const T& b, const T& c)
651  {
652    return std::max(std::max(a,b),c);
653  }
654
655
656  /**
657     \return max of values
658   */
659  template <typename T>
660  T max(const T& a, const T& b, const T& c, const T& d)
661  {
662    return std::max(std::max(a,b), std::max(c,d));
663  }
664
665
666  /**
667     \return max of values
668   */
669  template <typename T>
670  T max(const T& a, const T& b, const T& c, const T& d, const T& e)
671  {
672    return std::max(max(a,b,c,d), e);
673  }
674
675
676  /**
677     \return max of values
678   */
679  template <typename T>
680  T max(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f)
681  {
682    return std::max(max(a,b,c,d), std::max(e,f));
683  }
684
685
686  ///
687  /// @brief Functor comparing pairs using second.
688  ///
689  /// STL provides operator< for the pair.first element, but none for
690  /// pair.second. This template provides this and can be used as the
691  /// comparison object in generic functions such as the STL sort.
692  ///
693  template <class T1,class T2>
694  struct pair_value_compare
695  {
696    ///
697    /// @return true if x.second<y.second or (!(y.second<y.second) and
698    /// x.first<y.first)
699    ///
700    inline bool operator()(const std::pair<T1,T2>& x,
701                           const std::pair<T1,T2>& y) {
702      return ((x.second<y.second) ||
703              (!(y.second<x.second) && (x.first<y.first)));
704    }
705  };
706
707  /**
708     \brief Functor that return std::pair.first
709
710     \see pair_first_iterator
711
712     \since New in yat 0.5
713   */
714  template <class Pair>
715  struct PairFirst
716  {
717    /**
718       The type returned is Pair::first_type& with the exception when
719       Pair is const and Pair::first_type is non-const, in which case
720       const Pair::first_type& is return type.
721     */
722    typedef typename boost::mpl::if_<
723                  typename boost::is_const<Pair>::type,
724                  typename boost::add_const<typename Pair::first_type>::type&,
725                  typename Pair::first_type&>::type result_type;
726
727    /**
728       The argument type is Pair&.
729     */
730    typedef Pair& argument_type;
731
732    /**
733       \return p.first
734     */
735    inline result_type operator()(argument_type p) const
736    { return p.first; }
737
738  };
739
740
741  /**
742     \brief Functor that return std::pair.second
743
744     \see pair_second_iterator
745
746     \since New in yat 0.5
747   */
748  template <class Pair>
749  struct PairSecond
750  {
751    /**
752       The type returned is Pair::second_type& with the exception when
753       Pair is const and Pair::second_type is non-const, in which case
754       const Pair::first_type& is return type.
755     */
756    typedef typename boost::mpl::if_<
757                  typename boost::is_const<Pair>::type,
758                  typename boost::add_const<typename Pair::second_type>::type&,
759                  typename Pair::second_type&>::type result_type;
760
761    /**
762       The argument type is Pair&.
763     */
764    typedef Pair& argument_type;
765
766    /**
767       \return p.first
768     */
769    inline result_type operator()(argument_type p) const
770    { return p.second; }
771
772  };
773
774
775  /**
776     Creates a transform_iterator that transforms an iterator with
777     value type std::pair to an iterator with value type
778     std::pair::first_type. This can be used, for example, to
779     communicate between a std::map and std::vector
780
781     \code
782     std::map<std::string, int> map;
783     ...
784     std::vector<std::string> vec;
785     vec.resize(map.size());
786     std::copy(pair_first_iterator(map.begin()), pair_first_iterator(map.end()),
787               vec.begin());
788     \endcode
789
790     \since New in yat 0.5
791   */
792  template<class Iter>
793  boost::transform_iterator<
794    PairFirst<typename boost::remove_reference<
795                 typename std::iterator_traits<Iter>::reference
796                 >::type>,
797    Iter> pair_first_iterator(Iter i)
798  {
799    // We are going via ::reference in order to remain const info;
800    // ::value_type does not contain const information.
801    typedef typename std::iterator_traits<Iter>::reference ref_type;
802    typedef typename boost::remove_reference<ref_type>::type val_type;
803    typedef PairFirst<val_type> PF;
804    return boost::transform_iterator<PF, Iter>(i, PF());
805  }
806
807
808  /**
809     Creates a transform_iterator that transforms an iterator with
810     value type std::pair to an iterator with value type
811     std::pair::second_type. This can be used, for example, to
812     communicate between a std::map and std::vector
813
814     \code
815     std::map<std::string, int> map;
816     ...
817     std::vector<int> vec(map.size(),0);
818     std::copy(vec.begin(), vec.end(), pair_second_iterator(map.begin()));
819     \endcode
820
821     \since New in yat 0.5
822   */
823  template<class Iter>
824  boost::transform_iterator<
825    PairSecond<typename boost::remove_reference<
826                 typename std::iterator_traits<Iter>::reference
827                 >::type>,
828    Iter> pair_second_iterator(Iter i)
829  {
830    // We are going via ::reference in order to remain const info;
831    // ::value_type does not contain const information.
832    typedef typename std::iterator_traits<Iter>::reference ref_type;
833    typedef typename boost::remove_reference<ref_type>::type val_type;
834    typedef PairSecond<val_type> PS;
835    return boost::transform_iterator<PS, Iter>(i, PS());
836  }
837
838
839  /**
840     Convenient function that creates a binary predicate that can be
841     used to compare pointers when you want to compare them with
842     respect to the objects they point to.
843
844     Example:
845     \code
846     std::vector<MyClass*> vec(18);
847     ...
848     std::sort(vec.begin(), vec.end(),
849               make_ptr_compare(vec[0], std::greater<MyClass>());
850     \endcode
851
852
853     Type Requirement:
854     - \a compare must be a <a
855     href="http://www.sgi.com/tech/stl/AdaptableBinaryPredicate.html">Adaptable
856     Binary Predicate</a>.
857     - value_type of Pointer must be convertible to argument_type of
858       compare
859
860     \return a compose_f_gx_hy in which \c F is defined by \a compare
861     and both \c G and \c H are \c Dereferencer functors.
862
863     \see compose_f_gx_hy
864
865     \since New in yat 0.7
866   */
867  template<typename Pointer, class Compare>
868  compose_f_gx_hy<Compare, Dereferencer<Pointer>, Dereferencer<Pointer> >
869  make_ptr_compare(Pointer p, Compare compare)
870  {
871    return make_compose_f_gx_hy(compare, Dereferencer<Pointer>(),
872                                Dereferencer<Pointer>());
873  }
874
875  /**
876     Same as make_ptr_compare(2) except that std::less is used to
877     compare pointers.
878
879     \since New in yat 0.7
880   */
881  template<typename Pointer>
882  compose_f_gx_hy<std::less<typename std::iterator_traits<Pointer>::value_type>,
883                  Dereferencer<Pointer>, Dereferencer<Pointer> >
884  make_ptr_compare(Pointer p)
885  {
886    typedef typename std::iterator_traits<Pointer>::value_type value_type;
887    BOOST_CONCEPT_ASSERT((boost::LessThanComparable<value_type>));
888    std::less<value_type> compare;
889    return make_ptr_compare(p, compare);
890  }
891
892
893  ///
894  /// @brief Function converting a string to lower case
895  ///
896  std::string& to_lower(std::string& s);
897
898  ///
899  /// @brief Function converting a string to upper case
900  ///
901  std::string& to_upper(std::string& s);
902
903
904  // template implementations
905
906  template <typename Key, typename Tp, typename Compare, typename Alloc>
907  const Tp& get(const std::map<Key, Tp, Compare, Alloc>& m, const Key& key)
908  {
909    typename std::map<Key, Tp, Compare,Alloc>::const_iterator iter(m.find(key));
910    if (iter==m.end()) {
911      std::stringstream ss;
912      ss << "utility::get(const Map&, const Key&): '"
913         << key << "' not found in map\n";
914      throw runtime_error(ss.str());
915    }
916    return iter->second;
917  }
918
919}}} // of namespace utility, yat, and theplu
920#endif
Note: See TracBrowser for help on using the repository browser.