Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

SharedValidity.hh

Go to the documentation of this file.
00001 
00020 #ifndef MANGO_PTR_SHARED_VALIDATOR_H
00021 #define MANGO_PTR_SHARED_VALIDATOR_H
00022 
00023 #include <assert.h> // use inline
00024 #include <algorithm> // use swap
00025 #include "nullness.hh"
00026 
00027 namespace MangoPtr 
00028 {
00029     
00030 class SharedValidity
00031 {
00032     private:
00034         struct State 
00035         {
00037             static const unsigned short bitsPerByte = 8;
00039             static const size_t countBits = bitsPerByte*sizeof(size_t) - 1;
00040             
00041             size_t count:countBits; 
00042             size_t valid:1;         
00043             
00045             State(): count(1), valid(false) {}
00046         };
00047     
00048     protected:
00050         SharedValidity(): state(NullPtr) {}
00051         inline SharedValidity(bool);
00052         inline SharedValidity(const SharedValidity&);
00053         inline SharedValidity& operator=(const SharedValidity&);
00055         inline ~SharedValidity() { if (isNotNull(state)) freeCount(); }
00056         inline void reset(bool);
00057         inline void setValid(bool);
00058    
00059     public:
00061         bool isValid()  const {return (isNotNull(state)) && state->valid;}
00063         bool isShared() const {return (isNotNull(state)) && state->count > 1;}
00064         size_t getRefCount() const {return isNull(state) ? 1 : state->count;}
00066         inline void swap(SharedValidity& rhs) { std::swap(state, rhs.state); }
00067         
00068         #if ! defined NDEBUG && defined TEST_SHARED
00069         static void setDeleted(bool);
00070         static void test();
00071         #endif
00072     
00073     private:
00075         void setValid()   {assert(isNotNull(state)); state->valid = true;}
00077         void setInvalid() {assert(isNotNull(state)); state->valid = false;}
00078         
00079         static inline State* newCount();
00080         inline State* getCountPtr() const;
00081         inline void freeCount();
00082     
00083     private: // data
00085         typedef State* SP;
00088         mutable SP state;
00089 };
00090 
00096 inline 
00097 SharedValidity::SharedValidity(const bool valid)
00098     : state(NullPtr) 
00099 {
00100     // only bother creating a new counter if 
00101     // setting to true since count=null implies false.
00102     if (valid) 
00103     {
00104         state = newCount(); // could throw bad_alloc
00105         setValid();
00106     }
00107 }
00108 
00115 inline 
00116 SharedValidity::SharedValidity(const SharedValidity& vv)
00117     : state(vv.getCountPtr()) // could throw bad_alloc
00118 {
00119     assert(isNotNull(state));
00120     state->count ++;
00121 }
00122 
00131 inline SharedValidity& 
00132 SharedValidity::operator=(const SharedValidity& vv)
00133 {
00134     State* const tmp = vv.getCountPtr(); // could throw bad_alloc
00135     if (tmp != state) // otherwise, self-assignment
00136     {
00137         if (isNotNull(state)) freeCount();
00138         (state = tmp)->count ++;
00139     }
00140     return *this;
00141 }
00142 
00149 inline SharedValidity::State* 
00150 SharedValidity::newCount() 
00151 { 
00152     #if ! defined NDEBUG && defined TEST_SHARED
00153     setDeleted(false);
00154     #endif
00155     return new State; 
00156 }
00157 
00162 inline void
00163 SharedValidity::freeCount()
00164 {
00165     assert(isNotNull(state));
00166     state->count --; 
00167     // always true: assert(state->count >= 0);
00168     if (0 == state->count) 
00169     {
00170         delete state;
00171         #if ! defined NDEBUG && defined TEST_SHARED
00172         setDeleted(true);
00173         #endif
00174     }
00175 }
00176    
00183 inline SharedValidity::State*
00184 SharedValidity::getCountPtr() 
00185 const
00186 {
00187     if (isNull(state)) state = newCount();
00188     assert(isNotNull(state));
00189     return state;
00190 }
00191 
00197 inline void 
00198 SharedValidity::setValid(const bool valid) 
00199 {
00200     if (valid) 
00201     {
00202         if (isNull(state)) state = newCount();
00203         setValid();
00204     }
00205     else
00206     {
00207         if (isValid()) setInvalid();
00208     }
00209 }
00210 
00218 inline void 
00219 SharedValidity::reset(const bool valid)
00220 {
00221     if (isShared())
00222     {
00223         assert(isNotNull(state));
00224         if (valid) 
00225         {
00226             State* tmp = newCount(); // could throw
00227             state->count --; 
00228             state = tmp;
00229             setValid();
00230         }
00231         else // false, just nullify pointer
00232         {
00233             state->count --; 
00234             nullify(state); // doesn't affect those who share our validity
00235         }
00236     }
00237     else setValid(valid);
00238 }
00239 
00240 } // namespace MangoPtr
00241 
00272 #endif // MANGO_PTR_SHARED_VALIDATOR_H
00273 

Generated on Tue Nov 12 20:43:53 2002 for Mango-ptr Library by doxygen1.2.18