00001 /* vim:sw=2: 00002 * Copyright (c) 2007, Gennady Bystritsky <bystr@mac.com> 00003 * 00004 * Distributed under the MIT Licence. 00005 * This is free software. See 'LICENSE' for details. 00006 * You must read and accept the license prior to use. 00007 */ 00008 00009 #ifndef _SK_UTIL_SLOT_POLICY_SHARING_HXX_ 00010 #define _SK_UTIL_SLOT_POLICY_SHARING_HXX_ 00011 00012 #include <sk/util/slot/mixin/LinkCounter.h> 00013 #include <sk/util/slot/policy/Storing.hxx> 00014 #include <sk/util/IllegalStateException.h> 00015 00016 namespace sk { 00017 namespace util { 00018 namespace slot { 00019 namespace policy { 00020 template<typename T> 00021 class Sharing 00022 : public Storing<T, slot::mixin::LinkCounter> 00023 { 00024 typedef Storing<T, slot::mixin::LinkCounter> Super; 00025 00026 public: 00027 Sharing() {} 00028 00029 Sharing(const Sharing<T>& other) { 00030 accept(other); 00031 } 00032 00033 void operator=(const Sharing<T>& other) { 00034 accept(other); 00035 } 00036 00037 int getLinks() const { 00038 return Super::getSlot().getCounter(); 00039 } 00040 00041 protected: 00042 void setObject(T* object) { 00043 if(Super::hasSlot() == true) { 00044 if(Super::getSlot().isOwner() == false) { 00045 throw sk::util::IllegalStateException("Non-replacable shared content"); 00046 } 00047 delete Super::getSlot().replace(object); 00048 } 00049 else { 00050 Super::setObject(object); 00051 Super::getSlot().link(); 00052 } 00053 } 00054 00055 void setObject(T& object) { 00056 if(Super::hasSlot() == true) { 00057 throw sk::util::IllegalStateException("Non-replacable shared content"); 00058 } 00059 else { 00060 Super::setObject(object); 00061 Super::getSlot().link(); 00062 } 00063 } 00064 00065 void clearSlot() { 00066 if(Super::hasSlot() == true) { 00067 if(Super::getSlot().unlink() == true) { 00068 Super::clearSlot(); 00069 } 00070 else { 00071 Super::setSlot(0); 00072 } 00073 } 00074 } 00075 00076 private: 00077 void accept(const Sharing<T>& other) { 00078 if(&other == this) { 00079 return; 00080 } 00081 clearSlot(); 00082 00083 if(other.hasSlot() == true) { 00084 Super::setSlot(&other.getSlot()); 00085 Super::getSlot().link(); 00086 } 00087 } 00088 }; 00089 } 00090 } 00091 } 00092 } 00093 00094 #endif /* _SK_UTIL_SLOT_POLICY_SHARING_HXX_ */