summaryrefslogtreecommitdiff
path: root/include/o3tl/heap_ptr.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'include/o3tl/heap_ptr.hxx')
-rw-r--r--include/o3tl/heap_ptr.hxx305
1 files changed, 305 insertions, 0 deletions
diff --git a/include/o3tl/heap_ptr.hxx b/include/o3tl/heap_ptr.hxx
new file mode 100644
index 000000000000..713aa21c41b8
--- /dev/null
+++ b/include/o3tl/heap_ptr.hxx
@@ -0,0 +1,305 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_O3TL_HEAP_PTR_HXX
+#define INCLUDED_O3TL_HEAP_PTR_HXX
+
+
+#include <boost/assert.hpp>
+#include <boost/checked_delete.hpp>
+
+
+namespace o3tl
+{
+/** heap_ptr<> owns an object on the heap, which will be automatically
+ deleted, when ~heap_ptr<>() is called.
+
+ Applicability
+ -------------
+ heap_ptr<> can be used for class members on the heap.
+ - One cannot forget to delete them in the destructor.
+ - Constness will be transfered from the owning instance.
+
+ heap_ptr<> can also be used as smart pointer in function bodies to
+ ensure exception safety.
+
+ Special Characteristics
+ -----------------------
+ - heap_ptr<> transfers constness from the owning object to
+ the pointed to object. Such it behaves like if *get() would be
+ a normal member of the owning object, not a pointer member.
+ This is preferable to the normal pointer behaviour, because
+ if an object is owned by another one, it is normally part of
+ its state.
+
+ - heap_ptr<> provides a ->release() function
+
+ - For reasons of simplicity and portability ->is()
+ is preferred over the safe-bool idiom.
+
+ Copyability
+ -----------
+ heap_ptr is non copyable.
+ - It forbids the copyconstructor and operator=(self).
+
+ - Owning classes will automatically be non copyable, if they do not
+ redefine those two functions themselves.
+
+ Incomplete Types
+ ----------------
+ heap_ptr<> also works with incomplete types. You only need to write
+ class T;
+ but need not include <T>.hxx.
+
+ If you use heap_ptr<> with an incomplete type, the owning class
+ needs to define a non-inline destructor. Else the compiler will
+ complain.
+*/
+template <class T>
+class heap_ptr
+{
+ public:
+ typedef T element_type; /// Provided for generic programming.
+ typedef heap_ptr<T> self;
+
+#ifndef __SUNPRO_CC
+ typedef T * (self::* safe_bool )();
+#endif
+
+ /// Now, pass_heapObject is owned by this.
+ explicit heap_ptr(
+ T * pass_heapObject = 0 );
+ ~heap_ptr();
+
+
+ /** Identical to reset(), except of the return value.
+ @see heap_ptr<>::reset()
+ */
+ self & operator=(
+ T * pass_heapObject );
+ const T & operator*() const;
+ T & operator*();
+ const T * operator->() const;
+ T * operator->();
+
+ /// True, if pHeapObject != 0.
+#ifndef __SUNPRO_CC
+ operator safe_bool() const;
+#else // workaround opt bug of Sun C++ compiler, when compiling with -xO3
+ operator bool() const;
+#endif
+
+
+ /** This deletes any prevoiusly existing ->pHeapObject.
+ Now, pass_heapObject, if != 0, is owned by this.
+
+ @onerror
+ Ignores self-assignment.
+ Such, multiple assignment of the same pointer to the same
+ instance of heap_ptr<> is possible (though not recommended).
+ */
+ void reset(
+ T * pass_heapObject );
+ /** @return An object on the heap that must be deleted by the caller,
+ or 0.
+
+ @postcond get() == 0;
+ */
+ T * release();
+ void swap(
+ self & io_other );
+
+ /// True, if pHeapObject != 0.
+ bool is() const;
+ const T * get() const;
+ T * get();
+
+ private:
+ // Forbidden functions:
+ heap_ptr( const self & ); /// Prevent copies.
+ self & operator=( const self & ); /// Prevent copies.
+
+ /// @attention Does not set ->pHeapObject = 0.
+ void internal_delete();
+
+ // DATA
+ /// Will be deleted, when *this is destroyed.
+ T * pHeapObject;
+};
+
+
+/** Supports the semantic of std::swap(). Provided as an aid to
+ generic programming.
+*/
+template<class T>
+inline void
+swap( heap_ptr<T> & io_a,
+ heap_ptr<T> & io_b )
+{
+ io_a.swap(io_b);
+}
+
+
+
+// IMPLEMENTATION
+
+template <class T>
+inline void
+heap_ptr<T>::internal_delete()
+{
+ ::boost::checked_delete(pHeapObject);
+
+ // Do not set pHeapObject to 0, because
+ // that is reset to a value in all code
+ // where internal_delete() is used.
+}
+
+template <class T>
+inline
+heap_ptr<T>::heap_ptr( T * pass_heapObject )
+ : pHeapObject(pass_heapObject)
+{
+}
+
+template <class T>
+inline
+heap_ptr<T>::~heap_ptr()
+{
+ internal_delete();
+}
+
+template <class T>
+inline heap_ptr<T> &
+heap_ptr<T>::operator=(T * pass_heapObject)
+{
+ reset(pass_heapObject);
+ return *this;
+}
+
+template <class T>
+inline const T &
+heap_ptr<T>::operator*() const
+{
+ BOOST_ASSERT( pHeapObject != 0
+ && "Accessing a heap_ptr<>(0)." );
+ return *pHeapObject;
+}
+
+template <class T>
+inline T &
+heap_ptr<T>::operator*()
+{
+ BOOST_ASSERT( pHeapObject != 0
+ && "Accessing a heap_ptr<>(0)." );
+ return *pHeapObject;
+}
+
+template <class T>
+inline const T *
+heap_ptr<T>::operator->() const
+{
+ return pHeapObject;
+}
+
+template <class T>
+inline T *
+heap_ptr<T>::operator->()
+{
+ return pHeapObject;
+}
+
+#ifndef __SUNPRO_CC
+
+template <class T>
+inline
+heap_ptr<T>::operator typename heap_ptr<T>::safe_bool() const
+{
+ return is()
+ ? safe_bool(&self::get)
+ : safe_bool(0);
+}
+
+#else
+
+template <class T>
+inline heap_ptr<T>::operator bool() const
+{
+ return is();
+}
+
+#endif // !defined(__SUNPRO_CC)
+
+
+
+template <class T>
+void
+heap_ptr<T>::reset(T * pass_heapObject)
+{
+ if ( pHeapObject != 0
+ && pHeapObject == pass_heapObject)
+ return;
+
+ internal_delete();
+ pHeapObject = pass_heapObject;
+}
+
+template <class T>
+T *
+heap_ptr<T>::release()
+{
+ T * ret = pHeapObject;
+ pHeapObject = 0;
+ return ret;
+}
+
+template <class T>
+void
+heap_ptr<T>::swap(self & io_other)
+{
+ T * temp = io_other.pHeapObject;
+ io_other.pHeapObject = pHeapObject;
+ pHeapObject = temp;
+}
+
+template <class T>
+inline bool
+heap_ptr<T>::is() const
+{
+ return pHeapObject != 0;
+}
+
+template <class T>
+inline const T *
+heap_ptr<T>::get() const
+{
+ return pHeapObject;
+}
+
+template <class T>
+inline T *
+heap_ptr<T>::get()
+{
+ return pHeapObject;
+}
+
+
+} // namespace o3tl
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */