VirtualBox

Changeset 10974 in vbox for trunk/include/iprt/autores


Ignore:
Timestamp:
Jul 30, 2008 11:49:30 AM (16 years ago)
Author:
vboxsync
Message:

Runtime: updated and simplified the autores code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/autores

    r10927 r10974  
    2222# define ___iprt_autores___
    2323
     24#include <iprt/types.h>
    2425#include <iprt/mem.h>
     26#include <iprt/assert.h>
     27#include <iprt/cpputils.h>
    2528
    2629/**
    27  * Wrapper class around RTAutoRes to provide reference semantics.  This is
    28  * needed to construct AutoRes objects from constant references to other
    29  * AutoRes objects (such as temporary objects returned from functions) which
    30  * can not be modified due to their const modifier, but are not actually
    31  * constant objects.  See a discussion of auto_ptr and auto_ptr_ref for more
    32  * details.
     30 * A callable class template which returns the correct value against which an
     31 * IPRT type must be compared to see if it is invalid.
     32 * @note this template must be specialised for the types it is to work with.
    3333 */
    34 template <class T, void Destruct(T)>
    35 struct RTAutoResRef
    36 {
    37     T mValue;
     34template <class T>
     35inline T RTResNul(void)
     36{ AssertLogRelMsgFailedReturn (("Unspecialized template!\n"), (T) 0); }
    3837
    39     explicit RTAutoResRef(T aValue) { mValue = aValue; }
    40 };
     38/**
     39 * A function template which calls the correct destructor for an IPRT type.
     40 * @note this template must be specialised for the types it is to work with.
     41 */
     42template <class T> inline void RTResDestruct(T aHandle)
     43{ AssertLogRelMsgFailedReturn (("Unspecialized template!\n"), (T) 0); }
    4144
    4245/**
    4346 * An auto pointer-type class for resources which take a C-style destructor
    44  * destructor (free() or equivalent).
     47 * (RTMemFree() or equivalent).
     48 *
     49 * The idea of this class is to manage resources which the current code is
     50 * responsible for freeing.  By wrapping the resource in an RTAutoRes, you
     51 * ensure that the resource will be freed when you leave the scope in which
     52 * the RTAutoRes is defined, unless you explicitly release the resource again.
     53 *
     54 * A typical use case is when a function is allocating a number of resources.
     55 * If any single allocation fails then all other resources must be freed.  If
     56 * all allocations succeed, then the resources should be returned to the
     57 * caller.  By placing all allocated resources in RTAutoRes containers, you
     58 * ensure that they will be freed on failure, and only have to take care of
     59 * releasing them when you return them.
     60 * @param T         the type of the resource
     61 * @param Destruct  the function to be used to free the resource
     62 * @note The class can not be initialised directly using assignment, due to
     63 *       the lack of a copy constructor.
    4564 */
    46 template <class T, void Destruct(T)>
    47 class RTAutoRes
     65template <class T, void Destruct(T) = RTResDestruct<T>, T NulRes(void) = RTResNul<T> >
     66class RTAutoRes : public stdx::non_copyable
    4867{
    4968private:
     
    5271public:
    5372    /** Constructor */
    54     RTAutoRes(T aValue = 0) { mValue = aValue; }
     73    RTAutoRes(T aValue = NulRes()) { mValue = aValue; }
    5574
    5675    /** Destructor */
    57     ~RTAutoRes() { if (mValue != 0) Destruct(mValue); }
    58 
    59     /** Copy constructor */
    60     RTAutoRes(RTAutoRes &orig) { mValue = orig.release(); }
    61 
    62     /** Copy from equivalent class */
    63     template <class T1>
    64     RTAutoRes(RTAutoRes<T1, Destruct> &orig)
    65     { mValue = orig.release(); }
    66 
    67     /** Convert a reference structure into an AutoRes pointer. */
    68     RTAutoRes(RTAutoResRef<T, Destruct> ref) { mValue = ref.mValue; }
    69 
    70     /** Assignment operator. */
    71     RTAutoRes& operator=(RTAutoRes &orig)
    72     {
    73         reset(orig.release());
    74         return *this;
    75     }
    76 
    77     /** Assignment from equivalent class. */
    78     template <class T1>
    79     RTAutoRes& operator=(RTAutoRes<T1, Destruct> &orig)
    80     {
    81         reset(orig.release);
    82         return *this;
    83     }
     76    ~RTAutoRes() { if (mValue != NulRes()) Destruct(mValue); }
    8477
    8578    /** Assignment from a value. */
    8679    RTAutoRes& operator=(T aValue)
    8780    {
    88         if (mValue != 0)
     81        if (mValue != NulRes())
    8982        {
    9083            Destruct(mValue);
     
    9487    }
    9588
    96     /** Assign from a reference structure into an AutoRes pointer. */
    97     RTAutoRes& operator=(RTAutoResRef<T, Destruct> ref)
    98     {
    99         if (ref.mValue != mValue)
    100         {
    101             Destruct(mValue);
    102             mValue = ref.mValue;
    103         }
    104         return *this;
    105     }
    106 
    107     /** Typecast an AutoRes pointer to an AutoRes pointer of a different type. */
    108     template <class T1>
    109     operator RTAutoRes<T1, Destruct>()
    110     { return RTAutoRes<T1, Destruct>(release()); }
    111 
    112     /** Typecast an AutoRes pointer to a reference structure. */
    113     template <class T1>
    114     operator RTAutoResRef<T1, Destruct>()
    115     { return RTAutoResRef<T1, Destruct>(release()); }
    116 
    11789    /** release method to get the pointer's value and "reset" the pointer. */
    118     T release(void) { T aTmp = mValue; mValue = 0; return aTmp; }
     90    T release(void) { T aTmp = mValue; mValue = NulRes(); return aTmp; }
    11991
    12092    /** reset the pointer value to zero or to another pointer. */
    121     void reset(T aValue = 0) { if (aValue != mValue) { Destruct(mValue); mValue = aValue; } }
     93    void reset(T aValue = NulRes()) { if (aValue != mValue)
     94    { Destruct(mValue); mValue = aValue; } }
    12295
    12396    /** Accessing the value inside. */
     
    129102inline void RTAutoResRecastVoid(T *aValue) { fn(aValue); }
    130103
     104template <class T>
     105T *RTMemAutoNul(void) { return (T *)(NULL); }
     106
     107/**
     108 * An auto pointer-type class for structures allocated using C-like APIs.
     109 *
     110 * The idea of this class is to manage resources which the current code is
     111 * responsible for freeing.  By wrapping the resource in an RTAutoRes, you
     112 * ensure that the resource will be freed when you leave the scope in which
     113 * the RTAutoRes is defined, unless you explicitly release the resource again.
     114 *
     115 * A typical use case is when a function is allocating a number of resources.
     116 * If any single allocation fails then all other resources must be freed.  If
     117 * all allocations succeed, then the resources should be returned to the
     118 * caller.  By placing all allocated resources in RTAutoRes containers, you
     119 * ensure that they will be freed on failure, and only have to take care of
     120 * releasing them when you return them.
     121 * @param T         the type of the resource
     122 * @param Destruct  the function to be used to free the resource
     123 */
    131124template <class T, void Destruct(T *) = RTAutoResRecastVoid <T, RTMemFree> >
    132 class RTMemAutoPtr : public RTAutoRes <T *, Destruct>
     125class RTMemAutoPtr : public RTAutoRes <T *, Destruct, RTMemAutoNul<T> >
    133126{
    134127public:
    135128    /** Constructor */
    136     RTMemAutoPtr(T *aValue = NULL) : RTAutoRes <T *, Destruct>(aValue) {}
     129    RTMemAutoPtr(T *aValue = NULL) : RTAutoRes <T *, Destruct, RTMemAutoNul<T> >(aValue) {}
    137130
    138     /** Copy constructors */
    139     RTMemAutoPtr(RTMemAutoPtr &orig) : RTAutoRes <T *, Destruct>(orig) {}
    140     template <class T1>
    141     RTMemAutoPtr(RTMemAutoPtr<T1, Destruct> &orig) : RTAutoRes<T1 *, Destruct>(orig) {}
    142 
    143     /** Assignment operators */
    144     RTMemAutoPtr& operator=(RTMemAutoPtr &orig)
    145     { this->RTAutoRes <T *, Destruct>::operator=(orig); }
    146     template <class T1>
    147     RTMemAutoPtr& operator=(RTMemAutoPtr<T1, Destruct> &orig)
    148     { this->RTAutoRes<T1 *, Destruct>::operator=(orig); return *this; }
    149131    RTMemAutoPtr& operator=(T *aValue)
    150     { this->RTAutoRes <T *, Destruct>::operator=(aValue); return *this; }
    151     RTMemAutoPtr& operator=(RTAutoResRef<T *, Destruct> ref)
    152     { this->RTAutoRes <T *, Destruct>::operator=(ref); return *this; }
     132    { this->RTAutoRes <T *, Destruct, RTMemAutoNul<T> >::operator=(aValue); return *this; }
    153133
    154134    /** Dereference with * operator. */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette