Go to the documentation of this file.00001 #ifndef FORIA_LOCKABLE_HH
00002 #define FORIA_LOCKABLE_HH
00003
00004 #include <stdexcept>
00005 #include <string>
00006
00007 #include "boost/smart_ptr.hpp"
00008
00009 namespace ForIA{
00010
00011 using std::string;
00012 using std::runtime_error;
00013
00014 class LockedException: public runtime_error{
00015
00016 public:
00017
00018 LockedException(const string &name): runtime_error(name + ": object is locked!"){}
00019
00020 };
00021
00022 class LockableObject{
00023
00024 public:
00025
00026 LockableObject(): m_locked(true){}
00027
00028 bool isLocked()const{return m_locked;}
00029
00030 void throwIfLocked()const{
00031 if(isLocked()) throw LockedException(this->name());
00032 return;
00033 }
00034
00035
00036 protected:
00037 string name()const{return "Lockable";}
00038
00039 private:
00040
00041 template<class T> friend class LockableCreator;
00042
00043 void lock(){m_locked=true;}
00044 void unlock(){m_locked=false;}
00045
00046 bool m_locked;
00047
00048 };
00049
00050
00051 template<typename T>
00052 class LockableValue{
00053
00054 public:
00055
00056 LockableValue(const LockableObject* parent): m_parent(parent){};
00057
00058 LockableValue &operator=(const T &val){
00059
00060 m_parent->throwIfLocked();
00061 m_value = val;
00062 return *this;
00063 }
00064
00065 const T &value()const{return m_value;};
00066
00067 private:
00068
00069 LockableValue(){}
00070
00071 const LockableObject *m_parent;
00072
00073 T m_value;
00074 };
00075
00076 template<class T>
00077 class LockableCreator{
00078
00079 public:
00080
00081 LockableCreator(){
00082
00083 m_ptr = new T();
00084 m_ptr->unlock();
00085 }
00086
00087 ~LockableCreator(){
00088 m_ptr->lock();
00089 }
00090
00091 boost::shared_ptr<T> object()const{return boost::shared_ptr<T>(m_ptr);}
00092
00093
00094 private:
00095
00096 T *m_ptr;
00097
00098 };
00099 }
00100
00101 #endif