/usr/include/boost/phoenix/function
Edit: /usr/include/boost/phoenix/function/lazy_reuse.hpp (9763B)
////////////////////////////////////////////////////////////////////////////
// lazy_reuse.hpp
//
// Build lazy operations for Phoenix equivalents for FC++
//
// These are equivalents of the Boost FC++ functoids in reuse.hpp
//
// Implemented so far:
//
// 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.
//
// The functor type F must be an operator defined with
// boost::phoenix::function.
// See the example Apply in lazy_prelude.hpp
//
////////////////////////////////////////////////////////////////////////////
/*=============================================================================
Copyright (c) 2000-2003 Brian McNamara and Yannis Smaragdakis
Copyright (c) 2001-2007 Joel de Guzman
Copyright (c) 2015 John Fletcher
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#ifndef BOOST_PHOENIX_FUNCTION_LAZY_REUSE
#define BOOST_PHOENIX_FUNCTION_LAZY_REUSE
#include
#include
#include
namespace boost {
namespace phoenix {
namespace fcpp {
//////////////////////////////////////////////////////////////////////
// Original FC++ comment:
// "Reuser"s are effectively special-purpose versions of curry() that
// enable recursive list functoids to reuse the thunk of the curried
// recursive call. See
// http://www.cc.gatech.edu/~yannis/fc++/New/reusers.html
// for a more detailed description.
//////////////////////////////////////////////////////////////////////
// For efficiency, we mark parameters as either "VAR"iant or "INV"ariant.
struct INV {};
struct VAR {};
template struct Maybe_Var_Inv;
template
struct Maybe_Var_Inv {
static void remake( X& x, const X& val ) {
x.~X();
new (&x) X(val);
}
static X clone( const X& x ) { return X(x); }
};
template
struct Maybe_Var_Inv {
static void remake( X&, const X& ) {}
static const X& clone( const X& x ) { return x; }
};
/////////////////////////////////////////////////////////////////////
// ThunkImpl is an implementation of Fun0Impl for this use.
/////////////////////////////////////////////////////////////////////
template
class ThunkImpl
{
mutable RefCountType refC;
public:
ThunkImpl() : refC(0) {}
virtual Result operator()() const =0;
virtual ~ThunkImpl() {}
template
friend void intrusive_ptr_add_ref( const ThunkImpl* p );
template
friend void intrusive_ptr_release( const ThunkImpl* p );
};
template
void intrusive_ptr_add_ref( const ThunkImpl* p ) {
++ (p->refC);
}
template
void intrusive_ptr_release( const ThunkImpl* p ) {
if( !--(p->refC) ) delete p;
}
//////////////////////////////////////////////////////////////////////
// reuser1 is needed in list operations
//////////////////////////////////////////////////////////////////////
template
struct reuser1;
template
struct Thunk1 : public ThunkImpl {
mutable F f;
mutable X x;
Thunk1( const F& ff, const X& xx ) : f(ff), x(xx) {}
void init( const F& ff, const X& xx ) const {
Maybe_Var_Inv::remake( f, ff );
Maybe_Var_Inv::remake( x, xx );
}
R operator()() const {
return Maybe_Var_Inv::clone(f)(
Maybe_Var_Inv::clone(x),
reuser1(this) );
}
};
template
struct reuser1 {
typedef typename F::template result::type R;
typedef typename boost::phoenix::function fun0_type;
typedef Thunk1 M;
typedef M result_type;
boost::intrusive_ptr ref;
reuser1(a_unique_type_for_nil) {}
reuser1(const M* m) : ref(m) {}
M operator()( const F& f, const X& x ) {
if( !ref ) ref = boost::intrusive_ptr( new M(f,x) );
else ref->init(f,x);
return *ref;
}
void iter( const F& f, const X& x ) {
if( ref ) ref->init(f,x);
}
};
//////////////////////////////////////////////////////////////////////
// reuser2 is needed in list
//////////////////////////////////////////////////////////////////////
template
struct reuser2;
template
struct Thunk2 : public ThunkImpl {
mutable F f;
mutable X x;
mutable Y y;
Thunk2( const F& ff, const X& xx, const Y& yy ) : f(ff), x(xx), y(yy) {}
void init( const F& ff, const X& xx, const Y& yy ) const {
Maybe_Var_Inv::remake( f, ff );
Maybe_Var_Inv::remake( x, xx );
Maybe_Var_Inv::remake( y, yy );
}
R operator()() const {
return Maybe_Var_Inv::clone(f)(
Maybe_Var_Inv::clone(x),
Maybe_Var_Inv::clone(y),
reuser2(this) );
}
};
template
struct reuser2 {
typedef typename F::template result::type R;
typedef Thunk2 M;
typedef M result_type;
boost::intrusive_ptr ref;
reuser2(a_unique_type_for_nil) {}
reuser2(const M* m) : ref(m) {}
M operator()( const F& f, const X& x, const Y& y ) {
if( !ref ) ref = boost::intrusive_ptr( new M(f,x,y) );
else ref->init(f,x,y);
return *ref;
}
void iter( const F& f, const X& x, const Y& y ) {
if( ref ) ref->init(f,x,y);
}
};
//////////////////////////////////////////////////////////////////////
// reuser3
//////////////////////////////////////////////////////////////////////
template
struct reuser3;
template
struct Thunk3 : public ThunkImpl {
mutable F f;
mutable X x;
mutable Y y;
mutable Z z;
Thunk3( const F& ff, const X& xx, const Y& yy, const Z& zz )
: f(ff), x(xx), y(yy), z(zz) {}
void init( const F& ff, const X& xx, const Y& yy, const Z& zz ) const {
Maybe_Var_Inv::remake( f, ff );
Maybe_Var_Inv::remake( x, xx );
Maybe_Var_Inv::remake( y, yy );
Maybe_Var_Inv::remake( z, zz );
}
R operator()() const {
return Maybe_Var_Inv::clone(f)(
Maybe_Var_Inv::clone(x),
Maybe_Var_Inv::clone(y),
Maybe_Var_Inv::clone(z),
reuser3(this) );
}
};
template
struct reuser3 {
typedef typename F::template result::type R;
typedef Thunk3 M;
typedef M result_type;
boost::intrusive_ptr ref;
reuser3(a_unique_type_for_nil) {}
reuser3(const M* m) : ref(m) {}
M operator()( const F& f, const X& x, const Y& y, const Z& z ) {
if( !ref ) ref = boost::intrusive_ptr( new M(f,x,y,z) );
else ref->init(f,x,y,z);
return *ref;
}
void iter( const F& f, const X& x, const Y& y, const Z& z ) {
if( ref ) ref->init(f,x,y,z);
}
};
//////////////////////////////////////////////////////////////////////
// reuser4
//////////////////////////////////////////////////////////////////////
template
struct reuser4;
template
struct Thunk4 : public ThunkImpl {
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::remake( f, ff );
Maybe_Var_Inv::remake( w, ww );
Maybe_Var_Inv::remake( x, xx );
Maybe_Var_Inv::remake( y, yy );
Maybe_Var_Inv::remake( z, zz );
}
R operator()() const {
return Maybe_Var_Inv::clone(f)(
Maybe_Var_Inv::clone(w),
Maybe_Var_Inv::clone(x),
Maybe_Var_Inv::clone(y),
Maybe_Var_Inv::clone(z),
reuser4(this) );
}
};
template
struct reuser4 {
typedef typename F::template result::type R;
typedef Thunk4 M;
typedef M result_type;
boost::intrusive_ptr 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( 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);
}
};
}
}
}
#endif