// handle_ref.C
// ----------------------------------------------------------------
// COMP 290-001: Algorithm Library Design, Lutz Kettner, 01/11/2000
// Example for a simple reference counted class.

#include <assert.h>

struct Rep {
    int  count;    
    Rep() : count( 1) {}
};

// Precondition: REP must have a member 'int count'.
template < class REP >
class Handle {
protected:
    // Invariant:  ptr is always != 0.
    REP* ptr;

public:
    Handle() : ptr( new REP) {}
    Handle( const REP& rep) : ptr( new REP(rep)) {}
    Handle( const Handle<REP>& x) : ptr(x.ptr) { ++ptr->count; }
    ~Handle() {
	if ( --ptr->count == 0) 
	    delete ptr;
    }    
    Handle<REP>&  operator=( const Handle<REP>& x) {
	++( x.ptr->count);  // this order of ++/-- works with self assignment!
	if ( --ptr->count == 0) 
	    delete ptr;	
	ptr = x.ptr;
	return *this;
    }
};

struct Integer_rep : public Rep {
    int i;
    Integer_rep() {}
    Integer_rep( int j) : i(j) {}
};

class Integer : public Handle<Integer_rep> {
public:
    Integer() {}
    Integer( int i) : Handle<Integer_rep>(i) {}    
    int value() const  { return ptr->i; }
};

int main() {
    Integer a(5);
    Integer b(a);
    a = b;
    assert( b.value() == 5);
}

// EOF //

