- INTERNAL use only! Installed backdoor to directly access a Resolvables
authorMichael Andres <ma@suse.de>
Thu, 16 Feb 2006 09:20:25 +0000 (09:20 +0000)
committerMichael Andres <ma@suse.de>
Thu, 16 Feb 2006 09:20:25 +0000 (09:20 +0000)
  implementation class. For target::store, as we have to serialize data,
  not exposed in the ResObjects public interface.

zypp/ResObject.h
zypp/detail/ImplConnect.h

index 9ea0bc9..c36115b 100644 (file)
@@ -80,6 +80,22 @@ namespace zypp
   };
   ///////////////////////////////////////////////////////////////////
 
+  /** Convert ResObject::Ptr into Ptr of a certain Kind.
+   * \return \c NULL iff \a p is \c NULL or points to a Resolvable
+   * not of the specified Kind.
+   * \relates ResObject
+   * \code
+   * asKind<Package>(resPtr);
+   * \endcode
+  */
+  template<class _Res>
+    inline typename ResTraits<_Res>::PtrType asKind( const ResObject::Ptr & p )
+    { return dynamic_pointer_cast<_Res>(p); }
+
+  template<class _Res>
+    inline typename ResTraits<_Res>::constPtrType asKind( const ResObject::constPtr & p )
+    { return dynamic_pointer_cast<const _Res>(p); }
+
   /////////////////////////////////////////////////////////////////
 } // namespace zypp
 ///////////////////////////////////////////////////////////////////
index cef7e6e..bcfd319 100644 (file)
@@ -12,6 +12,8 @@
 #ifndef ZYPP_DETAIL_IMPLCONNECT_H
 #define ZYPP_DETAIL_IMPLCONNECT_H
 
+#include "zypp/detail/ResObjectImplIf.h"
+
 ///////////////////////////////////////////////////////////////////
 namespace zypp
 { /////////////////////////////////////////////////////////////////
@@ -23,22 +25,41 @@ namespace zypp
     //
     // CLASS NAME : ImplConnect
     //
-    /** */
+    /** Connect to an implementation (internal).
+     * \note This is not to be exposed in some public interface!
+     * ImplConnect::resimpl takes a _Ptr to a resolvable as argument, and returns
+     * a _Ptr to it's implementation class:
+     * \code
+     * // ResObject::Ptr      -> detail::ResImplTraits<ResObject::Impl>::Ptr
+     * // ResObject::constPtr -> detail::ResImplTraits<ResObject::Impl>::constPtr
+     * // Package::Ptr        -> detail::ResImplTraits<Package::Impl>::Ptr
+     * // Package::constPtr   -> detail::ResImplTraits<Package::Impl>::constPtr
+     *
+     * ResObject::constPtr ptr;
+     * detail::ResImplTraits<Package::Impl>::constPtr implPtr;
+     *
+     * implPtr = detail::ImplConnect::resimpl( asKind<Package>(ptr) );
+     *
+     * // implPtr will be NULL, if ptr is NULL or does not refer to a Package.
+     * \endcode
+     * Basically makes a ResObjectImplIf
+    */
     struct ImplConnect
     {
       template<class _Res>
-        static typename _Res::Impl & resimpl( _Res & obj )
-        { return dynamic_cast<typename _Res::Impl &>( static_cast<ResObject &>(obj) ); }
+        static typename ResImplTraits<typename _Res::Impl>::Ptr resimpl( const intrusive_ptr<_Res> & obj )
+        { return dynamic_pointer_cast<typename _Res::Impl>(getImpl( obj )); }
 
       template<class _Res>
-        static const typename _Res::Impl & resimpl( const _Res & obj )
-        { return dynamic_cast<const typename _Res::Impl &>( static_cast<const ResObject &>(obj) ); }
+        static typename ResImplTraits<typename _Res::Impl>::constPtr resimpl( const intrusive_ptr<const _Res> & obj )
+        { return dynamic_pointer_cast<const typename _Res::Impl>(getConstImpl( obj )); }
 
-      static ResObject::Impl & resimpl( ResObject & obj )
-      { return obj.pimpl(); }
+    private:
+      static ResImplTraits<ResObject::Impl>::Ptr getImpl( const ResObject::Ptr & obj )
+      { return( obj ? &obj->pimpl() : NULL ); }
 
-      static const ResObject::Impl & resimpl( const ResObject & obj )
-      { return obj.pimpl(); }
+      static ResImplTraits<ResObject::Impl>::constPtr getConstImpl( const ResObject::constPtr & obj )
+      { return( obj ? &obj->pimpl() : NULL ); }
      };
     ///////////////////////////////////////////////////////////////////