IMP  2.1.0
The Integrative Modeling Platform
base/Pointer.h
Go to the documentation of this file.
1 /**
2  * \file IMP/base/Pointer.h
3  * \brief A nullptr-initialized pointer to an \imp Object.
4  *
5  * Copyright 2007-2013 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPBASE_POINTER_H
10 #define IMPBASE_POINTER_H
11 
12 #include <IMP/base/base_config.h>
13 #include "internal/PointerBase.h"
14 #include "WeakPointer.h"
15 
16 IMPBASE_BEGIN_NAMESPACE
17 
18 //! A smart pointer to a reference counted object
19 /** Any time you store an Object in a C++ program, you should use a
20  Pointer, rather than a raw C++ pointer (or PointerMember, if the pointer
21  is stored in a class). Using a pointer manages
22  the reference counting and makes sure that the object is not deleted
23  prematurely when, for example, all Python references go away and
24  that it is deleted properly if an exception is thrown during the
25  function.
26  Use the IMP_NEW() macro to aid creation of pointers to new objects.
27 
28  For example, when implementing a kernel::Restraint that uses a
29  kernel::PairScore, store the kernel::PairScore like this:
30  \code
31  base::PointerMember<PairScore> ps_;
32  \endcode
33 
34  When creating Object instances in C++, you should write code like:
35  \code
36  em::FitRestraint* create_fit_restraint(std::string mapname,
37  const kernel::ParticlesTemp &ps)
38  {
39  IMP_NEW(core::LeavesRefiner, lr, (atom::Hierarchy::get_traits()));
40  base::Pointer<em::DensityMap> map= em::read_map("file_name.mrc");
41  IMP_NEW(em::FitRestraint, fr, (ps, map, lr));
42  return fr.release();
43  }
44  \endcode
45  which is equivalent to
46  \code
47  IMP::em::FitRestraint* create_fit_restraint(std::string mapname,
48  const kernel::ParticlesTemp
49  &ps)
50  {
51  base::Pointer<core::LeavesRefiner> lr
52  = new core::LeavesRefiner(atom::Hierarchy::get_traits());
53  base::Pointer<IMP::em::DensityMap> map
54  = em::read_map("file_name.mrc");
55  base::Pointer<em::FitRestraint> fr
56  = new em::FitRestraint(ps, map, lr));
57  return fr.release();
58  }
59  \endcode
60  There are several important things to note in this code:
61  - the use of Pointer::release() on the return. Otherwise, when the
62  reference counted pointer goes out of scope, it will unref the
63  em::FitRestraint, notice the count is 0, and delete it, before
64  passing the (now invalid) pointer back to the calling function
65  - the use of reference counted pointers everywhere. This ensures
66  that if, for example, em::read_map() throws an exception since the
67  file name is invalid, the core::LeavesRefiner will be deleted
68  properly.
69 
70  \note Do not pass Pointers as arguments to functions; pass raw C++
71  pointers instead.
72 
73  \note Consider using IMP::base::PointerMember when storing pointers to
74  ref-counted objects as class members (the only difference is that
75  the object will be marked by the pointer as 'used')
76 
77  \note Use IMP::base::WeakPointer to break cycles or to point to
78  non-ref-counted objects.
79 
80  \param[in] O The type of RefCounted-derived object to point to
81 
82  \see PointerMember
83  \see WeakPointer
84  \see UncheckedWeakPointer
85  */
86 template <class O>
87 struct Pointer : internal::PointerBase<internal::RefCountedPointerTraits<O> > {
88  typedef internal::PointerBase<internal::RefCountedPointerTraits<O> > P;
89  template <class Any>
90  Pointer(const Any& o)
91  : P(o) {}
92  Pointer() {}
93  template <class OT>
94  base::Pointer<O>& operator=(const internal::PointerBase<OT>& o) {
95  P::operator=(o);
96  return *this;
97  }
98  template <class OT>
99  base::Pointer<O>& operator=(OT* o) {
100  P::operator=(o);
101  return *this;
102  }
103 #if defined(BOOST_NO_CXX11_NULLPTR) || defined(BOOST_NO_NULLPTR)
104  base::Pointer<O>& operator=(nullptr_t o) {
105  P::operator=(o);
106  return *this;
107  }
108 #endif
109  base::Pointer<O>& operator=(const P& o) {
110  P::operator=(o);
111  return *this;
112  }
113 
114 #ifdef IMP_DOXYGEN
115  //! Relinquish control of the raw pointer stored in the Pointer
116  /** Relinquish control of the raw pointer stored in the Pointer.
117  Use this to safely return objects allocated within functions.
118  The reference count of the object will be decreased by one,
119  but even it it becomes 0, the object will not be destroyed.
120 
121  @return a valid raw pointer to the object stored in Pointer
122  */
123  O* release();
124 
125  //! get the raw pointer to the object
126  O* get() const;
127 #endif
128 };
129 
130 //! A smart pointer to a ref-counted Object that is a class memeber
131 /** A smart pointer to a reference counted Object, which is
132  meant to be stored as a class member. This class is identical
133  to Pointer, but in addition, Object::set_was_used(true) will be called so
134  you don't get warnings about unused objects once the object is stored in the
135  owning class.
136 
137  @note The object being pointed to must inherit from IMP::base::Object.
138 
139  \param[in] O The type of IMP::RefCounted-derived object to point to
140 
141  \see Pointer
142  \see WeakPointer
143  \see UncheckedWeakPointer
144  */
145 template <class O>
147  : internal::PointerBase<internal::PointerMemberTraits<O> > {
148  typedef internal::PointerBase<internal::PointerMemberTraits<O> > P;
149  template <class Any>
150  PointerMember(const Any& o)
151  : P(o) {}
152  PointerMember() {}
153  template <class OT>
154  base::PointerMember<O>& operator=(const internal::PointerBase<OT>& o) {
155  P::operator=(o);
156  return *this;
157  }
158  template <class OT>
159  base::PointerMember<O>& operator=(OT* o) {
160  P::operator=(o);
161  return *this;
162  }
163 #if defined(BOOST_NO_CXX11_NULLPTR) || defined(BOOST_NO_NULLPTR)
164  base::PointerMember<O>& operator=(nullptr_t o) {
165  P::operator=(o);
166  return *this;
167  }
168 #endif
169  base::PointerMember<O>& operator=(const P& o) {
170  P::operator=(o);
171  return *this;
172  }
173 
174 #ifdef IMP_DOXYGEN
175  //! Relinquish control of the raw pointer stored in the PointerMember
176  /** Relinquish control of the raw pointer stored in the PointerMember.
177  Use this to safely return objects allocated within functions.
178  The reference count of the object will be decreased by one,
179  but even it it becomes 0, the object will not be destroyed.
180 
181  @return a valid raw pointer to the object stored in the PointerMember
182  */
183  O* release();
184 
185  //! get the raw pointer to the object
186  O* get() const;
187 #endif
188 };
189 
190 //! A reference counted pointer to an Object
191 /**
192  The object being pointed to must inherit from IMP::base::Object.
193  In addition to reference counting the object like Pointer,
194  Object::set_was_used(true) will be called so you don't get
195  warnings about unused objects.
196 
197  \param[in] O The type of IMP::RefCounted-derived object to point to
198 
199  \deprecated_at{2.1} Use ObjectMember instead
200  */
201 template <class O>
202 struct OwnerPointer : internal::PointerBase<internal::PointerMemberTraits<O> > {
203  typedef internal::PointerBase<internal::PointerMemberTraits<O> > P;
204  /** \deprecated_at{2.1} Use ObjectMember instead */
205  template <class Any>
206  IMPBASE_DEPRECATED_VALUE_DECL(2.1) OwnerPointer(const Any& o)
207  : P(o) {}
208  /** \deprecated_at{2.1} Use ObjectMember instead */
209  IMPBASE_DEPRECATED_VALUE_DECL(2.1)
211  template <class OT>
212  base::OwnerPointer<O>& operator=(const internal::PointerBase<OT>& o) {
213  P::operator=(o);
214  return *this;
215  }
216  template <class OT>
217  base::OwnerPointer<O>& operator=(OT* o) {
218  P::operator=(o);
219  return *this;
220  }
221 #if defined(BOOST_NO_CXX11_NULLPTR) || defined(BOOST_NO_NULLPTR)
222  base::OwnerPointer<O>& operator=(nullptr_t o) {
223  P::operator=(o);
224  return *this;
225  }
226 #endif
227  base::OwnerPointer<O>& operator=(const P& o) {
228  P::operator=(o);
229  return *this;
230  }
231 
232 #ifdef IMP_DOXYGEN
233  //! Relinquish control of the raw pointer stored in the OwnerPointer
234  /** Relinquish control of the raw pointer stored in the OwnerPointer.
235  Use this to safely return objects allocated within functions.
236  The reference count of the object will be decreased by one,
237  but even it it becomes 0, the object will not be destroyed.
238 
239  @return a valid raw pointer to the object stored in the OwnerPointer
240  */
241  O* release();
242 
243  //! get the raw pointer to the object
244  O* get() const;
245 #endif
246 };
247 
248 /******* streaming ********/
249 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
250 template <class T>
251 inline std::ostream& operator<<(std::ostream& out, base::Pointer<T> o) {
252  out << Showable(o.get());
253  return out;
254 }
255 template <class T>
256 inline std::ostream& operator<<(std::ostream& out, base::PointerMember<T> o) {
257  out << Showable(o.get());
258  return out;
259 }
260 
261 template <class T>
262 inline std::ostream& operator<<(std::ostream& out, base::OwnerPointer<T> o) {
263  out << Showable(o.get());
264  return out;
265 }
266 #endif
267 
268 IMPBASE_END_NAMESPACE
269 
270 #endif /* IMPBASE_POINTER_H */
A smart pointer to a ref-counted Object that is a class memeber.
Definition: base/Pointer.h:146
A smart pointer to a reference counted object.
Definition: base/Pointer.h:87
A reference counted pointer to an Object.
Definition: base/Pointer.h:202
A nullptr-initialized pointer to an Object.