IForwardsIterator.h

// IForwardsIterator.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2008

@import "IObject.h"

/*
todo: First we need to support templated interfaces.  The parser will need to account
for appearances of template parameters.

It should be straightforward to add the template parameters to the generated C++ 
interface.

A simple way to achieve registration is to simply register each fully qualified interface 
declaration.

Eg

$interface IForwardsIterator<int32>;

However, it would seem important to allow multiple dlls to register the same interface.

A more complex approach would allow for registering the abstract template itself, but then
we need a concept of generics in the byte code.  Maybe not such a bad idea - could lead to
substantial reductions in certain domains.

Eg byte code could support a range that designate variables that can be bound according to
a context.


todo: Should iterators be cloneable?
*/

namespace ceda
{

@if (false)
{
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    // IForwardsIterator<T>

    $interface+ IForwardsIterator<T> : IObject
    {
        // Returns true if we have reached the end of the sequence
        bool AtEnd() const;
        
        // Dereference the iterator at the current position.  
        // Must not be called if we have reached the end of the sequence
        T Get() const;
        
        // Move the iterator to the next position.
        // Must not be called if we have reached the end of the sequence
        void Next();
        
        // Iterator must be closed when it is no longer required
        void Close();
    };


    ///////////////////////////////////////////////////////////////////////////////////////////////////
    // ForwardsIterator<T>

    template<typename T>
    class ForwardsIterator
    {
        cxNotCloneable(ForwardsIterator)

    public:
        ForwardsIterator(ptr<IForwardsIterator<T> > i) : m_i(i) {}
        ~ForwardsIterator() { m_it->Close(): }
        
        T operator*() const { return m_it.Get(); }
        ForwardsIterator& operator++() { m_it->Next(); return *this; }
        explicit operator bool() const { return !m_it->AtEnd(); }

    private:
        ptr<IForwardsIterator<T> > m_it;
    };


    ///////////////////////////////////////////////////////////////////////////////////////////////////
    // MapIterator<K,V>

    // Used to help implement a forwards iterator on a map

    template <typename K, typename V>
    class MapIterator
    {
    public:
        typedef std::map<K,V> MAP;
        MapIterator(const MAP& m) : m_i(m.begin()), m_end(m.end()) {}
    
        bool AtEnd() const { return m_i == m_end; }
        MAP::value_type Get() { return *m_i; }
        void Next() { ++m_i; }
        void Close() { delete this; }
    
    private:
        MAP::const_iterator m_end;
        MAP::const_iterator m_i;
    };

}

} // namespace ceda