/** \file * Standard C++ iterators wrapping IEnumVARIANT objects. */ /* * Copyright © 2000 Sofus Mortensen * * This material is provided "as is", with absolutely no warranty * expressed or implied. Any use is at your own risk. Permission to * use or copy this software for any purpose is hereby granted without * fee, provided the above notices are retained on all copies. * Permission to modify the code and to distribute modified code is * granted, provided the above notices are retained, and a notice that * the code was modified is included with the above copyright notice. * * This header is part of Comet version 2. * https://github.com/alamaison/comet */ #ifndef COMET_VARIANT_ITERATOR_H #define COMET_VARIANT_ITERATOR_H #include #include #include #include namespace comet { /** \class variant_iterator enum.h comet/enum.h * STL style iterator for IEnumVariant interface. */ class variant_iterator { com_ptr enum_; variant_t ce_; public: /** Constructor. */ variant_iterator( const com_ptr& e ) : enum_(e) { next(); } variant_iterator() {} /** Move to next element. */ variant_iterator& operator++() { next(); return *this; } bool operator!=(const variant_iterator& v) { if (!v.enum_.is_null()) throw std::logic_error( "variant_iterator comparison does not work"); return !enum_.is_null(); } /** Move to next element (post increment). */ variant_iterator operator++(int) { variant_iterator t(*this); operator++(); return t; } /** Current element. */ variant_t& operator*() { return ce_; } private: void next() { if (enum_) { unsigned long x = 0; enum_->Next(1, ce_.out(), &x) | raise_exception; if (x == 0) enum_ = 0; } } }; /** \class itf_iterator enum.h comet/enum.h * STL style Iterator for IEnumVARIANT interface returning a contained * interface pointer. */ template class itf_iterator { com_ptr enum_; com_ptr p_; public: /** Constructor. */ itf_iterator( const com_ptr& e ) : enum_(e) { next(); } itf_iterator() {} /** Move to next element. */ itf_iterator& operator++() { next(); return *this; } bool operator!=(const itf_iterator& v) { if (v.enum_) throw std::logic_error( "itf_iterator comparison does not work"); return enum_ != 0; } /** Move to next element. */ itf_iterator operator++(int) { itf_iterator t(*this); operator++(); return t; } /** Access element. */ com_ptr& operator*() { return p_; } private: void next() { if (enum_) { unsigned long x = 0; variant_t v; enum_->Next(1, v.out(), &x) | raise_exception; if (x == 0) { enum_ = 0; p_ = 0; } else { p_ = try_cast(v); } } } }; } #endif