Thursday, Jul 12, 2001, 12:00 AM in Tools
STL Enumerator Iterator
Have you ever been jealous of the VB programmer who could write this:
sub EnumVariants(col as Collection) dim v as variant for each v in col ' Do something with v next v end sub
when we poor C++ programmers have to write this:
void EnumVariants(IEnumVARIANT* pevar) { HRESULT hr; enum { CHUNKSIZE = 100 }; VARIANT rgvar[CHUNKSIZE] = { 0 }; do { ULONG cFetched; hr = pevar->Next(CHUNKSIZE, rgvar, &cFetched) if( SUCCEEDED(hr) ) { if( hr == S_OK ) cFetched = CHUNKSIZE; for( ULONG i = 0; i < cFetched; i++ ) { // Do something with rgvar[i] VariantClear(&rgvar[i]); } } } while (hr == S_OK); }
Well no more! I've built an enumeration iterator class that holds IEnumXxx and exposes an STL-compatible iterator:
template <typename EnumItf, const IID* pIIDEnumItf, typename EnumType, typename CopyClass = _Copy<EnumType> > class enum_iterator;
It uses the same copy policy classes as ATL for convenience. Now you can write:
void EnumVariants(IEnumVARIANT* pevar) { typedef enum_iterator<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT> EVI; for( EVI i = EVI(pevar); i != EVI(); ++i ) { VARIANT& v = *i; // Do something with v } }
or you can use the typedefs for the standard enumerators:
void EnumVariants(IEnumVARIANT* pevar) { for( variant_iterator i = variant_iterator(pevar); i != variant_iterator(); ++i ) { VARIANT& v = *i; // Do something with v } }
or you can use STL algorithms (this is my personal favorite):
struct DoSomethingWithVariant { void operator()(const VARIANT& v) { // Do something with v } }; void EnumVariants(IEnumVARIANT* pevar) { for_each(enum_variant(pevar), enum_variant(), DoSomethingWithVariant()); }
Feel free to download the enum_iterator class for your own use. You'll also need a supporting file, atlcopies.h.