Ugly, not-to-be-pushed sucking in of all of Boost to get windows to work.
[dyninst.git] / external / boost / lambda / detail / lambda_functors.hpp
1 // Boost Lambda Library -  lambda_functors.hpp -------------------------------
2
3 // Copyright (C) 1999, 2000 Jaakko J√§rvi (jaakko.jarvi@cs.utu.fi)
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See
6 // accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // For more information, see http://www.boost.org
10
11 // ------------------------------------------------
12
13 #ifndef BOOST_LAMBDA_LAMBDA_FUNCTORS_HPP
14 #define BOOST_LAMBDA_LAMBDA_FUNCTORS_HPP
15
16 namespace boost { 
17 namespace lambda {
18
19 // -- lambda_functor --------------------------------------------
20 // --------------------------------------------------------------
21
22 //inline const null_type const_null_type() { return null_type(); }
23
24 namespace detail {
25 namespace {
26
27   static const null_type constant_null_type = null_type();
28
29 } // unnamed
30 } // detail
31
32 class unused {};
33
34 #define cnull_type() detail::constant_null_type
35
36 // -- free variables types -------------------------------------------------- 
37  
38   // helper to work around the case where the nullary return type deduction 
39   // is always performed, even though the functor is not nullary  
40 namespace detail {
41   template<int N, class Tuple> struct get_element_or_null_type {
42     typedef typename 
43       detail::tuple_element_as_reference<N, Tuple>::type type;
44   };
45   template<int N> struct get_element_or_null_type<N, null_type> {
46     typedef null_type type;
47   };
48 }
49
50 template <int I> struct placeholder;
51
52 template<> struct placeholder<FIRST> {
53
54   template<class SigArgs> struct sig {
55     typedef typename detail::get_element_or_null_type<0, SigArgs>::type type;
56   };
57
58   template<class RET, CALL_TEMPLATE_ARGS> 
59   RET call(CALL_FORMAL_ARGS) const { 
60     BOOST_STATIC_ASSERT(boost::is_reference<RET>::value); 
61     CALL_USE_ARGS; // does nothing, prevents warnings for unused args
62     return a; 
63   }
64 };
65
66 template<> struct placeholder<SECOND> {
67
68   template<class SigArgs> struct sig {
69     typedef typename detail::get_element_or_null_type<1, SigArgs>::type type;
70   };
71
72   template<class RET, CALL_TEMPLATE_ARGS> 
73   RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return b; }
74 };
75
76 template<> struct placeholder<THIRD> {
77
78   template<class SigArgs> struct sig {
79     typedef typename detail::get_element_or_null_type<2, SigArgs>::type type;
80   };
81
82   template<class RET, CALL_TEMPLATE_ARGS> 
83   RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return c; }
84 };
85
86 template<> struct placeholder<EXCEPTION> {
87
88   template<class SigArgs> struct sig {
89     typedef typename detail::get_element_or_null_type<3, SigArgs>::type type;
90   };
91
92   template<class RET, CALL_TEMPLATE_ARGS> 
93   RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return env; }
94 };
95    
96 typedef const lambda_functor<placeholder<FIRST> >  placeholder1_type;
97 typedef const lambda_functor<placeholder<SECOND> > placeholder2_type;
98 typedef const lambda_functor<placeholder<THIRD> >  placeholder3_type;
99    
100
101 ///////////////////////////////////////////////////////////////////////////////
102
103
104 // free variables are lambda_functors. This is to allow uniform handling with 
105 // other lambda_functors.
106 // -------------------------------------------------------------------
107
108
109
110 // -- lambda_functor NONE ------------------------------------------------
111 template <class T>
112 class lambda_functor : public T 
113 {
114
115 BOOST_STATIC_CONSTANT(int, arity_bits = get_arity<T>::value);
116  
117 public:
118   typedef T inherited;
119
120   lambda_functor() {}
121   lambda_functor(const lambda_functor& l) : inherited(l) {}
122
123   lambda_functor(const T& t) : inherited(t) {}
124
125   template <class SigArgs> struct sig {
126     typedef typename inherited::template 
127       sig<typename SigArgs::tail_type>::type type;
128   };
129
130   // Note that this return type deduction template is instantiated, even 
131   // if the nullary 
132   // operator() is not called at all. One must make sure that it does not fail.
133   typedef typename 
134     inherited::template sig<null_type>::type
135       nullary_return_type;
136
137   nullary_return_type operator()() const { 
138     return inherited::template 
139       call<nullary_return_type>
140         (cnull_type(), cnull_type(), cnull_type(), cnull_type()); 
141   }
142
143   template<class A>
144   typename inherited::template sig<tuple<A&> >::type
145   operator()(A& a) const { 
146     return inherited::template call<
147       typename inherited::template sig<tuple<A&> >::type
148     >(a, cnull_type(), cnull_type(), cnull_type());
149   }
150
151   template<class A, class B>
152   typename inherited::template sig<tuple<A&, B&> >::type
153   operator()(A& a, B& b) const { 
154     return inherited::template call<
155       typename inherited::template sig<tuple<A&, B&> >::type
156     >(a, b, cnull_type(), cnull_type()); 
157   }
158
159   template<class A, class B, class C>
160   typename inherited::template sig<tuple<A&, B&, C&> >::type
161   operator()(A& a, B& b, C& c) const
162   { 
163     return inherited::template call<
164       typename inherited::template sig<tuple<A&, B&, C&> >::type
165     >(a, b, c, cnull_type()); 
166   }
167
168   // for internal calls with env
169   template<CALL_TEMPLATE_ARGS>
170   typename inherited::template sig<tuple<CALL_REFERENCE_TYPES> >::type
171   internal_call(CALL_FORMAL_ARGS) const { 
172      return inherited::template 
173        call<typename inherited::template 
174          sig<tuple<CALL_REFERENCE_TYPES> >::type>(CALL_ACTUAL_ARGS); 
175   }
176
177   template<class A>
178   const lambda_functor<lambda_functor_base<
179                   other_action<assignment_action>,
180                   boost::tuple<lambda_functor,
181                   typename const_copy_argument <const A>::type> > >
182   operator=(const A& a) const {
183     return lambda_functor_base<
184                   other_action<assignment_action>,
185                   boost::tuple<lambda_functor,
186                   typename const_copy_argument <const A>::type> >
187      (  boost::tuple<lambda_functor,
188              typename const_copy_argument <const A>::type>(*this, a) );
189   }
190
191   template<class A> 
192   const lambda_functor<lambda_functor_base< 
193                   other_action<subscript_action>, 
194                   boost::tuple<lambda_functor, 
195                         typename const_copy_argument <const A>::type> > > 
196   operator[](const A& a) const { 
197     return lambda_functor_base< 
198                   other_action<subscript_action>, 
199                   boost::tuple<lambda_functor, 
200                         typename const_copy_argument <const A>::type> >
201      ( boost::tuple<lambda_functor, 
202              typename const_copy_argument <const A>::type>(*this, a ) ); 
203   } 
204 };
205
206
207 } // namespace lambda
208 } // namespace boost
209
210 #endif
211
212