You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

929 lines
24 KiB

/* /////////////////////////////////////////////////////////////////////////
* File: comstl/util/variant.hpp (originally MOVriant.h/.cpp, ::SynesisCom)
*
* Purpose: variant class.
*
* Created: 12th December 1996
* Updated: 5th March 2011
*
* Home: http://stlsoft.org/
*
* Copyright (c) 1996-2011, Matthew Wilson and Synesis Software
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
* any contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* ////////////////////////////////////////////////////////////////////// */
/** \file comstl/util/variant.hpp
*
* \brief [C++ only; requires COM] Definition of the comstl::variant class
* (\ref group__library__utility__com "COM Utility" Library).
*/
#ifndef COMSTL_INCL_COMSTL_UTIL_HPP_COMSTL_VARIANT
#define COMSTL_INCL_COMSTL_UTIL_HPP_COMSTL_VARIANT
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
# define _COMSTL_VER_COMSTL_UTIL_HPP_COMSTL_VARIANT_MAJOR 2
# define _COMSTL_VER_COMSTL_UTIL_HPP_COMSTL_VARIANT_MINOR 3
# define _COMSTL_VER_COMSTL_UTIL_HPP_COMSTL_VARIANT_REVISION 5
# define _COMSTL_VER_COMSTL_UTIL_HPP_COMSTL_VARIANT_EDIT 158
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
/* /////////////////////////////////////////////////////////////////////////
* Includes
*/
#ifndef COMSTL_INCL_COMSTL_H_COMSTL
# include <comstl/comstl.h>
#endif /* !COMSTL_INCL_COMSTL_H_COMSTL */
#ifndef COMSTL_INCL_COMSTL_STRING_H_BSTR_FUNCTIONS
# include <comstl/string/BSTR_functions.h>
#endif /* !COMSTL_INCL_COMSTL_STRING_H_BSTR_FUNCTIONS */
#ifndef COMSTL_INCL_COMSTL_SHIMS_ACCESS_HPP_STRING
# include <comstl/shims/access/string.hpp>
#endif /* !COMSTL_INCL_COMSTL_SHIMS_ACCESS_HPP_STRING */
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
# ifndef COMSTL_INCL_COMSTL_ERROR_HPP_EXCEPTIONS
# include <comstl/error/exceptions.hpp>
# endif /* !COMSTL_INCL_COMSTL_ERROR_HPP_EXCEPTIONS */
#endif /* !STLSOFT_CF_EXCEPTION_SUPPORT */
#ifndef COMSTL_INCL_COMSTL_UTIL_HPP_INTERFACE_TRAITS
# include <comstl/util/interface_traits.hpp>
#endif /* !COMSTL_INCL_COMSTL_UTIL_HPP_INTERFACE_TRAITS */
#ifndef COMSTL_INCL_COMSTL_UTIL_H_VARIANT_FUNCTIONS
# include <comstl/util/VARIANT_functions.h>
#endif /* !COMSTL_INCL_COMSTL_UTIL_H_VARIANT_FUNCTIONS */
#ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_CONSTRAINTS
# include <stlsoft/util/constraints.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_CONSTRAINTS */
/* /////////////////////////////////////////////////////////////////////////
* Namespace
*/
#ifndef _COMSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
/* There is no stlsoft namespace, so must define ::comstl */
namespace comstl
{
# else
/* Define stlsoft::comstl_project */
namespace stlsoft
{
namespace comstl_project
{
# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_COMSTL_NO_NAMESPACE */
/* /////////////////////////////////////////////////////////////////////////
* Classes
*/
/** \brief Facade for the COM VARIANT type
*
* \ingroup group__library__utility__com
*
* \remarks comstl::variant publicly derives from \c VARIANT as a measure
* of expedience, rather than as an act of design sophistication. Any
* manual manipulation of the instances, or their member variables, is
* at the user's risk. Notwithstanding, this is helped by the fact that
* comstl::variant declares no member variables and no virtual member
* functions - for most compilers this means that the Empty Derived
* Optimisation (see Section 12.4 of Imperfect C++) will apply.
*/
class variant
: public VARIANT
{
/// Member Types
public:
typedef variant class_type;
typedef cs_bool_t bool_type;
typedef cs_size_t size_type;
/// Conversion
public:
/** Default constructor
*
* Initialises the instance
*
* \post <code>assert(VT_EMPTY == this->vt)</code>
*
* \exception - Does not throw an exception
*/
variant();
/** Copying constructor
*
* Initialises the instance with a copy of the given \c VARIANT
*
* \post <code>assert(rhs == *this)</code>
*
* \exception comstl::com_exception If the copy fails
*/
variant(VARIANT const& rhs);
/** Copy constructor
*
* \post <code>assert(rhs == *this)</code>
*
* \exception comstl::com_exception If the copy fails
*/
variant(class_type const& rhs);
/** Copy assignment operator
*
* \post <code>assert(rhs == *this)</code>
*
* \exception comstl::com_exception If the copy fails
*/
class_type& operator =(class_type const& rhs);
/** Conversion constructor
*
* Initialises the instance with the given boolean value
*
* \post <code>assert(VT_BOOL == this->vt)</code>
* \post <code>assert(b == (VARIANT_TRUE == this->boolVal))</code>
*
* \exception - Does not throw an exception
*/
variant(bool b);
/** Conversion constructor
*
* Initialises the instance with the given 8-bit signed integer value
*
* \post <code>assert(VT_I1 == this->vt)</code>
* \post <code>assert(i == this->cVal)</code>
*
* \exception - Does not throw an exception
*/
variant(stlsoft::sint8_t i);
/** Conversion constructor
*
* Initialises the instance with the given 8-bit unsigned integer value
*
* \post <code>assert(VT_UI1 == this->vt)</code>
* \post <code>assert(i == this->bVal)</code>
*
* \exception - Does not throw an exception
*/
variant(stlsoft::uint8_t i);
/** Conversion constructor
*
* Initialises the instance with the given 16-bit signed integer value
*
* \post <code>assert(VT_I2 == this->vt)</code>
* \post <code>assert(i == this->iVal)</code>
*
* \exception - Does not throw an exception
*/
variant(stlsoft::sint16_t i);
/** Conversion constructor
*
* Initialises the instance with the given 16-bit unsigned integer value
*
* \post <code>assert(VT_UI2 == this->vt)</code>
* \post <code>assert(i == this->uiVal)</code>
*
* \exception - Does not throw an exception
*/
variant(stlsoft::uint16_t i);
/** Conversion constructor
*
* Initialises the instance with the given 32-bit signed integer value
*
* \post <code>assert(VT_I4 == this->vt)</code>
* \post <code>assert(i == this->lVal)</code>
*
* \exception - Does not throw an exception
*/
variant(stlsoft::sint32_t i);
/** Conversion constructor
*
* Initialises the instance with the given 32-bit unsigned integer value
*
* \post <code>assert(VT_UI4 == this->vt)</code>
* \post <code>assert(i == this->ulVal)</code>
*
* \exception - Does not throw an exception
*/
variant(stlsoft::uint32_t i);
//#ifdef STLSOFT_CF_64BIT_INT_SUPPORT
// variant(stlsoft::sint64_t i);
// variant(stlsoft::uint64_t i);
//#endif /* STLSOFT_CF_64BIT_INT_SUPPORT */
#ifdef STLSOFT_CF_SHORT_DISTINCT_INT_TYPE
/** Conversion constructor
*
* Initialises the instance with the given \c short value
*
* \post <code>assert(VT_I2 == this->vt)</code>
* \post <code>assert(i == this->iVal)</code>
*
* \exception - Does not throw an exception
*/
variant(short i);
/** Conversion constructor
*
* Initialises the instance with the given
* <code>unsigned short</code> value
*
* \post <code>assert(VT_UI2 == this->vt)</code>
* \post <code>assert(i == this->uiVal)</code>
*
* \exception - Does not throw an exception
*/
variant(unsigned short i);
#endif /* STLSOFT_CF_SHORT_DISTINCT_INT_TYPE */
#ifdef STLSOFT_CF_INT_DISTINCT_INT_TYPE
/** Conversion constructor
*
* Initialises the instance with the given \c int value
*
* \post <code>assert(VT_I4 == this->vt)</code>
* \post <code>assert(i == this->lVal)</code>
*
* \exception - Does not throw an exception
*/
variant(int i);
/** Conversion constructor
*
* Initialises the instance with the given
* <code>unsigned int</code> value
*
* \post <code>assert(VT_UI4 == this->vt)</code>
* \post <code>assert(i == this->ulVal)</code>
*
* \exception - Does not throw an exception
*/
variant(unsigned int i);
#endif /* STLSOFT_CF_INT_DISTINCT_INT_TYPE */
#ifdef STLSOFT_CF_LONG_DISTINCT_INT_TYPE
/** Conversion constructor
*
* Initialises the instance with the given \c long value
*
* \post <code>assert(VT_I4 == this->vt)</code>
* \post <code>assert(i == this->lVal)</code>
*
* \exception - Does not throw an exception
*/
variant(long i);
/** Conversion constructor
*
* Initialises the instance with the given
* <code>unsigned long</code> value
*
* \post <code>assert(VT_UI4 == this->vt)</code>
* \post <code>assert(i == this->ulVal)</code>
*
* \exception - Does not throw an exception
*/
variant(unsigned long i);
#endif /* STLSOFT_CF_LONG_DISTINCT_INT_TYPE */
/** Conversion constructor
*
* Initialises the instance with the given \c float value
*
* \post <code>assert(VT_R4 == this->vt)</code>
* \post <code>assert(r == this->fltVal)</code>
*
* \exception - Does not throw an exception
*/
variant(float r);
/** Conversion constructor
*
* Initialises the instance with the given \c double value
*
* \post <code>assert(VT_R8 == this->vt)</code>
* \post <code>assert(r == this->dblVal)</code>
*
* \exception - Does not throw an exception
*/
variant(double r);
/** Conversion constructor
*
* Initialises the instance with the given currency (\c CY) value
*
* \post <code>assert(VT_CY == this->vt)</code>
* \post <code>assert(r == this->cyVal)</code>
*
* \exception - Does not throw an exception
*/
variant(CY cy);
/** Conversion constructor
*
* Initialises the instance with the given \c DECIMAL value
*
* \post <code>assert(VT_DECIMAL == this->vt)</code>
* \post <code>assert(dec == this->decVal)</code>
*
* \exception - Does not throw an exception
*/
variant(DECIMAL const& dec);
variant(LPUNKNOWN punk, bool_type bAddRef);
variant(LPDISPATCH pdisp, bool_type bAddRef);
variant(cs_char_a_t const* s, int len = -1);
variant(cs_char_w_t const* s, int len = -1);
variant(VARIANT const& var, VARTYPE vt);
/** Releases any resources associated with the underlying
* <code>VARIANT</code>
*/
~variant() stlsoft_throw_0()
{
stlsoft_constraint_must_be_same_size(class_type, VARIANT);
::VariantClear(this);
}
/** Clears the variant
*
* \post <code>assert(VT_EMPTY == this->vt)</code>
*/
void clear();
/// Operations
public:
HRESULT try_conversion_copy(VARIANT const& var, VARTYPE vt);
HRESULT try_convert(VARTYPE vt);
class_type& convert(VARTYPE vt);
/** Returns a pointer to a specified interface on an object to which
* a client currently holds an interface pointer.
*
* \return An <code>HRESULT</code> code indicating the success of the
* operation.
* \retval <code>S_OK</code> The interface is supported:
* <code>*ppv</code> will hold the pointer to the requested interface
* \retval <code>E_INTERFACE</code> The interface is not supported: the
* value of <code>*ppv</code> is undefined.
*
* \pre <code>NULL != ppv</code>
*/
HRESULT QueryInterface(REFIID riid, void** ppv) const;
/** Returns a pointer to a specified interface on an object to which
* a client currently holds an interface pointer.
*
* \return An <code>HRESULT</code> code indicating the success of the
* operation.
* \retval <code>S_OK</code> The interface is supported:
* <code>*ppi</code> will hold the pointer to the requested interface
* \retval <code>E_INTERFACE</code> The interface is not supported: the
* value of <code>*ppi</code> is undefined.
*
* \pre <code>NULL != ppi</code>
*/
template <ss_typename_param_k I>
HRESULT QueryInterfaceValue(I** ppi)
{
return QueryInterface(IID_traits<I>::iid(), reinterpret_cast<void**>(ppi));
}
public:
/** Swaps the contents with another instance
*/
void swap(class_type& rhs);
/// Comparison
public:
bool_type equal(class_type const& rhs) const;
bool_type equal(VARIANT const& rhs) const;
/// Operators
public:
private:
static void swap_(VARIANT& lhs, VARIANT& rhs);
void handle_error_(char const* message, HRESULT hr);
};
/* /////////////////////////////////////////////////////////////////////////
* String access shims
*/
// No string access shims are defined, because there're already a set
// defined for VARIANT, in comstl/shims/access/string.hpp, which is included
// by this file.
/* /////////////////////////////////////////////////////////////////////////
* Operators
*/
inline cs_bool_t operator ==(variant const& lhs, variant const& rhs)
{
return lhs.equal(rhs);
}
inline cs_bool_t operator !=(variant const& lhs, variant const& rhs)
{
return !operator ==(lhs, rhs);
}
inline cs_bool_t operator ==(variant const& lhs, VARIANT const& rhs)
{
return lhs.equal(rhs);
}
inline cs_bool_t operator !=(variant const& lhs, VARIANT const& rhs)
{
return !operator ==(lhs, rhs);
}
inline cs_bool_t operator ==(VARIANT const& lhs, variant const& rhs)
{
return rhs.equal(lhs);
}
inline cs_bool_t operator !=(VARIANT const& lhs, variant const& rhs)
{
return !operator ==(lhs, rhs);
}
////////////////////////////////////////////////////////////////////////////
// Unit-testing
#ifdef STLSOFT_UNITTEST
# include "./unittest/variant_unittest_.h"
#endif /* STLSOFT_UNITTEST */
/* /////////////////////////////////////////////////////////////////////////
* Implementation
*/
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
inline void variant::handle_error_(char const* message, HRESULT hr)
{
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
STLSOFT_THROW_X(com_exception(message, hr));
#else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
STLSOFT_SUPPRESS_UNUSED(message);
::VariantClear(this);
this->vt = VT_ERROR;
this->scode = hr;
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
}
inline /* static */ void variant::swap_(VARIANT& lhs, VARIANT& rhs)
{
VARIANT t;
::memcpy(&t, &lhs, sizeof(VARIANT));
::memcpy(&lhs, &rhs, sizeof(VARIANT));
::memcpy(&rhs, &t, sizeof(VARIANT));
}
inline variant::variant()
{
::VariantInit(this);
}
inline variant::variant(class_type const& rhs)
{
::VariantInit(this);
class_type& rhs_ = const_cast<class_type&>(rhs);
HRESULT hr = ::VariantCopy(this, &rhs_);
if(FAILED(hr))
{
handle_error_("failed to copy variant", hr);
}
}
inline variant::variant(VARIANT const& rhs)
{
::VariantInit(this);
HRESULT hr = ::VariantCopy(this, const_cast<VARIANT*>(&rhs));
if(FAILED(hr))
{
handle_error_("failed to copy variant", hr);
}
}
inline variant::class_type& variant::operator =(variant::class_type const& rhs)
{
class_type r(rhs);
r.swap(*this);
return *this;
}
inline variant::variant(bool b)
{
::VariantInit(this);
this->vt = VT_BOOL;
this->boolVal = b ? VARIANT_TRUE : VARIANT_FALSE;
}
inline variant::variant(stlsoft::sint8_t i)
{
::VariantInit(this);
this->vt = VT_I1;
this->cVal = static_cast<CHAR>(i);
}
inline variant::variant(stlsoft::uint8_t i)
{
::VariantInit(this);
this->vt = VT_UI1;
this->bVal = static_cast<BYTE>(i);
}
inline variant::variant(stlsoft::sint16_t i)
{
::VariantInit(this);
this->vt = VT_I2;
this->iVal = static_cast<SHORT>(i);
}
inline variant::variant(stlsoft::uint16_t i)
{
::VariantInit(this);
this->vt = VT_UI2;
this->uiVal = static_cast<USHORT>(i);
}
inline variant::variant(stlsoft::sint32_t i)
{
::VariantInit(this);
this->vt = VT_I4;
this->lVal = static_cast<LONG>(i);
}
inline variant::variant(stlsoft::uint32_t i)
{
::VariantInit(this);
this->vt = VT_UI4;
this->ulVal = static_cast<ULONG>(i);
}
#ifdef STLSOFT_CF_SHORT_DISTINCT_INT_TYPE
inline variant::variant(short i)
{
::VariantInit(this);
this->vt = VT_I2;
this->iVal = i;
}
inline variant::variant(unsigned short i)
{
::VariantInit(this);
this->vt = VT_UI2;
this->uiVal = i;
}
#endif /* STLSOFT_CF_SHORT_DISTINCT_INT_TYPE */
#ifdef STLSOFT_CF_INT_DISTINCT_INT_TYPE
inline variant::variant(int i)
{
::VariantInit(this);
this->vt = VT_I4;
this->lVal = i;
}
inline variant::variant(unsigned int i)
{
::VariantInit(this);
this->vt = VT_UI4;
this->ulVal = i;
}
#endif /* STLSOFT_CF_INT_DISTINCT_INT_TYPE */
#ifdef STLSOFT_CF_LONG_DISTINCT_INT_TYPE
inline variant::variant(long i)
{
::VariantInit(this);
this->vt = VT_I4;
this->lVal = i;
}
inline variant::variant(unsigned long i)
{
::VariantInit(this);
this->vt = VT_UI4;
this->ulVal = i;
}
#endif /* STLSOFT_CF_LONG_DISTINCT_INT_TYPE */
inline variant::variant(float r)
{
::VariantInit(this);
this->vt = VT_R4;
this->fltVal = r;
}
inline variant::variant(double r)
{
::VariantInit(this);
this->vt = VT_R8;
this->dblVal = r;
}
inline variant::variant(CY cy)
{
::VariantInit(this);
this->vt = VT_CY;
this->cyVal = cy;
}
inline variant::variant(DECIMAL const& dec)
{
::VariantInit(this);
this->vt = VT_DECIMAL;
this->decVal.scale = dec.scale;
this->decVal.sign = dec.sign;
this->decVal.Hi32 = dec.Hi32;
this->decVal.Mid32 = dec.Mid32;
this->decVal.Lo32 = dec.Lo32;
}
inline variant::variant(LPUNKNOWN punk, bool_type bAddRef)
{
::VariantInit(this);
this->vt = VT_UNKNOWN;
this->punkVal = punk;
if( bAddRef &&
NULL != punk)
{
punk->AddRef();
}
}
inline variant::variant(LPDISPATCH pdisp, bool_type bAddRef)
{
::VariantInit(this);
this->vt = VT_DISPATCH;
this->pdispVal = pdisp;
if( bAddRef &&
NULL != pdisp)
{
pdisp->AddRef();
}
}
inline variant::variant(cs_char_a_t const* s, int len /* = -1 */)
{
::VariantInit(this);
this->vt = VT_BSTR;
this->bstrVal = (len < 0) ? bstr_create(s) : bstr_create(s, static_cast<size_type>(len));
if(NULL == this->bstrVal)
{
if( NULL != s &&
'\0' != 0[s])
{
handle_error_("could not initialise from string", E_OUTOFMEMORY);
}
}
}
inline variant::variant(cs_char_w_t const* s, int len /* = -1 */)
{
::VariantInit(this);
this->vt = VT_BSTR;
this->bstrVal = (len < 0) ? bstr_create(s) : bstr_create(s, static_cast<size_type>(len));
if(NULL == this->bstrVal)
{
if( NULL != s &&
'\0' != 0[s])
{
handle_error_("could not initialise from string", E_OUTOFMEMORY);
}
}
}
inline variant::variant(VARIANT const& var, VARTYPE vt)
{
::VariantInit(this);
class_type copy;
HRESULT hr = ::VariantChangeType(&copy, const_cast<VARIANT*>(&var), 0, vt);
if(FAILED(hr))
{
handle_error_("could not convert variant to requested type", hr);
}
else
{
copy.swap(*this);
}
}
inline void variant::clear()
{
::VariantClear(this);
}
inline HRESULT variant::try_conversion_copy(VARIANT const& var, VARTYPE vt)
{
HRESULT hr;
if(vt == this->vt)
{
hr = S_FALSE;
}
else
{
class_type copy;
hr = ::VariantChangeType(&copy, const_cast<VARIANT*>(&var), 0, vt);
if(SUCCEEDED(hr))
{
copy.swap(*this);
}
}
return hr;
}
inline HRESULT variant::try_convert(VARTYPE vt)
{
return try_conversion_copy(*this, vt);
}
inline variant::class_type& variant::convert(VARTYPE vt)
{
HRESULT hr = try_convert(vt);
if(FAILED(hr))
{
handle_error_("could not convert variant to requested type", hr);
}
return *this;
}
inline HRESULT variant::QueryInterface(REFIID riid, void** ppv) const
{
COMSTL_ASSERT(NULL != ppv);
if( VT_UNKNOWN == this->vt ||
VT_DISPATCH == this->vt)
{
return (NULL == this->punkVal) ? E_POINTER : this->punkVal->QueryInterface(riid, ppv);
}
return DISP_E_BADVARTYPE;
}
inline void variant::swap(variant::class_type& rhs)
{
swap_(*this, rhs);
}
inline variant::bool_type variant::equal(variant::class_type const& rhs) const
{
return equal(static_cast<VARIANT const&>(rhs));
}
inline variant::bool_type variant::equal(VARIANT const& rhs) const
{
HRESULT comparisonSucceeded;
int areEqual = VARIANT_equal(*this, rhs, &comparisonSucceeded);
if(FAILED(comparisonSucceeded))
{
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
STLSOFT_THROW_X(comstl::com_exception("support for comparison of variant type not currently supported", comparisonSucceeded));
#else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
OutputDebugStringA("support for comparison of variant type not currently supported\n");
return false;
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
}
return 0 != areEqual;
}
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
/* ////////////////////////////////////////////////////////////////////// */
#ifndef _COMSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} // namespace comstl
# else
} // namespace stlsoft::comstl_project
} // namespace stlsoft
# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_COMSTL_NO_NAMESPACE */
/* /////////////////////////////////////////////////////////////////////////
* Namespace
*
* The string access shims exist either in the stlsoft namespace, or in the
* global namespace. This is required by the lookup rules.
*
*/
#ifndef _COMSTL_NO_NAMESPACE
# if !defined(_STLSOFT_NO_NAMESPACE) && \
!defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
namespace stlsoft
{
# else /* ? _STLSOFT_NO_NAMESPACE */
/* There is no stlsoft namespace, so must define in the global namespace */
# endif /* !_STLSOFT_NO_NAMESPACE */
# if !defined(_STLSOFT_NO_NAMESPACE) && \
!defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} // namespace stlsoft
# else /* ? _STLSOFT_NO_NAMESPACE */
/* There is no stlsoft namespace, so must define in the global namespace */
# endif /* !_STLSOFT_NO_NAMESPACE */
#endif /* !_COMSTL_NO_NAMESPACE */
/* ////////////////////////////////////////////////////////////////////// */
#endif /* !COMSTL_INCL_COMSTL_UTIL_HPP_COMSTL_VARIANT */
/* ///////////////////////////// end of file //////////////////////////// */