00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 #ifndef COH_TYPED_HOLDER_HPP
00017 #define COH_TYPED_HOLDER_HPP
00018 
00019 #include "coherence/lang/compatibility.hpp"
00020 
00021 #include "coherence/lang/ChainedHandleElement.hpp"
00022 #include "coherence/lang/TypedHandle.hpp"
00023 
00024 #include <ostream>
00025 
00026 COH_OPEN_NAMESPACE2(coherence,lang)
00027 
00028 class Object;
00029 template<class T> class MemberHolder;
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 template<class T>
00058 class TypedHolder
00059     : public ChainedHandleElement
00060     {
00061     
00062 
00063     public:
00064 
00065 
00066 
00067         typedef const T ValueType;
00068 
00069 
00070 
00071 
00072         typedef typename T::Handle ValueHandle;
00073 
00074 
00075 
00076 
00077         typedef typename T::View ValueView;
00078 
00079 
00080     
00081 
00082     public:
00083 
00084 
00085 
00086         TypedHolder()
00087             : ChainedHandleElement( false), m_cpo(NULL)
00088             {
00089             }
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097         TypedHolder(const TypedHolder& that)
00098             : ChainedHandleElement(that, that.m_fView), m_cpo(that.m_cpo)
00099             {
00100             }
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111         template<class DT> TypedHolder(const TypedHandle<DT>& that)
00112             : ChainedHandleElement(that, constness<DT>::applied),
00113               m_cpo(get_pointer(that))
00114             {
00115             }
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123         template<class DT> TypedHolder(const TypedHolder<DT>& that)
00124             : ChainedHandleElement(that, that.m_fView), m_cpo(that.m_cpo)
00125             {
00126             }
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 
00136         TypedHolder(T* po)
00137             : ChainedHandleElement( false),
00138               m_cpo(po == NULL || po->_attach( false) == NULL
00139                       ? NULL : po)
00140             {
00141             }
00142 
00143 
00144 
00145 
00146 
00147 
00148         template<class DT> TypedHolder(DT* po)
00149             : ChainedHandleElement( constness<DT>::applied),
00150               m_cpo(po == NULL || po->_attach( false) == NULL
00151                       ? NULL : po)
00152             {
00153             }
00154 
00155 
00156 
00157 
00158         ~TypedHolder()
00159             {
00160             Action nAction = unlink();
00161             if (m_cpo && nAction != action_none)
00162                 {
00163                 performAction(nAction);
00164                 }
00165             }
00166 
00167 
00168     
00169 
00170     public:
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179         TypedHolder& operator=(const TypedHolder& that)
00180             {
00181             set(get_pointer(that), that.m_fView, that);
00182             return *this;
00183             }
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193         template<class DT> TypedHolder& operator=(const TypedHolder<DT>& that)
00194             {
00195             set(get_pointer(that), that.m_fView, that);
00196             return *this;
00197             }
00198 
00199 
00200 
00201 
00202 
00203 
00204         template<class PT>
00205         operator TypedHandle<const PT>() const
00206             {
00207             return TypedHandle<const PT>(m_cpo, *this);
00208             }
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217         const T& operator*() const
00218             {
00219             const T* po = m_cpo;
00220             if (NULL == po)
00221                 {
00222                 coh_throw_npe(typeid(T));
00223                 }
00224             return *po;
00225             }
00226 
00227 
00228 
00229 
00230 
00231 
00232         const T* operator->() const
00233             {
00234             const T* po = m_cpo;
00235             if (NULL == po)
00236                 {
00237                 coh_throw_npe(typeid(T));
00238                 }
00239             return po;
00240             }
00241 
00242 
00243     
00244 
00245     protected:
00246 
00247 
00248 
00249 
00250 
00251         bool isHandle() const
00252             {
00253             return m_fView == false;
00254             }
00255 
00256 
00257 
00258 
00259 
00260 
00261 
00262         TypedHandle<T> getHandle() const
00263             {
00264             if (m_fView)
00265                 {
00266                 return NULL;
00267                 }
00268             
00269             return TypedHandle<T>(const_cast<T*>(m_cpo), *this);
00270             }
00271 
00272 
00273 
00274 
00275 
00276 
00277         void set(const T* cp, bool fView, const ChainedHandleElement& that)
00278             {
00279             
00280             Action nAction = link(that);
00281             if (m_cpo && nAction != action_none)
00282                 {
00283                 performAction(nAction);
00284                 }
00285             m_cpo   = cp;
00286             m_fView = fView;
00287             }
00288 
00289 
00290 
00291 
00292 
00293 
00294         void performAction(Action nAction)
00295             {
00296             switch (nAction)
00297                 {
00298                 case action_flip:
00299                     m_cpo->_attach( false);
00300                     
00301                 case action_detach:
00302                     if (m_fView)
00303                         {
00304                         m_cpo->_detach( false);
00305                         }
00306                     else
00307                         {
00308                         const_cast<T*>(m_cpo)->_detach( false);
00309                         }
00310                     
00311                 case action_none:
00312                 default:
00313                     break;
00314                 }
00315             }
00316 
00317 
00318     
00319 
00320     protected:
00321 
00322 
00323 
00324         const T* m_cpo;
00325 
00326 
00327     
00328 
00329 
00330 
00331 
00332     template<class O> friend const O* get_pointer(const TypedHolder<O>& th);
00333 
00334 
00335 
00336 
00337     template<class O> friend bool is_handle(const TypedHolder<O>& th);
00338 
00339 
00340 
00341 
00342     template<class D, class H> friend D cast(const TypedHolder<H>& th,
00343             bool fTest);
00344 
00345 
00346 
00347 
00348     template<class> friend class TypedHolder;
00349 
00350 
00351 
00352 
00353     template<class> friend class MemberHolder;
00354     };
00355 
00356 
00357 
00358 
00359 
00360 
00361 
00362 
00363 
00364 
00365 
00366 
00367 
00368 template <typename Char, typename Traits, class T>
00369 COH_INLINE std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& out,
00370         const TypedHolder<T>& th)
00371     {
00372     out << (typename T::View) th;
00373     return out;
00374     }
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382 
00383 
00384 
00385 
00386 
00387 
00388 
00389 
00390 template<class T>
00391 const T* get_pointer(const TypedHolder<T>& th)
00392     {
00393     return th.m_cpo;
00394     }
00395 
00396 
00397 
00398 
00399 
00400 
00401 template<class T> void clear_handle(TypedHolder<T>& th)
00402     {
00403     th = NULL;
00404     }
00405 
00406 
00407 
00408 
00409 
00410 
00411 
00412 
00413 template<class T>
00414 bool is_null(const TypedHolder<T>& th)
00415     {
00416     return th == NULL;
00417     }
00418 
00419 
00420 
00421 
00422 
00423 
00424 
00425 
00426 template<class T>
00427 bool is_handle(const TypedHolder<T>& th)
00428     {
00429     return th.isHandle();
00430     }
00431 
00432 
00433 
00434 
00435 
00436 
00437 
00438 
00439 
00440 
00441 
00442 
00443 template<class D, class T>
00444 D cast(const TypedHolder<T>& th, bool fThrow = true)
00445     {
00446     TypedHandle<T> h = th.getHandle();
00447     if (NULL == h)
00448         {
00449         TypedHandle<const T> v = th;
00450 
00451         if (NULL == v)
00452             {
00453             
00454             return D(); 
00455             }
00456 
00457         
00458         if (constness<typename D::ValueType>::applied)
00459             {
00460             
00461             
00462             
00463             
00464             TypedHandle<typename D::ValueType> vD(
00465                 (typename D::ValueType*) get_pointer(
00466                         cast<typename D::ValueType::View>(v, fThrow)), v);
00467             return vD;
00468             }
00469         else
00470             {
00471             
00472             if (fThrow)
00473                 {
00474                 coh_throw_const_cast(typeid(typename D::ValueType), typeid(*th));
00475                 }
00476             return D(); 
00477             }
00478         }
00479 
00480     
00481     
00482     
00483     return cast<typename D::ValueType::Handle>(h, fThrow);
00484     }
00485 
00486 
00487 
00488 
00489 
00490 
00491 
00492 
00493 template<class D, class T>
00494 bool instanceof(const TypedHolder<T>& th)
00495     {
00496     return NULL !=th && NULL != cast<D>(th, false);
00497     }
00498 
00499 COH_CLOSE_NAMESPACE2
00500 
00501 #endif // COH_TYPED_HOLDER_HPP