00001 #ifndef NO_PTR_RREF_USAGE_H
00002 #define NO_PTR_RREF_USAGE_H
00003
00023 #include <assert.h>
00024 #include "nullness.hh"
00025 #include "RefCountedBool.hh"
00026 #include "NoPtrFwd.hh"
00027
00028 namespace NoPtr
00029 {
00030
00031 namespace NoPtrImpl
00032 {
00033
00034
00035
00036
00037 class RRefUsage
00038 {
00039 public:
00040
00041 RRefUsage(): _state(NullPtr) {}
00042
00043 ~RRefUsage() {}
00044
00045 RRefUsage(const RRefUsage& rhs): _state(rhs._state) {}
00046
00047 void operator=(const RRefUsage& rhs) { _state = rhs._state; }
00048
00049
00050
00051 void shareFrom(const RRefUsage& rhs)
00052 {
00053 assert(_state == NullPtr);
00054 _state = rhs._state;
00055 assert(_state && _state->valid);
00056 _state->count ++;
00057 }
00058
00059 void swap(RRefUsage& rhs)
00060 {
00061 RefCountedBool<>* tmp = _state;
00062 _state = rhs._state;
00063 rhs._state = tmp;
00064 }
00065
00066
00067
00068
00069 void doAssertState(RefCountedBool<>* state) const
00070 {
00071 if (state == NullPtr) assert(_state == NullPtr);
00072 else assert(*_state == *state);
00073 }
00074
00075 protected:
00076 RefCountedBool<>* _state;
00077 };
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 class RRefUsageForOwner: public RRefUsage
00088 {
00089 public:
00090 void swap(RRefUsageForOwner& rhs) {RRefUsage::swap(rhs);}
00091
00092 void create()
00093 {
00094 if (_state == NullPtr)
00095 _state = new RefCountedBool<>(true);
00096 }
00097
00098 void destroy()
00099 {
00100 if (_state)
00101 {
00102 if (-- _state->count) _state->valid = false;
00103 else delete _state;
00104 }
00105 }
00106
00107
00108
00109 void reset()
00110 {
00111 if (_state && _state->count > 1)
00112 {
00113 _state->count --;
00114 _state->valid = false;
00115 _state = NullPtr;
00116 }
00117
00118 }
00119
00120
00121 void moveTo(RRefUsageForOwner& rhs)
00122 {
00123 assert(rhs._state == NullPtr);
00124 rhs._state = _state;
00125 _state = NullPtr;
00126 }
00127 };
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 class RRefUsageForUser: public RRefUsage
00139 {
00140 private:
00141
00142 template <typename> friend class ::NoPtr::RRef;
00143 RRefUsageForUser() {}
00144
00145 public:
00146 void swap(RRefUsageForUser& rhs) {RRefUsage::swap(rhs);}
00147
00148
00149 bool isValid() const {return _state && _state->valid;}
00150
00151
00152 void destroy()
00153 {
00154 if (_state && !(-- _state->count)) delete _state;
00155 }
00156
00157
00158
00159 void reset()
00160 {
00161 if (_state)
00162 {
00163 if ( (-- _state->count) == 0)
00164 {
00165
00166 assert(! _state->valid);
00167 delete _state;
00168 }
00169 _state = NullPtr;
00170 }
00171
00172 }
00173
00174 };
00175
00176
00177 }
00178
00179 }
00180
00181 #endif // NO_PTR_RREF_USAGE_H