source: NonGTP/Boost/boost/lambda/detail/member_ptr.hpp @ 857

Revision 857, 26.5 KB checked in by igarcia, 19 years ago (diff)
RevLine 
[857]1// Boost Lambda Library -- member_ptr.hpp ---------------------
2
3// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
4// Copyright (C) 2000 Gary Powell (gary.powell@sierra.com)
5//
6// Distributed under the Boost Software License, Version 1.0. (See
7// accompanying file LICENSE_1_0.txt or copy at
8// http://www.boost.org/LICENSE_1_0.txt)
9//
10// For more information, see www.boost.org
11
12// --------------------------------------------------------------------------
13
14#if !defined(BOOST_LAMBDA_MEMBER_PTR_HPP)
15#define BOOST_LAMBDA_MEMBER_PTR_HPP
16
17namespace boost {
18namespace lambda {
19
20
21class member_pointer_action {};
22
23
24namespace detail {
25
26// the boost type_traits member_pointer traits are not enough,
27// need to know more details.
28template<class T>
29struct member_pointer {
30  typedef typename boost::add_reference<T>::type type;
31  typedef detail::unspecified class_type;
32  typedef detail::unspecified qualified_class_type;
33  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
34  BOOST_STATIC_CONSTANT(bool, is_function_member = false);
35};
36
37template<class T, class U>
38struct member_pointer<T U::*> {
39  typedef typename boost::add_reference<T>::type type;
40  typedef U class_type;
41  typedef U qualified_class_type;
42  BOOST_STATIC_CONSTANT(bool, is_data_member = true);
43  BOOST_STATIC_CONSTANT(bool, is_function_member = false);
44};
45
46template<class T, class U>
47struct member_pointer<const T U::*> {
48  typedef typename boost::add_reference<const T>::type type;
49  typedef U class_type;
50  typedef const U qualified_class_type;
51  BOOST_STATIC_CONSTANT(bool, is_data_member = true);
52  BOOST_STATIC_CONSTANT(bool, is_function_member = false);
53};
54
55template<class T, class U>
56struct member_pointer<volatile T U::*> {
57  typedef typename boost::add_reference<volatile T>::type type;
58  typedef U class_type;
59  typedef volatile U qualified_class_type;
60  BOOST_STATIC_CONSTANT(bool, is_data_member = true);
61  BOOST_STATIC_CONSTANT(bool, is_function_member = false);
62};
63
64template<class T, class U>
65struct member_pointer<const volatile T U::*> {
66  typedef typename boost::add_reference<const volatile T>::type type;
67  typedef U class_type;
68  typedef const volatile U qualified_class_type;
69  BOOST_STATIC_CONSTANT(bool, is_data_member = true);
70  BOOST_STATIC_CONSTANT(bool, is_function_member = false);
71};
72
73// -- nonconst member functions --
74template<class T, class U>
75struct member_pointer<T (U::*)()> {
76  typedef T type;
77  typedef U class_type;
78  typedef U qualified_class_type;
79  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
80  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
81};
82template<class T, class U, class A1>
83struct member_pointer<T (U::*)(A1)> {
84  typedef T type;
85  typedef U class_type;
86  typedef U qualified_class_type;
87  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
88  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
89};
90template<class T, class U, class A1, class A2>
91struct member_pointer<T (U::*)(A1, A2)> {
92  typedef T type;
93  typedef U class_type;
94  typedef U qualified_class_type;
95  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
96  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
97};
98template<class T, class U, class A1, class A2, class A3>
99struct member_pointer<T (U::*)(A1, A2, A3)> {
100  typedef T type;
101  typedef U class_type;
102  typedef U qualified_class_type;
103  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
104  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
105};
106template<class T, class U, class A1, class A2, class A3, class A4>
107struct member_pointer<T (U::*)(A1, A2, A3, A4)> {
108  typedef T type;
109  typedef U class_type;
110  typedef U qualified_class_type;
111  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
112  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
113};
114template<class T, class U, class A1, class A2, class A3, class A4, class A5>
115struct member_pointer<T (U::*)(A1, A2, A3, A4, A5)> {
116  typedef T type;
117  typedef U class_type;
118  typedef U qualified_class_type;
119  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
120  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
121};
122template<class T, class U, class A1, class A2, class A3, class A4, class A5,
123         class A6>
124struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6)> {
125  typedef T type;
126  typedef U class_type;
127  typedef U qualified_class_type;
128  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
129  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
130};
131template<class T, class U, class A1, class A2, class A3, class A4, class A5,
132         class A6, class A7>
133struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7)> {
134  typedef T type;
135  typedef U class_type;
136  typedef U qualified_class_type;
137  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
138  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
139};
140template<class T, class U, class A1, class A2, class A3, class A4, class A5,
141         class A6, class A7, class A8>
142struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8)> {
143  typedef T type;
144  typedef U class_type;
145  typedef U qualified_class_type;
146  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
147  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
148};
149template<class T, class U, class A1, class A2, class A3, class A4, class A5,
150         class A6, class A7, class A8, class A9>
151struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
152  typedef T type;
153  typedef U class_type;
154  typedef U qualified_class_type;
155  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
156  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
157};
158// -- const member functions --
159template<class T, class U>
160struct member_pointer<T (U::*)() const> {
161  typedef T type;
162  typedef U class_type;
163  typedef const U qualified_class_type;
164  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
165  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
166};
167template<class T, class U, class A1>
168struct member_pointer<T (U::*)(A1) const> {
169  typedef T type;
170  typedef U class_type;
171  typedef const U qualified_class_type;
172  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
173  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
174};
175template<class T, class U, class A1, class A2>
176struct member_pointer<T (U::*)(A1, A2) const> {
177  typedef T type;
178  typedef U class_type;
179  typedef const U qualified_class_type;
180  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
181  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
182};
183template<class T, class U, class A1, class A2, class A3>
184struct member_pointer<T (U::*)(A1, A2, A3) const> {
185  typedef T type;
186  typedef U class_type;
187  typedef const U qualified_class_type;
188  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
189  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
190};
191template<class T, class U, class A1, class A2, class A3, class A4>
192struct member_pointer<T (U::*)(A1, A2, A3, A4) const> {
193  typedef T type;
194  typedef U class_type;
195  typedef const U qualified_class_type;
196  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
197  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
198};
199template<class T, class U, class A1, class A2, class A3, class A4, class A5>
200struct member_pointer<T (U::*)(A1, A2, A3, A4, A5) const> {
201  typedef T type;
202  typedef U class_type;
203  typedef const U qualified_class_type;
204  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
205  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
206};
207template<class T, class U, class A1, class A2, class A3, class A4, class A5,
208         class A6>
209struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6) const> {
210  typedef T type;
211  typedef U class_type;
212  typedef const U qualified_class_type;
213  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
214  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
215};
216template<class T, class U, class A1, class A2, class A3, class A4, class A5,
217         class A6, class A7>
218struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7) const> {
219  typedef T type;
220  typedef U class_type;
221  typedef const U qualified_class_type;
222  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
223  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
224};
225template<class T, class U, class A1, class A2, class A3, class A4, class A5,
226         class A6, class A7, class A8>
227struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8) const> {
228  typedef T type;
229  typedef U class_type;
230  typedef const U qualified_class_type;
231  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
232  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
233};
234template<class T, class U, class A1, class A2, class A3, class A4, class A5,
235         class A6, class A7, class A8, class A9>
236struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const> {
237  typedef T type;
238  typedef U class_type;
239  typedef const U qualified_class_type;
240  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
241  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
242};
243  // -- volatile --
244template<class T, class U>
245struct member_pointer<T (U::*)() volatile> {
246  typedef T type;
247  typedef U class_type;
248  typedef volatile U qualified_class_type;
249  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
250  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
251};
252template<class T, class U, class A1>
253struct member_pointer<T (U::*)(A1) volatile> {
254  typedef T type;
255  typedef U class_type;
256  typedef volatile U qualified_class_type;
257  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
258  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
259};
260template<class T, class U, class A1, class A2>
261struct member_pointer<T (U::*)(A1, A2) volatile> {
262  typedef T type;
263  typedef U class_type;
264  typedef volatile U qualified_class_type;
265  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
266  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
267};
268template<class T, class U, class A1, class A2, class A3>
269struct member_pointer<T (U::*)(A1, A2, A3) volatile> {
270  typedef T type;
271  typedef U class_type;
272  typedef volatile U qualified_class_type;
273  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
274  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
275};
276template<class T, class U, class A1, class A2, class A3, class A4>
277struct member_pointer<T (U::*)(A1, A2, A3, A4) volatile> {
278  typedef T type;
279  typedef U class_type;
280  typedef volatile U qualified_class_type;
281  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
282  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
283};
284template<class T, class U, class A1, class A2, class A3, class A4, class A5>
285struct member_pointer<T (U::*)(A1, A2, A3, A4, A5) volatile> {
286  typedef T type;
287  typedef U class_type;
288  typedef volatile U qualified_class_type;
289  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
290  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
291};
292template<class T, class U, class A1, class A2, class A3, class A4, class A5,
293         class A6>
294struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6) volatile> {
295  typedef T type;
296  typedef U class_type;
297  typedef volatile U qualified_class_type;
298  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
299  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
300};
301template<class T, class U, class A1, class A2, class A3, class A4, class A5,
302         class A6, class A7>
303struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7) volatile> {
304  typedef T type;
305  typedef U class_type;
306  typedef volatile U qualified_class_type;
307  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
308  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
309};
310template<class T, class U, class A1, class A2, class A3, class A4, class A5,
311         class A6, class A7, class A8>
312struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8) volatile> {
313  typedef T type;
314  typedef U class_type;
315  typedef volatile U qualified_class_type;
316  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
317  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
318};
319template<class T, class U, class A1, class A2, class A3, class A4, class A5,
320         class A6, class A7, class A8, class A9>
321struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) volatile> {
322  typedef T type;
323  typedef U class_type;
324  typedef volatile U qualified_class_type;
325  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
326  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
327};
328  // -- const volatile
329template<class T, class U>
330struct member_pointer<T (U::*)() const volatile> {
331  typedef T type;
332  typedef U class_type;
333  typedef const volatile U qualified_class_type;
334  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
335  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
336};
337template<class T, class U, class A1>
338struct member_pointer<T (U::*)(A1) const volatile> {
339  typedef T type;
340  typedef U class_type;
341  typedef const volatile U qualified_class_type;
342  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
343  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
344};
345template<class T, class U, class A1, class A2>
346struct member_pointer<T (U::*)(A1, A2) const volatile> {
347  typedef T type;
348  typedef U class_type;
349  typedef const volatile U qualified_class_type;
350  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
351  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
352};
353template<class T, class U, class A1, class A2, class A3>
354struct member_pointer<T (U::*)(A1, A2, A3) const volatile> {
355  typedef T type;
356  typedef U class_type;
357  typedef const volatile U qualified_class_type;
358  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
359  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
360};
361template<class T, class U, class A1, class A2, class A3, class A4>
362struct member_pointer<T (U::*)(A1, A2, A3, A4) const volatile> {
363  typedef T type;
364  typedef U class_type;
365  typedef const volatile U qualified_class_type;
366};
367template<class T, class U, class A1, class A2, class A3, class A4, class A5>
368struct member_pointer<T (U::*)(A1, A2, A3, A4, A5) const volatile> {
369  typedef T type;
370  typedef U class_type;
371  typedef const volatile U qualified_class_type;
372  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
373  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
374};
375template<class T, class U, class A1, class A2, class A3, class A4, class A5,
376         class A6>
377struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6) const volatile> {
378  typedef T type;
379  typedef U class_type;
380  typedef const volatile U qualified_class_type;
381  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
382  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
383};
384template<class T, class U, class A1, class A2, class A3, class A4, class A5,
385         class A6, class A7>
386struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7) const volatile> {
387  typedef T type;
388  typedef U class_type;
389  typedef const volatile U qualified_class_type;
390  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
391  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
392};
393template<class T, class U, class A1, class A2, class A3, class A4, class A5,
394         class A6, class A7, class A8>
395struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8) const volatile> {
396  typedef T type;
397  typedef U class_type;
398  typedef const volatile U qualified_class_type;
399  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
400  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
401};
402template<class T, class U, class A1, class A2, class A3, class A4, class A5,
403         class A6, class A7, class A8, class A9>
404struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const volatile> {
405  typedef T type;
406  typedef U class_type;
407  typedef const volatile U qualified_class_type;
408  BOOST_STATIC_CONSTANT(bool, is_data_member = false);
409  BOOST_STATIC_CONSTANT(bool, is_function_member = true);
410};
411
412} // detail
413
414namespace detail {
415
416  // this class holds a pointer to a member function and the object.
417  // when called, it just calls the member function with the parameters
418  // provided
419
420  // It would have been possible to use existing lambda_functors to represent
421  // a bound member function like this, but to have a separate template is
422  // safer, since now this functor doesn't mix and match with lambda_functors
423  // only thing you can do with this is to call it
424
425  // note that previously instantiated classes
426  // (other_action<member_pointer_action> and member_pointer_action_helper
427  // guarantee, that A and B are
428  // such types, that for objects a and b of corresponding types, a->*b leads
429  // to the builtin ->* to be called. So types that would end in a  call to
430  // a user defined ->* do not create a member_pointer_caller object.
431
432template<class RET, class A, class B>
433class member_pointer_caller {
434  A a; B b;
435
436public:
437  member_pointer_caller(const A& aa, const B& bb) : a(aa), b(bb) {}
438
439  RET operator()() const { return (a->*b)(); }
440
441  template<class A1>
442  RET operator()(const A1& a1) const { return (a->*b)(a1); }
443
444  template<class A1, class A2>
445  RET operator()(const A1& a1, const A2& a2) const { return (a->*b)(a1, a2); }
446
447  template<class A1, class A2, class A3>
448  RET operator()(const A1& a1, const A2& a2, const A3& a3) const {
449    return (a->*b)(a1, a2, a3);
450  }
451
452  template<class A1, class A2, class A3, class A4>
453  RET operator()(const A1& a1, const A2& a2, const A3& a3,
454                 const A4& a4) const {
455    return (a->*b)(a1, a2, a3, a4);
456  }
457
458  template<class A1, class A2, class A3, class A4, class A5>
459  RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
460                 const A5& a5) const {
461    return (a->*b)(a1, a2, a3, a4, a5);
462  }
463
464  template<class A1, class A2, class A3, class A4, class A5, class A6>
465  RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
466                 const A5& a5, const A6& a6) const {
467    return (a->*b)(a1, a2, a3, a4, a5, a6);
468  }
469
470  template<class A1, class A2, class A3, class A4, class A5, class A6,
471           class A7>
472  RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
473                 const A5& a5, const A6& a6, const A7& a7) const {
474    return (a->*b)(a1, a2, a3, a4, a5, a6, a7);
475  }
476
477  template<class A1, class A2, class A3, class A4, class A5, class A6,
478           class A7, class A8>
479  RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
480                 const A5& a5, const A6& a6, const A7& a7,
481                 const A8& a8) const {
482    return (a->*b)(a1, a2, a3, a4, a5, a6, a7, a8);
483  }
484
485  template<class A1, class A2, class A3, class A4, class A5, class A6,
486           class A7, class A8, class A9>
487  RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
488                 const A5& a5, const A6& a6, const A7& a7,
489                 const A8& a8, const A9& a9) const {
490    return (a->*b)(a1, a2, a3, a4, a5, a6, a7, a8, a9);
491  }
492
493};
494
495// helper templates for return type deduction and action classes
496// different cases for data member, function member, neither
497
498// true-true case
499template <bool Is_data_member, bool Is_function_member>
500struct member_pointer_action_helper;
501  // cannot be both, no body provided
502
503  // data member case
504  // this means, that B is a data member and A is a pointer type,
505  // so either built-in ->* should be called, or there is an error
506template <>
507struct member_pointer_action_helper<true, false> {
508public:
509
510  template<class RET, class A, class B>
511  static RET apply(A& a, B& b) {
512    return a->*b;
513  }
514
515  template<class A, class B>
516  struct return_type {
517  private:
518    typedef typename detail::remove_reference_and_cv<B>::type plainB;
519
520    typedef typename detail::member_pointer<plainB>::type type0;
521    // we remove the reference now, as we may have to add cv:s
522    typedef typename boost::remove_reference<type0>::type type1;
523
524    // A is a reference to pointer
525    // remove the top level cv qualifiers and reference
526    typedef typename
527      detail::remove_reference_and_cv<A>::type non_ref_A;
528
529    // A is a pointer type, so take the type pointed to
530    typedef typename ::boost::remove_pointer<non_ref_A>::type non_pointer_A;
531
532  public:
533    // For non-reference types, we must add const and/or volatile if
534    // the pointer type has these qualifiers
535    // If the member is a reference, these do not have any effect
536    //   (cv T == T if T is a reference type)
537    typedef typename detail::IF<
538      ::boost::is_const<non_pointer_A>::value,
539      typename ::boost::add_const<type1>::type,
540      type1
541    >::RET type2;
542    typedef typename detail::IF<
543      ::boost::is_volatile<non_pointer_A>::value,
544      typename ::boost::add_volatile<type2>::type,
545      type2
546    >::RET type3;
547    // add reference back
548    typedef typename ::boost::add_reference<type3>::type type;
549  };
550};
551
552  // neither case
553template <>
554struct member_pointer_action_helper<false, false> {
555public:
556  template<class RET, class A, class B>
557  static RET apply(A& a, B& b) {
558// not a built in member pointer operator, just call ->*
559    return a->*b;
560  }
561  // an overloaded member pointer operators, user should have specified
562  // the return type
563  // At this point we know that there is no matching specialization for
564  // return_type_2, so try return_type_2_plain
565  template<class A, class B>
566  struct return_type {
567
568    typedef typename plain_return_type_2<
569      other_action<member_pointer_action>, A, B
570    >::type type;
571  };
572 
573};
574
575
576// member pointer function case
577// This is a built in ->* call for a member function,
578// the only thing that you can do with that, is to give it some arguments
579// note, it is guaranteed that A is a pointer type, and thus it cannot
580// be a call to overloaded ->*
581template <>
582struct member_pointer_action_helper<false, true> {
583  public:
584
585  template<class RET, class A, class B>
586  static RET apply(A& a, B& b) {
587    typedef typename ::boost::remove_cv<B>::type plainB;
588    typedef typename detail::member_pointer<plainB>::type ret_t;
589    typedef typename ::boost::remove_cv<A>::type plainA;
590
591    // we always strip cv:s to
592    // make the two routes (calling and type deduction)
593    // to give the same results (and the const does not make any functional
594    // difference)
595    return detail::member_pointer_caller<ret_t, plainA, plainB>(a, b);
596  }
597
598  template<class A, class B>
599  struct return_type {
600    typedef typename detail::remove_reference_and_cv<B>::type plainB;
601    typedef typename detail::member_pointer<plainB>::type ret_t;
602    typedef typename detail::remove_reference_and_cv<A>::type plainA;
603
604    typedef detail::member_pointer_caller<ret_t, plainA, plainB> type;
605  };
606};
607
608} // detail
609
610template<> class other_action<member_pointer_action>  {
611public:
612  template<class RET, class A, class B>
613  static RET apply(A& a, B& b) {
614    typedef typename
615      ::boost::remove_cv<B>::type plainB;
616
617    return detail::member_pointer_action_helper<
618        boost::is_pointer<A>::value &&
619          detail::member_pointer<plainB>::is_data_member,
620        boost::is_pointer<A>::value &&
621          detail::member_pointer<plainB>::is_function_member
622      >::template apply<RET>(a, b);
623    }
624};
625
626  // return type deduction --
627
628  // If the right argument is a pointer to data member,
629  // and the left argument is of compatible pointer to class type
630  // return type is a reference to the data member type
631
632  // if right argument is a pointer to a member function, and the left
633  // argument is of a compatible type, the return type is a
634  // member_pointer_caller (see above)
635
636  // Otherwise, return type deduction fails. There is either an error,
637  // or the user is trying to call an overloaded ->*
638  // In such a case either ret<> must be used, or a return_type_2 user
639  // defined specialization must be provided
640
641
642template<class A, class B>
643struct return_type_2<other_action<member_pointer_action>, A, B> {
644private:
645  typedef typename
646    detail::remove_reference_and_cv<B>::type plainB;
647public:
648  typedef typename
649    detail::member_pointer_action_helper<
650      detail::member_pointer<plainB>::is_data_member,
651      detail::member_pointer<plainB>::is_function_member
652    >::template return_type<A, B>::type type;
653};
654
655  // this is the way the generic lambda_functor_base functions instantiate
656  // return type deduction. We turn it into return_type_2, so that the
657  // user can provide specializations on that level.
658template<class Args>
659struct return_type_N<other_action<member_pointer_action>, Args> {
660  typedef typename boost::tuples::element<0, Args>::type A;
661  typedef typename boost::tuples::element<1, Args>::type B;
662  typedef typename
663    return_type_2<other_action<member_pointer_action>,
664                  typename boost::remove_reference<A>::type,
665                  typename boost::remove_reference<B>::type
666                 >::type type;
667};
668
669
670template<class Arg1, class Arg2>
671inline const
672lambda_functor<
673  lambda_functor_base<
674    action<2, other_action<member_pointer_action> >,
675    tuple<lambda_functor<Arg1>, typename const_copy_argument<Arg2>::type>
676  >
677>
678operator->*(const lambda_functor<Arg1>& a1, const Arg2& a2)
679{
680  return
681      lambda_functor_base<
682        action<2, other_action<member_pointer_action> >,
683        tuple<lambda_functor<Arg1>, typename const_copy_argument<Arg2>::type>
684      >
685      (tuple<lambda_functor<Arg1>,
686             typename const_copy_argument<Arg2>::type>(a1, a2));
687}
688
689template<class Arg1, class Arg2>
690inline const
691lambda_functor<
692  lambda_functor_base<
693    action<2, other_action<member_pointer_action> >,
694    tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
695  >
696>
697operator->*(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2)
698{
699  return
700      lambda_functor_base<
701        action<2, other_action<member_pointer_action> >,
702        tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
703      >
704    (tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
705}
706
707template<class Arg1, class Arg2>
708inline const
709lambda_functor<
710  lambda_functor_base<
711    action<2, other_action<member_pointer_action> >,
712    tuple<typename const_copy_argument<Arg1>::type, lambda_functor<Arg2> >
713  >
714>
715operator->*(const Arg1& a1, const lambda_functor<Arg2>& a2)
716{
717  return
718      lambda_functor_base<
719        action<2, other_action<member_pointer_action> >,
720        tuple<typename const_copy_argument<Arg1>::type, lambda_functor<Arg2> >
721      >
722      (tuple<typename const_copy_argument<Arg1>::type,
723             lambda_functor<Arg2> >(a1, a2));
724}
725
726
727} // namespace lambda
728} // namespace boost
729
730
731#endif
732
733
734
735
736
737
Note: See TracBrowser for help on using the repository browser.