123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- // Copyright 2020 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef BASE_WIN_VARIANT_UTIL_H_
- #define BASE_WIN_VARIANT_UTIL_H_
- #include "base/logging.h"
- namespace base {
- namespace win {
- namespace internal {
- // Returns true if a VARIANT of type |self| can be assigned to a
- // variant of type |other|.
- // Does not allow converting unsigned <-> signed or converting between
- // different sized types, but does allow converting IDispatch* -> IUnknown*.
- constexpr bool VarTypeIsConvertibleTo(VARTYPE self, VARTYPE other) {
- // IDispatch inherits from IUnknown, so it's safe to
- // upcast a VT_DISPATCH into an IUnknown*.
- return (self == other) || (self == VT_DISPATCH && other == VT_UNKNOWN);
- }
- // VartypeToNativeType contains the underlying |Type| and offset to the
- // VARIANT union member related to the |ElementVartype| for simple types.
- template <VARTYPE ElementVartype>
- struct VartypeToNativeType final {};
- template <>
- struct VartypeToNativeType<VT_BOOL> final {
- using Type = VARIANT_BOOL;
- static constexpr VARIANT_BOOL VARIANT::*kMemberOffset = &VARIANT::boolVal;
- };
- template <>
- struct VartypeToNativeType<VT_I1> final {
- using Type = int8_t;
- static constexpr CHAR VARIANT::*kMemberOffset = &VARIANT::cVal;
- };
- template <>
- struct VartypeToNativeType<VT_UI1> final {
- using Type = uint8_t;
- static constexpr BYTE VARIANT::*kMemberOffset = &VARIANT::bVal;
- };
- template <>
- struct VartypeToNativeType<VT_I2> final {
- using Type = int16_t;
- static constexpr SHORT VARIANT::*kMemberOffset = &VARIANT::iVal;
- };
- template <>
- struct VartypeToNativeType<VT_UI2> final {
- using Type = uint16_t;
- static constexpr USHORT VARIANT::*kMemberOffset = &VARIANT::uiVal;
- };
- template <>
- struct VartypeToNativeType<VT_I4> final {
- using Type = int32_t;
- static constexpr LONG VARIANT::*kMemberOffset = &VARIANT::lVal;
- };
- template <>
- struct VartypeToNativeType<VT_UI4> final {
- using Type = uint32_t;
- static constexpr ULONG VARIANT::*kMemberOffset = &VARIANT::ulVal;
- };
- template <>
- struct VartypeToNativeType<VT_I8> final {
- using Type = int64_t;
- static constexpr LONGLONG VARIANT::*kMemberOffset = &VARIANT::llVal;
- };
- template <>
- struct VartypeToNativeType<VT_UI8> final {
- using Type = uint64_t;
- static constexpr ULONGLONG VARIANT::*kMemberOffset = &VARIANT::ullVal;
- };
- template <>
- struct VartypeToNativeType<VT_R4> final {
- using Type = float;
- static constexpr FLOAT VARIANT::*kMemberOffset = &VARIANT::fltVal;
- };
- template <>
- struct VartypeToNativeType<VT_R8> final {
- using Type = double;
- static constexpr DOUBLE VARIANT::*kMemberOffset = &VARIANT::dblVal;
- };
- template <>
- struct VartypeToNativeType<VT_DATE> final {
- using Type = DATE;
- static constexpr DATE VARIANT::*kMemberOffset = &VARIANT::date;
- };
- template <>
- struct VartypeToNativeType<VT_BSTR> final {
- using Type = BSTR;
- static constexpr BSTR VARIANT::*kMemberOffset = &VARIANT::bstrVal;
- };
- template <>
- struct VartypeToNativeType<VT_UNKNOWN> final {
- using Type = IUnknown*;
- static constexpr IUnknown* VARIANT::*kMemberOffset = &VARIANT::punkVal;
- };
- template <>
- struct VartypeToNativeType<VT_DISPATCH> final {
- using Type = IDispatch*;
- static constexpr IDispatch* VARIANT::*kMemberOffset = &VARIANT::pdispVal;
- };
- // VariantUtil contains the underlying |Type| and helper methods
- // related to the |ElementVartype| for simple types.
- template <VARTYPE ElementVartype>
- struct VariantUtil final {
- using Type = typename VartypeToNativeType<ElementVartype>::Type;
- static constexpr bool IsConvertibleTo(VARTYPE vartype) {
- return VarTypeIsConvertibleTo(ElementVartype, vartype);
- }
- static constexpr bool IsConvertibleFrom(VARTYPE vartype) {
- return VarTypeIsConvertibleTo(vartype, ElementVartype);
- }
- // Get the associated VARIANT union member value.
- // Returns the value owned by the VARIANT without affecting the lifetime
- // of managed contents.
- // e.g. Does not affect IUnknown* reference counts or allocate a BSTR.
- static Type RawGet(const VARIANT& var) {
- DCHECK(IsConvertibleFrom(V_VT(&var)));
- return var.*VartypeToNativeType<ElementVartype>::kMemberOffset;
- }
- // Set the associated VARIANT union member value.
- // The caller is responsible for handling the lifetime of managed contents.
- // e.g. Incrementing IUnknown* reference counts or allocating a BSTR.
- static void RawSet(VARIANT* var, Type value) {
- DCHECK(IsConvertibleTo(V_VT(var)));
- var->*VartypeToNativeType<ElementVartype>::kMemberOffset = value;
- }
- };
- } // namespace internal
- } // namespace win
- } // namespace base
- #endif // BASE_WIN_VARIANT_UTIL_H_
|