The syntax coloring for this page was performed by vim, the powerful cross-platform editor. www.vim.org.
// Author: Dave Whipp, mailto:dave@whipp.name // Date: March 2000 // Company: Infineon Technologies Corp.ManagedRepresentation.h
#ifndef _utilities__ManagedRepresentation_h #define _utilities__ManagedRepresentation_h //#include "utilities/FastAllocate.h" namespace utilities { class ManagedRepresentation // : public FastAllocate { public: ManagedRepresentation(); virtual ~ManagedRepresentation(); void removeReference(); void addReference(); int getReferenceCount() const; private: unsigned int _ref_count; }; } #endif
ManagedRepresentation.cpp
#include "ManagedRepresentation.h" #include typeinfo> #include iostream> using namespace utilities; ManagedRepresentation::ManagedRepresentation() : _ref_count(1) {} ManagedRepresentation::~ManagedRepresentation() { if (_ref_count--) { cerr << "warning: dtor with non-zero ref count in ManagedRepresentation. are you using a stack-based variable?" << endl; } // ref count is -1! (might catch multiple deletions) } void ManagedRepresentation::removeReference() { if (--_ref_count == 0) delete this; } void ManagedRepresentation::addReference() { ++_ref_count; } int ManagedRepresentation::getReferenceCount() const { return _ref_count; }
ManagedPointer.h
#ifndef _utilities__ManagedPointer_h #define _utilities__ManagedPointer_h namespace utilities { template<class T> class ValueObject; template<class T> class ManagedPointer { public: ManagedPointer(); ManagedPointer(T* arg); ManagedPointer(const ManagedPointer& arg); virtual ~ManagedPointer(); void assign(const ManagedPointer& arg); const T& query() const; T& modify(); private: mutable T* _rep; friend class ValueObject; }; template<class T> inline ManagedPointer ::ManagedPointer() : _rep(new T) {} template<class T> inline ManagedPointer ::ManagedPointer(T* arg) : _rep(arg) {} template<class T> inline ManagedPointer ::ManagedPointer(const ManagedPointer& arg) : _rep(arg._rep) { _rep->addReference(); } template<class T> inline void ManagedPointer ::assign(const ManagedPointer& arg) { if (this != &arg) { _rep->removeReference(); arg._rep->addReference(); _rep = arg._rep; } } template<class T> inline ManagedPointer ::~ManagedPointer() { _rep->removeReference(); } template<class T> inline const T& ManagedPointer ::query() const { return *_rep; } template<class T> inline T& ManagedPointer ::modify() { return *_rep; } } #endif
ValueObject.h
#ifndef _utilities__ValueObject_h #define _utilities__ValueObject_h #include "utilities/ManagedPointer.h" namespace utilities { template<class T> class ValueObject : public ManagedPointer{ public: ValueObject(); ValueObject(T* arg); ValueObject(const ValueObject& arg); T& modify(); }; template<class T> inline ValueObject ::ValueObject() : ManagedPointer (new T) {} template<class T> inline ValueObject ::ValueObject(T* arg) : ManagedPointer (arg) {} template<class T> inline ValueObject ::ValueObject(const ValueObject& arg) : ManagedPointer (arg) {} template<class T> inline T& ValueObject ::modify() { if (_rep->getReferenceCount() > 1) { _rep->removeReference(); _rep=_rep->clone(); } return *_rep; } } #endif
test_ManagedRepresentation.cpp
#include "test_support.h" #include "ManagedRepresentation.h" #include "ManagedPointer.h" #include "ValueObject.h" using namespace utilities; class Representation : public ManagedRepresentation { public: Representation(int v) : ManagedRepresentation(), _value(v) {} Representation(const Representation& arg) : ManagedRepresentation(), _value(arg._value) {} Representation* clone() { return new Representation(*this); } int getValue() const { return _value; } void setValue(int v) {_value = v;} private: int _value; }; class Pointer : public ManagedPointer{ public: Pointer(int v) : ManagedPointer (new Representation(v)) {} Pointer(const Pointer& arg) : ManagedPointer (arg) {} Pointer& operator=(const Pointer& arg) {assign(arg); return *this;} int getValue() const {return query().getValue();} void setValue(int v) {modify().setValue(v);} }; class Value : public ValueObject { public: Value(int v) : ValueObject (new Representation(v)) {} Value(const Value& arg) : ValueObject (arg) {} Value& operator=(const Value& arg) {assign(arg); return *this;} int getValue() const {return query().getValue();} void setValue(int v) {modify().setValue(v);} }; void test_Pointer() { Pointer p1(1); Pointer p2(2); TEST_EQUAL(p1.getValue(), 1) TEST_EQUAL(p2.getValue(), 2) Pointer p3(-1); p3=p1; TEST_EQUAL(p3.getValue(), 1) p3.setValue(3); TEST_EQUAL(p3.getValue(), 3) TEST_EQUAL(p1.getValue(), 3) Pointer p4(p1); TEST_EQUAL(p4.getValue(), 3) p4.setValue(4); TEST_EQUAL(p4.getValue(), 4) TEST_EQUAL(p1.getValue(), 4) } void test_Value() { Value v1(11); Value v2(22); TEST_EQUAL(v1.getValue(), 11) TEST_EQUAL(v2.getValue(), 22) Value v3=33; TEST_EQUAL(v3.getValue(), 33) v3=v1; TEST_EQUAL(v3.getValue(), 11) v3.setValue(33); TEST_EQUAL(v3.getValue(), 33) TEST_EQUAL(v1.getValue(), 11) Value v4(v1); TEST_EQUAL(v4.getValue(), 11) v4.setValue(44); TEST_EQUAL(v4.getValue(), 44) TEST_EQUAL(v1.getValue(), 11) } void test_ManagedRepresentation() { test_Pointer(); test_Value(); }
test_support.h
#include iostream> #include stdexcept> extern int error_count; #ifdef DEBUG #define DEBUG_OUT(x,y) {std::cerr << "DEBUG: " << __FILE__ << " [" << (__LINE__) << "] : " << #x << " " << y << std::endl;} #else #define DEBUG_OUT(x,y) #endif #define FAIL(x) { error_count++; std::cerr << "ERROR: " << __FILE__ << " [" << (__LINE__) << "] : " << x << std::endl;} #define TEST(x) { DEBUG_OUT(TEST, #x) if (!(x)) FAIL(#x)} #define TEST_EQUAL(x,y) { DEBUG_OUT(TEST_EQUAL, #x << "," << #y) if ((x) != (y)) FAIL(#x << " == " << #y << " (" << (x) << " != " << (y) << ")") } #define TEST_CATCH(e,x) { DEBUG_OUT(TEST_CATCH, #e) try { {x;} FAIL("exception (" << #e << ") not thrown: " << #x) } catch (e) {} }