Listing 1: Wrapper to treat a forward iterator as an IEnum interface
///////////////////////////////////////////////////////////////
// ITERENUM.H
#include <objbase.h>
template <class Iterator,class T,class IEnum,const IID* piid>
interface IteratorAsEnum : IEnum {
// construct from pair of iterators
IteratorAsEnum(const Iterator& r, const Iterator& rend)
: nUsers(1), begin(r), curr(r), end(rend) {
}
// IUnknown methods
STDMETHOD(QueryInterface)(REFIID iid,LPVOID* pp) {
if (IsEqualIID(iid,*piid)) {
*((IEnum**)pp) = this;
return 0;
}
if (IsEqualIID(iid,IID_IUnknown)) {
*((IUnknown**)pp) = this;
return 0;
}
*pp = 0;
return E_NOINTERFACE;
}
STDMETHOD_(ULONG,AddRef)() {
return ++nUsers;
}
STDMETHOD_(ULONG,Release)() {
if (--nUsers == 0)
delete this;
return nUsers;
}
// IEnum methods
STDMETHOD(Next)(ULONG n, T* dest, ULONG* pn) {
try {
*pn = 0;
while (n--) {
if (curr == end)
return S_FALSE;
dest[(*pn)++] = *curr;
++curr;
}
} catch(...) {
return E_FAIL;
}
return 0;
}
STDMETHOD(Skip)(ULONG n) {
try {
while (n--) {
if (curr == end)
return S_FALSE;
++curr;
}
} catch(...) {
return E_FAIL;
}
return 0;
}
STDMETHOD(Reset)() {
try {
curr = begin;
} catch(...) {
return E_FAIL;
}
return 0;
}
STDMETHOD(Clone)(IEnum** ppenum) {
*ppenum = 0;
try {
IteratorAsEnum* p = new IteratorAsEnum(begin,end);
p->curr = curr;
*ppenum = p;
} catch(...) {
return E_FAIL;
}
return 0;
}
private:
ULONG nUsers;
Iterator begin, curr, end;
};
//End of File