diff options
author | Bjoern Michaelsen <bjoern.michaelsen@canonical.com> | 2013-04-18 18:26:28 +0200 |
---|---|---|
committer | Bjoern Michaelsen <bjoern.michaelsen@canonical.com> | 2013-04-23 22:20:31 +0200 |
commit | b9337e22ce1dbf2eba0e8c8db294ae99f4111f91 (patch) | |
tree | 53ee1bd3dfd213815a21579151983cb997922b05 /include/o3tl/heap_ptr.hxx | |
parent | move global headers script (diff) | |
download | core-b9337e22ce1dbf2eba0e8c8db294ae99f4111f91.tar.gz core-b9337e22ce1dbf2eba0e8c8db294ae99f4111f91.zip |
execute move of global headers
see https://gerrit.libreoffice.org/#/c/3367/
and Change-Id: I00c96fa77d04b33a6f8c8cd3490dfcd9bdc9e84a for details
Change-Id: I199a75bc4042af20817265d5ef85b1134a96ff5a
Diffstat (limited to 'include/o3tl/heap_ptr.hxx')
-rw-r--r-- | include/o3tl/heap_ptr.hxx | 305 |
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: */ |