auto_ptr.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2017 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 #ifndef LIBMESH_AUTO_PTR_H
19 #define LIBMESH_AUTO_PTR_H
20 
21 #include "libmesh/libmesh_config.h"
22 #include "libmesh_common.h" // for libmesh_deprecated()
23 #include "libmesh/safe_bool.h"
24 
25 // LibMesh's AutoPtr is now libmesh_deprecated(), just like the
26 // std::auto_ptr it is based on.
27 //
28 // New library code should use the UniquePtr typedef (which will
29 // eventually be a C++11 alias declaration). LibMesh's UniquePtr is
30 // one of:
31 // 1.) std::unique_ptr
32 // 2.) Howard Hinnant's C++03 compatible boost::unique_ptr
33 // 3.) The deprecated libMesh AutoPtr
34 // in that order, depending on what your compiler supports. If you
35 // are using a compiler that cannot compile Howard Hinnant's
36 // unique_ptr implementation, you should probably think about
37 // upgrading.
38 #ifdef LIBMESH_ENABLE_UNIQUE_PTR
39 #ifdef LIBMESH_HAVE_CXX11_UNIQUE_PTR
40 // If C++11 std::unique_ptr is available, alias declarations are also
41 // guaranteed to be available.
42 # include <memory>
43 namespace libMesh
44 {
45 template<typename T>
46 using UniquePtr = std::unique_ptr<T>;
47 }
48 #elif LIBMESH_HAVE_BOOST_MOVELIB_UNIQUE_PTR
49 // Disable warnings from boost header files under clang
50 # ifdef __clang__
51 # pragma clang diagnostic push
52 # pragma clang diagnostic ignored "-Wunused-local-typedef"
53 # endif
54 # include "boost/move/unique_ptr.hpp"
55 # ifdef __clang__
56 # pragma clang diagnostic pop
57 # endif
58 # define UniquePtr unique_ptr
59 namespace libMesh
60 {
61 // Declare that we are using boost Move's unique_ptr type
62 using boost::movelib::unique_ptr;
63 }
64 #elif LIBMESH_HAVE_HINNANT_UNIQUE_PTR
65 // As per Roy's suggestion, use a combination of a macro and a 'using'
66 // statement to make libMesh's UniquePtr type equivalent to the
67 // boost::unique_ptr implementation of Howard Hinnant.
68 # include "libmesh/unique_ptr.hpp"
69 # define UniquePtr unique_ptr
70 namespace libMesh
71 {
72 // Declare that we are using boost's unique_ptr type
73 using boost::unique_ptr;
74 }
75 #else
76 # define UniquePtr AutoPtr
77 #endif
78 #else
79 // libMesh was configured with --disable-unique-ptr, so we'll use
80 // libMesh's AutoPtr class instead.
81 #define UniquePtr AutoPtr
82 #endif
83 
84 
85 
86 // Set up the libmesh_make_unique macro. This is not yet used in the
87 // library since it requires at least C++11, but it is provided in the
88 // hope that it will be useful to application codes. The different
89 // cases are:
90 // 1.) If the compiler supports C++14 std::make_unique, use that.
91 // 2.) If the C++11 workaround is available, use that instead. See also:
92 // http://stackoverflow.com/questions/7038357/make-unique-and-perfect-forwarding
93 // 3.) Otherwise, make libmesh_make_unique something innocuous that
94 // produces a somewhat understandable compiler error.
95 #ifdef LIBMESH_HAVE_CXX14_MAKE_UNIQUE
96 #define libmesh_make_unique std::make_unique
97 
98 #elif LIBMESH_HAVE_CXX11_MAKE_UNIQUE_WORKAROUND
99 namespace libMesh
100 {
101 template<typename T, typename... Args>
102 std::unique_ptr<T> make_unique(Args &&... args)
103 {
104  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
105 }
106 }
107 #define libmesh_make_unique make_unique
108 
109 #else
110 #define libmesh_make_unique ; Error: You cannot use libmesh_make_unique with this compiler!
111 #endif
112 
113 
114 
115 namespace libMesh
116 {
117 
125 template<typename Tp1>
127 {
131  Tp1* _ptr;
132 
136  explicit
137  AutoPtrRef(Tp1* p)
138  : _ptr(p) {}
139 };
140 
141 
209 template<typename Tp>
210 class AutoPtr : public safe_bool<AutoPtr<Tp> >
211 {
212 private:
213 
217  Tp * _ptr;
218 
219 public:
223  typedef Tp element_type;
224 
235  explicit
236  AutoPtr(element_type * p = 0)
237  : _ptr(p)
238  {
239  }
240 
249  : _ptr(a.release())
250  {
251  }
252 
262  template<typename Tp1>
264  : _ptr(a.release())
265  {
266  }
267 
276  AutoPtr &
278  {
279  reset(a.release());
280  return *this;
281  }
282 
293  template <typename Tp1>
294  AutoPtr &
296  {
297  reset(a.release());
298  return *this;
299  }
300 
312  {
314  {
316  libmesh_deprecated();
317  }
318  delete _ptr;
319  }
320 
329  element_type &
330  operator*() const { return *_ptr; }
331 
338  element_type *
339  operator->() const { return _ptr; }
340 
351  element_type *
352  get() const { return _ptr; }
353 
365  element_type *
367  {
368  element_type * tmp = _ptr;
369  _ptr = 0;
370  return tmp;
371  }
372 
380  void
381  reset(element_type * p = 0)
382  {
383  if (p != _ptr)
384  {
385  delete _ptr;
386  _ptr = p;
387  }
388  }
389 
402  : _ptr(ref._ptr) {}
403 
411  AutoPtr &
413  {
414  if (ref._ptr != this->get())
415  {
416  delete _ptr;
417  _ptr = ref._ptr;
418  }
419  return *this;
420  }
421 
433  bool boolean_test() const
434  {
435  return (this->get() != NULL);
436  }
437 
441  template<typename Tp1>
442  operator AutoPtrRef<Tp1>()
443  { return AutoPtrRef<Tp1>(this->release()); }
444 
448  template<typename Tp1>
449  operator AutoPtr<Tp1>()
450  { return AutoPtr<Tp1>(this->release()); }
451 };
452 
453 
454 
455 } // namespace libMesh
456 
457 #endif // LIBMESH_AUTO_PTR_H
AutoPtr & operator=(AutoPtr &a)
AutoPtr assignment operator.
Definition: auto_ptr.h:277
bool warned_about_auto_ptr
AutoPtr(AutoPtr< Tp1 > &a)
An AutoPtr can be constructed from another AutoPtr.
Definition: auto_ptr.h:263
AutoPtr(element_type *p=0)
An AutoPtr is usually constructed from a raw pointer.
Definition: auto_ptr.h:236
bool boolean_test() const
Definition: auto_ptr.h:433
std::unique_ptr< T > make_unique(Args &&...args)
Definition: auto_ptr.h:102
AutoPtr(AutoPtrRef< element_type > ref)
Automatic conversions.
Definition: auto_ptr.h:401
element_type * release()
Bypassing the smart pointer.
Definition: auto_ptr.h:366
std::unique_ptr< T > UniquePtr
Definition: auto_ptr.h:46
AutoPtrRef(Tp1 *p)
Definition: auto_ptr.h:137
AutoPtr(AutoPtr &a)
An AutoPtr can be constructed from another AutoPtr.
Definition: auto_ptr.h:248
element_type & operator*() const
Smart pointer dereferencing.
Definition: auto_ptr.h:330
AutoPtr & operator=(AutoPtr< Tp1 > &a)
AutoPtr assignment operator.
Definition: auto_ptr.h:295
AutoPtr & operator=(AutoPtrRef< element_type > ref)
Definition: auto_ptr.h:412
void reset(element_type *p=0)
Forcibly deletes the managed object.
Definition: auto_ptr.h:381
element_type * operator->() const
Smart pointer dereferencing.
Definition: auto_ptr.h:339
A simple smart pointer providing strict ownership semantics.
Definition: auto_ptr.h:210