]> git.lyx.org Git - lyx.git/blob - src/support/lyxfunctional.h
small changes + patch from Dekel
[lyx.git] / src / support / lyxfunctional.h
1 // -*- C++ -*-
2
3 #ifndef LYX_FUNCTIONAL_H
4 #define LYX_FUNCTIONAL_H
5
6 /** \file lyxfunctional.h
7     \brief Convenient function objects for use with LyX
8     This is currently a small collection of small function objects for use
9     together with std::algorithms.
10 **/
11
12 #include <iterator>
13
14 //namespace lyx {
15
16
17 template<class R, class C, class A>
18 class class_fun_t {
19 public:
20         class_fun_t(C & ct, R(C::*p)(A)) 
21                 : c(ct), cmf(p) {}
22         R operator()(A & a) const {
23                 return (c.*cmf)(a);
24         }
25 private:
26         C & c;
27         R(C::*cmf)(A);
28 };
29
30
31 template<class C, class A>
32 class void_class_fun_t {
33 public:
34         void_class_fun_t(C & ct, void(C::*p)(A))
35                 : c(ct), cmf(p) {}
36         void operator()(A & a) const {
37                 (c.*cmf)(a);
38         }
39 private:
40         C & c;
41         void(C::*cmf)(A);
42 };
43
44
45 /// Use to call a class method with a container element.
46 /** Most easily used as a functor to std::algoritms.
47     Small example:
48     \verbatim
49     A a; // class that have a int print(string const &) method
50     vector<string> vs;
51     for_each(vs.begin(), vs.end(), class_fun(int, vs, &A::print);
52     \endverbatim
53 **/
54 template <class R, class C, class A> class_fun_t<R, C, A>
55 class_fun(C & c, R(C::*f)(A))
56 {
57         return class_fun_t<R, C, A>(c, f);
58 }
59
60
61 template <class C, class A> void_class_fun_t<C, A>
62 class_fun(C & c, void(C::*f)(A))
63 {
64         return void_class_fun_t<C, A>(c, f);
65 }
66
67
68 template <class Cont, class Type, class MemRet>
69 class back_insert_fun_iterator {
70 protected:
71         Cont * container;
72         MemRet(Type::*pmf)();
73 public:
74         typedef Cont container_type;
75         typedef std::output_iterator_tag iterator_category;
76         typedef void value_type;
77         typedef void difference_type;
78         typedef void pointer;
79         typedef void reference;
80        
81         back_insert_fun_iterator(Cont & x, MemRet(Type::*p)())
82                 : container(&x), pmf(p) {}
83
84         back_insert_fun_iterator &
85         operator=(Type * val) {
86                 container->push_back((val->*pmf)());
87                 return *this;
88         }
89
90         back_insert_fun_iterator &
91         operator=(Type & val) {
92                 container->push_back((val.*pmf)());
93                 return *this;
94         }
95
96         back_insert_fun_iterator & operator*() {
97                 return *this;
98         }
99         back_insert_fun_iterator & operator++() { // prefix ++
100                 return *this;
101         }
102         back_insert_fun_iterator & operator++(int) { // postfix ++
103                 return *this;
104         }
105 };
106
107
108 template <class Cont, class Type, class MemRet>
109 class const_back_insert_fun_iterator {
110 protected:
111         Cont * container;
112         MemRet(Type::*pmf)() const;
113 public:
114         typedef Cont container_type;
115         typedef std::output_iterator_tag iterator_category;
116         typedef void value_type;
117         typedef void difference_type;
118         typedef void pointer;
119         typedef void reference;
120         
121         const_back_insert_fun_iterator(Cont & x, MemRet(Type::*p)() const)
122                 : container(&x), pmf(p) {}
123         
124         ~const_back_insert_fun_iterator() {}
125       
126         const_back_insert_fun_iterator &
127         operator=(Type const * val) {
128                 container->push_back((val->*pmf)());
129                 return *this;
130         }
131
132         const_back_insert_fun_iterator &
133         operator=(Type const & val) {
134                 container->push_back((val.*pmf)());
135                 return *this;
136         }
137
138         const_back_insert_fun_iterator & operator*() {
139                 return *this;
140         }
141         const_back_insert_fun_iterator & operator++() { // prefix ++
142                 return *this;
143         }
144         const_back_insert_fun_iterator & operator++(int) { // postfix ++
145                 return *this;
146         }
147 };
148
149
150 template <class Cont, class Type, class MemRet>
151 back_insert_fun_iterator<Cont, Type, MemRet>
152 back_inserter_fun(Cont & cont, MemRet(Type::*p)())
153 {
154         return back_insert_fun_iterator<Cont, Type, MemRet>(cont, p);
155 }
156
157
158 template <class Cont, class Type, class MemRet>
159 const_back_insert_fun_iterator<Cont, Type, MemRet>
160 back_inserter_fun(Cont & cont, MemRet(Type::*p)() const)
161 {
162         return const_back_insert_fun_iterator<Cont, Type, MemRet>(cont, p);
163 }
164
165
166 template <class R, class C, class A>
167 class compare_memfun_t {
168 public:
169         compare_memfun_t(R(C::*p)(), A const & a)
170                 : pmf(p), arg(a) {}
171         bool operator()(C * c) {
172                 return (c->*pmf)() == arg;
173         }
174         bool operator()(C & c) {
175                 return (c.*pmf)() == arg;
176         }
177 private:
178         R(C::*pmf)();
179         A const & arg;
180 };
181
182
183 template <class R, class C, class A>
184 class const_compare_memfun_t {
185 public:
186         const_compare_memfun_t(R(C::*p)() const, A const & a)
187                 : pmf(p), arg(a) {}
188         bool operator()(C const * c) {
189                 return (c->*pmf)() == arg;
190         }
191         bool operator()(C const & c) {
192                 return (c.*pmf)() == arg;
193         }
194 private:
195         R(C::*pmf)() const;
196         A const & arg;
197 };
198
199
200 template <class R, class C, class A>
201 compare_memfun_t<R, C, A>
202 compare_memfun(R(C::*p)(), A const & a)
203 {
204         return compare_memfun_t<R, C, A>(p, a);
205 }
206
207
208 template <class R, class C, class A>
209 const_compare_memfun_t<R, C, A>
210 compare_memfun(R(C::*p)() const, A const & a)
211 {
212         return const_compare_memfun_t<R, C, A>(p, a);
213 }
214
215         
216 // Functors used in the template.
217
218 ///
219 template<typename T1, typename T2>
220 class equal_1st_in_pair {
221 public:
222         ///
223         equal_1st_in_pair(T1 const & value) : value_(value) {}
224         ///
225         typedef std::pair<T1, T2> pair_type;
226         ///
227         bool operator() (pair_type const & p) const {
228                 return p.first == value_;
229         }
230 private:
231         ///
232         T1 const & value_;
233 };
234
235
236 ///
237 template<typename T1, typename T2>
238 class equal_2nd_in_pair {
239 public:
240         ///
241         equal_2nd_in_pair(T2 const & value) : value_(value) {}
242         ///
243         typedef std::pair<T1, T2> pair_type;
244         ///
245         bool operator() (pair_type const & p) const {
246                 return p.second == value_;
247         }
248 private:
249         ///
250         T2 const & value_;
251 };
252
253
254 // }  // end of namespace lyx
255 #endif