+1  A: 

I see no reason why you can't implement this exactly as you've laid it out... am I missing something?

To clarify, you'll need to put some kind of accessor methods on your Container class. They can be private and you can declare MagicIterator as a friend, if you feel that's the best way to encapsulate it, but I'd expose them directly. These accessor methods would use a normal STL iterator inside Container and perform the conversion to IInterface. Thus the iterating would actually be done with the Container's accessor methods and MagicIterator would just be a kind of proxy object to make it easier. To make it reentrant, you could have the MagicIterator pass in some kind of ID to look up the STL iterator inside Container, or you could actually have it pass in the STL iterator as a void *.

rmeador
I don't want to have to make Container::Item public. I want the iterator to be externally unrelated to std::list::iterator; to appear to be iterating over a set of IInterface* pointers, and for Item to remain entirely private to Container. IInterface* comes from Item.pObject->GetInterface().
El Zorko
my solution does not require you to make Item public. The iterator is externally unrelated. The accessors are wrapping the std::list::iterator, so only the insides of Container know that is the implementation. That's also why I suggested using a void* to pass it for making it reentrant.
rmeador
Apologies, that was a mispost. [This is, as you can probably tell, my first time here. Very sorry!] I really want to keep MagicIterator decoupled from Container; I'd like to be able to re-use it on other arbitrary classes without changing it, even if said others had to have glue to make it work.
El Zorko
well, you could make Container implement some interface that provides appropriate accessor methods and thus be able to reuse MagicIterator with anything else that implements that inferface, but other than that, I'm out of ideas... sorry.
rmeador
Some form of IMagicIteratable<IInterface*>...that is a thought. But how would one write the accessor methods on Container in a manner that uses a stack-allocated std::list<Item> iterator without exposing it (and the private class Item) to the caller of said methods?
El Zorko
My proposal didn't have a stack-allocated std::list::iterator. the iterator was inside Container (or in an untyped pointer inside the MagicIterator class). in either case, Container would act as a factory for MagicIterator, thus it could create the iterator inside itself or the MagicIterator.
rmeador
At the risk of being dumb, if MagicIterator accesses the real iterator via an untyped pointer, where is said iterator? I want it on the stack somewhere really. It can't be in eg. a list in Container surely, as I don't want heap allocation during iteration...and I equally don't want to new() it.
El Zorko
+1  A: 

It really depends on the Container, because the return values of c.Begin() and c.End() are implementation-defined.

If a list of possible Containers is known to MagicIterator, a wrapper class could be used.

template<typename T>
class MagicIterator
{
    public:
        MagicIterator(std::vector<T>::const_iterator i)
        {
            vector_const_iterator = i;
        }

        // Reimplement similarly for more types.
        MagicIterator(std::vector<T>::iterator i);
        MagicIterator(std::list<T>::const_iterator i);
        MagicIterator(std::list<T>::iterator i);

        // Reimplement operators here...

    private:
        std::vector<T>::const_iterator vector_const_iterator;
        std::vector<T>::iterator       vector_iterator;
        std::list<T>::const_iterator   list_const_iterator;
        std::list<T>::iterator         list_iterator;
};

The easy way would be to use a template which accepts Container's type:

// C++0x
template<typename T>
class Iterator :
    public T::iterator
{
    using T::iterator::iterator;
};

for(Iterator<Container> i = c.begin(); i != c.end(); ++i)
{
    // ...
}

More information here.

strager
He isn't trying to support multiple container types with the same iterator (ala any_iterator)...
Greg Rogers
Aye, the main task is to hide the fact that we're really using a std::vector::iterator<Item>, and make it look like we're iterating over IInterface* pointers (obtained from Object, within each Item). In particular Item must remain private to Container, unlike Object and IInterface.
El Zorko
+3  A: 

Create an abstract IteratorImplementation class:

template<typename T>
class IteratorImplementation
{
    public:
        virtual ~IteratorImplementation() = 0;

        virtual T &operator*() = 0;
        virtual const T &operator*() const = 0;

        virtual Iterator<T> &operator++() = 0;
        virtual Iterator<T> &operator--() = 0;
};

And an Iterator class to wrap around it:

template<typename T>
class Iterator
{
    public:
        Iterator(IteratorImplementation<T> * = 0);
        ~Iterator();

        T &operator*();
        const T &operator*() const;

        Iterator<T> &operator++();
        Iterator<T> &operator--();

    private:
        IteratorImplementation<T> *i;
}

Iterator::Iterator(IteratorImplementation<T> *impl) :
    i(impl)
{
}

Iterator::~Iterator()
{
    delete i;
}

T &Iterator::operator*()
{
    if(!impl)
    {
        // Throw exception if you please.
        return;
    }

    return (*impl)();
}

// etc.

(You can make IteratorImplementation a class "inside" of Iterator to keep things tidy.)

In your Container class, return an instance of Iterator with a custom subclass of IteratorImplementation in the ctor:

class ObjectContainer
{
    public:
        void insert(Object *o);
        // ...

        Iterator<Object *> begin();
        Iterator<Object *> end();

    private:
        class CustomIteratorImplementation :
            public IteratorImplementation<Object *>
        {
            public:
                // Re-implement stuff here.
        }
};

Iterator<Object *> ObjectContainer::begin()
{
    CustomIteratorImplementation *impl = new CustomIteratorImplementation();  // Wish we had C++0x's "var" here.  ;P

    return Iterator<Object *>(impl);
}
strager
I did try that, but sadly the abstract Iterator class can't be instantiated, so the caller can't store it anywhere (even in a for loop header) without knowing the concrete type.
El Zorko
It can be instantiated. Your begin() and end() classes instantiate it. I don't see the problem.
strager
for (Iterator<Object*> i = c.begin(); i != c.end(); i++) ...will not compile, as Iterator<> is abstract.
El Zorko
Ah, you are right. Dang, and I thought I had something working. =] You *could* have a wrapper around the abstract class, and pass the wrapped class to the constructor of the Iterator object. I think that'd work.
strager
I have updated my answer with my idea implemented.
strager
Actually, having looked more closely, this won't do; the reason I didn't do it is I can't have heap allocation caused by iteration in my case, so "new" is out. alloca() (possibly via an evilly overloaded new operator) won't help either, as it'll go out of scope when ObjectContainer::begin() returns.
El Zorko
+3  A: 

Doesn't sound too complicated. You can define the iterator outside. You can also use typedefs. Something like this would fit i think. Note that it would be way cleaner if that MagicIterator would be not a free template, but a member of Item, typedefed in Container maybe. As it's now, there is a cyclic reference in it, which make it necassary to write some ugly workaround code.

namespace detail {
    template<typename T, typename U>
    struct constify;

    template<typename T, typename U>
    struct constify<T*, U*> {
        typedef T * type;
    };

    template<typename T, typename U>
    struct constify<T*, U const*> {
        typedef T const * type;
    };
}

template<typename DstType, 
         typename Container,
         typename InputIterator>
struct MagicIterator;

class Container
{
private:
    struct Item
    {
        Object* pObject;
    };

    std::list<Item> m_items;

public:

    // required by every Container for the iterator
    typedef std::list<Item> iterator;
    typedef std::list<Item> const_iterator;

    // convenience declarations
    typedef MagicIterator< IInterface*, Container, iterator > 
        item_iterator;
    typedef MagicIterator< IInterface*, Container, const_iterator > 
        const_item_iterator;

    item_iterator Begin();
    item_iterator End();
};

template<typename DstType, 
         typename Container = Container,
         typename InputIterator = typename Container::iterator>
struct MagicIterator : 
    // pick either const T or T, depending on whether it's a const_iterator.
    std::iterator<std::input_iterator_tag, 
                  typename detail::constify<
                           DstType, 
                           typename InputIterator::value_type*>::type> {
    typedef std::iterator<std::input_iterator_tag, 
                 typename detail::constify<
                          DstType, 
                          typename InputIterator::value_type*>::type> base;
    MagicIterator():wrapped() { }
    explicit MagicIterator(InputIterator const& it):wrapped(it) { }
    MagicIterator(MagicIterator const& that):wrapped(that.wrapped) { }

    typename base::value_type operator*() {
        return (*wrapped).pObject->GetInterface();
    }

    MagicIterator& operator++() {
        ++wrapped;
        return *this;
    }

    MagicIterator operator++(int) {
        MagicIterator it(*this);
        wrapped++;
        return it;
    }

    bool operator==(MagicIterator const& it) const {
        return it.wrapped == wrapped;
    }

    bool operator!=(MagicIterator const& it) const {
        return !(*this == it);
    }

    InputIterator wrapped;
};

// now that the iterator adepter is defined, we can define Begin and End
inline Container::item_iterator Container::Begin() {
    return item_iterator(m_items.begin());
}

inline Container::item_iterator Container::End() {
    return item_iterator(m_items.end());
}

Now, start using it:

for(MagicIterator<IInterface*> it = c.Begin(); it != c.End(); ++it) {
    // ...
}

You can also use a iterator mixin provided by boost, which works like the input version of boost::function_output_iterator. It calls your iterator's operator() which then returns the appropriate value, doing what we do above in our operator* in principle. You find it in random/detail/iterator_mixin.hpp. That would probably result in fewer code. But it also requires to wrack up our neck to ensure the friend-stuff because Item is private and the iterator isn't defined inside Item. Anyway, good luck :)

Johannes Schaub - litb
That compiles and runs beautifully except that Item is private to Container. I could move MagicIterator into Container, but I really want MagicIterator to be applicable to several Container-like classes, which perhaps implement MagicIterator-specific "glue" functionality.
El Zorko
@El Zorko, That's what friends are for.
strager
El, Zorko. the iterator is a friend of Container. so it should be able to see Item, even if it is private
Johannes Schaub - litb
El, Zorko. if you want to decouple the iterator from Container, make Container a template parameter too, and assert "each Container must have a typedef that declares the InputIterator wrapped as "wrapped_iterator" , for example. Then you can do Container::Item to get the item type too
Johannes Schaub - litb
(and default the InputIterator parameter to Container::wrapped_iterator or remove it completely)
Johannes Schaub - litb
@strager, perhaps it's just VC++ 2005 being out of touch, but it bitches and whines about the use of Container::Item within the default template parameter InputIterator.
El Zorko
Ei, Zorko. Oh that's interesting. comeau also rejects it. default arguments do not seem to be blessed by friendship. i will have to change the stuff :)
Johannes Schaub - litb
Ei, Zorko. can you try again? should work now.
Johannes Schaub - litb
Upon closer inspection, this sadly doesn't quite fit the bill either. MagicIterator has to accept a template argument indicating its container and the real iterator, which couples it directly to the COntainer class. I need a decoupled MagicIterator to work with multiple Container-esque classes.
El Zorko
EI Zorko, that's impossible without using new. your iterator needs to be polymorphic then. but you said you don't want that.
Johannes Schaub - litb
you *can* use stack allocation for the most common iterator sizes, but sooner or later, you will have to do with an iterator size that doesn't fit a small buffer optimization anymore, and then heap allocation will be needed. boost::any doesn't even buffer with that. it always uses the heap
Johannes Schaub - litb
i can show you a version that exactly fits your bill, but uses new behind the hood (using boost::any and boost::function). anyway, why the heck do you want to avoid new? can you show us an example where that hurts?
Johannes Schaub - litb
Apologies, but I did lead the post with a statement that I suspected it wasn't possible. This code is intended to ease iteration in a highly constrained environment where minimising use of heap allocation is very significant.
El Zorko
hmm, i see. if you have a limited set of containers, you can use boost::variant and avoid heap allocation here. maybe that would be an option?
Johannes Schaub - litb
otherwise, i would just use the new/delete stuff and profile first, to see whether it really causes any significant slowdown
Johannes Schaub - litb
I agree with @litb; new/delete may not be your bottleneck. You can reimplement it to use the stack, too. If you really wanted speed, why bother with MagicIterator in the first place? Also, "premature optimization is the root of all evil."
strager
Sadly you can't re-implement it to use the stack, without doing something evil like my solution below. I need speed, plus the ability to iterate over X* when really the underlying collection is of Y, with suitable abstraction. This is for performant code where excess heap allocs are unacceptable.
El Zorko
+4  A: 

I think you have two separate issues here:

First, create an iterator that will return the IInterface* from your list<Container::Item>. This is easily done with boost::iterator_adaptor:

class cont_iter
  : public boost::iterator_adaptor<
        cont_iter                       // Derived
      , std::list<Container::Item>::iterator // Base
      , IInterface*                     // Value
      , boost::forward_traversal_tag    // CategoryOrTraversal
      , IInterface*                     // Reference :)
    >
{
 public:
    cont_iter()
      : cont_iter::iterator_adaptor_() {}

    explicit cont_iter(const cont_iter::iterator_adaptor_::base_type& p)
      : cont_iter::iterator_adaptor_(p) {}

 private:
    friend class boost::iterator_core_access;
    IInterface* dereference() { return this->base()->pObject->GetInterface(); }
};

You would create this type as inner in Container and return in from its begin() and end() methods.

Second, you want the runtime-polymorphic MagicIterator. This is exactly what any_iterator does. the MagicIterator<IInterface*> is just any_iterator<IInterface*, boost::forward_traversal_tag, IInterface*>, and cont_iter can be just assigned to it.

jpalecek
That is beautifully brief, but I sadly don't have boost available. Terrible I know, and this is a neat answer which I may have to try in principle even though I can't use it in this case.
El Zorko
A: 

I've now found a solution which is fitter for my original purpose. I still don't like it though :)

The solution involves MagicIterator being templated on IInterface* and being constructed with both a void* to an iterator, the byte size of said iterator, and a table of pointers to functions which perform standard iteration functions on said void* such as increment, decrement, dereference, etc. MagicIterator assumes that it is safe to memcpy the given iterator into an internal buffer, and implements its own members by passing its own buffer as a void* to the supplied functions as if it were the original iterator.

Container then has to implement static iteration functions which cast back a supplied void* to a std::list::iterator. Container::begin() and Container::end() simply construct a std::list::iterator, pass a pointer to it into a MagicIterator along with a table of its iteration functions, and return the MagicIterator.

It's somewhat disgusting, and breaks my original rule regarding "no memcpy()", and makes assumptions about the internals of the iterators in question. But it avoids heap allocation, keeps Collection's internals (including Item) private, renders MagicIterator entirely independent of the collection in question and of IInterface*, and in theory allows MagicIterators to work with any collection (provided its iterators can be safely memcopy()'d).

El Zorko
A: 

A visitor may be a simpler (and therefore easier to maintain) solution.

Andrew