Main Page   Namespace List   Class Hierarchy   Compound List   File List   Header Files   Namespace Members   Compound Members   File Members  

arg_iterator.h

This is the verbatim text of the arg_iterator.h include file.

#ifndef ARG_GRIN_PTR_H
#define ARG_GRIN_PTR_H

#ifndef ARG_COMPILER_H
#include "arg_compiler.h"
#endif

#ifndef ARG_DEEP_COPY_H
#include "arg_deep_copy.h"
#endif

#include ARG_STLHDR(iterator)



namespace arg
{
    namespace iterator_body
    {
        template<typename value_type>
        struct forward : cloneable
        {
            virtual ~forward() {}
            virtual forward* clone() const = 0;
            virtual value_type& operator*() const = 0;
            virtual void increment() = 0;
            virtual bool equals(const forward& rhs) const = 0;
        };
        

        template<typename value_type>
        struct bidirectional
#ifndef ARG_COMPILER_NO_COVARIENT_RETURNS            
             : forward<value_type>
#else             
             : cloneable
#endif
        {
            virtual ~bidirectional() {}
            virtual bidirectional* clone() const = 0;
            virtual value_type& operator*() const = 0;
            virtual void increment() = 0;
            virtual void decrement() = 0;
            virtual bool equals(const bidirectional& rhs) const = 0;
#ifndef ARG_COMPILER_NO_COVARIENT_RETURNS            
            virtual bool equals(const forward<value_type>& rhs) const
                { return equals(static_cast<const bidirectional&>(rhs)); }
#endif                
        };
    }

    template<typename value_type> class bidirectional_iterator;

    template<typename value_type>
    class forward_iterator : public std::forward_iterator_tag
    {
    public:
        template<typename iterator>
        forward_iterator(const iterator& it)
            : body(new implementation<iterator>(it))
            {
            }

#ifdef _MSC_VER
        // MSVC won't use the above template constructor with pointer types
        forward_iterator(value_type* it)
            : body(new implementation<value_type*>(it)) {}
#endif

        /*
        *   Used to constructs a forward interator from a 
        *   bidirectional_iterator.
        *
        *   NB This conversion is not supportable on compilers (MSVC++) that
        *   disallow covarient return types.  This simply leads to less 
        *   efficient code - as the bidirectional_iterator gets wrapped up 
        *   inside the forward_iterator.
        */
#ifndef ARG_COMPILER_NO_COVARIENT_RETURNS            
        forward_iterator(const bidirectional_iterator<value_type>& rhs)
        : body(rhs.body->clone()) {}
#endif

        value_type& operator*() const       { return **body; }

        value_type* operator->() const      { return &**body; }

        forward_iterator& operator++()      { body->increment(); return *this; }

        forward_iterator operator++(int)
            { forward_iterator r(*this); return ++r; }

        bool equals(const forward_iterator& rhs) const
            { return body->equals(*rhs.body); }

    private:

        typedef iterator_body::forward<value_type> body_type;

        body_part_ptr<body_type> body;

        template<typename iterator>
        struct implementation : body_type
        {
            implementation(iterator it) : i(it)     {}
            virtual ~implementation()               {}
            
#ifndef ARG_COMPILER_NO_COVARIENT_RETURNS            
            virtual implementation* clone() const
#else
            virtual body_type* clone() const
#endif
                { return new implementation(*this); }
            
            virtual value_type& operator*() const   { return *i; }
            virtual void increment()                { ++i;  }
            virtual bool equals(const body_type& rhs) const
                { return i == static_cast<const implementation&>(rhs).i; }
            
            iterator i;
        };
    };

    template<typename value_type>
    inline bool operator==(
        const forward_iterator<value_type>& lhs,
        const forward_iterator<value_type>& rhs)
    {
        return lhs.equals(rhs);
    }

    template<typename value_type>
    inline bool operator!=(
        const forward_iterator<value_type>& lhs,
        const forward_iterator<value_type>& rhs)
    {
        return !lhs.equals(rhs);
    }


    template<typename value_type>
    class bidirectional_iterator : public std::bidirectional_iterator_tag
    {
    public:
        template<typename iterator>
        bidirectional_iterator(const iterator& it)
            : body(new implementation<iterator>(it))    {}

#ifdef _MSC_VER
        // MSVC can't use the above with pointer types
        bidirectional_iterator(value_type* it)
            : body(new implementation<value_type*>(it)) {}
#endif

        value_type& operator*() const           { return **body; }

        value_type* operator->() const          { return &**body; }

        bidirectional_iterator& operator++()    
            { body->increment(); return *this; }

        bidirectional_iterator operator++(int)
            { bidirectional_iterator r(*this); return ++r; }

        bidirectional_iterator& operator--()
            { body->decrement(); return *this; }

        bidirectional_iterator operator--(int)
            { bidirectional_iterator r(*this); return --r; }

        bool equals(const bidirectional_iterator& rhs) const
            { return body->equals(*rhs.body); }


    private:
#ifndef ARG_COMPILER_NO_COVARIENT_RETURNS            
        friend forward_iterator<value_type>;
#endif
        
        typedef iterator_body::bidirectional<value_type> body_type;

        body_part_ptr<body_type> body;

        template<typename iterator>
        struct implementation : body_type
        {
            implementation(iterator it) : i(it)     {}
            virtual ~implementation()               {}

#ifndef ARG_COMPILER_NO_COVARIENT_RETURNS            
            virtual implementation* clone() const
#else
            virtual body_type* clone() const
#endif
                { return new implementation(*this); }
            
            virtual value_type& operator*() const   { return *i; }
            virtual void increment()                { ++i; }
            virtual void decrement()                { --i; }
            virtual bool equals(const body_type& rhs) const
                { return i == static_cast<const implementation&>(rhs).i; }
            
            iterator i;
        };
    };

    template<typename value_type>
    inline bool operator==(
        const bidirectional_iterator<value_type>& lhs,
        const bidirectional_iterator<value_type>& rhs)
    {
        return lhs.equals(rhs);
    }

    template<typename value_type>
    inline bool operator!=(
        const bidirectional_iterator<value_type>& lhs,
        const bidirectional_iterator<value_type>& rhs)
    {
        return !lhs.equals(rhs);
    }
}
#endif

Copyright 1999-2000 Alan Griffiths