Moved the smart pointer types and related cast functions (PtrTypes.h)
[platform/upstream/libzypp.git] / zypp / base / PtrTypes.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/base/PtrTypes.h
10  *  \ingroup ZYPP_SMART_PTR
11  *  \see ZYPP_SMART_PTR
12 */
13 #ifndef ZYPP_BASE_PTRTYPES_H
14 #define ZYPP_BASE_PTRTYPES_H
15
16 #include <string>
17
18 #include <boost/scoped_ptr.hpp>
19 #include <boost/shared_ptr.hpp>
20 #include <boost/weak_ptr.hpp>
21 #include <boost/intrusive_ptr.hpp>
22
23 ///////////////////////////////////////////////////////////////////
24 namespace zypp
25 { /////////////////////////////////////////////////////////////////
26
27     /** \defgroup ZYPP_SMART_PTR Smart pointer types
28      *  Smart pointer types.
29      *
30      * Namespace zypp provides 3 smart pointer types \b using the
31      * boost smart pointer library.
32      *
33      * \li \c scoped_ptr Simple sole ownership of single objects. Noncopyable.
34      *
35      * \li \c shared_ptr Object ownership shared among multiple pointers
36      *
37      * \li \c weak_ptr Non-owning observers of an object owned by shared_ptr.
38      *
39      * And \ref zypp::RW_pointer, as wrapper around a smart pointer,
40      * poviding \c const correct read/write access to the object it refers.
41     */
42     /*@{*/
43
44     /** */
45     using boost::scoped_ptr;
46
47     /** */
48     using boost::shared_ptr;
49
50     /** */
51     using boost::weak_ptr;
52
53     /** Use boost::intrusive_ptr as Ptr type*/
54     using boost::intrusive_ptr;
55
56     using boost::static_pointer_cast;
57     using boost::const_pointer_cast;
58     using boost::dynamic_pointer_cast;
59
60     ///////////////////////////////////////////////////////////////////
61     //
62     //  CLASS NAME : RW_pointer
63     //
64     /** Wrapper for \c const correct access via \ref ZYPP_SMART_PTR.
65      *
66      * zypp::RW_pointer<tt>\<_D,_Ptr></tt> stores a \ref ZYPP_SMART_PTR
67      * of type \c _Ptr, which must be convertible into a <tt>_D *</tt>. Pointer
68      * style access (via \c -> and \c *) offers a <tt>const _D *</tt> in const
69      * a context, otherwise a <tt>_D *</tt>. Thus \em RW_ means \em read/write,
70      * as you get a different type, dependent on whether you're allowed to
71      * read or write.
72      *
73      * Forwarding access from an interface to an implemantation class, an
74      * RW_pointer prevents const interface methods from accidentally calling
75      * nonconst implementation methods. In case you have to do so, call
76      * unconst to get the <tt>_D *</tt>.
77      *
78      * The second template argument defaults to <tt>_Ptr = shared_ptr<_D></tt>.
79      * \code
80      * #include "zypp/base/PtrTypes.h"
81      *
82      * class Foo
83      * {
84      *   ...
85      *   private:
86      *     // Implementation class
87      *     struct Impl;
88      *     // Pointer to implementation; actually a shared_ptr<Impl>
89      *     RW_pointer<Impl> _pimpl;
90      *
91      *     void baa()       { _pimpl->... } // is Impl *
92      *     void baa() const { _pimpl->... } // is Impl const *
93      * };
94      * \endcode
95      * \todo refine ctor and assign.
96     */
97     template<class _D, class _Ptr = shared_ptr<_D> >
98       struct RW_pointer
99       {
100         typedef _D element_type;
101
102         explicit
103         RW_pointer( typename _Ptr::element_type * dptr = 0 )
104         : _dptr( dptr )
105         {}
106
107         explicit
108         RW_pointer( _Ptr dptr )
109         : _dptr( dptr )
110         {}
111
112         _D & operator*() { return *_dptr; }
113         const _D & operator*() const { return *_dptr; };
114         _D * operator->() { return _dptr.get(); }
115         const _D * operator->() const { return _dptr.get(); }
116         _D * get() { return _dptr.get(); }
117         const _D * get() const { return _dptr.get(); }
118
119         _D * unconst() const { return _dptr.get(); }
120
121         _Ptr _dptr;
122       };
123
124     /** \relates RW_pointer Stream output.
125      *
126      * Print the \c _D object the RW_pointer refers, or \c "NULL"
127      * if the pointer is \c NULL.
128     */
129     template<class _D, class _Ptr>
130       inline std::ostream &
131       operator<<( std::ostream & str, const RW_pointer<_D, _Ptr> & obj )
132       {
133         if ( obj.get() )
134           return str << *obj.get();
135         return str << std::string("NULL");
136       }
137
138     ///////////////////////////////////////////////////////////////////
139     /** Wrapper for \c const correct access via pointer.
140      *
141      * Template specialization of RW_pointer, storing a raw <tt>_P *</tt>,
142      * which must be convertible into a <tt>_D *</tt>.
143      *
144      * \note The object pointed to will \b not be deleted. If you need
145      * automatic cleanup, use a \ref ZYPP_SMART_PTR instead of a
146      * raw pointer.
147     */
148     template<class _D,class _P>
149       struct RW_pointer<_D,_P*>
150       {
151         typedef _D element_type;
152
153         explicit
154         RW_pointer( _P * dptr = 0 )
155         : _dptr( dptr )
156         {}
157
158         _D & operator*() { return *_dptr; }
159         const _D & operator*() const { return *_dptr; };
160         _D * operator->() { return _dptr; }
161         const _D * operator->() const { return _dptr; }
162         _D * get() { return _dptr; }
163         const _D * get() const { return _dptr; }
164
165         _D * unconst() const { return _dptr; }
166
167         _P * _dptr;
168       };
169
170     /////////////////////////////////////////////////////////////////
171
172     /*@}*/
173
174   /////////////////////////////////////////////////////////////////
175 } // namespace zypp
176 ///////////////////////////////////////////////////////////////////
177
178 /** Forward declaration of Ptr types */
179 #define DEFINE_PTR_TYPE(NAME) \
180 class NAME;                                                      \
181 extern void intrusive_ptr_add_ref( const NAME * );               \
182 extern void intrusive_ptr_release( const NAME * );               \
183 typedef zypp::intrusive_ptr<NAME>       NAME##_Ptr;        \
184 typedef zypp::intrusive_ptr<const NAME> NAME##_constPtr;
185
186 ///////////////////////////////////////////////////////////////////
187 #endif // ZYPP_BASE_PTRTYPES_H