Warning, file /include/boost/phoenix/function/lazy_reuse.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #ifndef BOOST_PHOENIX_FUNCTION_LAZY_REUSE
0033 #define BOOST_PHOENIX_FUNCTION_LAZY_REUSE
0034
0035 #include <boost/phoenix/core.hpp>
0036 #include <boost/phoenix/function.hpp>
0037 #include <boost/intrusive_ptr.hpp>
0038
0039
0040 namespace boost {
0041
0042 namespace phoenix {
0043
0044 namespace fcpp {
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 struct INV {};
0057 struct VAR {};
0058
0059 template <class V, class X> struct Maybe_Var_Inv;
0060 template <class X>
0061 struct Maybe_Var_Inv<VAR,X> {
0062 static void remake( X& x, const X& val ) {
0063 x.~X();
0064 new (&x) X(val);
0065 }
0066 static X clone( const X& x ) { return X(x); }
0067 };
0068 template <class X>
0069 struct Maybe_Var_Inv<INV,X> {
0070 static void remake( X&, const X& ) {}
0071 static const X& clone( const X& x ) { return x; }
0072 };
0073
0074
0075
0076
0077
0078 template <class Result>
0079 class ThunkImpl
0080 {
0081 mutable RefCountType refC;
0082 public:
0083 ThunkImpl() : refC(0) {}
0084 virtual Result operator()() const =0;
0085 virtual ~ThunkImpl() {}
0086 template <class X>
0087 friend void intrusive_ptr_add_ref( const ThunkImpl<X>* p );
0088 template <class X>
0089 friend void intrusive_ptr_release( const ThunkImpl<X>* p );
0090 };
0091
0092 template <class T>
0093 void intrusive_ptr_add_ref( const ThunkImpl<T>* p ) {
0094 ++ (p->refC);
0095 }
0096 template <class T>
0097 void intrusive_ptr_release( const ThunkImpl<T>* p ) {
0098 if( !--(p->refC) ) delete p;
0099 }
0100
0101
0102
0103
0104
0105 template <class V1, class V2, class F, class X>
0106 struct reuser1;
0107
0108 template <class V1, class V2, class F, class X, class R>
0109 struct Thunk1 : public ThunkImpl<R> {
0110 mutable F f;
0111 mutable X x;
0112 Thunk1( const F& ff, const X& xx ) : f(ff), x(xx) {}
0113 void init( const F& ff, const X& xx ) const {
0114 Maybe_Var_Inv<V1,F>::remake( f, ff );
0115 Maybe_Var_Inv<V2,X>::remake( x, xx );
0116 }
0117 R operator()() const {
0118 return Maybe_Var_Inv<V1,F>::clone(f)(
0119 Maybe_Var_Inv<V2,X>::clone(x),
0120 reuser1<V1,V2,F,X>(this) );
0121 }
0122 };
0123
0124 template <class V1, class V2, class F, class X>
0125 struct reuser1 {
0126 typedef typename F::template result<F(X)>::type R;
0127 typedef typename boost::phoenix::function<R> fun0_type;
0128 typedef Thunk1<V1,V2,F,X,R> M;
0129 typedef M result_type;
0130 boost::intrusive_ptr<const M> ref;
0131 reuser1(a_unique_type_for_nil) {}
0132 reuser1(const M* m) : ref(m) {}
0133 M operator()( const F& f, const X& x ) {
0134 if( !ref ) ref = boost::intrusive_ptr<const M>( new M(f,x) );
0135 else ref->init(f,x);
0136 return *ref;
0137 }
0138 void iter( const F& f, const X& x ) {
0139 if( ref ) ref->init(f,x);
0140 }
0141 };
0142
0143
0144
0145
0146
0147 template <class V1, class V2, class V3, class F, class X, class Y>
0148 struct reuser2;
0149
0150 template <class V1, class V2, class V3, class F, class X, class Y, class R>
0151 struct Thunk2 : public ThunkImpl<R> {
0152 mutable F f;
0153 mutable X x;
0154 mutable Y y;
0155 Thunk2( const F& ff, const X& xx, const Y& yy ) : f(ff), x(xx), y(yy) {}
0156 void init( const F& ff, const X& xx, const Y& yy ) const {
0157 Maybe_Var_Inv<V1,F>::remake( f, ff );
0158 Maybe_Var_Inv<V2,X>::remake( x, xx );
0159 Maybe_Var_Inv<V3,Y>::remake( y, yy );
0160 }
0161 R operator()() const {
0162 return Maybe_Var_Inv<V1,F>::clone(f)(
0163 Maybe_Var_Inv<V2,X>::clone(x),
0164 Maybe_Var_Inv<V3,Y>::clone(y),
0165 reuser2<V1,V2,V3,F,X,Y>(this) );
0166 }
0167 };
0168
0169 template <class V1, class V2, class V3, class F, class X, class Y>
0170 struct reuser2 {
0171 typedef typename F::template result<F(X,Y)>::type R;
0172 typedef Thunk2<V1,V2,V3,F,X,Y,R> M;
0173 typedef M result_type;
0174 boost::intrusive_ptr<const M> ref;
0175 reuser2(a_unique_type_for_nil) {}
0176 reuser2(const M* m) : ref(m) {}
0177 M operator()( const F& f, const X& x, const Y& y ) {
0178 if( !ref ) ref = boost::intrusive_ptr<const M>( new M(f,x,y) );
0179 else ref->init(f,x,y);
0180 return *ref;
0181 }
0182 void iter( const F& f, const X& x, const Y& y ) {
0183 if( ref ) ref->init(f,x,y);
0184 }
0185 };
0186
0187
0188
0189
0190
0191 template <class V1, class V2, class V3, class V4,
0192 class F, class X, class Y, class Z>
0193 struct reuser3;
0194
0195 template <class V1, class V2, class V3, class V4,
0196 class F, class X, class Y, class Z, class R>
0197 struct Thunk3 : public ThunkImpl<R> {
0198 mutable F f;
0199 mutable X x;
0200 mutable Y y;
0201 mutable Z z;
0202 Thunk3( const F& ff, const X& xx, const Y& yy, const Z& zz )
0203 : f(ff), x(xx), y(yy), z(zz) {}
0204 void init( const F& ff, const X& xx, const Y& yy, const Z& zz ) const {
0205 Maybe_Var_Inv<V1,F>::remake( f, ff );
0206 Maybe_Var_Inv<V2,X>::remake( x, xx );
0207 Maybe_Var_Inv<V3,Y>::remake( y, yy );
0208 Maybe_Var_Inv<V4,Z>::remake( z, zz );
0209 }
0210 R operator()() const {
0211 return Maybe_Var_Inv<V1,F>::clone(f)(
0212 Maybe_Var_Inv<V2,X>::clone(x),
0213 Maybe_Var_Inv<V3,Y>::clone(y),
0214 Maybe_Var_Inv<V4,Z>::clone(z),
0215 reuser3<V1,V2,V3,V4,F,X,Y,Z>(this) );
0216 }
0217 };
0218
0219 template <class V1, class V2, class V3, class V4,
0220 class F, class X, class Y, class Z>
0221 struct reuser3 {
0222 typedef typename F::template result<F(X,Y,Z)>::type R;
0223 typedef Thunk3<V1,V2,V3,V4,F,X,Y,Z,R> M;
0224 typedef M result_type;
0225 boost::intrusive_ptr<const M> ref;
0226 reuser3(a_unique_type_for_nil) {}
0227 reuser3(const M* m) : ref(m) {}
0228 M operator()( const F& f, const X& x, const Y& y, const Z& z ) {
0229 if( !ref ) ref = boost::intrusive_ptr<const M>( new M(f,x,y,z) );
0230 else ref->init(f,x,y,z);
0231 return *ref;
0232 }
0233 void iter( const F& f, const X& x, const Y& y, const Z& z ) {
0234 if( ref ) ref->init(f,x,y,z);
0235 }
0236 };
0237
0238
0239
0240
0241 template <class V1, class V2, class V3, class V4, class V5,
0242 class F, class W, class X, class Y, class Z>
0243 struct reuser4;
0244
0245 template <class V1, class V2, class V3, class V4, class V5,
0246 class F, class W, class X, class Y, class Z, class R>
0247 struct Thunk4 : public ThunkImpl<R> {
0248 mutable F f;
0249 mutable W w;
0250 mutable X x;
0251 mutable Y y;
0252 mutable Z z;
0253 Thunk4( const F& ff, const W& ww, const X& xx, const Y& yy, const Z& zz )
0254 : f(ff), w(ww), x(xx), y(yy), z(zz) {}
0255 void init( const F& ff, const W& ww, const X& xx, const Y& yy, const Z& zz ) const {
0256 Maybe_Var_Inv<V1,F>::remake( f, ff );
0257 Maybe_Var_Inv<V2,W>::remake( w, ww );
0258 Maybe_Var_Inv<V3,X>::remake( x, xx );
0259 Maybe_Var_Inv<V4,Y>::remake( y, yy );
0260 Maybe_Var_Inv<V5,Z>::remake( z, zz );
0261 }
0262 R operator()() const {
0263 return Maybe_Var_Inv<V1,F>::clone(f)(
0264 Maybe_Var_Inv<V2,W>::clone(w),
0265 Maybe_Var_Inv<V3,X>::clone(x),
0266 Maybe_Var_Inv<V4,Y>::clone(y),
0267 Maybe_Var_Inv<V5,Z>::clone(z),
0268 reuser4<V1,V2,V3,V4,V5,F,W,X,Y,Z>(this) );
0269 }
0270 };
0271
0272 template <class V1, class V2, class V3, class V4, class V5,
0273 class F, class W, class X, class Y, class Z>
0274 struct reuser4 {
0275 typedef typename F::template result<F(W,X,Y,Z)>::type R;
0276 typedef Thunk4<V1,V2,V3,V4,V5,F,W,X,Y,Z,R> M;
0277 typedef M result_type;
0278 boost::intrusive_ptr<const M> ref;
0279 reuser4(a_unique_type_for_nil) {}
0280 reuser4(const M* m) : ref(m) {}
0281 M operator()( const F& f, const W& w, const X& x, const Y& y, const Z& z ) {
0282 if( !ref ) ref = boost::intrusive_ptr<const M>( new M(f,w,x,y,z) );
0283 else ref->init(f,w,x,y,z);
0284 return *ref;
0285 }
0286 void iter( const F& f, const W& w, const X& x, const Y& y, const Z& z ) {
0287 if( ref ) ref->init(f,w,x,y,z);
0288 }
0289 };
0290
0291 }
0292
0293 }
0294 }
0295
0296 #endif