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 
231  explicit
232  AutoPtr(element_type * p = 0)
233  : _ptr(p)
234  {
235  // Note: we can't call libmesh_deprecated() here, since global
236  // AutoPtr variables are sometimes created before the libMesh::out
237  // stream is ready.
238  }
239 
248  : _ptr(a.release())
249  {
250  }
251 
261  template<typename Tp1>
263  : _ptr(a.release())
264  {
265  }
266 
275  AutoPtr &
277  {
278  reset(a.release());
279  return *this;
280  }
281 
292  template <typename Tp1>
293  AutoPtr &
295  {
296  reset(a.release());
297  return *this;
298  }
299 
313  {
315  {
317  libmesh_deprecated();
318  }
319  delete _ptr;
320  }
321 
330  element_type &
331  operator*() const { return *_ptr; }
332 
339  element_type *
340  operator->() const { return _ptr; }
341 
352  element_type *
353  get() const { return _ptr; }
354 
366  element_type *
368  {
369  element_type * tmp = _ptr;
370  _ptr = 0;
371  return tmp;
372  }
373 
381  void
382  reset(element_type * p = 0)
383  {
384  if (p != _ptr)
385  {
386  delete _ptr;
387  _ptr = p;
388  }
389  }
390 
403  : _ptr(ref._ptr) {}
404 
411  AutoPtr &
413  {
414  if (ref._ptr != this->get())
415  {
416  delete _ptr;
417  _ptr = ref._ptr;
418  }
419  return *this;
420  }
421 
427  bool boolean_test() const
428  {
429  return (this->get() != NULL);
430  }
431 
435  template<typename Tp1>
436  operator AutoPtrRef<Tp1>()
437  { return AutoPtrRef<Tp1>(this->release()); }
438 
442  template<typename Tp1>
443  operator AutoPtr<Tp1>()
444  { return AutoPtr<Tp1>(this->release()); }
445 };
446 
447 
448 
449 } // namespace libMesh
450 
451 #endif // LIBMESH_AUTO_PTR_H
AutoPtr & operator=(AutoPtr &a)
AutoPtr assignment operator.
Definition: auto_ptr.h:276
bool warned_about_auto_ptr
AutoPtr(AutoPtr< Tp1 > &a)
An AutoPtr can be constructed from another AutoPtr.
Definition: auto_ptr.h:262
AutoPtr(element_type *p=0)
An AutoPtr is usually constructed from a raw pointer.
Definition: auto_ptr.h:232
bool boolean_test() const
Definition: auto_ptr.h:427
std::unique_ptr< T > make_unique(Args &&...args)
Definition: auto_ptr.h:102
AutoPtr(AutoPtrRef< element_type > ref)
Automatic conversions.
Definition: auto_ptr.h:402
element_type * release()
Bypassing the smart pointer.
Definition: auto_ptr.h:367
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:247
element_type & operator*() const
Smart pointer dereferencing.
Definition: auto_ptr.h:331
AutoPtr & operator=(AutoPtr< Tp1 > &a)
AutoPtr assignment operator.
Definition: auto_ptr.h:294
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:382
element_type * operator->() const
Smart pointer dereferencing.
Definition: auto_ptr.h:340
A simple smart pointer providing strict ownership semantics.
Definition: auto_ptr.h:210