#include #include #include namespace test { template class iterator_base : public boost::iterator_facade, ValueType, boost::forward_traversal_tag> { friend class boost::iterator_core_access; protected: virtual void increment() = 0; virtual ReferenceType dereference() const = 0; public: virtual bool equal(iterator_base const & other) const = 0; virtual iterator_base* clone() const = 0; }; template class cplusplus_iterator_adaptor : public iterator_base::value_type, typename std::iterator_traits::reference> { private: CPlusPlusIterator backing; typedef typename std::iterator_traits::value_type ValueType; typedef typename std::iterator_traits::reference Reference; public: cplusplus_iterator_adaptor() {} cplusplus_iterator_adaptor(cplusplus_iterator_adaptor const & other) : backing(other.backing) {} explicit cplusplus_iterator_adaptor(CPlusPlusIterator iter) : backing(iter) {} virtual cplusplus_iterator_adaptor* clone() const { return new cplusplus_iterator_adaptor(*this); } virtual void increment() { ++backing; } virtual bool equal(iterator_base const & other) const { const cplusplus_iterator_adaptor * p = dynamic_cast(&other); if (p) { return backing == p->backing; } else { return false; } } Reference dereference() const { return *backing; } }; template class iterator_base_wrapper : public boost::iterator_facade, ValueType, boost::forward_traversal_tag, ReferenceType> { private: // iterator_base_wrapper acts as the RAII class for this. I // really want a cloning smart pointer, but there isn't one // standard. So I'll do it myself. iterator_base * backing; public: iterator_base_wrapper() : backing(0) {} iterator_base_wrapper(iterator_base_wrapper const & other) : backing(other.backing->clone()) {} template explicit iterator_base_wrapper(iterator_base const & base) : backing(base.clone()) {} ///////////////////////////// // Functions to support RAII private: void swap(iterator_base_wrapper & other) const // throw() { std::swap(backing, other.backing); } public: iterator_base_wrapper & operator=(iterator_base_wrapper const & other) { // Copy-and-swap iterator_base_wrapper copy(other); swap(copy); return *this; } ~iterator_base_wrapper() { delete backing; } private: friend class boost::iterator_core_access; //////////////////////////////// // Iterator functions virtual void increment() { ++(*backing); } virtual bool equal(iterator_base_wrapper const & other) const { return backing->equal(*other.backing); } ReferenceType dereference() const { return **backing; } }; int run() { const int arr[] = {0,1,2,3,4,5,6,7,8,9,10}; const int size_arr = sizeof(arr)/sizeof(arr[0]); std::vector v(arr, arr+size_arr); // Works with vector::iterator (if you also remove the consts // from a couple lines down), fails with // vector::const_iterator, cplusplus_iterator_adaptor::const_iterator> a_begin(v.begin()); cplusplus_iterator_adaptor::const_iterator> a_end(v.end()); iterator_base_wrapper ii(a_begin); iterator_base_wrapper ii_end(a_end); std::vector::const_iterator vi = v.begin(); while(ii != ii_end) { assert( *vi == *ii ); ++vi; ++ii; } assert( vi == v.end() ); return 0; } } int main() { return test::run(); }