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.