SAGA Adaptor CPI v.1.0
instance_data.hpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines