// Revision: 19 1.24.1.4 source/core/text/itext/itxtiter.hpp, text, ioc.v400, 980918 
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//      ITxtIter.hpp    (ITextIterators.h)
//
//  Contains various classes for iterating through the characters in an IText.
//      ICharacterReference                             - A proxy class that lets the user change characters in a safe way
//      ITextIterator                                   - Allows sequential access to the characters in an IText
//      IConstTextIterator                              - Allows sequential read-only access to the characters in an IText
//      IReverseTextIterator                    - An ITextIterator that moves backwards
//      IReverseConstTextIterator               - An IConstTextIterator that moves backwards
//      IFastTextIterator                               - A special iterator that is designed to be fast and doesn't have all
//                                                                              the safety precautions in it that ITextIterator has.
//
//              IBM Open Class Library
//              (C) Copyright International Business Machines Corporation 1997
//              Licensed Material - Program-Property of IBM - All Rights Reserved.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#ifndef _ITXTITER_
#define _ITXTITER_

#include <iprimtyp.hpp>

#include <stddef.h>

#if __IBMCPP__ >= 400
#pragma namemangling(compat)
#endif

class IText;

#pragma pack(push,4)

//========================================================================================
// CLASS ICharacterReference
// Proxy class for accessing characters safely.
//========================================================================================

class ICharacterReference {
        public:
                                                                ~ICharacterReference();

                ICharacterReference&    operator=(UniChar       newChar);
                ICharacterReference&    operator=(const ICharacterReference&    that);

                                                                operator UniChar() const;

                IText*                                  text() const;   // DEPRECATED!
                size_t                                  offset() const; // DEPRECATED!

                                                                ICharacterReference(const ICharacterReference&  that);

        private:
                                                                ICharacterReference(    UniChar*        theChar);

                                                                ICharacterReference(    IText*  text,
                                                                                                                size_t  offset);

                                                                ICharacterReference();

                UniChar                                 dereference() const;

                union {
                        UniChar*                                fChar;
                        IText*                                  fText;
                };
                size_t                                  fOffset;

                friend class IText;
                friend class ITextIterator;
};

//========================================================================================
// CLASS ITextIterator
// Forward iterator for IText.
//========================================================================================

class ITextIterator {
        public:
                                                                ITextIterator();
                                                                ITextIterator(const ITextIterator&      that);
                                                                ~ITextIterator();

                ITextIterator&                  operator=(const ITextIterator&  that);

                bool                                    operator==(const ITextIterator& that) const;
                bool                                    operator!=(const ITextIterator& that) const;

                bool                                    operator>(const ITextIterator&  that) const;
                bool                                    operator<(const ITextIterator&  that) const;
                bool                                    operator>=(const ITextIterator& that) const;
                bool                                    operator<=(const ITextIterator& that) const;

                ICharacterReference             operator[](long offset) const;
                ICharacterReference             operator*() const;

                ITextIterator&                  operator++();
                ITextIterator                   operator++(int);
                ITextIterator&                  operator--();
                ITextIterator                   operator--(int);

                ITextIterator&                  operator+=(long         distance);
                ITextIterator&                  operator-=(long         distance);

                ITextIterator                   operator-(long          distance) const;
                long                                    operator-(const ITextIterator&  that) const;

                IText*                                  text() const;
                size_t                                  offset() const;

        private:
                                                                ITextIterator(  IText*  theText,
                                                                                                size_t  theOffset);
                void                                    throwException() const;

                IText*                                  fText;
                size_t                                  fOffset;

                friend class IText;
                friend class IConstTextIterator;
};

//========================================================================================
// NON-MEMBER FUNCTIONS ON ITextIterator
//========================================================================================

ITextIterator   operator+(      const ITextIterator&    iterator,
                                                        long                                    offset);
ITextIterator   operator+(      long                                    offset,
                                                        const ITextIterator&    iterator);

UniChar*        value_type(const ITextIterator&);
long    distance_type(const ITextIterator&);

//random_access_iterator_tag    iterator_category(const ITextIterator&);

//========================================================================================
// CLASS IConstTextIterator
// Forward iterator for const IText.
//========================================================================================

class IConstTextIterator {
        public:
                                                                IConstTextIterator();
                                                                IConstTextIterator(const IConstTextIterator&    that);
                                                                ~IConstTextIterator();

                IConstTextIterator&             operator=(const IConstTextIterator&     that);

                                                                operator ITextIterator() const;

                bool                                    operator==(const IConstTextIterator&    that) const;
                bool                                    operator!=(const IConstTextIterator&    that) const;

                bool                                    operator>(const IConstTextIterator&     that) const;
                bool                                    operator<(const IConstTextIterator&     that) const;
                bool                                    operator>=(const IConstTextIterator&    that) const;
                bool                                    operator<=(const IConstTextIterator&    that) const;

                UniChar                                 operator[](long offset) const;
                UniChar                                 operator*() const;

                IConstTextIterator&             operator++();
                IConstTextIterator              operator++(int);
                IConstTextIterator&             operator--();
                IConstTextIterator              operator--(int);

                IConstTextIterator&             operator+=(long         distance);
                IConstTextIterator&             operator-=(long         distance);

                IConstTextIterator              operator-(long          distance) const;
                long                                    operator-(const IConstTextIterator&     that) const;

                const IText*                    text() const;
                size_t                                  offset() const;

        private:
                                                                IConstTextIterator(     const IText*    theText,
                                                                                                        size_t                  theOffset);
                void                                    throwException() const;

                const IText*                    fText;
                size_t                                  fOffset;

                friend class IText;
};

//========================================================================================
// NON-MEMBER FUNCTIONS ON IConstTextIterator
//========================================================================================

IConstTextIterator      operator+(      const IConstTextIterator&       iterator,
                                                                long                                    offset);
IConstTextIterator      operator+(      long                                    offset,
                                                                const IConstTextIterator&       iterator);

UniChar*        value_type(const IConstTextIterator&);
long    distance_type(const IConstTextIterator&);

//random_access_iterator_tag    iterator_category(const IConstTextIterator&);

//========================================================================================
// CLASS IReverseIterator
// A template class that wraps some other type of (bidirectional)
// iterator and causes it to iterate backwards  [i.e., calling ++ on the reverse iterator
// causes it to call -- on the iterator it wraps].
//
// THIS CLASS IS NOT PART OF THE OPEN CLASS API!  It is only here until we have the ANSI standard C++
// library at our disposal.  Then we will get rid of this class and use the standard
// reverse_iterator class instead.
//========================================================================================

template <class ARealIterator, class AReturnType>
class IReverseIterator {
        public:
                                                                IReverseIterator();
                                                                IReverseIterator(const ARealIterator&   theRealIterator);
                                                                IReverseIterator(const IReverseIterator<ARealIterator, AReturnType>&    that);
                                                                ~IReverseIterator();

                IReverseIterator<ARealIterator, AReturnType>&
                                                                operator=(const IReverseIterator<ARealIterator, AReturnType>&   that);

                                                                operator ARealIterator() const;

                bool                                    operator==(const IReverseIterator<ARealIterator, AReturnType>&  that) const;
                bool                                    operator!=(const IReverseIterator<ARealIterator, AReturnType>&  that) const;

                bool                                    operator>(const IReverseIterator<ARealIterator, AReturnType>&   that) const;
                bool                                    operator<(const IReverseIterator<ARealIterator, AReturnType>&   that) const;
                bool                                    operator>=(const IReverseIterator<ARealIterator, AReturnType>&  that) const;
                bool                                    operator<=(const IReverseIterator<ARealIterator, AReturnType>&  that) const;

                AReturnType                             operator[](long offset) const;
                AReturnType                             operator*() const;

                IReverseIterator<ARealIterator, AReturnType>&
                                                                operator++();
                IReverseIterator<ARealIterator, AReturnType>
                                                                operator++(int);
                IReverseIterator<ARealIterator, AReturnType>&
                                                                operator--();
                IReverseIterator<ARealIterator, AReturnType>
                                                                operator--(int);

                IReverseIterator<ARealIterator, AReturnType>&
                                                                operator+=(long         distance);
                IReverseIterator<ARealIterator, AReturnType>&
                                                                operator-=(long         distance);

                IReverseIterator<ARealIterator, AReturnType>
                                                                operator-(long          distance) const;
                long                                    operator-(const IReverseIterator<ARealIterator, AReturnType>&   that) const;

        private:
                ARealIterator                   fRealIterator;
};

//========================================================================================
// NON-MEMBER FUNCTIONS ON IReverseIterator<ARealIterator, AReturnType>
//========================================================================================

template <class ARealIterator, class AReturnType>
IReverseIterator<ARealIterator, AReturnType>
                                operator+(      const IReverseIterator<ARealIterator, AReturnType>&     iterator,
                                                        long                                                                                            offset);

template <class ARealIterator, class AReturnType>
IReverseIterator<ARealIterator, AReturnType>
                                operator+(      long                                                                                            offset,
                                                        const IReverseIterator<ARealIterator, AReturnType>&     iterator);

template <class ARealIterator, class AReturnType>
UniChar*        value_type(const IReverseIterator<ARealIterator, AReturnType>&);

template <class ARealIterator, class AReturnType>
long    distance_type(const IReverseIterator<ARealIterator, AReturnType>&);

// template <class ARealIterator, class AReturnType>
// random_access_iterator_tag   iterator_category(const IReverseIterator<ARealIterator, AReturnType>&);

//========================================================================================
// TYPEDEFS for the iterator types
//========================================================================================

typedef IReverseIterator<ITextIterator, ICharacterReference>    IReverseTextIterator;
typedef IReverseIterator<IConstTextIterator, UniChar>   IReverseConstTextIterator;

//========================================================================================
// TEMPLATE SPECIALIZATIONS
//========================================================================================
// The + operators defined below for IReverseTextIterator and IReverseConstTextIterator
// are intended to be explicit specializations of the template + operators defined above
// for all instantiations of IReverseIterator.  For some reason, without these functions,
// the templates never get instantiated and the user-defined conversions to the underlying
// type get called instead, followed by the underlying type's + operator (which moves us
// in the wrong direction).

IReverseTextIterator    operator+(      const IReverseTextIterator&     iterator,
                                                                        long                                            offset);

IReverseTextIterator    operator+(      long                                            offset,
                                                                        const IReverseTextIterator&     iterator);

IReverseConstTextIterator       operator+(      const IReverseConstTextIterator&        iterator,
                                                                                long                                                            offset);

IReverseConstTextIterator       operator+(      long                                                            offset,
                                                                                const IReverseConstTextIterator&        iterator);

//========================================================================================
// CLASS IFastTextIterator
//      High-performance forward iterator for IText.
//========================================================================================
class IFastTextIterator {
        public:
                                                                IFastTextIterator();
                                                                IFastTextIterator(const IFastTextIterator&      that);
                                                                IFastTextIterator(      const ITextIterator&    that,
                                                                                                        bool                                    willWrite = true);
                                                                IFastTextIterator(      const IConstTextIterator&       that,
                                                                                                        bool                                    willWrite = true);
                                                                ~IFastTextIterator();

                IFastTextIterator&              operator=(const IFastTextIterator&      that);

                bool                                    operator==(const IFastTextIterator&     that) const;
                bool                                    operator!=(const IFastTextIterator&     that) const;

                bool                                    operator>(const IFastTextIterator&      that) const;
                bool                                    operator<(const IFastTextIterator&      that) const;
                bool                                    operator>=(const IFastTextIterator&     that) const;
                bool                                    operator<=(const IFastTextIterator&     that) const;

                UniChar&                                operator[](long offset) const;
                UniChar&                                operator*() const;

                IFastTextIterator&              operator++();
                IFastTextIterator               operator++(int);
                IFastTextIterator&              operator--();
                IFastTextIterator               operator--(int);

                IFastTextIterator&              operator+=(long         distance);
                IFastTextIterator&              operator-=(long         distance);

                IFastTextIterator               operator-(long          distance) const;
                long                                    operator-(const IFastTextIterator&      that) const;

        private:
                                                                IFastTextIterator(      UniChar*        theChar,
                                                                                                        UniChar*        gapStart,
                                                                                                        size_t          gapLength);

                UniChar*                                fChar;
                UniChar*                                fGapStart;
                size_t                                  fGapLength;

                friend class ITextStorage;
};

#pragma pack(pop)

//========================================================================================
// NON-MEMBER FUNCTIONS ON IFastTextIterator
//========================================================================================

IFastTextIterator       operator+(      const IFastTextIterator&        iterator,
                                                                long                                            offset);
IFastTextIterator       operator+(      long                                            offset,
                                                                const IFastTextIterator&        iterator);

UniChar*        value_type(const IFastTextIterator&);
long    distance_type(const IFastTextIterator&);

#if __IBMCPP__ >= 400
#pragma namemangling()
#endif

//random_access_iterator_tag    iterator_category(const IFastTextIterator&);

#include <itxtiter.inl>

#endif // _ITXTITER_
