A

#### alan

cell_internal is an abstract base class, intended to encapsulate

deferred computation.

cell is just a wrapped pointer around cell_body; this is the user's

interface to this code.

When a cell is created, it creates a cell_body and attaches a

shared_ptr member (value_) to the body. This shared_ptr should never

be changed; the cell can only have one cell_body during its lifetime.

The cell_body holds a pointer to a cell_internal; when the cell's

value is taken by the member get_value(), it calls cell_body's

get_value(), which calls cell_internal's virtual cell_value(). This

virtual cell_value then computes the correct value. Basically the

get_value() function performs the computation that has been deferred.

Copying a cell to a cell does not, in fact, copy the cell; instead,

the destination cell is "attached" to the source cell, so that

changing the value of one changes the value of the other. So:

cell<int> i, j;

i = j;

j = 1; //now i is also 1

Actually what is being attached are the cell_body's. A new

cell_internal derived class (cell_shadow) is created, whose virtual

get_value() simply calls the get_value() of the cell_body it is

constructed with.

I don't use cell_body directly because of the possibility of

temporaries. When a cell is destroyed, its cell_body may still

survive, for example when referred from a global variable.

I think I may need to do swap-copy, but I don't quite understand yet

where I need to put it.

/*

* */

#include <boost/shared_ptr.hpp>

#include <boost/scoped_ptr.hpp>

/* cell_internal

* Interface to handle the deferred computation

* */

template<class T>

class cell_internal{

public:

virtual T get_value(void) const=0;

virtual ~cell_internal(){};

};

template<class T>

struct cell_internal_ptr{

typedef boost::shared_ptr< const cell_internal<T> > type;

};

/* cell_constant

* Handles constant numeric values

* */

template<class T>

class cell_constant: public cell_internal<T>{

T c_;

public:

cell_constant<T>(const T& v): c_(v) {};

T get_value(void) const {return c_;};

};

/* cell_body

* The actual cell structure

* */

template<class T>

class cell_body{

typename cell_internal_ptr<T>::type value_;

public:

cell_body(const cell_internal<T>* v): value_(v) {};

cell_body(const typename cell_internal_ptr<T>::type v): value_(v) {}

T get_value(void) const {

return value_->get_value();

};

void set(const cell_internal<T>* v){

value_.reset(v);

}

};

template<class T>

struct cell_body_ptr{

typedef boost::shared_ptr< const cell_body<T> > type;

};

/* cell_shadow

* Shadows a given cell_body

* */

template<class T>

class cell_shadow: public cell_internal<T>{

boost::shared_ptr< const cell_body<T> > var_;

public:

cell_shadow<T>(const cell_body<T>* v) : var_(v){};

cell_shadow<T>(const boost::shared_ptr< cell_body<T> >& v):

var_(v){};

T get_value(void) const {return var_->get_value();};

};

/* cell_op

* Handles a binary operation

* */

template<class T, class BinaryOperation>

class cell_op: public cell_internal<T>{

boost::shared_ptr< const cell_body<T> > lhs_;

boost::shared_ptr< const cell_body<T> > rhs_;

public:

cell_op<T, BinaryOperation>( const boost::shared_ptr< const

cell_body<T> >& lhs,

const boost::shared_ptr< const cell_body<T> >& rhs

) :

lhs_(lhs),

rhs_(rhs) { };

cell_op<T, BinaryOperation>( cell_body<T>* lhs, cell_body<T>* rhs):

lhs_(lhs),

rhs_(rhs) { };

T get_value(void) const {

return BinaryOperation()(lhs_->get_value(), rhs_->get_value());

};

};

/* cell_singelop

* Handles a unary operation

* */

//template<class T, class UnaryOperation>

//class cell_singleop: public cell_internal<T>{

//};

/* cell

* Acts as the user's interface to the cell_body

* Effectively just a wrapper around a pointer to the cell_body

* IMPORTANT. Each cell will have one, and only one, cell_body

* during its lifetime. A cell_body, however, may outlive its

* cell (for example if the cell is a local variable that is

* then used in the formula for a global variable - at the end

* of the function the local cell is destroyed, but the cell_body

* is retained via a cell_shadow by the formula for the global).

* */

template<class T>

class cell{

void set(const cell_internal<T>* v){

value_->set(v);

}

boost::shared_ptr< cell_body<T> > value_;

public:

cell<T>(const cell<T>& v){

value_.reset(new cell_body<T>(new cell_shadow<T>(v.value_)));

}

cell<T>(const T& v=T()){

value_.reset(new cell_body<T>(new cell_constant<T>(v)));

}

cell<T>(const typename cell_internal_ptr<T>::type& v){

value_.reset(new cell_body<T>(v));

}

cell<T>(const cell_internal<T>* v){

value_.reset(new cell_body<T>(v));

}

cell<T>& operator=(const cell<T>& v){

if(&v != this){

set(new cell_shadow<T>(v.value_));

}

}

cell<T>& operator=(const T& v){

set(new cell_constant<T>(v));

}

cell<T>& operator=(const typename cell_internal_ptr<T>::type& v){

set(&(*v));

}

cell<T> operator+(const cell<T>& rhs) const {

return cell<T>(

new cell_op<T, std:lus<T> >(

value_,

rhs.value_

)

);

};

T get_value(void) const {return value_->get_value();}

};

template<class T>

inline cell<T> operator+(const cell<T>& lhs, const T& rhs){

return lhs + cell<T>(rhs);

}

template<class T>

inline cell<T> operator+(const T& lhs, const cell<T>& rhs){

return cell<T>(lhs) + rhs;

}