summaryrefslogtreecommitdiff
path: root/boost/phoenix/function/lazy_reuse.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/phoenix/function/lazy_reuse.hpp')
-rw-r--r--boost/phoenix/function/lazy_reuse.hpp58
1 files changed, 56 insertions, 2 deletions
diff --git a/boost/phoenix/function/lazy_reuse.hpp b/boost/phoenix/function/lazy_reuse.hpp
index cef2ded820..845cc1c90b 100644
--- a/boost/phoenix/function/lazy_reuse.hpp
+++ b/boost/phoenix/function/lazy_reuse.hpp
@@ -7,9 +7,10 @@
//
// Implemented so far:
//
-// reuser1 (not yet tested)
-// reuser2 (not yet tested)
+// reuser1
+// reuser2
// reuser3
+// reuser4 (not yet tested)
//
// NOTE: It has been possible to simplify the operation of this code.
// It now makes no use of boost::function or old FC++ code.
@@ -233,6 +234,59 @@ struct reuser3 {
if( ref ) ref->init(f,x,y,z);
}
};
+//////////////////////////////////////////////////////////////////////
+// reuser4
+//////////////////////////////////////////////////////////////////////
+
+ template <class V1, class V2, class V3, class V4, class V5,
+ class F, class W, class X, class Y, class Z>
+struct reuser4;
+
+ template <class V1, class V2, class V3, class V4, class V5,
+ class F, class W, class X, class Y, class Z, class R>
+struct Thunk4 : public ThunkImpl<R> {
+ mutable F f;
+ mutable W w;
+ mutable X x;
+ mutable Y y;
+ mutable Z z;
+ Thunk4( const F& ff, const W& ww, const X& xx, const Y& yy, const Z& zz )
+ : f(ff), w(ww), x(xx), y(yy), z(zz) {}
+ void init( const F& ff, const W& ww, const X& xx, const Y& yy, const Z& zz ) const {
+ Maybe_Var_Inv<V1,F>::remake( f, ff );
+ Maybe_Var_Inv<V2,W>::remake( w, ww );
+ Maybe_Var_Inv<V3,X>::remake( x, xx );
+ Maybe_Var_Inv<V4,Y>::remake( y, yy );
+ Maybe_Var_Inv<V5,Z>::remake( z, zz );
+ }
+ R operator()() const {
+ return Maybe_Var_Inv<V1,F>::clone(f)(
+ Maybe_Var_Inv<V2,W>::clone(w),
+ Maybe_Var_Inv<V3,X>::clone(x),
+ Maybe_Var_Inv<V4,Y>::clone(y),
+ Maybe_Var_Inv<V5,Z>::clone(z),
+ reuser4<V1,V2,V3,V4,V5,F,W,X,Y,Z>(this) );
+ }
+};
+
+ template <class V1, class V2, class V3, class V4, class V5,
+ class F, class W, class X, class Y, class Z>
+ struct reuser4 {
+ typedef typename F::template result<F(W,X,Y,Z)>::type R;
+ typedef Thunk4<V1,V2,V3,V4,V5,F,W,X,Y,Z,R> M;
+ typedef M result_type;
+ boost::intrusive_ptr<const M> ref;
+ reuser4(a_unique_type_for_nil) {}
+ reuser4(const M* m) : ref(m) {}
+ M operator()( const F& f, const W& w, const X& x, const Y& y, const Z& z ) {
+ if( !ref ) ref = boost::intrusive_ptr<const M>( new M(f,w,x,y,z) );
+ else ref->init(f,w,x,y,z);
+ return *ref;
+ }
+ void iter( const F& f, const W& w, const X& x, const Y& y, const Z& z ) {
+ if( ref ) ref->init(f,w,x,y,z);
+ }
+ };
}