2 * Copyright (C) 2007 Apple Inc. All Rights Reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef COMEnumVariant_h
27 #define COMEnumVariant_h
31 #include "COMVariantSetter.h"
33 template<typename ContainerType>
34 class COMEnumVariant final : public IEnumVARIANT {
35 WTF_MAKE_NONCOPYABLE(COMEnumVariant);
37 static COMEnumVariant* adopt(ContainerType&);
38 static COMEnumVariant* createInstance(const ContainerType&);
41 virtual HRESULT STDMETHODCALLTYPE QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject);
42 virtual ULONG STDMETHODCALLTYPE AddRef();
43 virtual ULONG STDMETHODCALLTYPE Release();
46 virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, VARIANT* rgVar, ULONG* pCeltFetched);
47 virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt);
48 virtual HRESULT STDMETHODCALLTYPE Reset();
49 virtual HRESULT STDMETHODCALLTYPE Clone(_COM_Outptr_opt_ IEnumVARIANT** ppEnum);
56 COMEnumVariant(const ContainerType& container)
57 : m_container(container)
58 , m_currentPos(m_container.begin())
64 ULONG m_refCount { 0 };
66 ContainerType m_container;
67 typename ContainerType::const_iterator m_currentPos;
70 // COMEnumVariant ------------------------------------------------------------------
71 template<typename ContainerType>
72 COMEnumVariant<ContainerType>* COMEnumVariant<ContainerType>::adopt(ContainerType& container)
74 COMEnumVariant* instance = new COMEnumVariant;
75 instance->m_container.swap(container);
76 instance->m_currentPos = instance->m_container.begin();
81 template<typename ContainerType>
82 COMEnumVariant<ContainerType>* COMEnumVariant<ContainerType>::createInstance(const ContainerType& container)
84 COMEnumVariant* instance = new COMEnumVariant(container);
89 // IUnknown ------------------------------------------------------------------------
90 template<typename ContainerType>
91 HRESULT STDMETHODCALLTYPE COMEnumVariant<ContainerType>::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
96 if (IsEqualGUID(riid, IID_IUnknown))
97 *ppvObject = static_cast<COMEnumVariant*>(this);
98 else if (IsEqualGUID(riid, IID_IEnumVARIANT))
99 *ppvObject = static_cast<COMEnumVariant*>(this);
101 return E_NOINTERFACE;
107 template<typename ContainerType>
108 ULONG STDMETHODCALLTYPE COMEnumVariant<ContainerType>::AddRef()
113 template<typename ContainerType>
114 ULONG STDMETHODCALLTYPE COMEnumVariant<ContainerType>::Release()
116 ULONG newRef = --m_refCount;
123 // IEnumVARIANT --------------------------------------------------------------------
124 template<typename ContainerType>
125 HRESULT STDMETHODCALLTYPE COMEnumVariant<ContainerType>::Next(ULONG celt, VARIANT* rgVar, ULONG* pCeltFetched)
131 for (unsigned i = 0 ; i < celt; i++)
132 ::VariantInit(&rgVar[i]);
134 for (unsigned i = 0; i < celt; i++) {
135 if (m_currentPos == m_container.end())
138 COMVariantSetter<typename ContainerType::ValueType>::setVariant(&rgVar[i], *m_currentPos);
147 template<typename ContainerType>
148 HRESULT STDMETHODCALLTYPE COMEnumVariant<ContainerType>::Skip(ULONG celt)
150 for (unsigned i = 0; i < celt; i++) {
151 if (m_currentPos == m_container.end())
159 template<typename ContainerType>
160 HRESULT STDMETHODCALLTYPE COMEnumVariant<ContainerType>::Reset()
162 m_currentPos = m_container.begin();
166 template<typename ContainerType>
167 HRESULT STDMETHODCALLTYPE COMEnumVariant<ContainerType>::Clone(_COM_Outptr_opt_ IEnumVARIANT** ppEnum)