Author: mcalmer
Date: Sun Jul 4 17:08:27 2010
New Revision: 2681
URL: http://svn.opensuse.org/viewcvs/limal?rev=2681&view=rev
Log:
add PtrTypes
Added:
limal-branches/mc-devel/limal-ca-mgm/src/limal/PtrTypes.hpp
Added: limal-branches/mc-devel/limal-ca-mgm/src/limal/PtrTypes.hpp
URL: http://svn.opensuse.org/viewcvs/limal/limal-branches/mc-devel/limal-ca-mgm/src/limal/PtrTypes.hpp?rev=2681&view=auto
==============================================================================
--- limal-branches/mc-devel/limal-ca-mgm/src/limal/PtrTypes.hpp (added)
+++ limal-branches/mc-devel/limal-ca-mgm/src/limal/PtrTypes.hpp Sun Jul 4 17:08:27 2010
@@ -0,0 +1,506 @@
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file limal/PtrTypes.h
+*/
+#ifndef LIMAL_BASE_PTRTYPES_H
+#define LIMAL_BASE_PTRTYPES_H
+
+#include <string>
+
+#include
+#include
+#include
+#include
+
+///////////////////////////////////////////////////////////////////
+namespace ca_mgm
+{ /////////////////////////////////////////////////////////////////
+
+ /** \defgroup ZYPP_SMART_PTR Smart pointer types
+ * Smart pointer types.
+ *
+ * Namespace ca_mgm provides 3 smart pointer types \b using the
+ * boost smart pointer library.
+ *
+ * \li \c scoped_ptr Simple sole ownership of single objects. Noncopyable.
+ *
+ * \li \c shared_ptr Object ownership shared among multiple pointers
+ *
+ * \li \c weak_ptr Non-owning observers of an object owned by shared_ptr.
+ *
+ * And \ref ca_mgm::RW_pointer, as wrapper around a smart pointer,
+ * poviding \c const correct read/write access to the object it refers.
+ */
+ /*@{*/
+
+ /** shared_ptr custom deleter doing nothing.
+ * A custom deleter is a function being called when the
+ * last shared_ptr goes out of score. Per default the
+ * object gets deleted, but you can insall custom deleters
+ * as well. This one does nothing.
+ *
+ * \code
+ * // Some class providing a std::istream
+ * struct InpuStream
+ * {
+ * // Per deafult use std::cin.
+ * InputStream()
+ * : _stream( &std::cin, NullDeleter() )
+ * {}
+ * // Or read from a file.
+ * InputStream( const Pathname & file_r )
+ * : _stream( new ifgzstream( _path.asString().c_str() ) )
+ * {}
+ * // Or use a stream priovided by the application.
+ * InputStream( std::istream & stream_r )
+ * : _stream( &stream_r, NullDeleter() )
+ * {}
+ *
+ * std::istream & stream()
+ * { return *_stream; }
+ *
+ * private:
+ * shared_ptrstd::istream _stream;
+ * };
+ * \endcode
+ */
+ struct NullDeleter
+ {
+ void operator()( const void *const ) const
+ {}
+ };
+
+ /** \class scoped_ptr */
+ using boost::scoped_ptr;
+
+ /** \class shared_ptr */
+ using boost::shared_ptr;
+
+ /** \class weak_ptr */
+ using boost::weak_ptr;
+
+ /** \class intrusive_ptr */
+ using boost::intrusive_ptr;
+
+ /** */
+ using boost::static_pointer_cast;
+ /** */
+ using boost::const_pointer_cast;
+ /** */
+ using boost::dynamic_pointer_cast;
+
+ /////////////////////////////////////////////////////////////////
+} // namespace ca_mgm
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+namespace std
+{ /////////////////////////////////////////////////////////////////
+
+ // namespace sub {
+ // class Foo;
+ // typedef ca_mgm::intrusive_ptr<Foo> Foo_Ptr; // see DEFINE_PTR_TYPE(NAME) macro below
+ // }
+
+ // Defined in namespace std g++ finds the output operator (König-Lookup),
+ // even if we typedef the pointer in a different namespace than ::ca_mgm.
+ // Otherwise we had to define an output operator always in the same namespace
+ // as the typedef (else g++ will just print the pointer value).
+
+ /** \relates ca_mgm::shared_ptr Stream output. */
+ template<class _D>
+ inline std::ostream & operator<<( std::ostream & str, const ca_mgm::shared_ptr<_D> & obj )
+ {
+ if ( obj )
+ return str << *obj;
+ return str << std::string("NULL");
+ }
+ /** \relates ca_mgm::shared_ptr Stream output. */
+ template<class _D>
+ inline std::ostream & dumpOn( std::ostream & str, const ca_mgm::shared_ptr<_D> & obj )
+ {
+ if ( obj )
+ return dumpOn( str, *obj );
+ return str << std::string("NULL");
+ }
+
+ /** \relates ca_mgm::intrusive_ptr Stream output. */
+ template<class _D>
+ inline std::ostream & operator<<( std::ostream & str, const ca_mgm::intrusive_ptr<_D> & obj )
+ {
+ if ( obj )
+ return str << *obj;
+ return str << std::string("NULL");
+ }
+ /** \relates ca_mgm::intrusive_ptr Stream output. */
+ template<class _D>
+ inline std::ostream & dumpOn( std::ostream & str, const ca_mgm::intrusive_ptr<_D> & obj )
+ {
+ if ( obj )
+ return dumpOn( str, *obj );
+ return str << std::string("NULL");
+ }
+ /////////////////////////////////////////////////////////////////
+} // namespace std
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+namespace ca_mgm
+{ /////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // RW_pointer traits
+ //
+ ///////////////////////////////////////////////////////////////////
+ /**
+ * Don't forgett to provide versions for _Ptr and _constPtr,
+ * esp. if creation a of temporary is not acceptable (eg. when
+ * checking the ref count value).
+ */
+ namespace rw_pointer {
+
+ template<class _D>
+ struct Shared
+ {
+ typedef shared_ptr<_D> _Ptr;
+ typedef shared_ptr<const _D> _constPtr;
+ /** Check whether pointer is not shared. */
+ bool unique( const _constPtr & ptr_r )
+ { return !ptr_r || ptr_r.unique(); }
+ bool unique( const _Ptr & ptr_r )
+ { return !ptr_r || ptr_r.unique(); }
+ /** Return number of references. */
+ long use_count( const _constPtr & ptr_r ) const
+ { return ptr_r.use_count(); }
+ long use_count( const _Ptr & ptr_r ) const
+ { return ptr_r.use_count(); }
+ };
+
+ template<class _D>
+ struct Intrusive
+ {
+ typedef intrusive_ptr<_D> _Ptr;
+ typedef intrusive_ptr<const _D> _constPtr;
+ /** Check whether pointer is not shared. */
+ bool unique( const _constPtr & ptr_r )
+ { return !ptr_r || (ptr_r->refCount() <= 1); }
+ bool unique( const _Ptr & ptr_r )
+ { return !ptr_r || (ptr_r->refCount() <= 1); }
+ /** Return number of references. */
+ long use_count( const _constPtr & ptr_r ) const
+ { return ptr_r ? ptr_r->refCount() : 0; }
+ long use_count( const _Ptr & ptr_r ) const
+ { return ptr_r ? ptr_r->refCount() : 0; }
+ };
+
+ template<class _D>
+ struct Scoped
+ {
+ typedef scoped_ptr<_D> _Ptr;
+ typedef scoped_ptr<const _D> _constPtr;
+ /** Check whether pointer is not shared. */
+ bool unique( const _constPtr & ptr_r )
+ { return true; }
+ bool unique( const _Ptr & ptr_r )
+ { return true; }
+ /** Return number of references. */
+ long use_count( const _constPtr & ptr_r ) const
+ { return ptr_r ? 1 : 0; }
+ long use_count( const _Ptr & ptr_r ) const
+ { return ptr_r ? 1 : 0; }
+ };
+
+ }
+ ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : RW_pointer
+ //
+ /** Wrapper for \c const correct access via \ref ZYPP_SMART_PTR.
+ *
+ * ca_mgm::RW_pointer<tt>\<_D,_Traits></tt> stores a \ref ZYPP_SMART_PTR
+ * of type \c _Traits::_Ptr, which must be convertible into a <tt>_D *</tt>.
+ * Pointer style access (via \c -> and \c *) offers a <tt>const _D *</tt> in const
+ * a context, otherwise a <tt>_D *</tt>. Thus \em RW_ means \em read/write,
+ * as you get a different type, dependent on whether you're allowed to
+ * read or write.
+ *
+ * Forwarding access from an interface to an implemantation class, an
+ * RW_pointer prevents const interface methods from accidentally calling
+ * nonconst implementation methods.
+ *
+ * The second template argument defaults to
+ * <tt>_Traits = rw_pointer::Shared<_D></tt> thus wraping a
+ * <tt>shared_ptr<_D></tt>. To wrap an <tt>intrusive_ptr<_D></tt>
+ * use <tt>rw_pointer::Intrusive<_D></tt>.
+ *
+ * \see ca_mgm::RWCOW_pointer for 'copy on write' functionality.
+ *
+ * \code
+ * #include "ca_mgm/base/PtrTypes.h"
+ *
+ * class Foo
+ * {
+ * ...
+ * private:
+ * // Implementation class
+ * struct Impl;
+ * // Pointer to implementation; actually a shared_ptr<Impl>
+ * RW_pointer<Impl> _pimpl;
+ *
+ * void baa() { _pimpl->... } // is Impl *
+ * void baa() const { _pimpl->... } // is Impl const *
+ * };
+ * \endcode
+ */
+ template >
+ struct RW_pointer
+ {
+ typedef typename _Traits::_Ptr _Ptr;
+ typedef typename _Traits::_constPtr _constPtr;
+ typedef typename _Ptr::unspecified_bool_type unspecified_bool_type;
+
+ explicit
+ RW_pointer( typename _Ptr::element_type * dptr = 0 )
+ : _dptr( dptr )
+ {}
+
+ explicit
+ RW_pointer( _Ptr dptr )
+ : _dptr( dptr )
+ {}
+
+ void reset()
+ { _Ptr().swap( _dptr ); }
+
+ void reset( typename _Ptr::element_type * dptr )
+ { _Ptr( dptr ).swap( _dptr ); }
+
+ void swap( RW_pointer & rhs )
+ { _dptr.swap( rhs._dptr ); }
+
+ void swap( _Ptr & rhs )
+ { _dptr.swap( rhs ); }
+
+ operator unspecified_bool_type() const
+ { return _dptr; }
+
+ const _D & operator*() const
+ { return *_dptr; };
+
+ const _D * operator->() const
+ { return _dptr.get(); }
+
+ const _D * get() const
+ { return _dptr.get(); }
+
+ _D & operator*()
+ { return *_dptr; }
+
+ _D * operator->()
+ { return _dptr.get(); }
+
+ _D * get()
+ { return _dptr.get(); }
+
+ public:
+ bool unique() const
+ { return _Traits().unique( _dptr ); }
+
+ long use_count() const
+ { return _Traits().use_count( _dptr ); }
+
+ _constPtr getPtr() const
+ { return _dptr; }
+
+ _Ptr getPtr()
+ { return _dptr; }
+
+ private:
+ _Ptr _dptr;
+ };
+ ///////////////////////////////////////////////////////////////////
+
+ /** \relates RW_pointer Stream output.
+ *
+ * Print the \c _D object the RW_pointer refers, or \c "NULL"
+ * if the pointer is \c NULL.
+ */
+ template
+ inline std::ostream &
+ operator<<( std::ostream & str, const RW_pointer<_D, _Ptr> & obj )
+ {
+ if ( obj.get() )
+ return str << *obj.get();
+ return str << std::string("NULL");
+ }
+
+ /** \relates RW_pointer */
+ template
+ inline bool
+ operator==( const RW_pointer<_D, _Ptr> & lhs, const RW_pointer<_D, _Ptr> & rhs )
+ {
+ return( lhs.get() == rhs.get() );
+ }
+
+ /** \relates RW_pointer */
+ template
+ inline bool
+ operator!=( const RW_pointer<_D, _Ptr> & lhs, const RW_pointer<_D, _Ptr> & rhs )
+ {
+ return ! ( lhs == rhs );
+ }
+
+ ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : RWCOW_pointer
+ //
+ /** \ref RW_pointer supporting 'copy on write' functionality.
+ *
+ * \em Write access to the underlying object creates a copy, iff
+ * the object is shared.
+ *
+ * See \ref RW_pointer.
+ */
+ template >
+ struct RWCOW_pointer
+ {
+ typedef typename _Traits::_Ptr _Ptr;
+ typedef typename _Traits::_constPtr _constPtr;
+ typedef typename _Ptr::unspecified_bool_type unspecified_bool_type;
+
+ explicit
+ RWCOW_pointer( typename _Ptr::element_type * dptr = 0 )
+ : _dptr( dptr )
+ {}
+
+ explicit
+ RWCOW_pointer( _Ptr dptr )
+ : _dptr( dptr )
+ {}
+
+ void reset()
+ { _Ptr().swap( _dptr ); }
+
+ void reset( typename _Ptr::element_type * dptr )
+ { _Ptr( dptr ).swap( _dptr ); }
+
+ void swap( RWCOW_pointer & rhs )
+ { _dptr.swap( rhs._dptr ); }
+
+ void swap( _Ptr & rhs )
+ { _dptr.swap( rhs ); }
+
+ operator unspecified_bool_type() const
+ { return _dptr; }
+
+ const _D & operator*() const
+ { return *_dptr; };
+
+ const _D * operator->() const
+ { return _dptr.get(); }
+
+ const _D * get() const
+ { return _dptr.get(); }
+
+ _D & operator*()
+ { assertUnshared(); return *_dptr; }
+
+ _D * operator->()
+ { assertUnshared(); return _dptr.get(); }
+
+ _D * get()
+ { assertUnshared(); return _dptr.get(); }
+
+ public:
+ bool unique() const
+ { return _Traits().unique( _dptr ); }
+
+ long use_count() const
+ { return _Traits().use_count( _dptr ); }
+
+ _constPtr getPtr() const
+ { return _dptr; }
+
+ _Ptr getPtr()
+ { assertUnshared(); return _dptr; }
+
+ private:
+
+ void assertUnshared()
+ {
+ if ( !unique() )
+ _Ptr( rwcowClone( _dptr.get() ) ).swap( _dptr );
+ }
+
+ private:
+ _Ptr _dptr;
+ };
+ ///////////////////////////////////////////////////////////////////
+
+ /** \relates RWCOW_pointer Clone the underlying object.
+ * Calls \a rhs <tt>-\>clone()</tt>. Being defined as a
+ * function outside \ref RWCOW_pointer allows to overload
+ * it, in case a specific \a _D does not have <tt>clone()</tt>.
+ */
+ template<class _D>
+ inline _D * rwcowClone( const _D * rhs )
+ { return rhs->clone(); }
+
+ ///////////////////////////////////////////////////////////////////
+
+ /** \relates RWCOW_pointer Stream output.
+ *
+ * Print the \c _D object the RWCOW_pointer refers, or \c "NULL"
+ * if the pointer is \c NULL.
+ */
+ template
+ inline std::ostream &
+ operator<<( std::ostream & str, const RWCOW_pointer<_D, _Ptr> & obj )
+ {
+ if ( obj.get() )
+ return str << *obj.get();
+ return str << std::string("NULL");
+ }
+
+ /** \relates RWCOW_pointer */
+ template
+ inline bool
+ operator==( const RWCOW_pointer<_D, _Ptr> & lhs, const RWCOW_pointer<_D, _Ptr> & rhs )
+ {
+ return( lhs.get() == rhs.get() );
+ }
+
+ /** \relates RWCOW_pointer */
+ template
+ inline bool
+ operator!=( const RWCOW_pointer<_D, _Ptr> & lhs, const RWCOW_pointer<_D, _Ptr> & rhs )
+ {
+ return ! ( lhs == rhs );
+ }
+
+ ///////////////////////////////////////////////////////////////////
+
+ /*@}*/
+ /////////////////////////////////////////////////////////////////
+} // namespace ca_mgm
+///////////////////////////////////////////////////////////////////
+
+/** Forward declaration of Ptr types */
+#define DEFINE_PTR_TYPE(NAME) \
+class NAME; \
+extern void intrusive_ptr_add_ref( const NAME * ); \
+extern void intrusive_ptr_release( const NAME * ); \
+typedef ca_mgm::intrusive_ptr<NAME> NAME##_Ptr; \
+typedef ca_mgm::intrusive_ptr<const NAME> NAME##_constPtr;
+
+///////////////////////////////////////////////////////////////////
+#endif // LIMAL_BASE_PTRTYPES_H
--
To unsubscribe, e-mail: limal-commit+unsubscribe@opensuse.org
For additional commands, e-mail: limal-commit+help@opensuse.org