Changeset 6076 in vbox for trunk/include
- Timestamp:
- Dec 14, 2007 7:23:03 PM (17 years ago)
- Location:
- trunk/include
- Files:
-
- 1 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/com/Guid.h
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * MS COM / XPCOM Abstraction Layer: … … 34 36 #include "VBox/com/string.h" 35 37 38 #include <iprt/cpputils.h> 36 39 #include <iprt/uuid.h> 37 40 … … 51 54 Guid (const RTUUID &that) { uuid = that; } 52 55 Guid (const GUID &that) { ::memcpy (&uuid, &that, sizeof (GUID)); } 53 Guid (const char *that) { 56 Guid (const char *that) 57 { 54 58 ::RTUuidClear (&uuid); 55 59 ::RTUuidFromStr (&uuid, that); 56 60 } 57 61 58 Guid &operator= (const Guid &that) { 62 Guid &operator= (const Guid &that) 63 { 59 64 ::memcpy (&uuid, &that.uuid, sizeof (RTUUID)); 60 65 return *this; 61 66 } 62 Guid &operator= (const GUID &guid) { 67 Guid &operator= (const GUID &guid) 68 { 63 69 ::memcpy (&uuid, &guid, sizeof (GUID)); 64 70 return *this; 65 71 } 66 Guid &operator= (const RTUUID &guid) { 72 Guid &operator= (const RTUUID &guid) 73 { 67 74 ::memcpy (&uuid, &guid, sizeof (RTUUID)); 68 75 return *this; 69 76 } 70 Guid &operator= (const char *str) { 77 Guid &operator= (const char *str) 78 { 71 79 ::RTUuidFromStr (&uuid, str); 72 80 return *this; … … 76 84 void clear() { ::RTUuidClear (&uuid); } 77 85 78 Utf8Str toString () const { 86 Utf8Str toString () const 87 { 79 88 char buf [RTUUID_STR_LENGTH]; 80 89 ::RTUuidToStr (&uuid, buf, RTUUID_STR_LENGTH); … … 92 101 bool operator< (const GUID &guid) const { return ::RTUuidCompare (&uuid, (PRTUUID) &guid) < 0; } 93 102 94 / / to pass instances as GUIDPARAM parameters to interface methods103 /* to pass instances as GUIDPARAM parameters to interface methods */ 95 104 operator const GUID &() const { return *(GUID *) &uuid; } 96 105 97 / / to directly pass instances to CFGLDRQueryUUID()106 /* to directly pass instances to CFGLDRQueryUUID() */ 98 107 PRTUUID ptr() { return &uuid; } 99 108 100 / / to pass instances to printf-like functions109 /* to pass instances to printf-like functions */ 101 110 PCRTUUID raw() const { return &uuid; } 102 111 103 / / to pass instances to RTUuid*() as a constant argument112 /* to pass instances to RTUuid*() as a constant argument */ 104 113 operator const RTUUID * () const { return &uuid; } 105 114 106 115 #if defined(RT_OS_WINDOWS) 107 116 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 { 110 121 if (pguid) { ::memcpy (pguid, &uuid, sizeof (GUID)); } 111 122 return *this; 112 123 } 113 124 114 / / to pass instances as GUIDPARAMOUT parameters to interface methods125 /* to pass instances as GUIDPARAMOUT parameters to interface methods */ 115 126 GUID *asOutParam() { return (GUID *) &uuid; } 116 127 117 128 #else 118 129 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 { 121 134 if (ppguid) { *ppguid = (nsID *) nsMemory::Clone (&uuid, sizeof (nsID)); } 122 135 return *this; 123 136 } 124 137 125 // internal helper class for asOutParam() 126 class GuidOutParam { 138 /* internal helper class for asOutParam() */ 139 class GuidOutParam 140 { 127 141 GuidOutParam (Guid &guid) : ptr (0), outer (guid) { outer.clear(); } 128 142 nsID *ptr; … … 132 146 public: 133 147 operator nsID **() { return &ptr; } 134 ~GuidOutParam() { 148 ~GuidOutParam() 149 { 135 150 if (ptr && outer.isEmpty()) { outer = *ptr; nsMemory::Free (ptr); } 136 151 } … … 138 153 }; 139 154 140 / / to pass instances as GUIDPARAMOUT parameters to interface methods155 /* to pass instances as GUIDPARAMOUT parameters to interface methods */ 141 156 GuidOutParam asOutParam() { return GuidOutParam (*this); } 142 157 143 158 #endif 144 159 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; 147 170 148 171 private: … … 151 174 }; 152 175 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 */ 177 WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP (Guid); 163 178 164 179 } /* namespace com */ 165 180 166 #endif 181 #endif /* ___VBox_com_Guid_h */ 167 182 -
trunk/include/VBox/com/assert.h
r5999 r6076 79 79 80 80 /** 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 /** 81 91 * A special version of AssertComRC that just breaks if the result code is 82 92 * failed. … … 88 98 89 99 /** 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 /** 90 109 * Checks whether the given COM result code is successful. 91 110 * If not, executes the return statement with this result code. … … 104 123 #define CheckComRCBreakRC(rc) \ 105 124 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) 106 134 107 135 /* -
trunk/include/VBox/com/defs.h
r5999 r6076 77 77 #define COM_IIDOF(I) _ATL_IIDOF (I) 78 78 79 #else / / defined (RT_OS_WINDOWS)79 #else /* defined (RT_OS_WINDOWS) */ 80 80 81 81 #error "VBOX_WITH_XPCOM is not defined!" 82 82 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) */ 86 86 87 87 // XPCOM … … 101 101 #undef TRUE 102 102 103 #endif / / defined (RT_OS_OS2)103 #endif /* defined (RT_OS_OS2) */ 104 104 105 105 #if defined (RT_OS_DARWIN) … … 289 289 } 290 290 291 #endif / / !defined (RT_OS_WINDOWS)291 #endif /* !defined (RT_OS_WINDOWS) */ 292 292 293 293 /** … … 304 304 #endif 305 305 306 #endif 307 306 #endif /* ___VBox_com_defs_h */ 307 -
trunk/include/VBox/com/string.h
r5999 r6076 1 /* $Id$ */ 2 1 3 /** @file 2 4 * MS COM / XPCOM Abstraction Layer: … … 36 38 37 39 #include <iprt/string.h> 40 #include <iprt/cpputils.h> 38 41 #include <iprt/alloc.h> 39 42 … … 208 211 BSTR *asOutParam() { setNull(); return &bstr; } 209 212 213 /** 214 * Static immutable null object. May be used for comparison purposes. 215 */ 216 static const Bstr Null; 217 210 218 private: 211 219 … … 417 425 char **asOutParam() { setNull(); return &str; } 418 426 427 /** 428 * Static immutable null object. May be used for comparison purposes. 429 */ 430 static const Utf8Str Null; 431 419 432 private: 420 433 … … 568 581 } /* namespace com */ 569 582 570 #endif 583 #endif /* ___VBox_com_string_h */ -
trunk/include/iprt/assert.h
r5999 r6076 235 235 #endif 236 236 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 237 261 238 262 /** @def AssertMsg … … 334 358 #endif 335 359 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 336 386 337 387 /** @def AssertFailed … … 407 457 #endif 408 458 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 409 476 410 477 /** @def AssertMsgFailed … … 488 555 break; \ 489 556 } 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) 490 577 #endif 491 578 … … 564 651 */ 565 652 #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) 573 677 574 678 … … 607 711 } while (0) 608 712 609 /** @def AssertReleaseMsgReturn 713 /** @def AssertReleaseMsgReturnVoid 610 714 * Assert that an expression is true, print the message and hit a breakpoint and return if it isn't. 611 715 * … … 641 745 } else do {} while (0) 642 746 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 643 764 644 765 /** @def AssertReleaseFailed … … 663 784 } while (0) 664 785 665 /** @def AssertReleaseFailedReturn 786 /** @def AssertReleaseFailedReturnVoid 666 787 * An assertion failed, hit a breakpoint and return. 667 788 */ … … 686 807 break; \ 687 808 } 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) 688 819 689 820 … … 743 874 } else do {} while (0) 744 875 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) 745 888 746 889 … … 841 984 #define AssertRCBreak(rc, stmt) AssertMsgRCBreak(rc, ("%Vra\n", (rc)), stmt) 842 985 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 843 994 /** @def AssertMsgRC 844 995 * Asserts a iprt status code successful. … … 891 1042 do { AssertMsgBreak(RT_SUCCESS_NP(rc), msg, stmt); NOREF(rc); } while (0) 892 1043 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 893 1056 /** @def AssertRCSuccess 894 1057 * Asserts an iprt status code equals VINF_SUCCESS. … … 927 1090 #define AssertRCSuccessBreak(rc, stmt) AssertMsgBreak((rc) == VINF_SUCCESS, ("%Vra\n", (rc)), stmt) 928 1091 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 929 1100 930 1101 /** @def AssertReleaseRC … … 973 1144 #define AssertReleaseRCBreak(rc, stmt) AssertReleaseMsgRCBreak(rc, ("%Vra\n", (rc)), stmt) 974 1145 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 975 1157 /** @def AssertReleaseMsgRC 976 1158 * Asserts a iprt status code successful. … … 1022 1204 #define AssertReleaseMsgRCBreak(rc, msg, stmt) AssertReleaseMsgBreak(RT_SUCCESS_NP(rc), msg, stmt) 1023 1205 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 1024 1218 /** @def AssertReleaseRCSuccess 1025 1219 * Asserts that an iprt status code equals VINF_SUCCESS. … … 1067 1261 #define AssertReleaseRCSuccessBreak(rc, stmt) AssertReleaseMsgBreak((rc) == VINF_SUCCESS, ("%Vra\n", (rc)), stmt) 1068 1262 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 1069 1274 1070 1275 /** @def AssertFatalRC … … 1130 1335 #define AssertPtrBreak(pv, stmt) AssertMsgBreak(VALID_PTR(pv), ("%p\n", (pv)), stmt) 1131 1336 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 1132 1344 /** @def AssertPtrNull 1133 1345 * Asserts that a pointer is valid or NULL. … … 1159 1371 */ 1160 1372 #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))) 1161 1380 1162 1381 -
trunk/include/iprt/cdefs.h
r5999 r6076 1248 1248 #ifdef __cplusplus 1249 1249 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 1250 1286 /** @def WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP 1251 1287 * Macro to work around error C2593 of the not-so-smart MSVC 7.x ambiguity -
trunk/include/iprt/cpputils.h
r5999 r6076 26 26 #ifndef ___iprt_cpputils_h 27 27 #define ___iprt_cpputils_h 28 29 #include <iprt/assert.h> 30 31 #include <memory> 28 32 29 33 /** @defgroup grp_rt_cpputils C++ Utilities … … 61 65 inline C *unconst (const C *that) { return const_cast <C *> (that); } 62 66 67 68 /** 69 * Extensions to the std namespace. 70 */ 71 namespace stdx 72 { 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 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 */ 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 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 */ 126 template <class C> 127 class auto_ref_ptr 128 { 129 public: 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 201 protected: 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 */ 236 class exception_trap_base 237 { 238 public: 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 */ 298 template <typename T> 299 class exception_trap : public exception_trap_base 300 { 301 public: 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 */ 330 template <typename T> 331 static exception_trap <T> * 332 new_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 */ 352 class char_auto_ptr : public std::auto_ptr <char> 353 { 354 public: 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 63 387 /** @} */ 64 388
Note:
See TracChangeset
for help on using the changeset viewer.