#ifndef INCLUDED_BOBCAT_ITERATOR_
#define INCLUDED_BOBCAT_ITERATOR_

#include <iterator>
#include <limits>
#include <memory>

namespace FBB
{

template <typename Type>
class Iterator;

template <typename Type>
struct ReverseIterator: public std::reverse_iterator<Iterator<Type>>
{
    explicit ReverseIterator(Type const &value);
    explicit ReverseIterator(Iterator<Type> const &iter);

    static ReverseIterator<Type> last(Type const &value);
};

template <typename Type>
bool operator==(Iterator<Type> const &lhs, Iterator<Type> const &rhs);

template <typename Type>
class Iterator: public std::iterator<std::input_iterator_tag, Type const>
{
    friend  bool operator==<>(Iterator<Type> const &lhs, 
                            Iterator<Type> const &rhs);

    Type d_value;
    std::shared_ptr<Type> d_type;

    public:
        Iterator() = default;
        explicit Iterator(Type const &value);
    
        Iterator<Type> &operator++();
        Iterator<Type> operator++(int);
    
        Type const &operator*() const;

        static Iterator<Type> last(Type value);
        static Iterator<Type> min();
        static Iterator<Type> max();

    private:
        friend struct std::reverse_iterator<Iterator<Type>>;

        Iterator<Type> &operator--();
        Iterator<Type> operator--(int);
};


#include "iterator1.f"
#include "last.f"
#include "max.f"
#include "min.f"
#include "operatordec.f"
#include "operatorequal.f"
#include "operatorinc.f"
#include "operatorpostdec.f"
#include "operatorpostinc.f"
#include "operatorstarconst.f"
#include "operatorunequal.f"
#include "reverseiterator1.f"
#include "reverseiterator2.f"
#include "reverseiteratorlast.f"

} // FBB

#endif






