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

Revision 857, 6.5 KB checked in by igarcia, 18 years ago (diff)
Line 
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
16namespace boost {
17namespace lambda {
18
19// -- lambda_functor --------------------------------------------
20// --------------------------------------------------------------
21
22//inline const null_type const_null_type() { return null_type(); }
23
24namespace detail {
25namespace {
26
27  static const null_type constant_null_type = null_type();
28
29} // unnamed
30} // detail
31
32class 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 
40namespace 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
50template <int I> struct placeholder;
51
52template<> 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
66template<> 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
76template<> 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
86template<> 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   
96typedef const lambda_functor<placeholder<FIRST> >  placeholder1_type;
97typedef const lambda_functor<placeholder<SECOND> > placeholder2_type;
98typedef 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 ------------------------------------------------
111template <class T>
112class lambda_functor : public T
113{
114
115BOOST_STATIC_CONSTANT(int, arity_bits = get_arity<T>::value);
116 
117public:
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
Note: See TracBrowser for help on using the repository browser.