LCOV - code coverage report
Current view: top level - include/o3tl - heap_ptr.hxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 20 0.0 %
Date: 2014-04-14 Functions: 0 21 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #ifndef INCLUDED_O3TL_HEAP_PTR_HXX
      21             : #define INCLUDED_O3TL_HEAP_PTR_HXX
      22             : 
      23             : 
      24             : #include <boost/assert.hpp>
      25             : #include <boost/checked_delete.hpp>
      26             : 
      27             : 
      28             : namespace o3tl
      29             : {
      30             : /** heap_ptr<> owns an object on the heap, which will be automatically
      31             :     deleted, when ~heap_ptr<>() is called.
      32             : 
      33             :     Applicability
      34             :     -------------
      35             :     heap_ptr<> can be used for class members on the heap.
      36             :       - One cannot forget to delete them in the destructor.
      37             :       - Constness will be transfered from the owning instance.
      38             : 
      39             :     heap_ptr<> can also be used as smart pointer in function bodies to
      40             :     ensure exception safety.
      41             : 
      42             :     Special Characteristics
      43             :     -----------------------
      44             :       - heap_ptr<> transfers constness from the owning object to
      45             :         the pointed to object. Such it behaves like if *get() would be
      46             :         a normal member of the owning object, not a pointer member.
      47             :         This is preferable to the normal pointer behaviour, because
      48             :         if an object is owned by another one, it is normally part of
      49             :         its state.
      50             : 
      51             :       - heap_ptr<> provides a ->release() function
      52             : 
      53             :       - For reasons of simplicity and portability ->is()
      54             :         is preferred over the safe-bool idiom.
      55             : 
      56             :     Copyability
      57             :     -----------
      58             :     heap_ptr is non copyable.
      59             :       - It forbids the copyconstructor and operator=(self).
      60             : 
      61             :       - Owning classes will automatically be non copyable, if they do not
      62             :         redefine those two functions themselves.
      63             : 
      64             :     Incomplete Types
      65             :     ----------------
      66             :     heap_ptr<> also works with incomplete types. You only need to write
      67             :         class T;
      68             :     but need not include <T>.hxx.
      69             : 
      70             :     If you use heap_ptr<> with an incomplete type, the owning class
      71             :     needs to define a non-inline destructor. Else the compiler will
      72             :     complain.
      73             : */
      74             : template <class T>
      75             : class heap_ptr
      76             : {
      77             :   public:
      78             :     typedef T               element_type;       /// Provided for generic programming.
      79             :     typedef heap_ptr<T>     self;
      80             : 
      81             :     typedef T * (self::*    safe_bool )();
      82             : 
      83             :     /// Now, pass_heapObject is owned by this.
      84             :     explicit            heap_ptr(
      85             :                             T *                 pass_heapObject = 0 );
      86             :                         ~heap_ptr();
      87             : 
      88             : 
      89             :     /** Identical to reset(), except of the return value.
      90             :         @see heap_ptr<>::reset()
      91             :     */
      92             :     self &              operator=(
      93             :                             T *                 pass_heapObject );
      94             :     const T &           operator*() const;
      95             :     T &                 operator*();
      96             :     const T *           operator->() const;
      97             :     T *                 operator->();
      98             : 
      99             :                         operator safe_bool() const;
     100             : 
     101             :     /** This deletes any prevoiusly existing ->pHeapObject.
     102             :         Now, pass_heapObject, if != 0, is owned by this.
     103             : 
     104             :         @onerror
     105             :         Ignores self-assignment.
     106             :         Such, multiple assignment of the same pointer to the same
     107             :         instance of heap_ptr<> is possible (though not recommended).
     108             :     */
     109             :     void                reset(
     110             :                             T *                 pass_heapObject );
     111             :     /** @return     An object on the heap that must be deleted by the caller,
     112             :                     or 0.
     113             : 
     114             :         @postcond   get() == 0;
     115             :     */
     116             :     T *                 release();
     117             :     void                swap(
     118             :                             self &              io_other );
     119             : 
     120             :     /// True, if pHeapObject != 0.
     121             :     bool                is() const;
     122             :     const T *           get() const;
     123             :     T *                 get();
     124             : 
     125             :   private:
     126             :     // Forbidden functions:
     127             :                           heap_ptr( const self & );   /// Prevent copies.
     128             :     self &              operator=( const self & );  /// Prevent copies.
     129             : 
     130             :     /// @attention Does not set ->pHeapObject = 0.
     131             :       void              internal_delete();
     132             : 
     133             :   // DATA
     134             :     /// Will be deleted, when *this is destroyed.
     135             :     T *                 pHeapObject;
     136             : };
     137             : 
     138             : 
     139             : /** Supports the semantic of std::swap(). Provided as an aid to
     140             :     generic programming.
     141             : */
     142             : template<class T>
     143             : inline void
     144             : swap( heap_ptr<T> &       io_a,
     145             :       heap_ptr<T> &       io_b )
     146             : {
     147             :     io_a.swap(io_b);
     148             : }
     149             : 
     150             : 
     151             : 
     152             : // IMPLEMENTATION
     153             : 
     154             : template <class T>
     155             : inline void
     156           0 : heap_ptr<T>::internal_delete()
     157             : {
     158           0 :     ::boost::checked_delete(pHeapObject);
     159             : 
     160             :     // Do not set pHeapObject to 0, because
     161             :     //   that is reset to a value in all code
     162             :     //   where internal_delete() is used.
     163           0 : }
     164             : 
     165             : template <class T>
     166             : inline
     167           0 : heap_ptr<T>::heap_ptr( T * pass_heapObject )
     168           0 :     : pHeapObject(pass_heapObject)
     169             : {
     170           0 : }
     171             : 
     172             : template <class T>
     173             : inline
     174           0 : heap_ptr<T>::~heap_ptr()
     175             : {
     176           0 :     internal_delete();
     177           0 : }
     178             : 
     179             : template <class T>
     180             : inline heap_ptr<T> &
     181             : heap_ptr<T>::operator=(T * pass_heapObject)
     182             : {
     183             :     reset(pass_heapObject);
     184             :     return *this;
     185             : }
     186             : 
     187             : template <class T>
     188             : inline const T &
     189             : heap_ptr<T>::operator*() const
     190             : {
     191             :     BOOST_ASSERT( pHeapObject != 0
     192             :                   && "Accessing a heap_ptr<>(0)." );
     193             :     return *pHeapObject;
     194             : }
     195             : 
     196             : template <class T>
     197             : inline T &
     198             : heap_ptr<T>::operator*()
     199             : {
     200             :     BOOST_ASSERT( pHeapObject != 0
     201             :                   && "Accessing a heap_ptr<>(0)." );
     202             :     return *pHeapObject;
     203             : }
     204             : 
     205             : template <class T>
     206             : inline const T *
     207             : heap_ptr<T>::operator->() const
     208             : {
     209             :     return pHeapObject;
     210             : }
     211             : 
     212             : template <class T>
     213             : inline T *
     214             : heap_ptr<T>::operator->()
     215             : {
     216             :     return pHeapObject;
     217             : }
     218             : 
     219             : template <class T>
     220             : inline
     221             : heap_ptr<T>::operator typename heap_ptr<T>::safe_bool() const
     222             : {
     223             :     return is()
     224             :             ? safe_bool(&self::get)
     225             :             : safe_bool(0);
     226             : }
     227             : 
     228             : template <class T>
     229             : void
     230           0 : heap_ptr<T>::reset(T * pass_heapObject)
     231             : {
     232           0 :     if (    pHeapObject != 0
     233             :         &&  pHeapObject == pass_heapObject)
     234           0 :         return;
     235             : 
     236           0 :     internal_delete();
     237           0 :     pHeapObject = pass_heapObject;
     238             : }
     239             : 
     240             : template <class T>
     241             : T *
     242           0 : heap_ptr<T>::release()
     243             : {
     244           0 :     T * ret = pHeapObject;
     245           0 :     pHeapObject = 0;
     246           0 :     return ret;
     247             : }
     248             : 
     249             : template <class T>
     250             : void
     251             : heap_ptr<T>::swap(self & io_other)
     252             : {
     253             :     T * temp = io_other.pHeapObject;
     254             :     io_other.pHeapObject = pHeapObject;
     255             :     pHeapObject = temp;
     256             : }
     257             : 
     258             : template <class T>
     259             : inline bool
     260             : heap_ptr<T>::is() const
     261             : {
     262             :     return pHeapObject != 0;
     263             : }
     264             : 
     265             : template <class T>
     266             : inline const T *
     267             : heap_ptr<T>::get() const
     268             : {
     269             :     return pHeapObject;
     270             : }
     271             : 
     272             : template <class T>
     273             : inline T *
     274           0 : heap_ptr<T>::get()
     275             : {
     276           0 :     return pHeapObject;
     277             : }
     278             : 
     279             : 
     280             : }   // namespace o3tl
     281             : #endif
     282             : 
     283             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10