VirtualBox

Changeset 6076 in vbox for trunk/include


Ignore:
Timestamp:
Dec 14, 2007 7:23:03 PM (17 years ago)
Author:
vboxsync
Message:

Merged dmik/s2 branch (r25959:26751) to the trunk.

Location:
trunk/include
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/com/Guid.h

    r5999 r6076  
     1/* $Id$ */
     2
    13/** @file
    24 * MS COM / XPCOM Abstraction Layer:
     
    3436#include "VBox/com/string.h"
    3537
     38#include <iprt/cpputils.h>
    3639#include <iprt/uuid.h>
    3740
     
    5154    Guid (const RTUUID &that) { uuid = that; }
    5255    Guid (const GUID &that) { ::memcpy (&uuid, &that, sizeof (GUID)); }
    53     Guid (const char *that) {
     56    Guid (const char *that)
     57    {
    5458        ::RTUuidClear (&uuid);
    5559        ::RTUuidFromStr (&uuid, that);
    5660    }
    5761
    58     Guid &operator= (const Guid &that) {
     62    Guid &operator= (const Guid &that)
     63    {
    5964        ::memcpy (&uuid, &that.uuid, sizeof (RTUUID));
    6065        return *this;
    6166    }
    62     Guid &operator= (const GUID &guid) {
     67    Guid &operator= (const GUID &guid)
     68    {
    6369        ::memcpy (&uuid, &guid, sizeof (GUID));
    6470        return *this;
    6571    }
    66     Guid &operator= (const RTUUID &guid) {
     72    Guid &operator= (const RTUUID &guid)
     73    {
    6774        ::memcpy (&uuid, &guid, sizeof (RTUUID));
    6875        return *this;
    6976    }
    70     Guid &operator= (const char *str) {
     77    Guid &operator= (const char *str)
     78    {
    7179        ::RTUuidFromStr (&uuid, str);
    7280        return *this;
     
    7684    void clear() { ::RTUuidClear (&uuid); }
    7785
    78     Utf8Str toString () const {
     86    Utf8Str toString () const
     87    {
    7988        char buf [RTUUID_STR_LENGTH];
    8089        ::RTUuidToStr (&uuid, buf, RTUUID_STR_LENGTH);
     
    92101    bool operator< (const GUID &guid) const { return ::RTUuidCompare (&uuid, (PRTUUID) &guid) < 0; }
    93102
    94     // to pass instances as GUIDPARAM parameters to interface methods
     103    /* to pass instances as GUIDPARAM parameters to interface methods */
    95104    operator const GUID &() const { return *(GUID *) &uuid; }
    96105
    97     // to directly pass instances to CFGLDRQueryUUID()
     106    /* to directly pass instances to CFGLDRQueryUUID() */
    98107    PRTUUID ptr() { return &uuid; }
    99108
    100     // to pass instances to printf-like functions
     109    /* to pass instances to printf-like functions */
    101110    PCRTUUID raw() const { return &uuid; }
    102111
    103     // to pass instances to RTUuid*() as a constant argument
     112    /* to pass instances to RTUuid*() as a constant argument */
    104113    operator const RTUUID * () const { return &uuid; }
    105114
    106115#if defined(RT_OS_WINDOWS)
    107116
    108     // to assign instances to GUIDPARAMOUT parameters from within the interface method
    109     const Guid &cloneTo (GUID *pguid) const {
     117    /* to assign instances to GUIDPARAMOUT parameters from within the
     118     *  interface method */
     119    const Guid &cloneTo (GUID *pguid) const
     120    {
    110121        if (pguid) { ::memcpy (pguid, &uuid, sizeof (GUID)); }
    111122        return *this;
    112123    }
    113124
    114     // to pass instances as GUIDPARAMOUT parameters to interface methods
     125    /* to pass instances as GUIDPARAMOUT parameters to interface methods */
    115126    GUID *asOutParam() { return (GUID *) &uuid; }
    116127
    117128#else
    118129
    119     // to assign instances to GUIDPARAMOUT parameters from within the interface method
    120     const Guid &cloneTo (nsID **ppguid) const {
     130    /* to assign instances to GUIDPARAMOUT parameters from within the
     131     * interface method */
     132    const Guid &cloneTo (nsID **ppguid) const
     133    {
    121134        if (ppguid) { *ppguid = (nsID *) nsMemory::Clone (&uuid, sizeof (nsID)); }
    122135        return *this;
    123136    }
    124137
    125     // internal helper class for asOutParam()
    126     class GuidOutParam {
     138    /* internal helper class for asOutParam() */
     139    class GuidOutParam
     140    {
    127141        GuidOutParam (Guid &guid) : ptr (0), outer (guid) { outer.clear(); }
    128142        nsID *ptr;
     
    132146    public:
    133147        operator nsID **() { return &ptr; }
    134         ~GuidOutParam() {
     148        ~GuidOutParam()
     149        {
    135150            if (ptr && outer.isEmpty()) { outer = *ptr; nsMemory::Free (ptr); }
    136151        }
     
    138153    };
    139154
    140     // to pass instances as GUIDPARAMOUT parameters to interface methods
     155    /* to pass instances as GUIDPARAMOUT parameters to interface methods */
    141156    GuidOutParam asOutParam() { return GuidOutParam (*this); }
    142157
    143158#endif
    144159
    145     // to directly test GUIDPARAM interface method's parameters
    146     static BOOL isEmpty (const GUID &guid) { return ::RTUuidIsNull ((PRTUUID) &guid); }
     160    /* to directly test GUIDPARAM interface method's parameters */
     161    static bool isEmpty (const GUID &guid)
     162    {
     163        return ::RTUuidIsNull ((PRTUUID) &guid) != 0;
     164    }
     165
     166    /**
     167     *  Static immutable empty object. May be used for comparison purposes.
     168     */
     169    static const Guid Empty;
    147170
    148171private:
     
    151174};
    152175
    153 #if defined (_MSC_VER)
    154 
    155 // work around error C2593 of the stupid MSVC 7.x ambiguity resolver
    156 inline bool operator! (const Guid& guid) { return !bool (guid); }
    157 inline bool operator&& (const Guid& guid, bool b) { return bool (guid) && b; }
    158 inline bool operator|| (const Guid& guid, bool b) { return bool (guid) || b; }
    159 inline bool operator&& (bool b, const Guid& guid) { return b && bool (guid); }
    160 inline bool operator|| (bool b, const Guid& guid) { return b || bool (guid); }
    161 
    162 #endif
     176/* work around error C2593 of the stupid MSVC 7.x ambiguity resolver */
     177WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP (Guid);
    163178
    164179} /* namespace com */
    165180
    166 #endif
     181#endif /* ___VBox_com_Guid_h */
    167182
  • trunk/include/VBox/com/assert.h

    r5999 r6076  
    7979
    8080/**
     81 *  A special version of AssertComRC that evaluates the given expression and
     82 *  throws it if the result code is failed.
     83 *
     84 *  @param rc   COM result code
     85 *  @param eval the expression to evaluate
     86 */
     87#define AssertComRCThrow(rc, eval)      \
     88    if (1) { AssertComRC (rc); if (!SUCCEEDED (rc)) { throw (eval); } } else do {} while (0)
     89
     90/**
    8191 *  A special version of AssertComRC that just breaks if the result code is
    8292 *  failed.
     
    8898
    8999/**
     100 *  A special version of AssertComRC that just throws @a rc if the result code is
     101 *  failed.
     102 *
     103 *  @param rc   COM result code
     104 */
     105#define AssertComRCThrowRC(rc)          \
     106    if (1) { AssertComRC (rc); if (!SUCCEEDED (rc)) { throw rc; } } else do {} while (0)
     107
     108/**
    90109 *  Checks whether the given COM result code is successful.
    91110 *  If not, executes the return statement with this result code.
     
    104123#define CheckComRCBreakRC(rc)      \
    105124    if (1) { if (!SUCCEEDED (rc)) { break; } } else do {} while (0)
     125
     126/**
     127 *  Checks whether the given COM result code is successful.
     128 *  If not, throws the given COM result.
     129 *
     130 *  @param rc   COM result code
     131 */
     132#define CheckComRCThrowRC(rc)      \
     133    if (1) { if (!SUCCEEDED (rc)) { throw rc; } } else do {} while (0)
    106134
    107135/*
  • trunk/include/VBox/com/defs.h

    r5999 r6076  
    7777#define COM_IIDOF(I) _ATL_IIDOF (I)
    7878
    79 #else // defined (RT_OS_WINDOWS)
     79#else /* defined (RT_OS_WINDOWS) */
    8080
    8181#error "VBOX_WITH_XPCOM is not defined!"
    8282
    83 #endif // defined (RT_OS_WINDOWS)
    84 
    85 #else // !defined (VBOX_WITH_XPCOM)
     83#endif /* defined (RT_OS_WINDOWS) */
     84
     85#else /* !defined (VBOX_WITH_XPCOM) */
    8686
    8787// XPCOM
     
    101101#undef TRUE
    102102
    103 #endif // defined (RT_OS_OS2)
     103#endif /* defined (RT_OS_OS2) */
    104104
    105105#if defined (RT_OS_DARWIN)
     
    289289}
    290290
    291 #endif // !defined (RT_OS_WINDOWS)
     291#endif /* !defined (RT_OS_WINDOWS) */
    292292
    293293/**
     
    304304#endif
    305305
    306 #endif
    307 
     306#endif /* ___VBox_com_defs_h */
     307
  • trunk/include/VBox/com/string.h

    r5999 r6076  
     1/* $Id$ */
     2
    13/** @file
    24 * MS COM / XPCOM Abstraction Layer:
     
    3638
    3739#include <iprt/string.h>
     40#include <iprt/cpputils.h>
    3841#include <iprt/alloc.h>
    3942
     
    208211    BSTR *asOutParam() { setNull(); return &bstr; }
    209212
     213    /**
     214     *  Static immutable null object. May be used for comparison purposes.
     215     */
     216    static const Bstr Null;
     217
    210218private:
    211219
     
    417425    char **asOutParam() { setNull(); return &str; }
    418426
     427    /**
     428     *  Static immutable null object. May be used for comparison purposes.
     429     */
     430    static const Utf8Str Null;
     431
    419432private:
    420433
     
    568581} /* namespace com */
    569582
    570 #endif
     583#endif /* ___VBox_com_string_h */
  • trunk/include/iprt/assert.h

    r5999 r6076  
    235235#endif
    236236
     237/** @def AssertBreakVoid
     238 * Assert that an expression is true and breaks if it isn't.
     239 * In RT_STRICT mode it will hit a breakpoint before returning.
     240 *
     241 * @param   expr    Expression which should be true.
     242 */
     243#ifdef RT_STRICT
     244# define AssertBreakVoid(expr) \
     245    do { \
     246        if (RT_UNLIKELY(!(expr))) \
     247        { \
     248            AssertMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
     249            AssertBreakpoint(); \
     250            break; \
     251        } \
     252    } while (0)
     253#else
     254# define AssertBreakVoid(expr) \
     255    do { \
     256        if (RT_UNLIKELY(!(expr))) \
     257            break; \
     258    } while (0)
     259#endif
     260
    237261
    238262/** @def AssertMsg
     
    334358#endif
    335359
     360/** @def AssertMsgBreakVoid
     361 * Assert that an expression is true and breaks if it isn't.
     362 * In RT_STRICT mode it will hit a breakpoint before returning.
     363 *
     364 * @param   expr    Expression which should be true.
     365 * @param   a       printf argument list (in parenthesis).
     366 */
     367#ifdef RT_STRICT
     368# define AssertMsgBreakVoid(expr, a)  \
     369    do { \
     370        if (RT_UNLIKELY(!(expr))) \
     371        { \
     372            AssertMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
     373            AssertMsg2 a; \
     374            AssertBreakpoint(); \
     375            break; \
     376        } \
     377    } while (0)
     378#else
     379# define AssertMsgBreakVoid(expr, a) \
     380    do { \
     381        if (RT_UNLIKELY(!(expr))) \
     382            break; \
     383    } while (0)
     384#endif
     385
    336386
    337387/** @def AssertFailed
     
    407457#endif
    408458
     459/** @def AssertFailedBreakVoid
     460 * An assertion failed, hit breakpoint (RT_STRICT mode only) and break.
     461 */
     462#ifdef RT_STRICT
     463# define AssertFailedBreakVoid()  \
     464    do { \
     465        AssertMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
     466        AssertBreakpoint(); \
     467        break; \
     468    } while (0)
     469#else
     470# define AssertFailedBreakVoid()  \
     471    do { \
     472        break; \
     473    } while (0)
     474#endif
     475
    409476
    410477/** @def AssertMsgFailed
     
    488555        break; \
    489556    } else do {} while (0)
     557#endif
     558
     559/** @def AssertMsgFailedBreakVoid
     560 * An assertion failed, hit breakpoint with message (RT_STRICT mode only) and break.
     561 *
     562 * @param   a       printf argument list (in parenthesis).
     563 */
     564#ifdef RT_STRICT
     565# define AssertMsgFailedBreakVoid(a)  \
     566    do { \
     567        AssertMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
     568        AssertMsg2 a; \
     569        AssertBreakpoint(); \
     570        break; \
     571    } while (0)
     572#else
     573# define AssertMsgFailedBreakVoid(a)  \
     574    do { \
     575        break; \
     576    } while (0)
    490577#endif
    491578
     
    564651 */
    565652#define AssertReleaseBreak(expr, stmt)  \
    566     if (RT_UNLIKELY(!(expr))) { \
    567         AssertMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
    568         AssertReleaseBreakpoint(); \
    569         stmt; \
    570         break; \
    571     } else do {} while (0)
    572 
     653    do { \
     654        if (RT_UNLIKELY(!(expr))) \
     655        { \
     656            AssertMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
     657            AssertReleaseBreakpoint(); \
     658            stmt; \
     659            break; \
     660        } \
     661    } while (0)
     662
     663/** @def AssertReleaseBreakVoid
     664 * Assert that an expression is true, hit a breakpoing and break if it isn't.
     665 *
     666 * @param   expr    Expression which should be true.
     667 */
     668#define AssertReleaseBreakVoid(expr)  \
     669    do { \
     670        if (RT_UNLIKELY(!(expr))) \
     671        { \
     672            AssertMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
     673            AssertReleaseBreakpoint(); \
     674            break; \
     675        } \
     676    } while (0)
    573677
    574678
     
    607711    } while (0)
    608712
    609 /** @def AssertReleaseMsgReturn
     713/** @def AssertReleaseMsgReturnVoid
    610714 * Assert that an expression is true, print the message and hit a breakpoint and return if it isn't.
    611715 *
     
    641745    } else do {} while (0)
    642746
     747/** @def AssertReleaseMsgBreakVoid
     748 * Assert that an expression is true, print the message and hit a breakpoint and break if it isn't.
     749 *
     750 * @param   expr    Expression which should be true.
     751 * @param   a       printf argument list (in parenthesis).
     752 */
     753#define AssertReleaseMsgBreakVoid(expr, a)  \
     754    do { \
     755        if (RT_UNLIKELY(!(expr))) \
     756        { \
     757            AssertMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
     758            AssertMsg2 a; \
     759            AssertReleaseBreakpoint(); \
     760            break; \
     761        } \
     762    } while (0)
     763
    643764
    644765/** @def AssertReleaseFailed
     
    663784    } while (0)
    664785
    665 /** @def AssertReleaseFailedReturn
     786/** @def AssertReleaseFailedReturnVoid
    666787 * An assertion failed, hit a breakpoint and return.
    667788 */
     
    686807        break; \
    687808    } else do {} while (0)
     809
     810/** @def AssertReleaseFailedBreakVoid
     811 * An assertion failed, hit a breakpoint and break.
     812 */
     813#define AssertReleaseFailedBreakVoid()  \
     814    do { \
     815        AssertMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
     816        AssertReleaseBreakpoint(); \
     817        break; \
     818    } while (0)
    688819
    689820
     
    743874    } else do {} while (0)
    744875
     876/** @def AssertReleaseMsgFailedBreakVoid
     877 * An assertion failed, print a message, hit a breakpoint and break.
     878 *
     879 * @param   a   printf argument list (in parenthesis).
     880 */
     881#define AssertReleaseMsgFailedBreakVoid(a) \
     882    do { \
     883        AssertMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
     884        AssertMsg2 a; \
     885        AssertReleaseBreakpoint(); \
     886        break; \
     887    } while (0)
    745888
    746889
     
    841984#define AssertRCBreak(rc, stmt)   AssertMsgRCBreak(rc, ("%Vra\n", (rc)), stmt)
    842985
     986/** @def AssertRCBreakVoid
     987 * Asserts a iprt status code successful, bitch (RT_STRICT mode only) and break if it isn't.
     988 *
     989 * @param   rc      iprt status code.
     990 * @remark  rc is references multiple times. In release mode is NOREF()'ed.
     991 */
     992#define AssertRCBreakVoid(rc)   AssertMsgRCBreakVoid(rc, ("%Vra\n", (rc)))
     993
    843994/** @def AssertMsgRC
    844995 * Asserts a iprt status code successful.
     
    8911042    do { AssertMsgBreak(RT_SUCCESS_NP(rc), msg, stmt); NOREF(rc); } while (0)
    8921043
     1044/** @def AssertMsgRCBreakVoid
     1045 * Asserts a iprt status code successful and if it's not break.
     1046 *
     1047 * If RT_STRICT is defined the message will be printed and a breakpoint hit before it breaks
     1048 *
     1049 * @param   rc      iprt status code.
     1050 * @param   msg     printf argument list (in parenthesis).
     1051 * @remark  rc is references multiple times. In release mode is NOREF()'ed.
     1052 */
     1053#define AssertMsgRCBreakVoid(rc, msg) \
     1054    do { AssertMsgBreakVoid(RT_SUCCESS(rc), msg); NOREF(rc); } while (0)
     1055
    8931056/** @def AssertRCSuccess
    8941057 * Asserts an iprt status code equals VINF_SUCCESS.
     
    9271090#define AssertRCSuccessBreak(rc, stmt)    AssertMsgBreak((rc) == VINF_SUCCESS, ("%Vra\n", (rc)), stmt)
    9281091
     1092/** @def AssertRCSuccessBreakVoid
     1093 * Asserts that an iprt status code equals VINF_SUCCESS, bitch (RT_STRICT mode only) and break if it isn't.
     1094 *
     1095 * @param   rc      iprt status code.
     1096 * @remark  rc is references multiple times. In release mode is NOREF()'ed.
     1097 */
     1098#define AssertRCSuccessBreakVoid(rc)    AssertMsgBreakVoid((rc) == VINF_SUCCESS, ("%Vra\n", (rc)))
     1099
    9291100
    9301101/** @def AssertReleaseRC
     
    9731144#define AssertReleaseRCBreak(rc, stmt) AssertReleaseMsgRCBreak(rc, ("%Vra\n", (rc)), stmt)
    9741145
     1146/** @def AssertReleaseRCBreakVoid
     1147 * Asserts a iprt status code successful, breaking if it isn't.
     1148 *
     1149 * On failure information about the error will be printed, a breakpoint hit
     1150 * and finally breaking the current statement if the breakpoint is somehow ignored.
     1151 *
     1152 * @param   rc      iprt status code.
     1153 * @remark  rc is references multiple times.
     1154 */
     1155#define AssertReleaseRCBreakVoid(rc) AssertReleaseMsgRCBreakVoid(rc, ("%Vra\n", (rc)))
     1156
    9751157/** @def AssertReleaseMsgRC
    9761158 * Asserts a iprt status code successful.
     
    10221204#define AssertReleaseMsgRCBreak(rc, msg, stmt)    AssertReleaseMsgBreak(RT_SUCCESS_NP(rc), msg, stmt)
    10231205
     1206/** @def AssertReleaseMsgRCBreakVoid
     1207 * Asserts a iprt status code successful.
     1208 *
     1209 * On failure a custom message is printed, a breakpoint is hit, and finally
     1210 * breaking the current status if the breakpoint is showhow ignored.
     1211 *
     1212 * @param   rc      iprt status code.
     1213 * @param   msg     printf argument list (in parenthesis).
     1214 * @remark  rc is references multiple times.
     1215 */
     1216#define AssertReleaseMsgRCBreakVoid(rc, msg)    AssertReleaseMsgBreakVoid(RT_SUCCESS(rc), msg)
     1217
    10241218/** @def AssertReleaseRCSuccess
    10251219 * Asserts that an iprt status code equals VINF_SUCCESS.
     
    10671261#define AssertReleaseRCSuccessBreak(rc, stmt)     AssertReleaseMsgBreak((rc) == VINF_SUCCESS, ("%Vra\n", (rc)), stmt)
    10681262
     1263/** @def AssertReleaseRCSuccessBreakVoid
     1264 * Asserts that an iprt status code equals VINF_SUCCESS.
     1265 *
     1266 * On failure information about the error will be printed, a breakpoint hit
     1267 * and finally breaking the current statement if the breakpoint is somehow ignored.
     1268 *
     1269 * @param   rc      iprt status code.
     1270 * @remark  rc is references multiple times.
     1271 */
     1272#define AssertReleaseRCSuccessBreakVoid(rc)     AssertReleaseMsgBreakVoid((rc) == VINF_SUCCESS, ("%Vra\n", (rc)))
     1273
    10691274
    10701275/** @def AssertFatalRC
     
    11301335#define AssertPtrBreak(pv, stmt)  AssertMsgBreak(VALID_PTR(pv), ("%p\n", (pv)), stmt)
    11311336
     1337/** @def AssertPtrBreakVoid
     1338 * Asserts that a pointer is valid.
     1339 *
     1340 * @param   pv      The pointer.
     1341 */
     1342#define AssertPtrBreakVoid(pv)  AssertMsgBreakVoid(VALID_PTR(pv), ("%p\n", (pv)))
     1343
    11321344/** @def AssertPtrNull
    11331345 * Asserts that a pointer is valid or NULL.
     
    11591371 */
    11601372#define AssertPtrNullBreak(pv, stmt)  AssertMsgBreak(VALID_PTR(pv) || (pv) == NULL, ("%p\n", (pv)), stmt)
     1373
     1374/** @def AssertPtrNullBreakVoid
     1375 * Asserts that a pointer is valid or NULL.
     1376 *
     1377 * @param   pv      The pointer.
     1378 */
     1379#define AssertPtrNullBreakVoid(pv)  AssertMsgBreakVoid(VALID_PTR(pv) || (pv) == NULL, ("%p\n", (pv)))
    11611380
    11621381
  • trunk/include/iprt/cdefs.h

    r5999 r6076  
    12481248#ifdef __cplusplus
    12491249
     1250/** @def DECLEXPORT_CLASS
     1251 * How to declare an exported class. Place this macro after the 'class'
     1252 * keyword in the declaration of every class you want to export.
     1253 *
     1254 * @note It is necessary to use this macro even for inner classes declared
     1255 * inside the already exported classes. This is a GCC specific requirement,
     1256 * but it seems not to harm other compilers.
     1257 */
     1258#if defined(_MSC_VER) || defined(RT_OS_OS2)
     1259# define DECLEXPORT_CLASS       __declspec(dllexport)
     1260#else
     1261# ifdef VBOX_HAVE_VISIBILITY_HIDDEN
     1262#  define DECLEXPORT_CLASS      __attribute__((visibility("default")))
     1263# else
     1264#  define DECLEXPORT_CLASS
     1265# endif
     1266#endif
     1267
     1268/** @def DECLIMPORT_CLASS
     1269 * How to declare an imported class Place this macro after the 'class'
     1270 * keyword in the declaration of every class you want to export.
     1271 *
     1272 * @note It is necessary to use this macro even for inner classes declared
     1273 * inside the already exported classes. This is a GCC specific requirement,
     1274 * but it seems not to harm other compilers.
     1275 */
     1276#if defined(_MSC_VER) || (defined(RT_OS_OS2) && !defined(__IBMC__) && !defined(__IBMCPP__))
     1277# define DECLIMPORT_CLASS       __declspec(dllimport)
     1278#else
     1279# ifdef VBOX_HAVE_VISIBILITY_HIDDEN
     1280#  define DECLIMPORT_CLASS      __attribute__((visibility("default")))
     1281# else
     1282#  define DECLIMPORT_CLASS
     1283# endif
     1284#endif
     1285
    12501286/** @def WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP
    12511287 * Macro to work around error C2593 of the not-so-smart MSVC 7.x ambiguity
  • trunk/include/iprt/cpputils.h

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