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