variant.h

Go to the documentation of this file.
00001 00004 /* 00005 * Copyright © 2000, 2001 Sofus Mortensen, Michael Geddes 00006 * 00007 * This material is provided "as is", with absolutely no warranty 00008 * expressed or implied. Any use is at your own risk. Permission to 00009 * use or copy this software for any purpose is hereby granted without 00010 * fee, provided the above notices are retained on all copies. 00011 * Permission to modify the code and to distribute modified code is 00012 * granted, provided the above notices are retained, and a notice that 00013 * the code was modified is included with the above copyright notice. 00014 * 00015 * This header is part of comet. 00016 * http://www.lambdasoft.dk/comet 00017 */ 00018 00019 #ifndef COMET_VARIANT_H 00020 #define COMET_VARIANT_H 00021 00022 #include <comet/config.h> 00023 #include <comet/datetime.h> 00024 #include <comet/error_fwd.h> 00025 #include <comet/assert.h> 00026 #include <comet/common.h> 00027 #include <comet/bstr.h> 00028 #include <comet/currency.h> 00029 00030 #include <iostream> 00031 00032 #pragma warning(push) 00033 #pragma warning(disable : 4127) 00034 00035 #define COMET_VARIANT_OPERATOR(op, name) \ 00036 variant_t operator##op(const variant_t& x) const \ 00037 { \ 00038 VARIANT t; \ 00039 Var##name(const_cast<VARIANT*>(get_var()), const_cast<VARIANT*>(x.get_var()), &t) | raise_exception; \ 00040 return auto_attach(t); \ 00041 } \ 00042 \ 00043 variant_t& operator##op##=(const variant_t& x) \ 00044 { \ 00045 return operator=(operator##op(x)); \ 00046 } 00047 00048 #define COMET_VARIANT_CONVERTERS_EX_(type, vartype, func) \ 00049 variant_t(type x) throw() \ 00050 { \ 00051 V_##vartype(this) = x; V_VT(this) = VT_##vartype; \ 00052 } \ 00053 \ 00054 func() const \ 00055 { \ 00056 if (V_VT(this) == VT_##vartype) return V_##vartype(this); \ 00057 variant_t v(*this, VT_##vartype); \ 00058 return V_##vartype(v.get_var()); \ 00059 } \ 00060 \ 00061 variant_t& operator=(type x) throw() \ 00062 { \ 00063 clear(); \ 00064 V_##vartype(this) = x; V_VT(this) = VT_##vartype; \ 00065 return *this; \ 00066 } 00067 00068 #define COMET_VARIANT_CONVERTERS_EXPLICIT(type, vartype, funcname) COMET_VARIANT_CONVERTERS_EX_(type,vartype, type funcname) 00069 #define COMET_VARIANT_CONVERTERS(type, vartype) COMET_VARIANT_CONVERTERS_EX_(type,vartype, operator type ) 00070 00071 #define COMET_VARIANT_FRIENDS(type) \ 00072 inline bool operator!=(type x, const variant_t& y) { return y != x; } \ 00073 inline bool operator==(type x, const variant_t& y) { return y == x; } \ 00074 inline bool operator<(type x, const variant_t& y) { return y > x; } \ 00075 inline bool operator<=(type x, const variant_t& y) { return y >= x; } \ 00076 inline bool operator>(type x, const variant_t& y) { return y < x; } \ 00077 inline bool operator>=(type x, const variant_t& y) { return y <= x; } 00078 00079 namespace comet { 00080 00081 template<typename T> class safearray_t; 00082 00083 namespace impl { 00084 }; 00085 00086 template<typename Itf> class com_ptr; 00087 00088 00092 00094 00096 class variant_t : private ::tagVARIANT 00097 { 00098 private: 00099 void init() throw() 00100 { 00101 //::VariantInit(this); 00102 tagVARIANT * x = this; 00103 V_VT(x)= VT_EMPTY; 00104 } 00105 00106 void create(const VARIANT& v) throw(com_error) 00107 { 00108 HRESULT hr = ::VariantCopy(this, const_cast<VARIANT*>(&v)); 00109 if (FAILED(hr)) { 00110 ::VariantClear(this); 00111 raise_exception(hr); 00112 } 00113 } 00114 00115 public: 00117 variant_t() throw() 00118 { 00119 init(); 00120 } 00121 00122 private: 00123 struct tagMissing {}; 00124 00125 variant_t(const tagMissing&) throw() 00126 { 00127 init(); 00128 vt = VT_ERROR; 00129 scode = DISP_E_PARAMNOTFOUND; 00130 } 00131 00132 struct tagNothing {}; 00133 00134 variant_t(const tagNothing&) throw() 00135 { 00136 init(); 00137 vt = VT_DISPATCH; 00138 pdispVal = 0; 00139 } 00140 00141 struct tagNull {}; 00142 00143 variant_t(const tagNull&) throw() 00144 { 00145 init(); 00146 vt = VT_NULL; 00147 } 00148 00149 public: 00151 00153 static const variant_t& missing() 00154 { 00155 static tagMissing t; 00156 static variant_t v(t); 00157 return v; 00158 } 00159 00161 00163 static const variant_t& nothing() 00164 { 00165 static tagNothing t; 00166 static variant_t v(t); 00167 return v; 00168 } 00169 00171 static const variant_t& null() 00172 { 00173 static tagNull t; 00174 static variant_t v(t); 00175 return v; 00176 } 00177 00179 00183 variant_t(const variant_t& v) throw(com_error) 00184 { 00185 init(); 00186 create(v); 00187 } 00188 00189 public: 00190 00192 00205 variant_t(const variant_t& v, VARTYPE vartype) throw(com_error) 00206 { 00207 init(); 00208 if (vartype != V_VT(&v)) 00209 ::VariantChangeTypeEx(get_var(), 00210 const_cast<VARIANT*>(v.get_var()), 00211 GetThreadLocale(), 00212 0, vartype) | raise_exception; 00213 else 00214 ::VariantCopy(this, const_cast<VARIANT*>(v.get_var())); 00215 } 00216 00217 variant_t(const variant_t& v, VARTYPE vartype, std::nothrow_t) throw(com_error) 00218 { 00219 init(); 00220 if (vartype != V_VT(&v)) 00221 ::VariantChangeTypeEx(get_var(), 00222 const_cast<VARIANT*>(v.get_var()), 00223 GetThreadLocale(), 00224 0, vartype); 00225 else 00226 ::VariantCopy(this, const_cast<VARIANT*>(v.get_var())); 00227 } 00228 00230 00234 explicit variant_t(const VARIANT& v) throw(com_error) 00235 { 00236 init(); 00237 create(v); 00238 } 00239 00241 00247 variant_t(const impl::auto_attach_t<VARIANT>& v) throw() 00248 { 00249 memcpy(this, &const_cast<VARIANT&>(v.get()), sizeof(VARIANT)); 00250 } 00251 00252 private: 00253 void clear() COMET_THROWS_ASSERT 00254 { 00255 HRESULT hr = ::VariantClear(this); 00256 COMET_ASSERT(SUCCEEDED(hr)); 00257 /* Avoid C4189 */ hr; 00258 } 00259 00260 public: 00261 00263 00270 ~variant_t() throw() 00271 { 00272 clear(); 00273 } 00274 00276 00277 private: 00278 template<typename Itf> void create(const com_ptr<Itf>& x) throw() 00279 { 00280 com_ptr< ::IDispatch > p( com_cast(x) ); 00281 if (p != 0) { 00282 V_VT(this) = VT_DISPATCH; 00283 V_DISPATCH(this) = p.detach(); 00284 } else { 00285 V_VT(this) = VT_UNKNOWN; 00286 // VTT_(punkVal) = static_cast<::IUnknown*>(com_ptr<Itf>(x).detach()); 00287 com_ptr< ::IUnknown > p( com_cast(x) ); 00288 V_UNKNOWN(this) = p.detach(); 00289 } 00290 } 00291 00292 public: 00293 template<typename Itf> variant_t(const com_ptr<Itf>& x) throw() 00294 { 00295 init(); 00296 create(x); 00297 } 00298 00299 template<typename Itf> 00300 variant_t& operator=(const com_ptr<Itf>& x) throw() 00301 { 00302 clear(); create(x); return *this; 00303 } 00304 00306 00307 00309 00310 variant_t(bool x) throw() { 00311 init(); 00312 V_VT(this) = VT_BOOL; 00313 V_BOOL(this) = x ? COMET_VARIANT_TRUE : COMET_VARIANT_FALSE; 00314 } 00315 00316 operator bool() const throw() 00317 { 00318 if (V_VT(this) == VT_BOOL) return (V_BOOL(this) != COMET_VARIANT_FALSE); 00319 variant_t v(*this, VT_BOOL); 00320 return (V_BOOL(&v) != COMET_VARIANT_FALSE); 00321 } 00322 00323 variant_t& operator=(bool x) throw() 00324 { 00325 clear(); 00326 V_VT(this) = VT_BOOL; 00327 V_BOOL(this) = x ? COMET_VARIANT_TRUE : COMET_VARIANT_FALSE; 00328 return *this; 00329 } 00330 00332 00334 00335 variant_t(const bstr_t& s) throw(std::bad_alloc) 00336 { 00337 init(); 00338 bstr_t t(s); 00339 V_BSTR(this) = bstr_t::detach(t); 00340 V_VT(this) = VT_BSTR; 00341 } 00342 00343 variant_t(const wchar_t* s) throw(std::bad_alloc) 00344 { 00345 init(); 00346 bstr_t t(s); 00347 V_BSTR(this) = bstr_t::detach(t); 00348 V_VT(this) = VT_BSTR; 00349 } 00350 00351 variant_t(const std::wstring& s) throw(std::bad_alloc) 00352 { 00353 init(); 00354 bstr_t t(s); 00355 V_BSTR(this) = bstr_t::detach(t); 00356 V_VT(this) = VT_BSTR; 00357 } 00358 00359 variant_t(const std::string& s) throw(std::bad_alloc) 00360 { 00361 init(); 00362 bstr_t bs(s); 00363 V_BSTR(this) = bstr_t::detach(bs); 00364 V_VT(this) = VT_BSTR; 00365 } 00366 00367 variant_t(const char* x) 00368 { 00369 init(); 00370 V_BSTR(this) = bstr_t::detach(x); 00371 V_VT(this) = VT_BSTR; 00372 } 00373 00380 variant_t( const impl::auto_attach_t<BSTR> &bstrVal) 00381 { 00382 V_BSTR(this) = bstrVal.get(); 00383 V_VT(this) = VT_BSTR; 00384 } 00385 00386 /* operator bstr_t() const 00387 { 00388 if (V_VT(this) == VT_BSTR) return V_BSTR(this); 00389 variant_t v(*this, VT_BSTR); 00390 VARIANT t = v.detach(); 00391 return auto_attach(V_BSTR(&t)); 00392 }*/ 00393 00394 bstr_t str() const 00395 { 00396 if (V_VT(this) == VT_BSTR) return V_BSTR(this); 00397 if (V_VT(this) == (VT_BSTR | VT_BYREF)) return *V_BSTRREF(this); 00398 if (V_VT(this) == VT_NULL) return bstr_t(); 00399 variant_t v(*this, VT_BSTR); 00400 VARIANT t = v.detach(); 00401 return auto_attach(V_BSTR(&t)); 00402 } 00403 00404 operator bstr_t() const 00405 { 00406 return str(); 00407 } 00408 00409 operator std::wstring() const 00410 { 00411 if (V_VT(this) == VT_BSTR) return V_BSTR(this); 00412 if (V_VT(this) == (VT_BSTR | VT_BYREF)) return *V_BSTRREF(this); 00413 if (V_VT(this) == VT_NULL) return std::wstring(); 00414 variant_t v(*this, VT_BSTR); 00415 return V_BSTR(&v) ? std::wstring(V_BSTR(&v)) : std::wstring(); 00416 } 00417 00418 operator std::string() const 00419 { 00420 return str().s_str(); 00421 } 00422 00423 variant_t& operator=(const bstr_t& s) 00424 { 00425 variant_t t(s); 00426 swap(t); 00427 return *this; 00428 } 00429 00430 variant_t& operator=(const wchar_t* s) 00431 { 00432 variant_t t(s); 00433 swap(t); 00434 return *this; 00435 } 00436 00437 variant_t& operator=(const char* s) 00438 { 00439 variant_t t(s); 00440 swap(t); 00441 return *this; 00442 } 00443 00444 variant_t& operator=(const std::wstring& s) 00445 { 00446 variant_t t(s); 00447 swap(t); 00448 return *this; 00449 } 00450 00451 variant_t& operator=(const std::string& s) 00452 { 00453 variant_t t(s); 00454 swap(t); 00455 return *this; 00456 } 00457 00459 00461 00462 template<typename SAT> 00463 variant_t(const safearray_t<SAT> &x) 00464 { 00465 safearray_t<SAT> sa( x ); 00466 V_ARRAY(this) = sa.detach(); 00467 V_VT(this) = (VT_ARRAY | safearray_t<SAT>::traits::vt); 00468 } 00469 00470 template<typename SAT> 00471 variant_t& operator=(const safearray_t<SAT> &x) throw() 00472 { 00473 variant_t t(x); 00474 swap(t); 00475 return *this; 00476 } 00477 00484 variant_t( const impl::auto_attach_t<SAFEARRAY*> &psa) 00485 { 00486 V_ARRAY(this) = psa.get(); 00487 VARTYPE vt; 00488 SafeArrayGetVartype( psa.get(), &vt) | raise_exception; 00489 V_VT(this) = VARTYPE(VT_ARRAY | vt) ; 00490 } 00491 00492 00494 00496 00497 00498 COMET_VARIANT_CONVERTERS_EXPLICIT(short, I2, as_short); 00499 inline operator short() const { return as_short(); } 00500 COMET_VARIANT_CONVERTERS_EXPLICIT(int, I4, as_int); // Do not use VT_INT, because VariantChangeTypeEx does not support VT_INT. 00501 inline operator int() const { return as_int(); } 00502 COMET_VARIANT_CONVERTERS_EXPLICIT(long, I4, as_long); 00503 inline operator long() const { return as_long(); } 00504 COMET_VARIANT_CONVERTERS_EXPLICIT(float, R4, as_float); 00505 inline operator float() const { return as_float(); } 00506 COMET_VARIANT_CONVERTERS_EXPLICIT(double, R8, as_double); 00507 inline operator double() const { return as_double(); } 00508 // These can't have implicit conversions as they cause confusion when 00509 // assigning some common objects from variant_ts. 00510 COMET_VARIANT_CONVERTERS_EXPLICIT(char, I1, as_char); 00511 COMET_VARIANT_CONVERTERS_EXPLICIT(unsigned char, UI1, as_uchar); 00512 COMET_VARIANT_CONVERTERS_EXPLICIT(unsigned short, UI2, as_ushort); 00513 COMET_VARIANT_CONVERTERS_EXPLICIT(unsigned int, UI4, as_uint); 00514 COMET_VARIANT_CONVERTERS_EXPLICIT(unsigned long, UI4, as_ulong); 00515 COMET_VARIANT_CONVERTERS_EXPLICIT(DECIMAL, DECIMAL, as_decimal); 00516 00517 wchar_t as_wchar_t() const { return as_ushort(); } 00519 // CONVERTERS(DATE, DATE); 00520 00522 00523 00524 variant_t(const currency_t &x) throw() 00525 { 00526 V_CY(this) = x.get(); 00527 V_VT(this) = VT_CY; 00528 } 00529 00530 operator currency_t() const 00531 { 00532 return as_curency(); 00533 } 00534 currency_t as_curency() const 00535 { 00536 if (V_VT(this) == VT_CY) return V_CY(this); 00537 variant_t v(*this, VT_CY); 00538 return V_CY(v.get_var()); 00539 } 00540 00541 variant_t& operator=(const currency_t &x) throw() 00542 { 00543 clear(); 00544 V_CY(this) = x.get(); 00545 V_VT(this) = VT_CY; 00546 return *this; 00547 } 00548 00550 00552 00553 00554 variant_t(const datetime_t &x) throw() 00555 { 00556 V_DATE(this) = x.get(); 00557 V_VT(this) = VT_DATE; 00558 } 00559 00560 operator datetime_t() const 00561 { 00562 if (V_VT(this) == VT_DATE) return datetime_t(V_DATE(this)); 00563 variant_t v(*this, VT_DATE); 00564 return datetime_t(V_DATE(v.get_var())); 00565 } 00566 00567 variant_t& operator=(const datetime_t &x) throw() 00568 { 00569 clear(); 00570 V_DATE(this) = x.get(); 00571 V_VT(this) = VT_DATE; 00572 return *this; 00573 } 00574 00576 00577 void swap(variant_t& x) throw() 00578 { 00579 ::tagVARIANT t; 00580 memcpy(&t, this, sizeof(VARIANT)); 00581 memcpy(this, &x, sizeof(VARIANT)); 00582 memcpy(&x, &t, sizeof(VARIANT)); 00583 } 00584 00586 variant_t& operator=(const variant_t& x) throw(com_error) 00587 { 00588 variant_t t(x); 00589 swap(t); 00590 return *this; 00591 } 00592 00594 00595 template<typename T> 00596 bool operator==(const T& x) const throw(com_error) 00597 { 00598 return operator==( variant_t(x) ); 00599 } 00600 00601 bool operator==(const variant_t& x) const throw(com_error) 00602 { 00603 if (V_VT(&x) != V_VT(this)) { 00604 if (V_VT(this) == VT_EMPTY || V_VT(&x) == VT_EMPTY) return false; 00605 variant_t tmp(x, V_VT(this), std::nothrow); 00606 if (V_VT(&tmp) != V_VT(this)) return false; 00607 return VARCMP_EQ == (VarCmp(const_cast<VARIANT*>(get_var()), const_cast<VARIANT*>(tmp.get_var()), GetThreadLocale(), 0) | raise_exception) ; 00608 } else { 00609 switch (VarCmp(const_cast<VARIANT*>(get_var()), const_cast<VARIANT*>(x.get_var()), GetThreadLocale(), 0)) 00610 { 00611 case VARCMP_EQ: 00612 case VARCMP_NULL: 00613 return true; 00614 default: 00615 return false; 00616 } 00617 } 00618 } 00619 00620 template<typename T> 00621 bool operator!=(const T& x) const throw(com_error) 00622 { 00623 return !operator==(variant_t(x)); 00624 } 00625 00626 bool operator!=(const variant_t& x) const throw(com_error) 00627 { 00628 return !operator==(x); 00629 } 00630 00631 template<typename T> 00632 bool operator<(const T& x) const throw(com_error) 00633 { 00634 return operator<(variant_t(x)); 00635 } 00636 00637 bool operator<(const variant_t& x) const throw(com_error) 00638 { 00639 if (V_VT(&x) != V_VT(this)) { 00640 return VARCMP_LT == (VarCmp(const_cast<VARIANT*>(get_var()), const_cast<VARIANT*>(variant_t(x, V_VT(this)).get_var()), GetThreadLocale(), 0) | raise_exception); 00641 } else { 00642 return VARCMP_LT == (VarCmp(const_cast<VARIANT*>(get_var()), const_cast<VARIANT*>(x.get_var()), GetThreadLocale(), 0) | raise_exception); 00643 } 00644 } 00645 00646 template<typename T> 00647 bool operator<=(const T& x) const throw(com_error) 00648 { 00649 return operator<=(variant_t(x)); 00650 } 00651 00652 template<typename T> 00653 bool operator>(const T& x) const throw(com_error) 00654 { 00655 return operator>(variant_t(x)); 00656 } 00657 00658 bool operator>(const variant_t& x) const throw(com_error) 00659 { 00660 if (V_VT(&x) != V_VT(this)) { 00661 return VARCMP_GT == (VarCmp(const_cast<VARIANT*>(get_var()), const_cast<VARIANT*>(variant_t(x, V_VT(this)).get_var()), GetThreadLocale(), 0) | raise_exception); 00662 } else { 00663 return VARCMP_GT == (VarCmp(const_cast<VARIANT*>(get_var()), const_cast<VARIANT*>(x.get_var()), GetThreadLocale(), 0) | raise_exception); 00664 } 00665 } 00666 00667 bool operator<=(const variant_t& x) const throw(com_error) 00668 { 00669 return !operator>(x); 00670 } 00671 00672 template<typename T> 00673 bool operator>=(const T& x) const throw(com_error) 00674 { 00675 return operator>=(variant_t(x)); 00676 } 00677 00678 bool operator>=(const variant_t& x) const throw(com_error) 00679 { 00680 return !operator<(x); 00681 } 00682 00684 00686 00687 COMET_VARIANT_OPERATOR(+,Add); 00688 COMET_VARIANT_OPERATOR(-,Sub); 00689 COMET_VARIANT_OPERATOR(*,Mul); 00690 COMET_VARIANT_OPERATOR(/,Div); 00691 COMET_VARIANT_OPERATOR(&,And); 00692 COMET_VARIANT_OPERATOR(|,Or); 00693 COMET_VARIANT_OPERATOR(^,Xor); 00694 COMET_VARIANT_OPERATOR(%,Mod); 00695 00696 variant_t operator-() const 00697 { 00698 VARIANT t; 00699 VarNeg(const_cast<VARIANT*>(get_var()), &t) | raise_exception; 00700 return auto_attach(t); 00701 } 00702 00703 void change_type(VARTYPE vartype) throw(com_error) 00704 { 00705 if (vartype != V_VT(this)) 00706 ::VariantChangeTypeEx(get_var(), 00707 get_var(), 00708 GetThreadLocale(), 00709 0, vartype) | raise_exception; 00710 } 00711 00713 00715 bool is_string() const 00716 { 00717 return VT_BSTR == get_vt(true); 00718 } 00719 00721 bool is_object() const 00722 { 00723 return VT_UNKNOWN == get_vt(true) || VT_DISPATCH == get_vt(true); 00724 } 00725 00729 bool is_empty() const throw() 00730 { 00731 return VT_EMPTY == get_vt(); 00732 } 00736 bool is_null() const throw() 00737 { 00738 return VT_NULL == get_vt(); 00739 } 00740 00746 bool is_nothing() const throw() 00747 { 00748 switch (get_vt()) { 00749 case VT_DISPATCH: return NULL == V_DISPATCH(&get()); 00750 case VT_UNKNOWN: return NULL == V_UNKNOWN(&get()); 00751 case VT_DISPATCH|VT_BYREF: return NULL == *V_DISPATCHREF(&get()); 00752 case VT_UNKNOWN|VT_BYREF: return NULL == *V_UNKNOWNREF(&get()); 00753 case VT_EMPTY: 00754 case VT_NULL: return true; 00755 } 00756 return false; 00757 } 00758 00759 00761 00762 const VARIANT& get() const throw() 00763 { 00764 return *get_var(); 00765 } 00766 00767 VARTYPE get_vt() const throw() 00768 { 00769 return VARTYPE(V_VT(this)); 00770 } 00771 00772 VARTYPE get_vt(bool ignore_byref) const throw() 00773 { 00774 return ignore_byref ? VARTYPE(V_VT(this) & ~VT_BYREF) : VARTYPE(V_VT(this)); 00775 } 00776 00777 static VARIANT detach(variant_t& v) throw() 00778 { 00779 return v.detach(); 00780 } 00781 00782 VARIANT detach() throw() 00783 { 00784 VARIANT r = *get_var(); 00785 V_VT(this) = VT_EMPTY; 00786 return r; 00787 } 00788 00789 static const variant_t& create_const_reference(const VARIANT& x) 00790 { 00791 return *reinterpret_cast<const variant_t*>(&x); 00792 } 00793 00794 static variant_t& create_reference(VARIANT& x) 00795 { 00796 return *reinterpret_cast<variant_t*>(&x); 00797 } 00798 00800 00810 VARIANT in() const throw() 00811 { 00812 return *get_var(); 00813 } 00814 00816 00826 VARIANT* in_ptr() const throw() 00827 { 00828 return const_cast<VARIANT*>(get_var()); 00829 } 00830 00832 00842 VARIANT* out() throw() 00843 { 00844 clear(); 00845 new (this) variant_t(); 00846 return get_var(); 00847 } 00848 00850 00860 VARIANT* inout() throw() 00861 { 00862 return get_var(); 00863 } 00865 00866 private: 00867 #define __COMET_VARAIANT_OUT(vartype) case VT_##vartype: os << V_##vartype(this); break 00868 #define __COMET_VARAIANT_OUT_CAST(vartype,cast) case VT_##vartype: os << cast(V_##vartype(this)); break 00869 template<typename CH> 00870 std::basic_ostream<CH> &output(std::basic_ostream<CH> &os) const 00871 { 00872 switch (V_VT(this)) 00873 { 00874 __COMET_VARAIANT_OUT_CAST(I1, short); 00875 __COMET_VARAIANT_OUT(I2); 00876 __COMET_VARAIANT_OUT(I4); 00877 __COMET_VARAIANT_OUT(INT); 00878 __COMET_VARAIANT_OUT_CAST(UI1, (unsigned short)); 00879 __COMET_VARAIANT_OUT(UI2); 00880 __COMET_VARAIANT_OUT(UI4); 00881 __COMET_VARAIANT_OUT(UINT); 00882 __COMET_VARAIANT_OUT(R4); 00883 __COMET_VARAIANT_OUT(R8); 00884 // __COMET_VARAIANT_OUT_CAST(CY, currency_t::create_const_reference); 00885 // __COMET_VARAIANT_OUT_CAST(DATE, datetime_t::create_const_reference); 00886 default: 00887 os << std::basic_string<CH>(*this); 00888 break; 00889 } 00890 return os; 00891 } 00892 #undef __COMET_VARAIANT_OUT 00893 public: 00894 friend 00895 std::basic_ostream<char> &operator<<(std::basic_ostream<char> &os, const variant_t &val) 00896 { 00897 return val.output(os); 00898 } 00899 00900 friend 00901 std::basic_ostream<wchar_t> &operator<<(std::basic_ostream<wchar_t> &os, const variant_t &val) 00902 { 00903 return val.output(os); 00904 } 00905 00906 private: 00907 const VARIANT* get_var() const throw() 00908 { 00909 #ifndef __BORLANDC__ 00910 return static_cast<const VARIANT*>(this); 00911 #else 00912 return reinterpret_cast<const VARIANT*>(this); 00913 #endif 00914 } 00915 00916 VARIANT* get_var() throw() 00917 { 00918 #ifdef __BORLANDC__ 00919 #if __BORLANDC__ >= 0x0551 00920 return reinterpret_cast<VARIANT*>(this); 00921 #else 00922 return static_cast<VARIANT*>(this); 00923 #endif 00924 #else 00925 return reinterpret_cast<VARIANT*>(this); 00926 #endif 00927 } 00928 }; 00930 00931 COMET_VARIANT_FRIENDS(short); 00932 COMET_VARIANT_FRIENDS(int); 00933 COMET_VARIANT_FRIENDS(long); 00934 COMET_VARIANT_FRIENDS(float); 00935 COMET_VARIANT_FRIENDS(double); 00936 00937 COMET_VARIANT_FRIENDS(const char*); 00938 COMET_VARIANT_FRIENDS(const wchar_t*); 00939 00940 COMET_VARIANT_FRIENDS(const std::wstring&); 00941 COMET_VARIANT_FRIENDS(const std::string&); 00942 00943 COMET_VARIANT_FRIENDS(const DECIMAL&); 00944 00945 } // namespace 00946 00947 #include <comet/error.h> 00948 #include <comet/ptr.h> 00949 00950 namespace std { 00951 template<> inline void swap(comet::variant_t& x, comet::variant_t& y) COMET_STD_SWAP_NOTHROW 00952 { 00953 x.swap(y); 00954 } 00955 } 00956 00957 #undef COMET_VARIANT_CONVERTERS 00958 #undef COMET_VARIANT_CONVERTERS_EX_ 00959 #undef COMET_VARIANT_CONVERTERS_EXPLICIT 00960 #undef COMET_VARIANT_OPERATOR 00961 #undef COMET_VARIANT_FRIENDS 00962 00963 namespace comet { 00967 00968 inline bool operator!=(const bstr_t& b, const variant_t& v) 00969 { 00970 return v != b; 00971 } 00972 00973 inline bool operator==(const bstr_t& b, const variant_t& v) 00974 { 00975 return v == b; 00976 } 00977 00978 inline bool operator<(const bstr_t& b, const variant_t& v) 00979 { 00980 return v > b; 00981 } 00982 00983 inline bool operator>(const bstr_t& b, const variant_t& v) 00984 { 00985 return v < b; 00986 } 00987 00988 inline bool operator<=(const bstr_t& b, const variant_t& v) 00989 { 00990 return v >= b; 00991 } 00992 00993 inline bool operator>=(const bstr_t& b, const variant_t& v) 00994 { 00995 return v <= b; 00996 } 00998 } 00999 01000 #pragma warning(pop) 01001 01002 #endif