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
35 #include "COMVariantSetter.h"
37 template<typename ContainerType>
38 class COMEnumVariant : public IEnumVARIANT {
39 WTF_MAKE_NONCOPYABLE(COMEnumVariant);
41 static COMEnumVariant* adopt(ContainerType&);
42 static COMEnumVariant* createInstance(const ContainerType&);
45 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
46 virtual ULONG STDMETHODCALLTYPE AddRef();
47 virtual ULONG STDMETHODCALLTYPE Release();
50 virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, VARIANT* rgVar, ULONG* pCeltFetched);
51 virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt);
52 virtual HRESULT STDMETHODCALLTYPE Reset();
53 virtual HRESULT STDMETHODCALLTYPE Clone(IEnumVARIANT** ppEnum);
61 COMEnumVariant(const ContainerType& container)
63 , m_container(container)
64 , m_currentPos(m_container.begin())
72 ContainerType m_container;
73 typename ContainerType::const_iterator m_currentPos;
76 // COMEnumVariant ------------------------------------------------------------------
77 template<typename ContainerType>
78 COMEnumVariant<typename ContainerType>* COMEnumVariant<ContainerType>::adopt(ContainerType& container)
80 COMEnumVariant* instance = new COMEnumVariant;
81 instance->m_container.swap(container);
82 instance->m_currentPos = instance->m_container.begin();
87 template<typename ContainerType>
88 COMEnumVariant<typename ContainerType>* COMEnumVariant<ContainerType>::createInstance(const ContainerType& container)
90 COMEnumVariant* instance = new COMEnumVariant(container);
95 // IUnknown ------------------------------------------------------------------------
96 template<typename ContainerType>
97 HRESULT STDMETHODCALLTYPE COMEnumVariant<ContainerType>::QueryInterface(REFIID riid, void** ppvObject)
100 if (IsEqualGUID(riid, IID_IUnknown))
101 *ppvObject = static_cast<COMEnumVariant*>(this);
102 else if (IsEqualGUID(riid, IID_IEnumVARIANT))
103 *ppvObject = static_cast<COMEnumVariant*>(this);
105 return E_NOINTERFACE;
111 template<typename ContainerType>
112 ULONG STDMETHODCALLTYPE COMEnumVariant<ContainerType>::AddRef()
117 template<typename ContainerType>
118 ULONG STDMETHODCALLTYPE COMEnumVariant<ContainerType>::Release()
120 ULONG newRef = --m_refCount;
127 // IEnumVARIANT --------------------------------------------------------------------
128 template<typename ContainerType>
129 HRESULT STDMETHODCALLTYPE COMEnumVariant<ContainerType>::Next(ULONG celt, VARIANT* rgVar, ULONG* pCeltFetched)
135 for (unsigned i = 0 ; i < celt; i++)
136 VariantInit(&rgVar[i]);
138 for (unsigned i = 0; i < celt; i++) {
139 if (m_currentPos == m_container.end())
142 COMVariantSetter<ContainerType::ValueType>::setVariant(&rgVar[i], *m_currentPos);
151 template<typename ContainerType>
152 HRESULT STDMETHODCALLTYPE COMEnumVariant<ContainerType>::Skip(ULONG celt)
154 for (unsigned i = 0; i < celt; i++) {
155 if (m_currentPos == m_container.end())
163 template<typename ContainerType>
164 HRESULT STDMETHODCALLTYPE COMEnumVariant<ContainerType>::Reset()
166 m_currentPos = m_container.begin();
170 template<typename ContainerType>
171 HRESULT STDMETHODCALLTYPE COMEnumVariant<ContainerType>::Clone(IEnumVARIANT** ppEnum)