| 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 | |
|---|