1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/lambda/closures.hpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,274 @@
1.4 +/*=============================================================================
1.5 + Adaptable closures
1.6 +
1.7 + Phoenix V0.9
1.8 + Copyright (c) 2001-2002 Joel de Guzman
1.9 +
1.10 + Distributed under the Boost Software License, Version 1.0. (See
1.11 + accompanying file LICENSE_1_0.txt or copy at
1.12 + http://www.boost.org/LICENSE_1_0.txt)
1.13 +
1.14 + URL: http://spirit.sourceforge.net/
1.15 +
1.16 +==============================================================================*/
1.17 +#ifndef PHOENIX_CLOSURES_HPP
1.18 +#define PHOENIX_CLOSURES_HPP
1.19 +
1.20 +///////////////////////////////////////////////////////////////////////////////
1.21 +#include "boost/lambda/core.hpp"
1.22 +///////////////////////////////////////////////////////////////////////////////
1.23 +namespace boost {
1.24 +namespace lambda {
1.25 +
1.26 +///////////////////////////////////////////////////////////////////////////////
1.27 +//
1.28 +// Adaptable closures
1.29 +//
1.30 +// The framework will not be complete without some form of closures
1.31 +// support. Closures encapsulate a stack frame where local
1.32 +// variables are created upon entering a function and destructed
1.33 +// upon exiting. Closures provide an environment for local
1.34 +// variables to reside. Closures can hold heterogeneous types.
1.35 +//
1.36 +// Phoenix closures are true hardware stack based closures. At the
1.37 +// very least, closures enable true reentrancy in lambda functions.
1.38 +// A closure provides access to a function stack frame where local
1.39 +// variables reside. Modeled after Pascal nested stack frames,
1.40 +// closures can be nested just like nested functions where code in
1.41 +// inner closures may access local variables from in-scope outer
1.42 +// closures (accessing inner scopes from outer scopes is an error
1.43 +// and will cause a run-time assertion failure).
1.44 +//
1.45 +// There are three (3) interacting classes:
1.46 +//
1.47 +// 1) closure:
1.48 +//
1.49 +// At the point of declaration, a closure does not yet create a
1.50 +// stack frame nor instantiate any variables. A closure declaration
1.51 +// declares the types and names[note] of the local variables. The
1.52 +// closure class is meant to be subclassed. It is the
1.53 +// responsibility of a closure subclass to supply the names for
1.54 +// each of the local variable in the closure. Example:
1.55 +//
1.56 +// struct my_closure : closure<int, string, double> {
1.57 +//
1.58 +// member1 num; // names the 1st (int) local variable
1.59 +// member2 message; // names the 2nd (string) local variable
1.60 +// member3 real; // names the 3rd (double) local variable
1.61 +// };
1.62 +//
1.63 +// my_closure clos;
1.64 +//
1.65 +// Now that we have a closure 'clos', its local variables can be
1.66 +// accessed lazily using the dot notation. Each qualified local
1.67 +// variable can be used just like any primitive actor (see
1.68 +// primitives.hpp). Examples:
1.69 +//
1.70 +// clos.num = 30
1.71 +// clos.message = arg1
1.72 +// clos.real = clos.num * 1e6
1.73 +//
1.74 +// The examples above are lazily evaluated. As usual, these
1.75 +// expressions return composite actors that will be evaluated
1.76 +// through a second function call invocation (see operators.hpp).
1.77 +// Each of the members (clos.xxx) is an actor. As such, applying
1.78 +// the operator() will reveal its identity:
1.79 +//
1.80 +// clos.num() // will return the current value of clos.num
1.81 +//
1.82 +// *** [note] Acknowledgement: Juan Carlos Arevalo-Baeza (JCAB)
1.83 +// introduced and initilally implemented the closure member names
1.84 +// that uses the dot notation.
1.85 +//
1.86 +// 2) closure_member
1.87 +//
1.88 +// The named local variables of closure 'clos' above are actually
1.89 +// closure members. The closure_member class is an actor and
1.90 +// conforms to its conceptual interface. member1..memberN are
1.91 +// predefined typedefs that correspond to each of the listed types
1.92 +// in the closure template parameters.
1.93 +//
1.94 +// 3) closure_frame
1.95 +//
1.96 +// When a closure member is finally evaluated, it should refer to
1.97 +// an actual instance of the variable in the hardware stack.
1.98 +// Without doing so, the process is not complete and the evaluated
1.99 +// member will result to an assertion failure. Remember that the
1.100 +// closure is just a declaration. The local variables that a
1.101 +// closure refers to must still be instantiated.
1.102 +//
1.103 +// The closure_frame class does the actual instantiation of the
1.104 +// local variables and links these variables with the closure and
1.105 +// all its members. There can be multiple instances of
1.106 +// closure_frames typically situated in the stack inside a
1.107 +// function. Each closure_frame instance initiates a stack frame
1.108 +// with a new set of closure local variables. Example:
1.109 +//
1.110 +// void foo()
1.111 +// {
1.112 +// closure_frame<my_closure> frame(clos);
1.113 +// /* do something */
1.114 +// }
1.115 +//
1.116 +// where 'clos' is an instance of our closure 'my_closure' above.
1.117 +// Take note that the usage above precludes locally declared
1.118 +// classes. If my_closure is a locally declared type, we can still
1.119 +// use its self_type as a paramater to closure_frame:
1.120 +//
1.121 +// closure_frame<my_closure::self_type> frame(clos);
1.122 +//
1.123 +// Upon instantiation, the closure_frame links the local variables
1.124 +// to the closure. The previous link to another closure_frame
1.125 +// instance created before is saved. Upon destruction, the
1.126 +// closure_frame unlinks itself from the closure and relinks the
1.127 +// preceding closure_frame prior to this instance.
1.128 +//
1.129 +// The local variables in the closure 'clos' above is default
1.130 +// constructed in the stack inside function 'foo'. Once 'foo' is
1.131 +// exited, all of these local variables are destructed. In some
1.132 +// cases, default construction is not desirable and we need to
1.133 +// initialize the local closure variables with some values. This
1.134 +// can be done by passing in the initializers in a compatible
1.135 +// tuple. A compatible tuple is one with the same number of
1.136 +// elements as the destination and where each element from the
1.137 +// destination can be constructed from each corresponding element
1.138 +// in the source. Example:
1.139 +//
1.140 +// tuple<int, char const*, int> init(123, "Hello", 1000);
1.141 +// closure_frame<my_closure> frame(clos, init);
1.142 +//
1.143 +// Here now, our closure_frame's variables are initialized with
1.144 +// int: 123, char const*: "Hello" and int: 1000.
1.145 +//
1.146 +///////////////////////////////////////////////////////////////////////////////
1.147 +
1.148 +
1.149 +
1.150 +///////////////////////////////////////////////////////////////////////////////
1.151 +//
1.152 +// closure_frame class
1.153 +//
1.154 +///////////////////////////////////////////////////////////////////////////////
1.155 +template <typename ClosureT>
1.156 +class closure_frame : public ClosureT::tuple_t {
1.157 +
1.158 +public:
1.159 +
1.160 + closure_frame(ClosureT& clos)
1.161 + : ClosureT::tuple_t(), save(clos.frame), frame(clos.frame)
1.162 + { clos.frame = this; }
1.163 +
1.164 + template <typename TupleT>
1.165 + closure_frame(ClosureT& clos, TupleT const& init)
1.166 + : ClosureT::tuple_t(init), save(clos.frame), frame(clos.frame)
1.167 + { clos.frame = this; }
1.168 +
1.169 + ~closure_frame()
1.170 + { frame = save; }
1.171 +
1.172 +private:
1.173 +
1.174 + closure_frame(closure_frame const&); // no copy
1.175 + closure_frame& operator=(closure_frame const&); // no assign
1.176 +
1.177 + closure_frame* save;
1.178 + closure_frame*& frame;
1.179 +};
1.180 +
1.181 +///////////////////////////////////////////////////////////////////////////////
1.182 +//
1.183 +// closure_member class
1.184 +//
1.185 +///////////////////////////////////////////////////////////////////////////////
1.186 +template <int N, typename ClosureT>
1.187 +class closure_member {
1.188 +
1.189 +public:
1.190 +
1.191 + typedef typename ClosureT::tuple_t tuple_t;
1.192 +
1.193 + closure_member()
1.194 + : frame(ClosureT::closure_frame_ref()) {}
1.195 +
1.196 + template <typename TupleT>
1.197 + struct sig {
1.198 +
1.199 + typedef typename detail::tuple_element_as_reference<
1.200 + N, typename ClosureT::tuple_t
1.201 + >::type type;
1.202 + };
1.203 +
1.204 + template <class Ret, class A, class B, class C>
1.205 + // typename detail::tuple_element_as_reference
1.206 + // <N, typename ClosureT::tuple_t>::type
1.207 + Ret
1.208 + call(A&, B&, C&) const
1.209 + {
1.210 + assert(frame);
1.211 + return boost::tuples::get<N>(*frame);
1.212 + }
1.213 +
1.214 +
1.215 +private:
1.216 +
1.217 + typename ClosureT::closure_frame_t*& frame;
1.218 +};
1.219 +
1.220 +///////////////////////////////////////////////////////////////////////////////
1.221 +//
1.222 +// closure class
1.223 +//
1.224 +///////////////////////////////////////////////////////////////////////////////
1.225 +template <
1.226 + typename T0 = null_type,
1.227 + typename T1 = null_type,
1.228 + typename T2 = null_type,
1.229 + typename T3 = null_type,
1.230 + typename T4 = null_type
1.231 +>
1.232 +class closure {
1.233 +
1.234 +public:
1.235 +
1.236 + typedef tuple<T0, T1, T2, T3, T4> tuple_t;
1.237 + typedef closure<T0, T1, T2, T3, T4> self_t;
1.238 + typedef closure_frame<self_t> closure_frame_t;
1.239 +
1.240 + closure()
1.241 + : frame(0) { closure_frame_ref(&frame); }
1.242 + closure_frame_t& context() { assert(frame); return frame; }
1.243 + closure_frame_t const& context() const { assert(frame); return frame; }
1.244 +
1.245 + typedef lambda_functor<closure_member<0, self_t> > member1;
1.246 + typedef lambda_functor<closure_member<1, self_t> > member2;
1.247 + typedef lambda_functor<closure_member<2, self_t> > member3;
1.248 + typedef lambda_functor<closure_member<3, self_t> > member4;
1.249 + typedef lambda_functor<closure_member<4, self_t> > member5;
1.250 +
1.251 +private:
1.252 +
1.253 + closure(closure const&); // no copy
1.254 + closure& operator=(closure const&); // no assign
1.255 +
1.256 + template <int N, typename ClosureT>
1.257 + friend struct closure_member;
1.258 +
1.259 + template <typename ClosureT>
1.260 + friend class closure_frame;
1.261 +
1.262 + static closure_frame_t*&
1.263 + closure_frame_ref(closure_frame_t** frame_ = 0)
1.264 + {
1.265 + static closure_frame_t** frame = 0;
1.266 + if (frame_ != 0)
1.267 + frame = frame_;
1.268 + return *frame;
1.269 + }
1.270 +
1.271 + closure_frame_t* frame;
1.272 +};
1.273 +
1.274 +}}
1.275 + // namespace
1.276 +
1.277 +#endif