[857] | 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 |
|
---|