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