SAGA Adaptor CPI v.1.0
|
00001 // Copyright (c) 2005-2009 Hartmut Kaiser 00002 // Copyright (c) 2005 Stephan Hirmer (stephan.hirmer@gmail.com) 00003 // 00004 // Distributed under the Boost Software License, Version 1.0. (See accompanying 00005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 00006 00007 #ifndef SAGA_SAGA_ADAPTORS_INSTANCE_DATA_HPP 00008 #define SAGA_SAGA_ADAPTORS_INSTANCE_DATA_HPP 00009 00010 #include <string> 00011 00012 #include <boost/noncopyable.hpp> 00013 00014 #include <saga/saga/util.hpp> 00015 #include <saga/saga/adaptors/config.hpp> 00016 #include <saga/saga/adaptors/instance_data_base.hpp> 00017 #include <saga/saga/adaptors/task.hpp> 00018 00019 #include <saga/impl/engine/cpi.hpp> 00020 #include <saga/impl/engine/proxy.hpp> 00021 00023 // boost::get_pointer doesn't know anything about std::tr1::shared_ptr, 00024 // which is a pain 00025 #if defined(SAGA_USE_TR1_NAMESPACE) 00026 namespace boost 00027 { 00028 template<class T> 00029 inline T* get_pointer(std::tr1::shared_ptr<T> const& p) 00030 { 00031 return p.get(); 00032 } 00033 } 00034 #endif 00035 00037 namespace saga { namespace adaptors { 00038 00048 template <typename T> 00049 class instance_data 00050 : public boost::noncopyable 00051 { 00052 private: 00053 typedef saga::impl::proxy proxy; 00054 00055 // this holds the locked data 00056 proxy * proxy_; 00057 TR1::shared_ptr <T> data_; 00058 00059 public: 00060 typedef T instance_data_type; 00061 00069 instance_data (proxy* prxy) 00070 : proxy_ (prxy), 00071 data_ (TR1::static_pointer_cast<T>( 00072 proxy_->check_out_instance_data())) 00073 { 00074 } 00075 00076 template <typename Cpi> 00077 instance_data (Cpi *cpi_instance) 00078 : proxy_ (cpi_instance->get_proxy ()), 00079 data_ (TR1::static_pointer_cast<T>( 00080 proxy_->check_out_instance_data())) 00081 { 00082 } 00083 00084 // default constructor. 00085 instance_data () 00086 : proxy_ (NULL) 00087 { 00088 } 00089 00090 // This will be called by the initializing instance to provide the 00091 // initial data to be stored for the CPI instance 00092 template <typename Cpi> 00093 void init_data (Cpi *proxy, TR1::shared_ptr<instance_data_type> d) 00094 { 00095 proxy_ = proxy; 00096 data_ = TR1::static_pointer_cast<instance_data_type> ( 00097 proxy_->register_instance_data(d)); 00098 } 00099 00100 // This will be called by the last instance before it goes out of 00101 // scope 00102 template <typename Cpi> 00103 void release_data (Cpi *proxy) 00104 { 00105 proxy_ = proxy; 00106 proxy_->release_instance_data(); 00107 } 00108 00112 ~instance_data (void) 00113 { 00114 if ( NULL != proxy_ && data_ ) 00115 proxy_->check_in_instance_data (); 00116 } 00117 00118 // automatic conversion to the actual adaptor data type is provided 00119 T * operator->() const 00120 { 00121 return boost::get_pointer (data_); 00122 } 00123 }; 00124 00137 template <typename T> 00138 class dynamic_instance_data 00139 : public boost::noncopyable 00140 { 00141 private: 00142 typedef saga::impl::proxy proxy; 00143 00144 // this holds the locked data 00145 proxy * proxy_; 00146 TR1::shared_ptr<adaptors::instance_data_base> base_data_; 00147 TR1::shared_ptr<T> data_; 00148 00149 void tidy() 00150 { 00151 if (NULL != proxy_ && base_data_) 00152 { 00153 proxy_->check_in_instance_data(); 00154 base_data_.reset(); 00155 data_.reset(); 00156 } 00157 } 00158 00159 public: 00160 typedef T instance_data_type; 00161 00169 dynamic_instance_data (proxy* prxy) 00170 : proxy_(prxy), 00171 base_data_(proxy_->check_out_instance_data()), 00172 data_(TR1::dynamic_pointer_cast<T>(base_data_)) 00173 { 00174 if (!is_valid()) 00175 tidy(); 00176 } 00177 00178 template <typename Cpi> 00179 dynamic_instance_data (Cpi *cpi_instance) 00180 : proxy_ (cpi_instance->get_proxy ()), 00181 base_data_(proxy_->check_out_instance_data()), 00182 data_(TR1::dynamic_pointer_cast<T>(base_data_)) 00183 { 00184 if (!is_valid()) 00185 tidy(); 00186 } 00187 00188 // default constructor. 00189 dynamic_instance_data() 00190 : proxy_ (NULL) 00191 { 00192 } 00193 00194 // This will be called by the initializing instance to provide the 00195 // initial data to be stored for the CPI instance 00196 template <typename Cpi> 00197 void init_data (Cpi *proxy, TR1::shared_ptr<instance_data_type> d) 00198 { 00199 proxy_ = proxy; 00200 base_data_ = proxy_->register_instance_data(d); 00201 data_ = TR1::dynamic_pointer_cast<instance_data_type>(base_data_); 00202 if (!is_valid()) 00203 tidy(); 00204 } 00205 00206 // This will be called by the last instance before it goes out of 00207 // scope 00208 template <typename Cpi> 00209 void release_data (Cpi *proxy) 00210 { 00211 proxy_ = proxy; 00212 proxy_->release_instance_data(); 00213 } 00214 00218 ~dynamic_instance_data (void) 00219 { 00220 tidy(); 00221 } 00222 00223 // automatic conversion to the actual adaptor data type is provided 00224 T * operator->() const 00225 { 00226 return boost::get_pointer(data_); 00227 } 00228 00229 // return, if the object got initialized correctly 00230 bool is_valid() const 00231 { 00232 return data_; 00233 } 00234 }; 00235 00236 }} // namespace saga::adaptors 00238 00239 #endif // SAGA_SAGA_ADAPTORS_INSTANCE_DATA_HPP 00240