Reference documentation for deal.II version 9.1.0-pre
smartpointer.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2017 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_smartpointer_h
17 #define dealii_smartpointer_h
18 
19 
20 #include <deal.II/base/config.h>
21 
22 #include <deal.II/base/subscriptor.h>
23 
24 DEAL_II_NAMESPACE_OPEN
25 
63 template <typename T, typename P = void>
65 {
66 public:
71  SmartPointer();
72 
77  template <class Q>
79 
85 
94  SmartPointer(T *t, const char *id);
95 
102  SmartPointer(T *t);
103 
104 
108  ~SmartPointer();
109 
117  operator=(T *tt);
118 
123  template <class Q>
125  operator=(const SmartPointer<T, Q> &tt);
126 
132  operator=(const SmartPointer<T, P> &tt);
133 
137  void
138  clear();
139 
143  operator T *() const;
144 
149  T &operator*() const;
150 
155  T *operator->() const;
156 
166  template <class Q>
167  void
169 
178  void
179  swap(T *&tt);
180 
186  std::size_t
187  memory_consumption() const;
188 
189 private:
195  T *t;
196 
200  const char *const id;
201 };
202 
203 
204 /* --------------------- inline Template functions ------------------------- */
205 
206 
207 template <typename T, typename P>
209  : t(nullptr)
210  , id(typeid(P).name())
211 {}
212 
213 
214 
215 template <typename T, typename P>
217  : t(t)
218  , id(typeid(P).name())
219 {
220  if (t != nullptr)
221  t->subscribe(id);
222 }
223 
224 
225 
226 template <typename T, typename P>
227 inline SmartPointer<T, P>::SmartPointer(T *t, const char *id)
228  : t(t)
229  , id(id)
230 {
231  if (t != nullptr)
232  t->subscribe(id);
233 }
234 
235 
236 
237 template <typename T, typename P>
238 template <class Q>
240  : t(tt.t)
241  , id(tt.id)
242 {
243  if (t != nullptr)
244  t->subscribe(id);
245 }
246 
247 
248 
249 template <typename T, typename P>
251  : t(tt.t)
252  , id(tt.id)
253 {
254  if (t != nullptr)
255  t->subscribe(id);
256 }
257 
258 
259 
260 template <typename T, typename P>
262 {
263  if (t != nullptr)
264  t->unsubscribe(id);
265 }
266 
267 
268 
269 template <typename T, typename P>
270 inline void
272 {
273  if (t != nullptr)
274  {
275  t->unsubscribe(id);
276  delete t;
277  t = nullptr;
278  }
279 }
280 
281 
282 
283 template <typename T, typename P>
284 inline SmartPointer<T, P> &
286 {
287  // optimize if no real action is
288  // requested
289  if (t == tt)
290  return *this;
291 
292  if (t != nullptr)
293  t->unsubscribe(id);
294  t = tt;
295  if (tt != nullptr)
296  tt->subscribe(id);
297  return *this;
298 }
299 
300 
301 
302 template <typename T, typename P>
303 template <class Q>
304 inline SmartPointer<T, P> &
306 {
307  // if objects on the left and right
308  // hand side of the operator= are
309  // the same, then this is a no-op
310  if (&tt == this)
311  return *this;
312 
313  if (t != nullptr)
314  t->unsubscribe(id);
315  t = static_cast<T *>(tt);
316  if (tt != nullptr)
317  tt->subscribe(id);
318  return *this;
319 }
320 
321 
322 
323 template <typename T, typename P>
324 inline SmartPointer<T, P> &
326 {
327  // if objects on the left and right
328  // hand side of the operator= are
329  // the same, then this is a no-op
330  if (&tt == this)
331  return *this;
332 
333  if (t != nullptr)
334  t->unsubscribe(id);
335  t = static_cast<T *>(tt);
336  if (tt != nullptr)
337  tt->subscribe(id);
338  return *this;
339 }
340 
341 
342 
343 template <typename T, typename P>
345 {
346  return t;
347 }
348 
349 
350 
351 template <typename T, typename P>
353 {
354  Assert(t != nullptr, ExcNotInitialized());
355  return *t;
356 }
357 
358 
359 
360 template <typename T, typename P>
362 {
363  Assert(t != nullptr, ExcNotInitialized());
364  return t;
365 }
366 
367 
368 
369 template <typename T, typename P>
370 template <class Q>
371 inline void
373 {
374 #ifdef DEBUG
375  SmartPointer<T, P> aux(t, id);
376  *this = tt;
377  tt = aux;
378 #else
379  std::swap(t, tt.t);
380 #endif
381 }
382 
383 
384 
385 template <typename T, typename P>
386 inline void
388 {
389  if (t != nullptr)
390  t->unsubscribe(id);
391 
392  std::swap(t, tt);
393 
394  if (t != nullptr)
395  t->subscribe(id);
396 }
397 
398 
399 
400 template <typename T, typename P>
401 inline std::size_t
403 {
404  return sizeof(SmartPointer<T, P>);
405 }
406 
407 
408 
409 // The following function is not strictly necessary but is an optimization
410 // for places where you call swap(p1,p2) with SmartPointer objects p1, p2.
411 // Unfortunately, MS Visual Studio (at least up to the 2013 edition) trips
412 // over it when calling std::swap(v1,v2) where v1,v2 are std::vectors of
413 // SmartPointer objects: it can't determine whether it should call std::swap
414 // or ::swap on the individual elements (see bug #184 on our Google Code
415 // site. Consequently, just take this function out of the competition for this
416 // compiler.
417 #ifndef _MSC_VER
418 
423 template <typename T, typename P, class Q>
424 inline void
426 {
427  t1.swap(t2);
428 }
429 #endif
430 
431 
439 template <typename T, typename P>
440 inline void
441 swap(SmartPointer<T, P> &t1, T *&t2)
442 {
443  t1.swap(t2);
444 }
445 
446 
447 
455 template <typename T, typename P>
456 inline void
457 swap(T *&t1, SmartPointer<T, P> &t2)
458 {
459  t2.swap(t1);
460 }
461 
462 DEAL_II_NAMESPACE_CLOSE
463 
464 #endif
T & operator*() const
Definition: smartpointer.h:352
const char *const id
Definition: smartpointer.h:200
static::ExceptionBase & ExcNotInitialized()
#define Assert(cond, exc)
Definition: exceptions.h:1227
void swap(SmartPointer< T, Q > &tt)
Definition: smartpointer.h:372
SmartPointer< T, P > & operator=(T *tt)
Definition: smartpointer.h:285
void swap(Vector< Number > &u, Vector< Number > &v)
Definition: vector.h:1353
std::size_t memory_consumption() const
Definition: smartpointer.h:402
T * operator->() const
Definition: smartpointer.h:361