VirtualBox

Changeset 30681 in vbox for trunk/include/iprt/cpp


Ignore:
Timestamp:
Jul 6, 2010 5:20:20 PM (14 years ago)
Author:
vboxsync
Message:

Main: COM header cleanup (remove obscure and unused templates), second try

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/cpp/utils.h

    r30676 r30681  
    2727#define ___iprt_cpputils_h
    2828
    29 #include <iprt/assert.h>
    30 
    31 #include <memory>
    32 
    3329/** @defgroup grp_rt_cpputils   C++ Utilities
    3430 * @ingroup grp_rt
     
    4844 */
    4945template <class C>
    50 inline C &unconst (const C &that) { return const_cast <C &> (that); }
     46inline C& unconst(const C &that) { return const_cast<C&>(that); }
    5147
    5248
     
    6359 */
    6460template <class C>
    65 inline C *unconst (const C *that) { return const_cast <C *> (that); }
     61inline C* unconst(const C *that) { return const_cast<C*>(that); }
    6662
    6763
    68 /**
    69  * Extensions to the std namespace.
    70  */
    71 namespace stdx
     64namespace iprt
    7265{
    73 
    74 /* forward */
    75 template <class> class auto_ref_ptr;
    76 
    77 /**
    78  * Base class for objects willing to support smart reference counting using
    79  * the auto_ref_ptr template.
    80  *
    81  * When a class wants to be used with the auto_ref_ptr template it simply
    82  * declares the auto_ref class among its public base classes -- there is no
    83  * need to implement any additional methods.
    84  */
    85 class auto_ref
    86 {
    87 protected:
    88 
    89     auto_ref() : mRefs (0) {}
    90 
    91     /** Increases the reference counter and returns it */
    92     size_t ref() { return ++ mRefs; }
    93 
    94     /** Decreases the reference counter and returns it */
    95     size_t unref() { Assert (mRefs > 0); return -- mRefs; }
    96 
    97 private:
    98 
    99     size_t mRefs;
    100 
    101     template <class> friend class auto_ref_ptr;
    102 };
    103 
    104 /**
    105  * The auto_ref_ptr template manages pointers to objects that support
    106  * reference counting by implementing auto_ref or a similar interface.
    107  *
    108  * Pointer management includes the following key points:
    109  *
    110  *   1) Automatic increment of the object's reference counter when the given
    111  *      auto_ref_ptr instance starts managing a pointer to this object.
    112  *
    113  *   2) Automatic decrement of the reference counter when the given
    114  *      auto_ref_ptr instance is destroyed, or before it is assigned a pointer
    115  *      to a new object.
    116  *
    117  *   3) Automatic deletion of the managed object whenever its reference
    118  *      counter reaches zero after a decrement.
    119  *
    120  *   4) Providing the dereference operator-> that gives direct access to the
    121  *      managed pointer.
    122  *
    123  * The object class to manage must provide ref() and unref() methods that have
    124  * the same syntax and semantics as defined in the auto_ref class.
    125  *
    126  * @param C     Class to manage.
    127  */
    128 template <class C>
    129 class auto_ref_ptr
    130 {
    131 public:
    132 
    133     /**
    134      * Creates a null instance that does not manage anything.
    135      */
    136     auto_ref_ptr() : m (NULL) {}
    137 
    138     /**
    139      * Creates an instance that starts managing the given pointer. The
    140      * reference counter of the object pointed to by @a a is incremented by
    141      * one.
    142      *
    143      * @param a Pointer to manage.
    144      */
    145     auto_ref_ptr (C* a) : m (a) { if (m) m->ref(); }
    146 
    147     /**
    148      * Creates an instance that starts managing a pointer managed by the given
    149      * instance. The reference counter of the object managed by @a that is
    150      * incremented by one.
    151      *
    152      * @param that Instance to take a pointer to manage from.
    153      */
    154     auto_ref_ptr (const auto_ref_ptr &that) : m (that.m) { if (m) m->ref(); }
    155 
    156     ~auto_ref_ptr() { do_unref(); }
    157 
    158     /**
    159      * Assigns the given pointer to this instance and starts managing it. The
    160      * reference counter of the object pointed to by @a a is incremented by
    161      * one. The reference counter of the object previously managed by this
    162      * instance is decremented by one.
    163      *
    164      * @param a Pointer to assign.
    165      */
    166     auto_ref_ptr &operator= (C *a) { do_reref (a); return *this; }
    167 
    168     /**
    169      * Assigns a pointer managed by the given instance to this instance and
    170      * starts managing it. The reference counter of the object managed by @a
    171      * that is incremented by one. The reference counter of the object
    172      * previously managed by this instance is decremented by one.
    173      *
    174      * @param that Instance which pointer to reference.
    175      */
    176     auto_ref_ptr &operator= (const auto_ref_ptr &that) { do_reref (that.m); return *this; }
    177 
    178     /**
    179      * Returns @c true if this instance is @c null and false otherwise.
    180      */
    181     bool is_null() const { return m == NULL; }
    182 
    183     /**
    184      * Dereferences the instance by returning the managed pointer.
    185      * Asserts that the managed pointer is not @c NULL.
    186      */
    187     C *operator-> () const { AssertMsg (m, ("Managed pointer is NULL!\n")); return m; }
    188 
    189     /**
    190      * Returns the managed pointer or @c NULL if this instance is @c null.
    191      */
    192     C *raw() const { return m; }
    193 
    194     /**
    195      * Compares this auto_ref_ptr instance with another instance and returns
    196      * @c true if both instances manage the same or @c NULL pointer.
    197      *
    198      * Note that this method compares pointer values only, it doesn't try to
    199      * compare objects themselves. Doing otherwise would a) break the common
    200      * 'pointer to something' comparison semantics auto_ref_ptr tries to
    201      * follow and b) require to define the comparison operator in the managed
    202      * class which is not always possible. You may analyze pointed objects
    203      * yourself if you need more precise comparison.
    204      *
    205      * @param that Instance to compare this instance with.
    206      */
    207     bool operator== (const auto_ref_ptr &that) const
    208     {
    209         return m == that.m;
    210     }
    211 
    212 protected:
    213 
    214     void do_reref (C *a)
    215     {
    216         /* be aware of self assignment */
    217         if (a)
    218             a->ref();
    219         if (m)
    220         {
    221             size_t refs = m->unref();
    222             if (refs == 0)
    223             {
    224                 refs = 1; /* stabilize */
    225                 delete m;
    226             }
    227         }
    228         m = a;
    229     }
    230 
    231     void do_unref() { do_reref (NULL); }
    232 
    233     C *m;
    234 };
    235 
    236 /**
    237  * The exception_trap_base class is an abstract base class for all
    238  * exception_trap template instantiations.
    239  *
    240  * Pointer variables of this class are used to store a pointer any object of
    241  * any class instantiated from the exception_trap template, or in other words
    242  * to store a full copy of any exception wrapped into the exception_trap instance
    243  * allocated on the heap.
    244  *
    245  * See the exception_trap template for more info.
    246  */
    247 class exception_trap_base
    248 {
    249 public:
    250     virtual void rethrow() = 0;
    251     virtual ~exception_trap_base() {}
    252 };
    253 
    254 /**
    255  * The exception_trap template acts like a wrapper for the given exception
    256  * class that stores a full copy of the exception and therefore allows to
    257  * rethrow it preserving the actual type information about the exception
    258  * class.
    259  *
    260  * This functionality is useful in situations where it is necessary to catch a
    261  * (known) number of exception classes and pass the caught exception instance
    262  * to an upper level using a regular variable (rather than the exception
    263  * unwinding mechanism itself) *and* preserve all information about the type
    264  * (class) of the caight exception so that it may be rethrown on the upper
    265  * level unchanged.
    266  *
    267  * Usage pattern:
    268  * @code
    269     using namespace std;
    270     using namespace stdx;
    271 
    272     auto_ptr <exception_trap_base> trapped;
    273 
    274     int callback();
    275 
    276     int safe_callback()
    277     {
    278       try
    279       {
    280         // callback may throw a set of exceptions but we don't want it to start
    281         // unwinding the stack right now
    282 
    283         return callback();
    284       }
    285       catch (const MyException &err) { trapped = new_exception_trap (err); }
    286       catch (const MyException2 &err) { trapped = new_exception_trap (err); }
    287       catch (...) { trapped = new_exception_trap (logic_error()); }
    288 
    289       return -1;
    290     }
    291 
    292     void bar()
    293     {
    294       // call a funciton from some C library that supports callbacks but knows
    295       // nothing about exceptions so throwing one from a callback will leave
    296       // the library in an undetermined state
    297 
    298       do_something_with_callback (safe_callback());
    299 
    300       // check if we have got an exeption from callback() and rethrow it now
    301       // when we are not in the C library any more
    302       if (trapped.get() != NULL)
    303         trapped->rethrow();
    304     }
    305  * @endcode
    306  *
    307  * @param T Exception class to wrap.
    308  */
    309 template <typename T>
    310 class exception_trap : public exception_trap_base
    311 {
    312 public:
    313 
    314     exception_trap (const T &aTrapped) : trapped (aTrapped) {}
    315     void rethrow() { throw trapped; }
    316 
    317     T trapped;
    318 };
    319 
    320 /**
    321  * Convenience function that allocates a new exception_trap instance on the
    322  * heap by automatically deducing the exception_trap template argument from
    323  * the type of the exception passed in @a aTrapped.
    324  *
    325  * The following two lines of code inside the catch block are equivalent:
    326  *
    327  * @code
    328     using namespace std;
    329     using namespace stdx;
    330     catch (const MyException &err)
    331     {
    332       auto_ptr <exception_trap_base> t1 = new exception_trap <MyException> (err);
    333       auto_ptr <exception_trap_base> t2 = new_exception_trap (err);
    334     }
    335  * @endcode
    336  *
    337  * @param aTrapped Exception to put to the allocated trap.
    338  *
    339  * @return Allocated exception_trap object.
    340  */
    341 template <typename T>
    342 static exception_trap <T> *
    343 new_exception_trap (const T &aTrapped)
    344 {
    345     return new exception_trap <T> (aTrapped);
    346 }
    347 
    348 /**
    349  * Enhancement of std::auto_ptr @<char@> intended to take pointers to char
    350  * buffers allocated using new[].
    351  *
    352  * This differs from std::auto_ptr @<char@> so that it overloads some methods to
    353  * uses delete[] instead of delete to delete the owned data in order to
    354  * conform to the C++ standard (and avoid valgrind complaints).
    355  *
    356  * Note that you should not use instances of this class where pointers or
    357  * references to objects of std::auto_ptr @<char@> are expeced. Despite the fact
    358  * the classes are related, the base is not polymorphic (in particular,
    359  * neither the destructor nor the reset() method are virtual). It means that when
    360  * acessing instances of this class through the base pointer, overloaded
    361  * methods won't be called.
    362  */
    363 class char_auto_ptr : public std::auto_ptr <char>
    364 {
    365 public:
    366 
    367     explicit char_auto_ptr (char *a = 0) throw()
    368         : std::auto_ptr <char> (a) {}
    369 
    370     /* Note: we use unconst brute force below because the non-const version
    371      * of the copy constructor won't accept temporary const objects
    372      * (e.g. function return values) in GCC. std::auto_ptr has the same
    373      * "problem" but it seems overcome it using #pragma GCC system_header
    374      * which doesn't work here. */
    375     char_auto_ptr (const char_auto_ptr &that) throw()
    376         : std::auto_ptr <char> (unconst (that).release()) {}
    377 
    378     ~char_auto_ptr() { delete[] (release()); }
    379 
    380     char_auto_ptr &operator= (char_auto_ptr &that) throw()
    381     {
    382         std::auto_ptr <char>::operator= (that);
    383         return *this;
    384     }
    385 
    386     void reset (char *a) throw()
    387     {
    388         if (a != get())
    389         {
    390             delete[] (release());
    391             std::auto_ptr <char>::reset (a);
    392         }
    393     }
    394 };
    395 
    39666/**
    39767 * A simple class used to prevent copying and assignment.  Inherit from this
     
    40979};
    41080
    411 } /* namespace stdx */
     81} // namespace iprt
    41282
    41383/** @} */
    41484
    415 #endif
     85#endif // ___iprt_cpputils_h
    41686
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