[Win][Clang][WebKitLegacy] warning: expected a qualified name after 'typename' of...
[WebKit-https.git] / Source / WebKitLegacy / win / COMEnumVariant.h
1 /*
2  * Copyright (C) 2007 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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. 
24  */
25
26 #ifndef COMEnumVariant_h
27 #define COMEnumVariant_h
28
29 #include <unknwn.h>
30
31 #include "COMVariantSetter.h"
32
33 template<typename ContainerType>
34 class COMEnumVariant final : public IEnumVARIANT {
35     WTF_MAKE_NONCOPYABLE(COMEnumVariant);
36 public:
37     static COMEnumVariant* adopt(ContainerType&);
38     static COMEnumVariant* createInstance(const ContainerType&);
39
40     // IUnknown
41     virtual HRESULT STDMETHODCALLTYPE QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject);
42     virtual ULONG STDMETHODCALLTYPE AddRef();
43     virtual ULONG STDMETHODCALLTYPE Release();
44
45     // IEnumVARIANT
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);
50
51 private:
52     COMEnumVariant()
53     {
54     }
55
56     COMEnumVariant(const ContainerType& container)
57         : m_container(container)       
58         , m_currentPos(m_container.begin())
59     {
60     }
61
62     ~COMEnumVariant() {}
63
64     ULONG m_refCount { 0 };
65
66     ContainerType m_container;
67     typename ContainerType::const_iterator m_currentPos;
68 };
69
70 // COMEnumVariant ------------------------------------------------------------------
71 template<typename ContainerType>
72 COMEnumVariant<ContainerType>* COMEnumVariant<ContainerType>::adopt(ContainerType& container) 
73 {
74     COMEnumVariant* instance = new COMEnumVariant;
75     instance->m_container.swap(container);
76     instance->m_currentPos = instance->m_container.begin();
77     instance->AddRef();
78     return instance;
79 }
80
81 template<typename ContainerType>
82 COMEnumVariant<ContainerType>* COMEnumVariant<ContainerType>::createInstance(const ContainerType& container)
83 {
84     COMEnumVariant* instance = new COMEnumVariant(container);
85     instance->AddRef();
86     return instance;
87 }
88
89 // IUnknown ------------------------------------------------------------------------
90 template<typename ContainerType>
91 HRESULT STDMETHODCALLTYPE COMEnumVariant<ContainerType>::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
92 {
93     if (!ppvObject)
94         return E_POINTER;
95     *ppvObject = nullptr;
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);
100     else
101         return E_NOINTERFACE;
102
103     AddRef();
104     return S_OK;
105 }
106
107 template<typename ContainerType>
108 ULONG STDMETHODCALLTYPE COMEnumVariant<ContainerType>::AddRef()
109 {
110     return ++m_refCount;
111 }
112
113 template<typename ContainerType>
114 ULONG STDMETHODCALLTYPE COMEnumVariant<ContainerType>::Release()
115 {
116     ULONG newRef = --m_refCount;
117     if (!newRef)
118         delete this;
119
120     return newRef;
121 }
122
123 // IEnumVARIANT --------------------------------------------------------------------
124 template<typename ContainerType>
125 HRESULT STDMETHODCALLTYPE COMEnumVariant<ContainerType>::Next(ULONG celt, VARIANT* rgVar, ULONG* pCeltFetched)
126 {
127     if (pCeltFetched)
128         *pCeltFetched = 0;
129     if (!rgVar)
130         return E_POINTER;
131     for (unsigned i = 0 ; i < celt; i++)
132         ::VariantInit(&rgVar[i]);
133
134     for (unsigned i = 0; i < celt; i++) {
135         if (m_currentPos == m_container.end())
136             return S_FALSE;
137
138         COMVariantSetter<typename ContainerType::ValueType>::setVariant(&rgVar[i], *m_currentPos);
139         ++m_currentPos;
140         if (pCeltFetched)
141             (*pCeltFetched)++;
142     }
143
144     return S_OK;
145 }
146
147 template<typename ContainerType>
148 HRESULT STDMETHODCALLTYPE COMEnumVariant<ContainerType>::Skip(ULONG celt) 
149 {
150     for (unsigned i = 0; i < celt; i++) {
151         if (m_currentPos == m_container.end())
152             return S_FALSE;
153
154         ++m_currentPos;
155     }
156     return S_OK;
157 }
158     
159 template<typename ContainerType>
160 HRESULT STDMETHODCALLTYPE COMEnumVariant<ContainerType>::Reset() 
161 {
162     m_currentPos = m_container.begin();
163     return S_OK;
164 }
165     
166 template<typename ContainerType>
167 HRESULT STDMETHODCALLTYPE COMEnumVariant<ContainerType>::Clone(_COM_Outptr_opt_ IEnumVARIANT** ppEnum)
168 {
169     if (!ppEnum)
170         return E_POINTER;
171
172     *ppEnum = nullptr;
173     return E_NOTIMPL;
174 }
175
176 #endif