Итератор по набору std контейнеров
От: Vain Россия google.ru
Дата: 14.05.10 18:23
Оценка:
Во таконец решил допелить свой итератор до потребного уровня.
Итератор предназначен для итерации по std совместимым контейнерам в обе стороны.
Исходная тема была здесь
Автор: Vain
Дата: 09.12.09
.

Пример использования:
struct A
{
    int i;

    A(int i_)
    {
        i = i_;
    }
};

typedef std::vector<int> my_cont_1;
typedef std::vector<A> my_cont_2;
typedef std::list<int> my_cont_3;
//typedef std::set<int> my_cont_4;

typedef Fx::compatible_const_iterator<my_cont_1,my_cont_2,my_cont_3> my_compatible_it;  //compatible iterator - can treats up to 4 iterators of different compatible standard containers as one iterator.
typedef Fx::compatible_const_iterator_path<my_cont_1,my_cont_2,my_cont_3> my_compatible_const_it_path; //iterator path - stores a set of iteratable containers by set of compatible iterators.
typedef Fx::compatible_path_const_iterator<my_cont_1,my_cont_2,my_cont_3> my_compatible_path_const_it; //path iterator - iterates over "iterator path".

const int* getIteratorData(const my_compatible_it& it)
{
    if(it.done())
    {
        return 0;
    }

    if(it.typeIndex() == 0)
    {
        return &*it.get0();
    }
    else if(it.typeIndex() == 1)
    {
        return &it.get1()->i;
    }
    else if(it.typeIndex() == 2)
    {
        return &*it.get2();
    }
    else
    {
        assert(0);
    }

    return 0;
}

void iteratePathForward(const my_compatible_const_it_path& itPath)
{
    printf("Iterating forward:\n");

    int i = 0;

    my_compatible_path_const_it pathIt;
    for(pathIt.set(true,itPath); !pathIt.done(); pathIt.step(true), i++)
    {
        const int* data = getIteratorData(pathIt.get());
        if(data)
        {
            printf("i = %i\n",*data);
        }
    }
}

void iteratePathBackward(const my_compatible_const_it_path& itPath)
{
    printf("Iterating backward:\n");

    int i = 0;

    my_compatible_path_const_it pathIt;
    for(pathIt.set(false,itPath); !pathIt.done(); pathIt.step(false), i++)
    {
        const int* data = getIteratorData(pathIt.get());
        if(data)
        {
            printf("i = %i\n",*data);
        }
    }
}

int main()
{
    my_cont_1 cont1;
    cont1.push_back(1);
    cont1.push_back(2);
    cont1.push_back(3);

    my_cont_2 cont2;
    cont2.push_back(A(4));
    cont2.push_back(A(5));

    my_cont_3 cont3;
    cont3.push_back(6);
    cont3.push_back(7);
    cont3.push_back(8);

    my_compatible_const_it_path itPath;
    itPath.resize(3);
    {
        itPath[0] = &cont1;
        itPath[1] = &cont2;
        itPath[2] = &cont3;
    }

    iteratePathForward(itPath);

    iteratePathBackward(itPath);

    return 0;
}


Выводит:
Iterating forward:
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
Iterating backward:
i = 8
i = 7
i = 6
i = 5
i = 4
i = 3
i = 2
i = 1


Код:
#include <assert.h>
#include <stdio.h>

#include <vector>
#include <list>
#include <utility>

#include <boost/aligned_storage.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/utility/addressof.hpp>

namespace Fx
{
    //global_construct_storage
    template<class AS,class T>
    void global_construct_storage(T& storage)
    {
        ::new (reinterpret_cast<AS*>(boost::addressof(storage))) AS;
    }

    template<class AS,class T,class P1>
    void global_construct_storage(T& storage,const P1& p1)
    {
        ::new (reinterpret_cast<AS*>(boost::addressof(storage))) AS(p1);
    }

    //destruct_storage
    template<class AS,class T>
    void destruct_storage(T& storage)
    {
        reinterpret_cast<AS*>(boost::addressof(storage))->AS::~AS();
    }
}

namespace Fx
{
    class VoidType2
    {
    public:
        class iterator
        {
        public:
            bool operator ==(const iterator&) const { return true; }
            bool operator !=(const iterator&) const { return true; }
            iterator operator ++() { return iterator(); }
            iterator operator --() { return iterator(); }
            iterator operator ++(int) const { return iterator(); }
            iterator operator --(int) const { return iterator(); }
        };
        class const_iterator
        {
        public:
            bool operator ==(const const_iterator&) const { return true; }
            bool operator !=(const const_iterator&) const { return true; }
            const_iterator operator ++() { return const_iterator(); }
            const_iterator operator --() { return const_iterator(); }
            const_iterator operator ++(int) const { return const_iterator(); }
            const_iterator operator --(int) const { return const_iterator(); }
        };
        class reverse_iterator
        {
        public:
            bool operator ==(const reverse_iterator&) const { return true; }
            bool operator !=(const reverse_iterator&) const { return true; }
            reverse_iterator operator ++() { return reverse_iterator(); }
            reverse_iterator operator --() { return reverse_iterator(); }
            reverse_iterator operator ++(int) const { return reverse_iterator(); }
            reverse_iterator operator --(int) const { return reverse_iterator(); }
            iterator base() const { return iterator(); }
        };
        class const_reverse_iterator
        {
        public:
            bool operator ==(const const_reverse_iterator&) const { return true; }
            bool operator !=(const const_reverse_iterator&) const { return true; }
            const_reverse_iterator operator ++() { return const_reverse_iterator(); }
            const_reverse_iterator operator --() { return const_reverse_iterator(); }
            const_reverse_iterator operator ++(int) const { return const_reverse_iterator(); }
            const_reverse_iterator operator --(int) const { return const_reverse_iterator(); }
            const_iterator base() const { return const_iterator(); }
        };
        class value_type {};

        iterator begin() { return iterator(); };
        const_iterator begin() const { return const_iterator(); };
        reverse_iterator rbegin() { return reverse_iterator(); };
        const_reverse_iterator rbegin() const { return const_reverse_iterator(); };

        iterator end() { return iterator(); };
        const_iterator end() const { return const_iterator(); };
        reverse_iterator rend() { return reverse_iterator(); };
        const_reverse_iterator rend() const { return const_reverse_iterator(); };
    };

    class VoidType3
    {
    public:
        class iterator
        {
        public:
            bool operator ==(const iterator&) const { return true; }
            bool operator !=(const iterator&) const { return true; }
            iterator operator ++() { return iterator(); }
            iterator operator --() { return iterator(); }
            iterator operator ++(int) const { return iterator(); }
            iterator operator --(int) const { return iterator(); }
        };
        class const_iterator
        {
        public:
            bool operator ==(const const_iterator&) const { return true; }
            bool operator !=(const const_iterator&) const { return true; }
            const_iterator operator ++() { return const_iterator(); }
            const_iterator operator --() { return const_iterator(); }
            const_iterator operator ++(int) const { return const_iterator(); }
            const_iterator operator --(int) const { return const_iterator(); }
        };
        class reverse_iterator
        {
        public:
            bool operator ==(const reverse_iterator&) const { return true; }
            bool operator !=(const reverse_iterator&) const { return true; }
            reverse_iterator operator ++() { return reverse_iterator(); }
            reverse_iterator operator --() { return reverse_iterator(); }
            reverse_iterator operator ++(int) const { return reverse_iterator(); }
            reverse_iterator operator --(int) const { return reverse_iterator(); }
            iterator base() const { return iterator(); }
        };
        class const_reverse_iterator
        {
        public:
            bool operator ==(const const_reverse_iterator&) const { return true; }
            bool operator !=(const const_reverse_iterator&) const { return true; }
            const_reverse_iterator operator ++() { return const_reverse_iterator(); }
            const_reverse_iterator operator --() { return const_reverse_iterator(); }
            const_reverse_iterator operator ++(int) const { return const_reverse_iterator(); }
            const_reverse_iterator operator --(int) const { return const_reverse_iterator(); }
            const_iterator base() const { return const_iterator(); }
        };
        class value_type {};

        iterator begin() { return iterator(); };
        const_iterator begin() const { return const_iterator(); };
        reverse_iterator rbegin() { return reverse_iterator(); };
        const_reverse_iterator rbegin() const { return const_reverse_iterator(); };

        iterator end() { return iterator(); };
        const_iterator end() const { return const_iterator(); };
        reverse_iterator rend() { return reverse_iterator(); };
        const_reverse_iterator rend() const { return const_reverse_iterator(); };
    };

    class VoidType4
    {
    public:
        class iterator
        {
        public:
            bool operator ==(const iterator&) const { return true; }
            bool operator !=(const iterator&) const { return true; }
            iterator operator ++() { return iterator(); }
            iterator operator --() { return iterator(); }
            iterator operator ++(int) const { return iterator(); }
            iterator operator --(int) const { return iterator(); }
        };
        class const_iterator
        {
        public:
            bool operator ==(const const_iterator&) const { return true; }
            bool operator !=(const const_iterator&) const { return true; }
            const_iterator operator ++() { return const_iterator(); }
            const_iterator operator --() { return const_iterator(); }
            const_iterator operator ++(int) const { return const_iterator(); }
            const_iterator operator --(int) const { return const_iterator(); }
        };
        class reverse_iterator
        {
        public:
            bool operator ==(const reverse_iterator&) const { return true; }
            bool operator !=(const reverse_iterator&) const { return true; }
            reverse_iterator operator ++() { return reverse_iterator(); }
            reverse_iterator operator --() { return reverse_iterator(); }
            reverse_iterator operator ++(int) const { return reverse_iterator(); }
            reverse_iterator operator --(int) const { return reverse_iterator(); }
            iterator base() const { return iterator(); }
        };
        class const_reverse_iterator
        {
        public:
            bool operator ==(const const_reverse_iterator&) const { return true; }
            bool operator !=(const const_reverse_iterator&) const { return true; }
            const_reverse_iterator operator ++() { return const_reverse_iterator(); }
            const_reverse_iterator operator --() { return const_reverse_iterator(); }
            const_reverse_iterator operator ++(int) const { return const_reverse_iterator(); }
            const_reverse_iterator operator --(int) const { return const_reverse_iterator(); }
            const_iterator base() const { return const_iterator(); }
        };
        class value_type {};

        iterator begin() { return iterator(); };
        const_iterator begin() const { return const_iterator(); };
        reverse_iterator rbegin() { return reverse_iterator(); };
        const_reverse_iterator rbegin() const { return const_reverse_iterator(); };

        iterator end() { return iterator(); };
        const_iterator end() const { return const_iterator(); };
        reverse_iterator rend() { return reverse_iterator(); };
        const_reverse_iterator rend() const { return const_reverse_iterator(); };
    };

    template<bool b,int i1,int i2>
    class int_if
    {
    public:
        enum { value = i1 };
    };

    template<int i1,int i2>
    class int_if<false,i1,i2>
    {
    public:
        enum { value = i2 };
    };

    template<int i1,int i2,int i3,int i4>
    class int_max
    {
    protected:
        enum
        {
            is_i1_less = (i1 < i2 ? 1 : 0),
            is_i3_less = (i3 < i4 ? 1 : 0),
            max_i12 = int_if<is_i1_less,i2,i1>::value,
            max_i34 = int_if<is_i3_less,i4,i3>::value,
            is_max_i12_less = (max_i12 < max_i34 ? 1 : 0)
        };

    public:
        enum { value = int_if<is_max_i12_less,max_i34,max_i12>::value };
    };

    template<int i1,int i2>
    class int_max<i1,i2,-1,-1>
    {
    protected:
        enum
        {
            is_i1_less = (i1 < i2 ? 1 : 0)
        };

    public:
        enum { value = int_if<is_i1_less,i2,i1>::value };
    };

    template<int i1,int i2,int i3>
    class int_max<i1,i2,i3,-1>
    {
    protected:
        enum
        {
            is_i1_less = (i1 < i2 ? 1 : 0),
            max_i12 = int_if<is_i1_less,i2,i1>::value,
            is_max_i12_less = (max_i12 < i3 ? 1 : 0)
        };

    public:
        enum { value = int_if<is_max_i12_less,i3,max_i12>::value };
    };

    //Wrapper around boost aligned storage to disable all unspecified behaviour and
    //implement specific copy-constructor.
    class constructed_storage {};

    template<std::size_t S,std::size_t A>
    class aligned_storage
    {
    public:
        boost::aligned_storage<S,A> storage;

        aligned_storage()
        {
        }

        aligned_storage(const constructed_storage&) //Specific constructor.
        {
        }

    private:
        aligned_storage(const aligned_storage& storage_);
        const aligned_storage& operator =(const aligned_storage& storage_);
    };

    template<class C1,class C2 = VoidType2,class C3 = VoidType3,class C4 = VoidType4>
    class compatible_iterator_path_node;

    template<class C1,class C2 = VoidType2,class C3 = VoidType3,class C4 = VoidType4>
    class compatible_const_iterator_path_node;

    //Iterator which have method "done", instead of comparison on end iterator for
    //cases where target iterator and end iterator could points to different objects of
    //different standard compatible containers. Designed for up to 4 different containers.
    template<class C1,class C2 = VoidType2,class C3 = VoidType3,class C4 = VoidType4>
    class compatible_iterator
    {
    public:
        typedef typename C1::iterator C1_iterator;
        typedef typename C2::iterator C2_iterator;
        typedef typename C3::iterator C3_iterator;
        typedef typename C4::iterator C4_iterator;

        typedef typename C1::iterator C1_forward_iterator;
        typedef typename C2::iterator C2_forward_iterator;
        typedef typename C3::iterator C3_forward_iterator;
        typedef typename C4::iterator C4_forward_iterator;

        typedef typename C1::reverse_iterator C1_backward_iterator;
        typedef typename C2::reverse_iterator C2_backward_iterator;
        typedef typename C3::reverse_iterator C3_backward_iterator;
        typedef typename C4::reverse_iterator C4_backward_iterator;

    protected:
        enum
        {
            it_sizeof_C1 = sizeof(C1_iterator),
            it_sizeof_C2 = sizeof(C2_iterator),
            it_sizeof_C3 = sizeof(C3_iterator),
            it_sizeof_C4 = sizeof(C4_iterator),
            it_sizeof_max = int_max<it_sizeof_C1,it_sizeof_C2,it_sizeof_C3,it_sizeof_C4>::value
        };

        enum
        {
            it_alignof_C1 = boost::alignment_of<C1_iterator>::value,
            it_alignof_C2 = boost::alignment_of<C2_iterator>::value,
            it_alignof_C3 = boost::alignment_of<C3_iterator>::value,
            it_alignof_C4 = boost::alignment_of<C4_iterator>::value,
            it_alignof_max = int_max<it_alignof_C1,it_alignof_C2,it_alignof_C3,it_alignof_C4>::value
        };

        typedef aligned_storage<it_sizeof_max,it_alignof_max> aligned_storage_iterator_type;

    protected:
        aligned_storage_iterator_type m_itStorage;  //Deferred iterator.
        int                           m_itType;     //Deferred iterator target type.
        void*                         m_itCont;     //Deferred iterator container.
        bool                          m_asForward;

    protected:
        constructed_storage ConstructStorage(const compatible_iterator& it);
        constructed_storage ConstructStorage(const C1_iterator& it,bool asDefault);
        constructed_storage ConstructStorage(const C2_iterator& it,bool asDefault);
        constructed_storage ConstructStorage(const C3_iterator& it,bool asDefault);
        constructed_storage ConstructStorage(const C4_iterator& it,bool asDefault);
        void DestructStorage(aligned_storage_iterator_type& storage,int as);

        C1_iterator& CastStorageToRef0();
        C2_iterator& CastStorageToRef1();
        C3_iterator& CastStorageToRef2();
        C4_iterator& CastStorageToRef3();

        C1_iterator CastStorageTo0() const;
        C2_iterator CastStorageTo1() const;
        C3_iterator CastStorageTo2() const;
        C4_iterator CastStorageTo3() const;

    public:
        compatible_iterator();
        compatible_iterator(const compatible_iterator& it);
        compatible_iterator(const C1_iterator& it,C1* itCont);
        compatible_iterator(const C2_iterator& it,C2* itCont);
        compatible_iterator(const C3_iterator& it,C3* itCont);
        compatible_iterator(const C4_iterator& it,C4* itCont);
        ~compatible_iterator();

        const compatible_iterator& operator =(const compatible_iterator& it);

        int typeIndex() const;
        compatible_iterator_path_node<C1,C2,C3,C4> pathNode() const;

        C1_iterator get0() const;
        C2_iterator get1() const;
        C3_iterator get2() const;
        C4_iterator get3() const;

        void start(bool forward);
        void start(bool forward,C1* itCont);
        void start(bool forward,C2* itCont);
        void start(bool forward,C3* itCont);
        void start(bool forward,C4* itCont);
        bool done() const;
        void step(bool forward);
        bool isForward() const;

        void set(const compatible_iterator& it);
        void set(const C1_iterator& it,C1* itCont);
        void set(const C2_iterator& it,C2* itCont);
        void set(const C3_iterator& it,C3* itCont);
        void set(const C4_iterator& it,C4* itCont);
        void set(bool forward,const compatible_iterator_path_node<C1,C2,C3,C4>& itPathNode);
        void clear();
    };

    template<class C1,class C2 = VoidType2,class C3 = VoidType3,class C4 = VoidType4>
    class compatible_const_iterator
    {
        friend class compatible_iterator<C1,C2,C3,C4>;

    public:
        typedef typename C1::const_iterator C1_const_iterator;
        typedef typename C2::const_iterator C2_const_iterator;
        typedef typename C3::const_iterator C3_const_iterator;
        typedef typename C4::const_iterator C4_const_iterator;

        typedef typename C1::const_iterator C1_const_forward_iterator;
        typedef typename C2::const_iterator C2_const_forward_iterator;
        typedef typename C3::const_iterator C3_const_forward_iterator;
        typedef typename C4::const_iterator C4_const_forward_iterator;

        typedef typename C1::const_reverse_iterator C1_const_backward_iterator;
        typedef typename C2::const_reverse_iterator C2_const_backward_iterator;
        typedef typename C3::const_reverse_iterator C3_const_backward_iterator;
        typedef typename C4::const_reverse_iterator C4_const_backward_iterator;

    protected:
        enum
        {
            it_sizeof_C1 = sizeof(C1_const_iterator),
            it_sizeof_C2 = sizeof(C2_const_iterator),
            it_sizeof_C3 = sizeof(C3_const_iterator),
            it_sizeof_C4 = sizeof(C4_const_iterator),
            it_sizeof_max = int_max<it_sizeof_C1,it_sizeof_C2,it_sizeof_C3,it_sizeof_C4>::value
        };

        enum
        {
            it_alignof_C1 = boost::alignment_of<C1_const_iterator>::value,
            it_alignof_C2 = boost::alignment_of<C2_const_iterator>::value,
            it_alignof_C3 = boost::alignment_of<C3_const_iterator>::value,
            it_alignof_C4 = boost::alignment_of<C4_const_iterator>::value,
            it_alignof_max = int_max<it_alignof_C1,it_alignof_C2,it_alignof_C3,it_alignof_C4>::value
        };

        typedef aligned_storage<it_sizeof_max,it_alignof_max> aligned_storage_iterator_type;

    protected:
        aligned_storage_iterator_type m_itStorage;  //Deferred iterator.
        int                           m_itType;     //Deferred iterator target type.
        const void*                   m_itCont;     //Deferred iterator container.
        bool                          m_asForward;

    protected:
        constructed_storage ConstructStorage(const compatible_const_iterator& it);
        constructed_storage ConstructStorage(const compatible_iterator<C1,C2,C3,C4>& it);
        constructed_storage ConstructStorage(const C1_const_iterator& it,bool asDefault);
        constructed_storage ConstructStorage(const C2_const_iterator& it,bool asDefault);
        constructed_storage ConstructStorage(const C3_const_iterator& it,bool asDefault);
        constructed_storage ConstructStorage(const C4_const_iterator& it,bool asDefault);
        void DestructStorage(aligned_storage_iterator_type& storage,int as);

        C1_const_iterator& CastStorageToRef0();
        C2_const_iterator& CastStorageToRef1();
        C3_const_iterator& CastStorageToRef2();
        C4_const_iterator& CastStorageToRef3();

        C1_const_iterator CastStorageTo0() const;
        C2_const_iterator CastStorageTo1() const;
        C3_const_iterator CastStorageTo2() const;
        C4_const_iterator CastStorageTo3() const;

    public:
        compatible_const_iterator();
        compatible_const_iterator(const compatible_const_iterator& it);
        compatible_const_iterator(const compatible_iterator<C1,C2,C3,C4>& it);
        compatible_const_iterator(const C1_const_iterator& it,const C1* itCont);
        compatible_const_iterator(const C2_const_iterator& it,const C2* itCont);
        compatible_const_iterator(const C3_const_iterator& it,const C3* itCont);
        compatible_const_iterator(const C4_const_iterator& it,const C4* itCont);
        ~compatible_const_iterator();

        const compatible_const_iterator& operator =(const compatible_const_iterator& it);
        const compatible_const_iterator& operator =(const compatible_iterator<C1,C2,C3,C4>& it);

        int typeIndex() const;
        compatible_const_iterator_path_node<C1,C2,C3,C4> pathNode() const;

        C1_const_iterator get0() const;
        C2_const_iterator get1() const;
        C3_const_iterator get2() const;
        C4_const_iterator get3() const;

        void start(bool forward);
        void start(bool forward,const C1* itCont);
        void start(bool forward,const C2* itCont);
        void start(bool forward,const C3* itCont);
        void start(bool forward,const C4* itCont);
        bool done() const;
        void step(bool forward);
        bool isForward() const;

        void set(const compatible_const_iterator& it);
        void set(const compatible_iterator<C1,C2,C3,C4>& it);
        void set(const C1_const_iterator& it,const C1* itCont);
        void set(const C2_const_iterator& it,const C2* itCont);
        void set(const C3_const_iterator& it,const C3* itCont);
        void set(const C4_const_iterator& it,const C4* itCont);
        void set(bool forward,const compatible_const_iterator_path_node<C1,C2,C3,C4>& itPathNode);
        void set(bool forward,const compatible_iterator_path_node<C1,C2,C3,C4>& itPathNode);

        void clear();
    };

    template<class C1,class C2,class C3,class C4>
    class compatible_iterator_path_node
    {
    protected:
        int   m_itType;
        void* m_itCont;

    public:
        compatible_iterator_path_node();
        compatible_iterator_path_node(C1* pCont);
        compatible_iterator_path_node(C2* pCont);
        compatible_iterator_path_node(C3* pCont);
        compatible_iterator_path_node(C4* pCont);

        const compatible_iterator_path_node& operator =(C1* pCont);
        const compatible_iterator_path_node& operator =(C2* pCont);
        const compatible_iterator_path_node& operator =(C3* pCont);
        const compatible_iterator_path_node& operator =(C4* pCont);

        int typeIndex() const;
        void* get() const;
        C1* get0() const;
        C2* get1() const;
        C3* get2() const;
        C4* get3() const;
    };

    template<class C1,class C2,class C3,class C4>
    class compatible_const_iterator_path_node
    {
    protected:
        int         m_itType;
        const void* m_itCont;

    public:
        compatible_const_iterator_path_node();
        compatible_const_iterator_path_node(const C1* pCont);
        compatible_const_iterator_path_node(const C2* pCont);
        compatible_const_iterator_path_node(const C3* pCont);
        compatible_const_iterator_path_node(const C4* pCont);

        const compatible_const_iterator_path_node& operator =(const C1* pCont);
        const compatible_const_iterator_path_node& operator =(const C2* pCont);
        const compatible_const_iterator_path_node& operator =(const C3* pCont);
        const compatible_const_iterator_path_node& operator =(const C4* pCont);

        int typeIndex() const;
        const void* get() const;
        const C1* get0() const;
        const C2* get1() const;
        const C3* get2() const;
        const C4* get3() const;
    };

    template<class C1,class C2 = VoidType2,class C3 = VoidType3,class C4 = VoidType4>
    class compatible_iterator_path
    {
    public:
        typedef compatible_iterator_path_node<C1,C2,C3,C4> path_node;

    protected:
        typedef typename std::vector<path_node> iterator_path;

    public:
        typedef typename std::vector<path_node>::size_type size_type;

    protected:
        iterator_path m_itPath;

    public:
        path_node& operator [](typename iterator_path::size_type index);
        const path_node& operator [](typename iterator_path::size_type index) const;

        void appendContainer(C1* itCont);
        void appendContainer(C2* itCont);
        void appendContainer(C3* itCont);
        void appendContainer(C4* itCont);

        typename iterator_path::size_type size() const;
        typename iterator_path::size_type capacity() const;
        void resize(typename iterator_path::size_type size);
        void reserve(typename iterator_path::size_type size);
        void clear();

        path_node& front();
        const path_node& front() const;
        path_node& back();
        const path_node& back() const;
    };

    template<class C1,class C2 = VoidType2,class C3 = VoidType3,class C4 = VoidType4>
    class compatible_const_iterator_path
    {
    public:
        typedef compatible_const_iterator_path_node<C1,C2,C3,C4> path_node;

    protected:
        typedef typename std::vector<path_node> iterator_path;

    public:
        typedef typename std::vector<path_node>::size_type size_type;

    protected:
        iterator_path m_itPath;

    public:
        path_node& operator [](typename iterator_path::size_type index);
        const path_node& operator [](typename iterator_path::size_type index) const;

        void appendContainer(const C1* itCont);
        void appendContainer(const C2* itCont);
        void appendContainer(const C3* itCont);
        void appendContainer(const C4* itCont);

        typename iterator_path::size_type size() const;
        typename iterator_path::size_type capacity() const;
        void resize(typename iterator_path::size_type size);
        void reserve(typename iterator_path::size_type size);
        void clear();

        path_node& front();
        const path_node& front() const;
        path_node& back();
        const path_node& back() const;
    };

    template<class C1,class C2 = VoidType2,class C3 = VoidType3,class C4 = VoidType4>
    class compatible_path_iterator
    {
    protected:
        typedef compatible_iterator<C1,C2,C3,C4> iterator;
        typedef compatible_iterator_path<C1,C2,C3,C4> iterator_path;
        typedef compatible_iterator_path_node<C1,C2,C3,C4> iterator_path_node;

    public:
        typedef typename iterator_path::size_type size_type;

    protected:
        iterator      m_it;
        const iterator_path* m_pItPath;
        size_type     m_itPathNodeIndex;
        bool          m_asForward;

    public:
        compatible_path_iterator();

        const iterator& get() const;

        void start(bool forward);
        bool done() const;
        void step(bool forward);
        void step();
        bool isForward() const;

        void seekBeginPathNode(bool forward);
        void seekEndPathNode(bool forward);

        void set(bool forward,const iterator_path& itPath);
        void clear();
    };

    template<class C1,class C2 = VoidType2,class C3 = VoidType3,class C4 = VoidType4>
    class compatible_path_const_iterator
    {
    protected:
        typedef compatible_const_iterator<C1,C2,C3,C4> iterator;
        typedef compatible_const_iterator_path<C1,C2,C3,C4> iterator_path;
        typedef compatible_const_iterator_path_node<C1,C2,C3,C4> iterator_path_node;

    public:
        typedef typename iterator_path::size_type size_type;

    protected:
        iterator      m_it;
        const iterator_path* m_pItPath;
        size_type     m_itPathNodeIndex;
        bool          m_asForward;

    public:
        compatible_path_const_iterator();

        const iterator& get() const;

        void start(bool forward);
        bool done() const;
        void step(bool forward);
        bool isForward() const;

        void seekBeginPathNode(bool forward);
        void seekEndPathNode(bool forward);

        void set(bool forward,const iterator_path& itPath);
        void clear();
    };

    //-------------------------------------------------------------------------

    //compatible_iterator
    template<class C1,class C2,class C3,class C4>
    constructed_storage compatible_iterator<C1,C2,C3,C4>::ConstructStorage(const compatible_iterator& it)
    {
        switch(it.m_itType)
        {
            case 0:
            {
                return ConstructStorage(it.CastStorageTo0(),false);
            }
            break;

            case 1:
            {
                return ConstructStorage(it.CastStorageTo1(),false);
            }
            break;

            case 2:
            {
                return ConstructStorage(it.CastStorageTo2(),false);
            }
            break;

            case 3:
            {
                return ConstructStorage(it.CastStorageTo3(),false);
            }
            break;

            default:
                assert(0);
        }

        return constructed_storage();
    }

    template<class C1,class C2,class C3,class C4>
    constructed_storage compatible_iterator<C1,C2,C3,C4>::ConstructStorage(const typename C1::iterator& it,bool asDefault)
    {
        if(asDefault)
        {
            Fx::global_construct_storage<typename C1::iterator>(m_itStorage);
        }
        else
        {
            Fx::global_construct_storage<typename C1::iterator>(m_itStorage,it);
        }

        return constructed_storage();
    }

    template<class C1,class C2,class C3,class C4>
    constructed_storage compatible_iterator<C1,C2,C3,C4>::ConstructStorage(const typename C2::iterator& it,bool asDefault)
    {
        if(asDefault)
        {
            Fx::global_construct_storage<typename C2::iterator>(m_itStorage);
        }
        else
        {
            Fx::global_construct_storage<typename C2::iterator>(m_itStorage,it);
        }

        return constructed_storage();
    }

    template<class C1,class C2,class C3,class C4>
    constructed_storage compatible_iterator<C1,C2,C3,C4>::ConstructStorage(const typename C3::iterator& it,bool asDefault)
    {
        if(asDefault)
        {
            Fx::global_construct_storage<typename C3::iterator>(m_itStorage);
        }
        else
        {
            Fx::global_construct_storage<typename C3::iterator>(m_itStorage,it);
        }

        return constructed_storage();
    }

    template<class C1,class C2,class C3,class C4>
    constructed_storage compatible_iterator<C1,C2,C3,C4>::ConstructStorage(const typename C4::iterator& it,bool asDefault)
    {
        if(asDefault)
        {
            Fx::global_construct_storage<typename C4::iterator>(m_itStorage);
        }
        else
        {
            Fx::global_construct_storage<typename C4::iterator>(m_itStorage,it);
        }

        return constructed_storage();
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator<C1,C2,C3,C4>::DestructStorage(typename compatible_iterator<C1,C2,C3,C4>::aligned_storage_iterator_type& storage,int as)
    {
        switch(as)
        {
            case 0:
            {
                Fx::destruct_storage<typename C1::iterator>(m_itStorage);
            }
            break;

            case 1:
            {
                Fx::destruct_storage<typename C2::iterator>(m_itStorage);
            }
            break;

            case 2:
            {
                Fx::destruct_storage<typename C3::iterator>(m_itStorage);
            }
            break;

            case 3:
            {
                Fx::destruct_storage<typename C4::iterator>(m_itStorage);
            }
            break;

            default:
                assert(0);
        }
    }

    template<class C1,class C2,class C3,class C4>
    typename C1::iterator& compatible_iterator<C1,C2,C3,C4>::CastStorageToRef0()
    {
        return reinterpret_cast<typename C1::iterator&>(m_itStorage);
    }

    template<class C1,class C2,class C3,class C4>
    typename C2::iterator& compatible_iterator<C1,C2,C3,C4>::CastStorageToRef1()
    {
        return reinterpret_cast<typename C2::iterator&>(m_itStorage);
    }

    template<class C1,class C2,class C3,class C4>
    typename C3::iterator& compatible_iterator<C1,C2,C3,C4>::CastStorageToRef2()
    {
        return reinterpret_cast<typename C3::iterator&>(m_itStorage);
    }

    template<class C1,class C2,class C3,class C4>
    typename C4::iterator& compatible_iterator<C1,C2,C3,C4>::CastStorageToRef3()
    {
        return reinterpret_cast<typename C4::iterator&>(m_itStorage);
    }

    template<class C1,class C2,class C3,class C4>
    typename C1::iterator compatible_iterator<C1,C2,C3,C4>::CastStorageTo0() const
    {
        return reinterpret_cast<const typename C1::iterator&>(m_itStorage);
    }

    template<class C1,class C2,class C3,class C4>
    typename C2::iterator compatible_iterator<C1,C2,C3,C4>::CastStorageTo1() const
    {
        return reinterpret_cast<const typename C2::iterator&>(m_itStorage);
    }

    template<class C1,class C2,class C3,class C4>
    typename C3::iterator compatible_iterator<C1,C2,C3,C4>::CastStorageTo2() const
    {
        return reinterpret_cast<const typename C3::iterator&>(m_itStorage);
    }

    template<class C1,class C2,class C3,class C4>
    typename C4::iterator compatible_iterator<C1,C2,C3,C4>::CastStorageTo3() const
    {
        return reinterpret_cast<const typename C4::iterator&>(m_itStorage);
    }

    template<class C1,class C2,class C3,class C4>
    compatible_iterator<C1,C2,C3,C4>::compatible_iterator() :
        m_itType(-1),
        m_itCont(0),
        m_asForward(true)
    {
    }

    template<class C1,class C2,class C3,class C4>
    compatible_iterator<C1,C2,C3,C4>::compatible_iterator(const compatible_iterator& it) :
        m_itType(-1),
        m_itCont(0),
        m_asForward(true)
    {
        set(it);
    }

    template<class C1,class C2,class C3,class C4>
    compatible_iterator<C1,C2,C3,C4>::compatible_iterator(const typename C1::iterator& it,C1* itCont) :
        m_itType(-1),
        m_itCont(0),
        m_asForward(true)
    {
        set(it,itCont);
    }

    template<class C1,class C2,class C3,class C4>
    compatible_iterator<C1,C2,C3,C4>::compatible_iterator(const typename C2::iterator& it,C2* itCont) :
        m_itType(-1),
        m_itCont(0),
        m_asForward(true)
    {
        set(it,itCont);
    }

    template<class C1,class C2,class C3,class C4>
    compatible_iterator<C1,C2,C3,C4>::compatible_iterator(const typename C3::iterator& it,C3* itCont) :
        m_itType(-1),
        m_itCont(0),
        m_asForward(true)
    {
        set(it,itCont);
    }

    template<class C1,class C2,class C3,class C4>
    compatible_iterator<C1,C2,C3,C4>::compatible_iterator(const typename C4::iterator& it,C4* itCont) :
        m_itType(-1),
        m_itCont(0),
        m_asForward(true)
    {
        set(it,itCont);
    }

    template<class C1,class C2,class C3,class C4>
    compatible_iterator<C1,C2,C3,C4>::~compatible_iterator()
    {
        if(m_itType != -1)
        {
            DestructStorage(m_itStorage,m_itType);
            m_itType = -1;
            m_itCont = 0;
        }
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_iterator<C1,C2,C3,C4>& compatible_iterator<C1,C2,C3,C4>::operator =(const compatible_iterator& it)
    {
        set(it);

        return *this;
    }

    template<class C1,class C2,class C3,class C4>
    int compatible_iterator<C1,C2,C3,C4>::typeIndex() const
    {
        return m_itType;
    }

    template<class C1,class C2,class C3,class C4>
    compatible_iterator_path_node<C1,C2,C3,C4> compatible_iterator<C1,C2,C3,C4>::pathNode() const
    {
        switch(m_itType)
        {
            case 0:
            {
                return compatible_iterator_path_node<C1,C2,C3,C4>(reinterpret_cast<C1*>(m_itCont));
            }
            break;

            case 1:
            {
                return compatible_iterator_path_node<C1,C2,C3,C4>(reinterpret_cast<C2*>(m_itCont));
            }
            break;

            case 2:
            {
                return compatible_iterator_path_node<C1,C2,C3,C4>(reinterpret_cast<C3*>(m_itCont));
            }
            break;

            case 3:
            {
                return compatible_iterator_path_node<C1,C2,C3,C4>(reinterpret_cast<C4*>(m_itCont));
            }
            break;
        }

        assert(0);

        return compatible_iterator_path_node<C1,C2,C3,C4>();
    }

    template<class C1,class C2,class C3,class C4>
    typename C1::iterator compatible_iterator<C1,C2,C3,C4>::get0() const
    {
        if(m_asForward)
        {
            return CastStorageTo0();
        }

        typename C1::reverse_iterator rit((CastStorageTo0()));
        rit++;

        return rit.base();
    }

    template<class C1,class C2,class C3,class C4>
    typename C2::iterator compatible_iterator<C1,C2,C3,C4>::get1() const
    {
        if(m_asForward)
        {
            return CastStorageTo1();
        }

        typename C2::reverse_iterator rit((CastStorageTo1()));
        rit++;

        return rit.base();
    }

    template<class C1,class C2,class C3,class C4>
    typename C3::iterator compatible_iterator<C1,C2,C3,C4>::get2() const
    {
        if(m_asForward)
        {
            return CastStorageTo2();
        }

        typename C3::reverse_iterator rit((CastStorageTo2()));
        rit++;

        return rit.base();
    }

    template<class C1,class C2,class C3,class C4>
    typename C4::iterator compatible_iterator<C1,C2,C3,C4>::get3() const
    {
        if(m_asForward)
        {
            return CastStorageTo3();
        }

        typename C4::reverse_iterator rit((CastStorageTo3()));
        rit++;

        return rit.base();
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator<C1,C2,C3,C4>::start(bool forward)
    {
        switch(m_itType)
        {
            case 0:
            {
                if(forward)
                {
                    C1* pCont = reinterpret_cast<C1*>(m_itCont);
                    set(pCont->begin(),pCont);
                }
                else
                {
                    C1* pCont = reinterpret_cast<C1*>(m_itCont);
                    set(pCont->rbegin().base(),pCont);
                }
                m_asForward = forward;
            }
            break;

            case 1:
            {
                if(forward)
                {
                    C2* pCont = reinterpret_cast<C2*>(m_itCont);
                    set(pCont->begin(),pCont);
                }
                else
                {
                    C2* pCont = reinterpret_cast<C2*>(m_itCont);
                    set(pCont->rbegin().base(),pCont);
                }
                m_asForward = forward;
            }
            break;

            case 2:
            {
                if(forward)
                {
                    C3* pCont = reinterpret_cast<C3*>(m_itCont);
                    set(pCont->begin(),pCont);
                }
                else
                {
                    C3* pCont = reinterpret_cast<C3*>(m_itCont);
                    set(pCont->rbegin().base(),pCont);
                }
                m_asForward = forward;
            }
            break;

            case 3:
            {
                if(forward)
                {
                    C4* pCont = reinterpret_cast<C4*>(m_itCont);
                    set(pCont->begin(),pCont);
                }
                else
                {
                    C4* pCont = reinterpret_cast<C4*>(m_itCont);
                    set(pCont->rbegin().base(),pCont);
                }
                m_asForward = forward;
            }
            break;

            default:
                assert(0);
        }
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator<C1,C2,C3,C4>::start(bool forward,C1* pCont)
    {
        if(!pCont)
        {
            return start(forward);
        }

        if(forward)
        {
            set(pCont->begin(),pCont);
        }
        else
        {
            set(pCont->rbegin().base(),pCont);
        }
        m_asForward = forward;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator<C1,C2,C3,C4>::start(bool forward,C2* pCont)
    {
        if(!pCont)
        {
            return start(forward);
        }

        if(forward)
        {
            set(pCont->begin(),pCont);
        }
        else
        {
            set(pCont->rbegin().base(),pCont);
        }
        m_asForward = forward;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator<C1,C2,C3,C4>::start(bool forward,C3* pCont)
    {
        if(!pCont)
        {
            return start(forward);
        }

        if(forward)
        {
            set(pCont->begin(),pCont);
        }
        else
        {
            set(pCont->rbegin().base(),pCont);
        }
        m_asForward = forward;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator<C1,C2,C3,C4>::start(bool forward,C4* pCont)
    {
        if(!pCont)
        {
            return start(forward);
        }

        if(forward)
        {
            set(pCont->begin(),pCont);
        }
        else
        {
            set(pCont->rbegin().base(),pCont);
        }
        m_asForward = forward;
    }

    template<class C1,class C2,class C3,class C4>
    bool compatible_iterator<C1,C2,C3,C4>::done() const
    {
        if(!m_itCont)
        {
            return true;
        }

        switch(m_itType)
        {
            case 0:
            {
                if(m_asForward)
                {
                    return CastStorageTo0() == reinterpret_cast<C1*>(m_itCont)->end();
                }
                else
                {
                    return CastStorageTo0() == reinterpret_cast<C1*>(m_itCont)->rend().base();
                }
            }
            break;

            case 1:
            {
                if(m_asForward)
                {
                    return CastStorageTo1() == reinterpret_cast<C2*>(m_itCont)->end();
                }
                else
                {
                    return CastStorageTo1() == reinterpret_cast<C2*>(m_itCont)->rend().base();
                }
            }
            break;

            case 2:
            {
                if(m_asForward)
                {
                    return CastStorageTo2() == reinterpret_cast<C3*>(m_itCont)->end();
                }
                else
                {
                    return CastStorageTo2() == reinterpret_cast<C3*>(m_itCont)->rend().base();
                }
            }
            break;

            case 3:
            {
                if(m_asForward)
                {
                    return CastStorageTo3() == reinterpret_cast<C4*>(m_itCont)->end();
                }
                else
                {
                    return CastStorageTo3() == reinterpret_cast<C4*>(m_itCont)->rend().base();
                }
            }
            break;

            default:
                assert(0);
        }

        return true;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator<C1,C2,C3,C4>::step(bool forward)
    {
        switch(m_itType)
        {
            case 0:
            {
                if(forward)
                {
                    if(CastStorageTo0() != reinterpret_cast<C1*>(m_itCont)->end())
                    {
                        CastStorageToRef0() = ++CastStorageTo0();
                    }
                }
                else
                {
                    if(CastStorageTo0() != reinterpret_cast<C1*>(m_itCont)->rend().base())
                    {
                        CastStorageToRef0() = --CastStorageTo0();
                    }
                }
            }
            break;

            case 1:
            {
                if(forward)
                {
                    if(CastStorageTo1() != reinterpret_cast<C2*>(m_itCont)->end())
                    {
                        CastStorageToRef1() = ++CastStorageTo1();
                    }
                }
                else
                {
                    if(CastStorageTo1() != reinterpret_cast<C2*>(m_itCont)->rend().base())
                    {
                        CastStorageToRef1() = --CastStorageTo1();
                    }
                }
            }
            break;

            case 2:
            {
                if(forward)
                {
                    if(CastStorageTo2() != reinterpret_cast<C3*>(m_itCont)->end())
                    {
                        CastStorageToRef2() = ++CastStorageTo2();
                    }
                }
                else
                {
                    if(CastStorageTo2() != reinterpret_cast<C3*>(m_itCont)->rend().base())
                    {
                        CastStorageToRef2() = --CastStorageTo2();
                    }
                }
            }
            break;

            case 3:
            {
                if(forward)
                {
                    if(CastStorageTo3() != reinterpret_cast<C4*>(m_itCont)->end())
                    {
                        CastStorageToRef3() = ++CastStorageTo3();
                    }
                }
                else
                {
                    if(CastStorageTo3() != reinterpret_cast<C4*>(m_itCont)->rend().base())
                    {
                        CastStorageToRef3() = --CastStorageTo3();
                    }
                }
            }
            break;

            default:
                assert(0);
        }
    }

    template<class C1,class C2,class C3,class C4>
    bool compatible_iterator<C1,C2,C3,C4>::isForward() const
    {
        return m_asForward;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator<C1,C2,C3,C4>::set(const compatible_iterator& it)
    {
        switch(it.m_itType)
        {
            case 0:
            {
                set(it.CastStorageTo0(),reinterpret_cast<C1*>(it.m_itCont));
                m_asForward = it.m_asForward;
            }
            break;

            case 1:
            {
                set(it.CastStorageTo1(),reinterpret_cast<C2*>(it.m_itCont));
                m_asForward = it.m_asForward;
            }
            break;

            case 2:
            {
                set(it.CastStorageTo2(),reinterpret_cast<C3*>(it.m_itCont));
                m_asForward = it.m_asForward;
            }
            break;

            case 3:
            {
                set(it.CastStorageTo3(),reinterpret_cast<C4*>(it.m_itCont));
                m_asForward = it.m_asForward;
            }
            break;

            default:
                assert(0);
        }
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator<C1,C2,C3,C4>::set(const typename C1::iterator& it,C1* itCont)
    {
        assert(itCont);
        (void)(it == itCont->end()); //Force check iterators compatability.

        if(m_itType == 0)
        {
            CastStorageTo0() = it;
        }
        else
        {
            if(m_itType != -1)
            {
                DestructStorage(m_itStorage,m_itType);
            }
            ConstructStorage(it,false);
            m_itType = 0;
        }

        m_itCont = itCont;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator<C1,C2,C3,C4>::set(const typename C2::iterator& it,C2* itCont)
    {
        assert(itCont);
        (void)(it == itCont->end()); //Force check iterators compatability.

        if(m_itType == 1)
        {
            CastStorageTo1() = it;
        }
        else
        {
            if(m_itType != -1)
            {
                DestructStorage(m_itStorage,m_itType);
            }
            ConstructStorage(it,false);
            m_itType = 1;
        }

        m_itCont = itCont;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator<C1,C2,C3,C4>::set(const typename C3::iterator& it,C3* itCont)
    {
        assert(itCont);
        (void)(it == itCont->end()); //Force check iterators compatability.

        if(m_itType == 2)
        {
            CastStorageTo2() = it;
        }
        else
        {
            if(m_itType != -1)
            {
                DestructStorage(m_itStorage,m_itType);
            }
            ConstructStorage(it,false);
            m_itType = 2;
        }

        m_itCont = itCont;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator<C1,C2,C3,C4>::set(const typename C4::iterator& it,C4* itCont)
    {
        assert(itCont);
        (void)(it == itCont->end()); //Force check iterators compatability.

        if(m_itType == 3)
        {
            CastStorageTo3() = it;
        }
        else
        {
            if(m_itType != -1)
            {
                DestructStorage(m_itStorage,m_itType);
            }
            ConstructStorage(it,false);
            m_itType = 3;
        }

        m_itCont = itCont;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator<C1,C2,C3,C4>::set(bool forward,
                                               const compatible_iterator_path_node<C1,C2,C3,C4>& itPathNode)
    {
        if(itPathNode.typeIndex() == -1 || !itPathNode.get())
        {
            assert(0);
            clear();
            return;
        }

        switch(itPathNode.typeIndex())
        {
            case 0:
            {
                C1* pCont = reinterpret_cast<C1*>(itPathNode.get());
                start(forward,pCont);
            }
            break;

            case 1:
            {
                C2* pCont = reinterpret_cast<C2*>(itPathNode.get());
                start(forward,pCont);
            }
            break;

            case 2:
            {
                C3* pCont = reinterpret_cast<C3*>(itPathNode.get());
                start(forward,pCont);
            }
            break;

            case 3:
            {
                C4* pCont = reinterpret_cast<C4*>(itPathNode.get());
                start(forward,pCont);
            }
            break;

            default:
                assert(0);
                clear();
        }
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator<C1,C2,C3,C4>::clear()
    {
        if(m_itType != -1)
        {
            DestructStorage(m_itStorage,m_itType);
            m_itType = -1;
        }
        m_itCont = 0;
        m_asForward = true;
    }

    //compatible_const_iterator
    template<class C1,class C2,class C3,class C4>
    constructed_storage compatible_const_iterator<C1,C2,C3,C4>::ConstructStorage(const compatible_const_iterator& it)
    {
        switch(it.m_itType)
        {
            case 0:
            {
                return ConstructStorage(it.CastStorageTo0(),false);
            }
            break;

            case 1:
            {
                return ConstructStorage(it.CastStorageTo1(),false);
            }
            break;

            case 2:
            {
                return ConstructStorage(it.CastStorageTo2(),false);
            }
            break;

            case 3:
            {
                return ConstructStorage(it.CastStorageTo3(),false);
            }
            break;

            default:
                assert(0);
        }

        return constructed_storage();
    }

    template<class C1,class C2,class C3,class C4>
    constructed_storage compatible_const_iterator<C1,C2,C3,C4>::ConstructStorage(const compatible_iterator<C1,C2,C3,C4>& it)
    {
        switch(it.m_itType)
        {
            case 0:
            {
                return ConstructStorage(it.CastStorageTo0(),false);
            }
            break;

            case 1:
            {
                return ConstructStorage(it.CastStorageTo1(),false);
            }
            break;

            case 2:
            {
                return ConstructStorage(it.CastStorageTo2(),false);
            }
            break;

            case 3:
            {
                return ConstructStorage(it.CastStorageTo3(),false);
            }
            break;

            default:
                assert(0);
        }

        return constructed_storage();
    }

    template<class C1,class C2,class C3,class C4>
    constructed_storage compatible_const_iterator<C1,C2,C3,C4>::ConstructStorage(const typename C1::const_iterator& it,bool asDefault)
    {
        if(asDefault)
        {
            Fx::global_construct_storage<typename C1::const_iterator>(m_itStorage);
        }
        else
        {
            Fx::global_construct_storage<typename C1::const_iterator>(m_itStorage,it);
        }

        return constructed_storage();
    }

    template<class C1,class C2,class C3,class C4>
    constructed_storage compatible_const_iterator<C1,C2,C3,C4>::ConstructStorage(const typename C2::const_iterator& it,bool asDefault)
    {
        if(asDefault)
        {
            Fx::global_construct_storage<typename C2::const_iterator>(m_itStorage);
        }
        else
        {
            Fx::global_construct_storage<typename C2::const_iterator>(m_itStorage,it);
        }

        return constructed_storage();
    }

    template<class C1,class C2,class C3,class C4>
    constructed_storage compatible_const_iterator<C1,C2,C3,C4>::ConstructStorage(const typename C3::const_iterator& it,bool asDefault)
    {
        if(asDefault)
        {
            Fx::global_construct_storage<typename C3::const_iterator>(m_itStorage);
        }
        else
        {
            Fx::global_construct_storage<typename C3::const_iterator>(m_itStorage,it);
        }

        return constructed_storage();
    }

    template<class C1,class C2,class C3,class C4>
    constructed_storage compatible_const_iterator<C1,C2,C3,C4>::ConstructStorage(const typename C4::const_iterator& it,bool asDefault)
    {
        if(asDefault)
        {
            Fx::global_construct_storage<typename C4::const_iterator>(m_itStorage);
        }
        else
        {
            Fx::global_construct_storage<typename C4::const_iterator>(m_itStorage,it);
        }

        return constructed_storage();
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator<C1,C2,C3,C4>::DestructStorage(typename compatible_const_iterator<C1,C2,C3,C4>::aligned_storage_iterator_type& storage,int as)
    {
        switch(as)
        {
            case 0:
            {
                Fx::destruct_storage<typename C1::const_iterator>(m_itStorage);
            }
            break;

            case 1:
            {
                Fx::destruct_storage<typename C2::const_iterator>(m_itStorage);
            }
            break;

            case 2:
            {
                Fx::destruct_storage<typename C3::const_iterator>(m_itStorage);
            }
            break;

            case 3:
            {
                Fx::destruct_storage<typename C4::const_iterator>(m_itStorage);
            }
            break;

            default:
                assert(0);
        }
    }

    template<class C1,class C2,class C3,class C4>
    typename C1::const_iterator& compatible_const_iterator<C1,C2,C3,C4>::CastStorageToRef0()
    {
        return reinterpret_cast<typename C1::const_iterator&>(m_itStorage);
    }

    template<class C1,class C2,class C3,class C4>
    typename C2::const_iterator& compatible_const_iterator<C1,C2,C3,C4>::CastStorageToRef1()
    {
        return reinterpret_cast<typename C2::const_iterator&>(m_itStorage);
    }

    template<class C1,class C2,class C3,class C4>
    typename C3::const_iterator& compatible_const_iterator<C1,C2,C3,C4>::CastStorageToRef2()
    {
        return reinterpret_cast<typename C3::const_iterator&>(m_itStorage);
    }

    template<class C1,class C2,class C3,class C4>
    typename C4::const_iterator& compatible_const_iterator<C1,C2,C3,C4>::CastStorageToRef3()
    {
        return reinterpret_cast<typename C4::const_iterator&>(m_itStorage);
    }

    template<class C1,class C2,class C3,class C4>
    typename C1::const_iterator compatible_const_iterator<C1,C2,C3,C4>::CastStorageTo0() const
    {
        return reinterpret_cast<const typename C1::const_iterator&>(m_itStorage);
    }

    template<class C1,class C2,class C3,class C4>
    typename C2::const_iterator compatible_const_iterator<C1,C2,C3,C4>::CastStorageTo1() const
    {
        return reinterpret_cast<const typename C2::const_iterator&>(m_itStorage);
    }

    template<class C1,class C2,class C3,class C4>
    typename C3::const_iterator compatible_const_iterator<C1,C2,C3,C4>::CastStorageTo2() const
    {
        return reinterpret_cast<const typename C3::const_iterator&>(m_itStorage);
    }

    template<class C1,class C2,class C3,class C4>
    typename C4::const_iterator compatible_const_iterator<C1,C2,C3,C4>::CastStorageTo3() const
    {
        return reinterpret_cast<const typename C4::const_iterator&>(m_itStorage);
    }

    template<class C1,class C2,class C3,class C4>
    compatible_const_iterator<C1,C2,C3,C4>::compatible_const_iterator() :
        m_itType(-1),
        m_itCont(0),
        m_asForward(true)
    {
    }

    template<class C1,class C2,class C3,class C4>
    compatible_const_iterator<C1,C2,C3,C4>::compatible_const_iterator(const compatible_const_iterator& it) :
        m_itType(-1),
        m_itCont(0),
        m_asForward(true)
    {
        set(it);
    }

    template<class C1,class C2,class C3,class C4>
    compatible_const_iterator<C1,C2,C3,C4>::compatible_const_iterator(const compatible_iterator<C1,C2,C3,C4>& it) :
        m_itType(-1),
        m_itCont(0),
        m_asForward(true)
    {
        set(it);
    }

    template<class C1,class C2,class C3,class C4>
    compatible_const_iterator<C1,C2,C3,C4>::compatible_const_iterator(const typename C1::const_iterator& it,const C1* itCont) :
        m_itType(-1),
        m_itCont(0),
        m_asForward(true)
    {
        set(it,itCont);
    }

    template<class C1,class C2,class C3,class C4>
    compatible_const_iterator<C1,C2,C3,C4>::compatible_const_iterator(const typename C2::const_iterator& it,const C2* itCont) :
        m_itType(-1),
        m_itCont(0),
        m_asForward(true)
    {
        set(it,itCont);
    }

    template<class C1,class C2,class C3,class C4>
    compatible_const_iterator<C1,C2,C3,C4>::compatible_const_iterator(const typename C3::const_iterator& it,const C3* itCont) :
        m_itType(-1),
        m_itCont(0),
        m_asForward(true)
    {
        set(it,itCont);
    }

    template<class C1,class C2,class C3,class C4>
    compatible_const_iterator<C1,C2,C3,C4>::compatible_const_iterator(const typename C4::const_iterator& it,const C4* itCont) :
        m_itType(-1),
        m_itCont(0),
        m_asForward(true)
    {
        set(it,itCont);
    }

    template<class C1,class C2,class C3,class C4>
    compatible_const_iterator<C1,C2,C3,C4>::~compatible_const_iterator()
    {
        if(m_itType != -1)
        {
            DestructStorage(m_itStorage,m_itType);
            m_itType = -1;
            m_itCont = 0;
        }
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_const_iterator<C1,C2,C3,C4>& compatible_const_iterator<C1,C2,C3,C4>::operator =(const compatible_const_iterator& it)
    {
        set(it);

        return *this;
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_const_iterator<C1,C2,C3,C4>& compatible_const_iterator<C1,C2,C3,C4>::operator =(const compatible_iterator<C1,C2,C3,C4>& it)
    {
        set(it);

        return *this;
    }

    template<class C1,class C2,class C3,class C4>
    int compatible_const_iterator<C1,C2,C3,C4>::typeIndex() const
    {
        return m_itType;
    }

    template<class C1,class C2,class C3,class C4>
    compatible_const_iterator_path_node<C1,C2,C3,C4> compatible_const_iterator<C1,C2,C3,C4>::pathNode() const
    {
        switch(m_itType)
        {
            case 0:
            {
                return compatible_const_iterator_path_node<C1,C2,C3,C4>(reinterpret_cast<const C1*>(m_itCont));
            }
            break;

            case 1:
            {
                return compatible_const_iterator_path_node<C1,C2,C3,C4>(reinterpret_cast<const C2*>(m_itCont));
            }
            break;

            case 2:
            {
                return compatible_const_iterator_path_node<C1,C2,C3,C4>(reinterpret_cast<const C3*>(m_itCont));
            }
            break;

            case 3:
            {
                return compatible_const_iterator_path_node<C1,C2,C3,C4>(reinterpret_cast<const C4*>(m_itCont));
            }
            break;
        }

        assert(0);

        return compatible_const_iterator_path_node<C1,C2,C3,C4>();
    }

    template<class C1,class C2,class C3,class C4>
    typename C1::const_iterator compatible_const_iterator<C1,C2,C3,C4>::get0() const
    {
        if(m_asForward)
        {
            return CastStorageTo0();
        }

        typename C1::const_reverse_iterator rit((CastStorageTo0()));
        rit++;

        return rit.base();
    }

    template<class C1,class C2,class C3,class C4>
    typename C2::const_iterator compatible_const_iterator<C1,C2,C3,C4>::get1() const
    {
        if(m_asForward)
        {
            return CastStorageTo1();
        }

        typename C2::const_reverse_iterator rit((CastStorageTo1()));
        rit++;

        return rit.base();
    }

    template<class C1,class C2,class C3,class C4>
    typename C3::const_iterator compatible_const_iterator<C1,C2,C3,C4>::get2() const
    {
        if(m_asForward)
        {
            return CastStorageTo2();
        }

        typename C3::const_reverse_iterator rit((CastStorageTo2()));
        rit++;

        return rit.base();
    }

    template<class C1,class C2,class C3,class C4>
    typename C4::const_iterator compatible_const_iterator<C1,C2,C3,C4>::get3() const
    {
        if(m_asForward)
        {
            return CastStorageTo3();
        }

        typename C4::const_reverse_iterator rit((CastStorageTo3()));
        rit++;

        return rit.base();
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator<C1,C2,C3,C4>::start(bool forward)
    {
        switch(m_itType)
        {
            case 0:
            {
                if(forward)
                {
                    const C1* pCont = reinterpret_cast<const C1*>(m_itCont);
                    set(pCont->begin(),pCont);
                }
                else
                {
                    const C1* pCont = reinterpret_cast<const C1*>(m_itCont);
                    set(pCont->rbegin().base(),pCont);
                }
                m_asForward = forward;
            }
            break;

            case 1:
            {
                if(forward)
                {
                    const C2* pCont = reinterpret_cast<const C2*>(m_itCont);
                    set(pCont->begin(),pCont);
                }
                else
                {
                    const C2* pCont = reinterpret_cast<const C2*>(m_itCont);
                    set(pCont->rbegin().base(),pCont);
                }
                m_asForward = forward;
            }
            break;

            case 2:
            {
                if(forward)
                {
                    const C3* pCont = reinterpret_cast<const C3*>(m_itCont);
                    set(pCont->begin(),pCont);
                }
                else
                {
                    const C3* pCont = reinterpret_cast<const C3*>(m_itCont);
                    set(pCont->rbegin().base(),pCont);
                }
                m_asForward = forward;
            }
            break;

            case 3:
            {
                if(forward)
                {
                    const C4* pCont = reinterpret_cast<const C4*>(m_itCont);
                    set(pCont->begin(),pCont);
                }
                else
                {
                    const C4* pCont = reinterpret_cast<const C4*>(m_itCont);
                    set(pCont->rbegin().base(),pCont);
                }
                m_asForward = forward;
            }
            break;

            default:
                assert(0);
        }
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator<C1,C2,C3,C4>::start(bool forward,const C1* pCont)
    {
        if(!pCont)
        {
            return start(forward);
        }

        if(forward)
        {
            set(pCont->begin(),pCont);
        }
        else
        {
            set(pCont->rbegin().base(),pCont);
        }
        m_asForward = forward;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator<C1,C2,C3,C4>::start(bool forward,const C2* pCont)
    {
        if(!pCont)
        {
            return start(forward);
        }

        if(forward)
        {
            set(pCont->begin(),pCont);
        }
        else
        {
            set(pCont->rbegin().base(),pCont);
        }
        m_asForward = forward;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator<C1,C2,C3,C4>::start(bool forward,const C3* pCont)
    {
        if(!pCont)
        {
            return start(forward);
        }

        if(forward)
        {
            set(pCont->begin(),pCont);
        }
        else
        {
            set(pCont->rbegin().base(),pCont);
        }
        m_asForward = forward;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator<C1,C2,C3,C4>::start(bool forward,const C4* pCont)
    {
        if(!pCont)
        {
            return start(forward);
        }

        if(forward)
        {
            set(pCont->begin(),pCont);
        }
        else
        {
            set(pCont->rbegin().base(),pCont);
        }
        m_asForward = forward;
    }

    template<class C1,class C2,class C3,class C4>
    bool compatible_const_iterator<C1,C2,C3,C4>::done() const
    {
        if(!m_itCont)
        {
            return true;
        }

        switch(m_itType)
        {
            case 0:
            {
                if(m_asForward)
                {
                    return CastStorageTo0() == reinterpret_cast<const C1*>(m_itCont)->end();
                }
                else
                {
                    return CastStorageTo0() == reinterpret_cast<const C1*>(m_itCont)->rend().base();
                }
            }
            break;

            case 1:
            {
                if(m_asForward)
                {
                    return CastStorageTo1() == reinterpret_cast<const C2*>(m_itCont)->end();
                }
                else
                {
                    return CastStorageTo1() == reinterpret_cast<const C2*>(m_itCont)->rend().base();
                }
            }
            break;

            case 2:
            {
                if(m_asForward)
                {
                    return CastStorageTo2() == reinterpret_cast<const C3*>(m_itCont)->end();
                }
                else
                {
                    return CastStorageTo2() == reinterpret_cast<const C3*>(m_itCont)->rend().base();
                }
            }
            break;

            case 3:
            {
                if(m_asForward)
                {
                    return CastStorageTo3() == reinterpret_cast<const C4*>(m_itCont)->end();
                }
                else
                {
                    return CastStorageTo3() == reinterpret_cast<const C4*>(m_itCont)->rend().base();
                }
            }
            break;

            default:
                assert(0);
        }

        return true;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator<C1,C2,C3,C4>::step(bool forward)
    {
        switch(m_itType)
        {
            case 0:
            {
                if(forward)
                {
                    if(CastStorageTo0() != reinterpret_cast<const C1*>(m_itCont)->end())
                    {
                        CastStorageToRef0() = ++CastStorageTo0();
                    }
                }
                else
                {
                    if(CastStorageTo0() != reinterpret_cast<const C1*>(m_itCont)->rend().base())
                    {
                        CastStorageToRef0() = --CastStorageTo0();
                    }
                }
            }
            break;

            case 1:
            {
                if(forward)
                {
                    if(CastStorageTo1() != reinterpret_cast<const C2*>(m_itCont)->end())
                    {
                        CastStorageToRef1() = ++CastStorageTo1();
                    }
                }
                else
                {
                    if(CastStorageTo1() != reinterpret_cast<const C2*>(m_itCont)->rend().base())
                    {
                        CastStorageToRef1() = --CastStorageTo1();
                    }
                }
            }
            break;

            case 2:
            {
                if(forward)
                {
                    if(CastStorageTo2() != reinterpret_cast<const C3*>(m_itCont)->end())
                    {
                        CastStorageToRef2() = ++CastStorageTo2();
                    }
                }
                else
                {
                    if(CastStorageTo2() != reinterpret_cast<const C3*>(m_itCont)->rend().base())
                    {
                        CastStorageToRef2() = --CastStorageTo2();
                    }
                }
            }
            break;

            case 3:
            {
                if(forward)
                {
                    if(CastStorageTo3() != reinterpret_cast<const C4*>(m_itCont)->end())
                    {
                        CastStorageToRef3() = ++CastStorageTo3();
                    }
                }
                else
                {
                    if(CastStorageTo3() != reinterpret_cast<const C4*>(m_itCont)->rend().base())
                    {
                        CastStorageToRef3() = --CastStorageTo3();
                    }
                }
            }
            break;

            default:
                assert(0);
        }
    }

    template<class C1,class C2,class C3,class C4>
    bool compatible_const_iterator<C1,C2,C3,C4>::isForward() const
    {
        return m_asForward;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator<C1,C2,C3,C4>::set(const compatible_const_iterator& it)
    {
        switch(it.m_itType)
        {
            case 0:
            {
                set(it.CastStorageTo0(),reinterpret_cast<const C1*>(it.m_itCont));
                m_asForward = it.m_asForward;
            }
            break;

            case 1:
            {
                set(it.CastStorageTo1(),reinterpret_cast<const C2*>(it.m_itCont));
                m_asForward = it.m_asForward;
            }
            break;

            case 2:
            {
                set(it.CastStorageTo2(),reinterpret_cast<const C3*>(it.m_itCont));
                m_asForward = it.m_asForward;
            }
            break;

            case 3:
            {
                set(it.CastStorageTo3(),reinterpret_cast<const C4*>(it.m_itCont));
                m_asForward = it.m_asForward;
            }
            break;

            default:
                assert(0);
        }
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator<C1,C2,C3,C4>::set(const compatible_iterator<C1,C2,C3,C4>& it)
    {
        switch(it.m_itType)
        {
            case 0:
            {
                set(it.CastStorageTo0(),reinterpret_cast<const C1*>(it.m_itCont));
                m_asForward = it.m_asForward;
            }
            break;

            case 1:
            {
                set(it.CastStorageTo1(),reinterpret_cast<const C2*>(it.m_itCont));
                m_asForward = it.m_asForward;
            }
            break;

            case 2:
            {
                set(it.CastStorageTo2(),reinterpret_cast<const C3*>(it.m_itCont));
                m_asForward = it.m_asForward;
            }
            break;

            case 3:
            {
                set(it.CastStorageTo3(),reinterpret_cast<const C4*>(it.m_itCont));
                m_asForward = it.m_asForward;
            }
            break;

            default:
                assert(0);
        }
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator<C1,C2,C3,C4>::set(const typename C1::const_iterator& it,const C1* itCont)
    {
        assert(itCont);
        (void)(it == itCont->end()); //Force check iterators compatability.

        if(m_itType == 0)
        {
            CastStorageTo0() = it;
        }
        else
        {
            if(m_itType != -1)
            {
                DestructStorage(m_itStorage,m_itType);
            }
            ConstructStorage(it,false);
            m_itType = 0;
        }

        m_itCont = itCont;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator<C1,C2,C3,C4>::set(const typename C2::const_iterator& it,const C2* itCont)
    {
        assert(itCont);
        (void)(it == itCont->end()); //Force check iterators compatability.

        if(m_itType == 1)
        {
            CastStorageTo1() = it;
        }
        else
        {
            if(m_itType != -1)
            {
                DestructStorage(m_itStorage,m_itType);
            }
            ConstructStorage(it,false);
            m_itType = 1;
        }

        m_itCont = itCont;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator<C1,C2,C3,C4>::set(const typename C3::const_iterator& it,const C3* itCont)
    {
        assert(itCont);
        (void)(it == itCont->end()); //Force check iterators compatability.

        if(m_itType == 2)
        {
            CastStorageTo2() = it;
        }
        else
        {
            if(m_itType != -1)
            {
                DestructStorage(m_itStorage,m_itType);
            }
            ConstructStorage(it,false);
            m_itType = 2;
        }

        m_itCont = itCont;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator<C1,C2,C3,C4>::set(const typename C4::const_iterator& it,const C4* itCont)
    {
        assert(itCont);
        (void)(it == itCont->end()); //Force check iterators compatability.

        if(m_itType == 3)
        {
            CastStorageTo3() = it;
        }
        else
        {
            if(m_itType != -1)
            {
                DestructStorage(m_itStorage,m_itType);
            }
            ConstructStorage(it,false);
            m_itType = 3;
        }

        m_itCont = itCont;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator<C1,C2,C3,C4>::set(bool forward,
                                                     const compatible_const_iterator_path_node<C1,C2,C3,C4>& itPathNode)
    {
        if(itPathNode.typeIndex() == -1 || !itPathNode.get())
        {
            assert(0);
            clear();
            return;
        }

        switch(itPathNode.typeIndex())
        {
            case 0:
            {
                const C1* pCont = reinterpret_cast<const C1*>(itPathNode.get());
                start(forward,pCont);
            }
            break;

            case 1:
            {
                const C2* pCont = reinterpret_cast<const C2*>(itPathNode.get());
                start(forward,pCont);
            }
            break;

            case 2:
            {
                const C3* pCont = reinterpret_cast<const C3*>(itPathNode.get());
                start(forward,pCont);
            }
            break;

            case 3:
            {
                const C4* pCont = reinterpret_cast<const C4*>(itPathNode.get());
                start(forward,pCont);
            }
            break;

            default:
                assert(0);
                clear();
        }
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator<C1,C2,C3,C4>::set(bool forward,
                                                     const compatible_iterator_path_node<C1,C2,C3,C4>& itPathNode)
    {
        if(itPathNode.typeIndex() == -1 || !itPathNode.get())
        {
            assert(0);
            clear();
            return;
        }

        switch(itPathNode.typeIndex())
        {
            case 0:
            {
                const C1* pCont = reinterpret_cast<const C1*>(itPathNode.get());
                start(forward,pCont);
            }
            break;

            case 1:
            {
                const C2* pCont = reinterpret_cast<const C2*>(itPathNode.get());
                start(forward,pCont);
            }
            break;

            case 2:
            {
                const C3* pCont = reinterpret_cast<const C3*>(itPathNode.get());
                start(forward,pCont);
            }
            break;

            case 3:
            {
                const C4* pCont = reinterpret_cast<const C4*>(itPathNode.get());
                start(forward,pCont);
            }
            break;

            default:
                assert(0);
                clear();
        }
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator<C1,C2,C3,C4>::clear()
    {
        if(m_itType != -1)
        {
            DestructStorage(m_itStorage,m_itType);
            m_itType = -1;
        }
        m_itCont = 0;
        m_asForward = true;
    }

    //compatible_iterator_path_node
    template<class C1,class C2,class C3,class C4>
    compatible_iterator_path_node<C1,C2,C3,C4>::compatible_iterator_path_node()
        : m_itType(-1),
          m_itCont(0)
    {
    }

    template<class C1,class C2,class C3,class C4>
    compatible_iterator_path_node<C1,C2,C3,C4>::compatible_iterator_path_node(C1* pCont)
    {
        *this = pCont;
    }

    template<class C1,class C2,class C3,class C4>
    compatible_iterator_path_node<C1,C2,C3,C4>::compatible_iterator_path_node(C2* pCont)
    {
        *this = pCont;
    }

    template<class C1,class C2,class C3,class C4>
    compatible_iterator_path_node<C1,C2,C3,C4>::compatible_iterator_path_node(C3* pCont)
    {
        *this = pCont;
    }

    template<class C1,class C2,class C3,class C4>
    compatible_iterator_path_node<C1,C2,C3,C4>::compatible_iterator_path_node(C4* pCont)
    {
        *this = pCont;
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_iterator_path_node<C1,C2,C3,C4>& compatible_iterator_path_node<C1,C2,C3,C4>::operator =(C1* pCont)
    {
        assert(pCont);
        m_itType = 0;
        m_itCont = pCont;

        return *this;
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_iterator_path_node<C1,C2,C3,C4>& compatible_iterator_path_node<C1,C2,C3,C4>::operator =(C2* pCont)
    {
        assert(pCont);
        m_itType = 1;
        m_itCont = pCont;

        return *this;
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_iterator_path_node<C1,C2,C3,C4>& compatible_iterator_path_node<C1,C2,C3,C4>::operator =(C3* pCont)
    {
        assert(pCont);
        m_itType = 2;
        m_itCont = pCont;

        return *this;
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_iterator_path_node<C1,C2,C3,C4>& compatible_iterator_path_node<C1,C2,C3,C4>::operator =(C4* pCont)
    {
        assert(pCont);
        m_itType = 3;
        m_itCont = pCont;

        return *this;
    }

    template<class C1,class C2,class C3,class C4>
    int compatible_iterator_path_node<C1,C2,C3,C4>::typeIndex() const
    {
        return m_itType;
    }

    template<class C1,class C2,class C3,class C4>
    void* compatible_iterator_path_node<C1,C2,C3,C4>::get() const
    {
        return m_itCont;
    }

    template<class C1,class C2,class C3,class C4>
    C1* compatible_iterator_path_node<C1,C2,C3,C4>::get0() const
    {
        if(m_itType == 0)
        {
            return reinterpret_cast<C1*>(m_itCont);
        }

        return 0;
    }

    template<class C1,class C2,class C3,class C4>
    C2* compatible_iterator_path_node<C1,C2,C3,C4>::get1() const
    {
        if(m_itType == 1)
        {
            return reinterpret_cast<C2*>(m_itCont);
        }

        return 0;
    }

    template<class C1,class C2,class C3,class C4>
    C3* compatible_iterator_path_node<C1,C2,C3,C4>::get2() const
    {
        if(m_itType == 2)
        {
            return reinterpret_cast<C3*>(m_itCont);
        }

        return 0;
    }

    template<class C1,class C2,class C3,class C4>
    C4* compatible_iterator_path_node<C1,C2,C3,C4>::get3() const
    {
        if(m_itType == 3)
        {
            return reinterpret_cast<C4*>(m_itCont);
        }

        return 0;
    }

    //compatible_iterator_path_node
    template<class C1,class C2,class C3,class C4>
    compatible_const_iterator_path_node<C1,C2,C3,C4>::compatible_const_iterator_path_node()
        : m_itType(-1),
          m_itCont(0)
    {
    }

    template<class C1,class C2,class C3,class C4>
    compatible_const_iterator_path_node<C1,C2,C3,C4>::compatible_const_iterator_path_node(const C1* pCont)
    {
        *this = pCont;
    }

    template<class C1,class C2,class C3,class C4>
    compatible_const_iterator_path_node<C1,C2,C3,C4>::compatible_const_iterator_path_node(const C2* pCont)
    {
        *this = pCont;
    }

    template<class C1,class C2,class C3,class C4>
    compatible_const_iterator_path_node<C1,C2,C3,C4>::compatible_const_iterator_path_node(const C3* pCont)
    {
        *this = pCont;
    }

    template<class C1,class C2,class C3,class C4>
    compatible_const_iterator_path_node<C1,C2,C3,C4>::compatible_const_iterator_path_node(const C4* pCont)
    {
        *this = pCont;
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_const_iterator_path_node<C1,C2,C3,C4>& compatible_const_iterator_path_node<C1,C2,C3,C4>::operator =(const C1* pCont)
    {
        assert(pCont);
        m_itType = 0;
        m_itCont = pCont;

        return *this;
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_const_iterator_path_node<C1,C2,C3,C4>& compatible_const_iterator_path_node<C1,C2,C3,C4>::operator =(const C2* pCont)
    {
        assert(pCont);
        m_itType = 1;
        m_itCont = pCont;

        return *this;
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_const_iterator_path_node<C1,C2,C3,C4>& compatible_const_iterator_path_node<C1,C2,C3,C4>::operator =(const C3* pCont)
    {
        assert(pCont);
        m_itType = 2;
        m_itCont = pCont;

        return *this;
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_const_iterator_path_node<C1,C2,C3,C4>& compatible_const_iterator_path_node<C1,C2,C3,C4>::operator =(const C4* pCont)
    {
        assert(pCont);
        m_itType = 3;
        m_itCont = pCont;

        return *this;
    }

    template<class C1,class C2,class C3,class C4>
    int compatible_const_iterator_path_node<C1,C2,C3,C4>::typeIndex() const
    {
        return m_itType;
    }

    template<class C1,class C2,class C3,class C4>
    const void* compatible_const_iterator_path_node<C1,C2,C3,C4>::get() const
    {
        return m_itCont;
    }

    template<class C1,class C2,class C3,class C4>
    const C1* compatible_const_iterator_path_node<C1,C2,C3,C4>::get0() const
    {
        if(m_itType == 0)
        {
            return reinterpret_cast<const C1*>(m_itCont);
        }

        return 0;
    }

    template<class C1,class C2,class C3,class C4>
    const C2* compatible_const_iterator_path_node<C1,C2,C3,C4>::get1() const
    {
        if(m_itType == 1)
        {
            return reinterpret_cast<const C2*>(m_itCont);
        }

        return 0;
    }

    template<class C1,class C2,class C3,class C4>
    const C3* compatible_const_iterator_path_node<C1,C2,C3,C4>::get2() const
    {
        if(m_itType == 2)
        {
            return reinterpret_cast<const C3*>(m_itCont);
        }

        return 0;
    }

    template<class C1,class C2,class C3,class C4>
    const C4* compatible_const_iterator_path_node<C1,C2,C3,C4>::get3() const
    {
        if(m_itType == 3)
        {
            return reinterpret_cast<const C4*>(m_itCont);
        }

        return 0;
    }

    //compatible_iterator_path
    template<class C1,class C2,class C3,class C4>
    compatible_iterator_path_node<C1,C2,C3,C4>& compatible_iterator_path<C1,C2,C3,C4>::operator [](typename compatible_iterator_path<C1,C2,C3,C4>::iterator_path::size_type index)
    {
        return m_itPath[index];
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_iterator_path_node<C1,C2,C3,C4>& compatible_iterator_path<C1,C2,C3,C4>::operator [](typename compatible_iterator_path<C1,C2,C3,C4>::iterator_path::size_type index) const
    {
        return m_itPath[index];
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator_path<C1,C2,C3,C4>::appendContainer(C1* itCont)
    {
        m_itPath.append(std::make_pair(0,itCont));
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator_path<C1,C2,C3,C4>::appendContainer(C2* itCont)
    {
        m_itPath.append(std::make_pair(1,itCont));
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator_path<C1,C2,C3,C4>::appendContainer(C3* itCont)
    {
        m_itPath.append(std::make_pair(2,itCont));
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator_path<C1,C2,C3,C4>::appendContainer(C4* itCont)
    {
        m_itPath.append(std::make_pair(3,itCont));
    }

    template<class C1,class C2,class C3,class C4>
    typename compatible_iterator_path<C1,C2,C3,C4>::iterator_path::size_type compatible_iterator_path<C1,C2,C3,C4>::size() const
    {
        return m_itPath.size();
    }

    template<class C1,class C2,class C3,class C4>
    typename compatible_iterator_path<C1,C2,C3,C4>::iterator_path::size_type compatible_iterator_path<C1,C2,C3,C4>::capacity() const
    {
        return m_itPath.capacity();
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator_path<C1,C2,C3,C4>::resize(typename compatible_iterator_path<C1,C2,C3,C4>::iterator_path::size_type size)
    {
        m_itPath.resize(size);
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator_path<C1,C2,C3,C4>::reserve(typename compatible_iterator_path<C1,C2,C3,C4>::iterator_path::size_type size)
    {
        m_itPath.reserve(size);
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_iterator_path<C1,C2,C3,C4>::clear()
    {
        m_itPath.clear();
    }

    template<class C1,class C2,class C3,class C4>
    compatible_iterator_path_node<C1,C2,C3,C4>& compatible_iterator_path<C1,C2,C3,C4>::front()
    {
        return m_itPath.front();
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_iterator_path_node<C1,C2,C3,C4>& compatible_iterator_path<C1,C2,C3,C4>::front() const
    {
        return m_itPath.front();
    }

    template<class C1,class C2,class C3,class C4>
    compatible_iterator_path_node<C1,C2,C3,C4>& compatible_iterator_path<C1,C2,C3,C4>::back()
    {
        return m_itPath.back();
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_iterator_path_node<C1,C2,C3,C4>& compatible_iterator_path<C1,C2,C3,C4>::back() const
    {
        return m_itPath.back();
    }

    //compatible_iterator_path
    template<class C1,class C2,class C3,class C4>
    compatible_const_iterator_path_node<C1,C2,C3,C4>& compatible_const_iterator_path<C1,C2,C3,C4>::operator [](typename compatible_const_iterator_path<C1,C2,C3,C4>::iterator_path::size_type index)
    {
        return m_itPath[index];
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_const_iterator_path_node<C1,C2,C3,C4>& compatible_const_iterator_path<C1,C2,C3,C4>::operator [](typename compatible_const_iterator_path<C1,C2,C3,C4>::iterator_path::size_type index) const
    {
        return m_itPath[index];
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator_path<C1,C2,C3,C4>::appendContainer(const C1* itCont)
    {
        m_itPath.append(std::make_pair(0,itCont));
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator_path<C1,C2,C3,C4>::appendContainer(const C2* itCont)
    {
        m_itPath.append(std::make_pair(1,itCont));
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator_path<C1,C2,C3,C4>::appendContainer(const C3* itCont)
    {
        m_itPath.append(std::make_pair(2,itCont));
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator_path<C1,C2,C3,C4>::appendContainer(const C4* itCont)
    {
        m_itPath.append(std::make_pair(3,itCont));
    }

    template<class C1,class C2,class C3,class C4>
    typename compatible_const_iterator_path<C1,C2,C3,C4>::iterator_path::size_type compatible_const_iterator_path<C1,C2,C3,C4>::size() const
    {
        return m_itPath.size();
    }

    template<class C1,class C2,class C3,class C4>
    typename compatible_const_iterator_path<C1,C2,C3,C4>::iterator_path::size_type compatible_const_iterator_path<C1,C2,C3,C4>::capacity() const
    {
        return m_itPath.capacity();
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator_path<C1,C2,C3,C4>::resize(typename compatible_const_iterator_path<C1,C2,C3,C4>::iterator_path::size_type size)
    {
        m_itPath.resize(size);
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator_path<C1,C2,C3,C4>::reserve(typename compatible_const_iterator_path<C1,C2,C3,C4>::iterator_path::size_type size)
    {
        m_itPath.reserve(size);
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_const_iterator_path<C1,C2,C3,C4>::clear()
    {
        m_itPath.clear();
    }

    template<class C1,class C2,class C3,class C4>
    compatible_const_iterator_path_node<C1,C2,C3,C4>& compatible_const_iterator_path<C1,C2,C3,C4>::front()
    {
        return m_itPath.front();
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_const_iterator_path_node<C1,C2,C3,C4>& compatible_const_iterator_path<C1,C2,C3,C4>::front() const
    {
        return m_itPath.front();
    }

    template<class C1,class C2,class C3,class C4>
    compatible_const_iterator_path_node<C1,C2,C3,C4>& compatible_const_iterator_path<C1,C2,C3,C4>::back()
    {
        return m_itPath.back();
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_const_iterator_path_node<C1,C2,C3,C4>& compatible_const_iterator_path<C1,C2,C3,C4>::back() const
    {
        return m_itPath.back();
    }

    //compatible_path_iterator
    template<class C1,class C2,class C3,class C4>
    compatible_path_iterator<C1,C2,C3,C4>::compatible_path_iterator()
        : m_pItPath(0),
          m_itPathNodeIndex(-1),
          m_asForward(true)
    {
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_iterator<C1,C2,C3,C4>& compatible_path_iterator<C1,C2,C3,C4>::get() const
    {
        return m_it;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_path_iterator<C1,C2,C3,C4>::start(bool forward)
    {
        if(!m_pItPath)
        {
            assert(0);
            return;
        }

        const size_type numItConts = m_pItPath->size();
        if(!numItConts)
        {
            assert(0);
            return;
        }

        const iterator_path_node& itPathNode = forward ? *m_pItPath->begin() : *m_pItPath->back();
        switch(itPathNode.typeIndex())
        {
            case 0:
            {
                C1* pCont = reinterpret_cast<C1*>(itPathNode.get());
                m_it.start(forward,pCont);
            }
            break;

            case 1:
            {
                C2* pCont = reinterpret_cast<C2*>(itPathNode.get());
                m_it.start(forward,pCont);
            }
            break;

            case 2:
            {
                C3* pCont = reinterpret_cast<C3*>(itPathNode.get());
                m_it.start(forward,pCont);
            }
            break;

            case 3:
            {
                C4* pCont = reinterpret_cast<C4*>(itPathNode.get());
                m_it.start(forward,pCont);
            }
            break;

            default:
                assert(0);
        }
        m_asForward = forward;

        //Iterate to valid node.
        if(m_it.done())
        {
            step(forward);
        }
    }

    template<class C1,class C2,class C3,class C4>
    bool compatible_path_iterator<C1,C2,C3,C4>::done() const
    {
        if(!m_pItPath || m_itPathNodeIndex == -1)
        {
            assert(0);
            return true;
        }

        const size_type numItConts = m_pItPath->size();
        if(!numItConts || numItConts <= m_itPathNodeIndex)
        {
            assert(0);
            return true;
        }

        iterator it = m_it;
        size_type itPathNodeIndex = m_itPathNodeIndex;

        while(it.done())
        {
            if(m_asForward && itPathNodeIndex < numItConts-1 || !m_asForward && itPathNodeIndex > 0)
            {
                const iterator_path_node& nextItPathNode = (*m_pItPath)[itPathNodeIndex+(m_asForward ? +1 : -1)];
                switch(nextItPathNode.typeIndex())
                {
                    case 0:
                    {
                        C1* pNextCont = reinterpret_cast<C1*>(nextItPathNode.get());
                        it.start(m_asForward,pNextCont);
                        m_asForward ? itPathNodeIndex++ : itPathNodeIndex--;
                    }
                    break;

                    case 1:
                    {
                        C2* pNextCont = reinterpret_cast<C2*>(nextItPathNode.get());
                        it.start(m_asForward,pNextCont);
                        m_asForward ? itPathNodeIndex++ : itPathNodeIndex--;
                    }
                    break;

                    case 2:
                    {
                        C3* pNextCont = reinterpret_cast<C3*>(nextItPathNode.get());
                        it.start(m_asForward,pNextCont);
                        m_asForward ? itPathNodeIndex++ : itPathNodeIndex--;
                    }
                    break;

                    case 3:
                    {
                        C4* pNextCont = reinterpret_cast<C4*>(nextItPathNode.get());
                        it.start(m_asForward,pNextCont);
                        m_asForward ? itPathNodeIndex++ : itPathNodeIndex--;
                    }
                    break;

                    default:
                        assert(0);
                        return true;
                }

                continue;
            }

            return true;
        }

        return false;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_path_iterator<C1,C2,C3,C4>::step(bool forward)
    {
        if(!m_pItPath || m_itPathNodeIndex == -1)
        {
            assert(0);
            return;
        }

        const size_type numItConts = m_pItPath->size();
        if(!numItConts || numItConts <= m_itPathNodeIndex)
        {
            assert(0);
            return;
        }

        m_it.step(forward);
        while(m_it.done())
        {
            if(forward && m_itPathNodeIndex < numItConts-1 || !forward && m_itPathNodeIndex > 0)
            {
                const iterator_path_node& nextItPathNode = (*m_pItPath)[m_itPathNodeIndex+(forward ? +1 : -1)];
                switch(nextItPathNode.typeIndex())
                {
                    case 0:
                    {
                        C1* pNextCont = reinterpret_cast<C1*>(nextItPathNode.get());
                        m_it.start(forward,pNextCont);
                        forward ? m_itPathNodeIndex++ : m_itPathNodeIndex--;
                    }
                    break;

                    case 1:
                    {
                        C2* pNextCont = reinterpret_cast<C2*>(nextItPathNode.get());
                        m_it.start(forward,pNextCont);
                        forward ? m_itPathNodeIndex++ : m_itPathNodeIndex--;
                    }
                    break;

                    case 2:
                    {
                        C3* pNextCont = reinterpret_cast<C3*>(nextItPathNode.get());
                        m_it.start(forward,pNextCont);
                        forward ? m_itPathNodeIndex++ : m_itPathNodeIndex--;
                    }
                    break;

                    case 3:
                    {
                        C4* pNextCont = reinterpret_cast<C4*>(nextItPathNode.get());
                        m_it.start(forward,pNextCont);
                        forward ? m_itPathNodeIndex++ : m_itPathNodeIndex--;
                    }
                    break;

                    default:
                        assert(0);
                        return;
                }

                continue;
            }

            return;
        }
    }

    template<class C1,class C2,class C3,class C4>
    bool compatible_path_iterator<C1,C2,C3,C4>::isForward() const
    {
        return m_it.isForward();
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_path_iterator<C1,C2,C3,C4>::seekBeginPathNode(bool forward)
    {
        if(!m_pItPath || m_itPathNodeIndex == -1)
        {
            assert(0);
            return;
        }

        const size_type numItConts = m_pItPath->size();
        if(!numItConts || numItConts <= m_itPathNodeIndex)
        {
            assert(0);
            return;
        }

        switch(m_it.typeIndex())
        {
            case 0:
            {
                const iterator_path_node& pathNode = m_it.pathNode();
                m_it.set(forward ? pathNode.get0()->begin() : pathNode.get0()->rbegin().base(),pathNode.get0());
            }
            break;

            case 1:
            {
                const iterator_path_node& pathNode = m_it.pathNode();
                m_it.set(forward ? pathNode.get1()->begin() : pathNode.get1()->rbegin().base(),pathNode.get1());
            }
            break;

            case 2:
            {
                const iterator_path_node& pathNode = m_it.pathNode();
                m_it.set(forward ? pathNode.get2()->begin() : pathNode.get2()->rbegin().base(),pathNode.get2());
            }
            break;

            case 3:
            {
                const iterator_path_node& pathNode = m_it.pathNode();
                m_it.set(forward ? pathNode.get3()->begin() : pathNode.get3()->rbegin().base(),pathNode.get3());
            }
            break;

            default:
                assert(0);
        }
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_path_iterator<C1,C2,C3,C4>::seekEndPathNode(bool forward)
    {
        if(!m_pItPath || m_itPathNodeIndex == -1)
        {
            assert(0);
            return;
        }

        const size_type numItConts = m_pItPath->size();
        if(!numItConts || numItConts <= m_itPathNodeIndex)
        {
            assert(0);
            return;
        }

        switch(m_it.typeIndex())
        {
            case 0:
            {
                const iterator_path_node& pathNode = m_it.pathNode();
                m_it.set(forward ? pathNode.get0()->end() : pathNode.get0()->rend().base(),pathNode.get0());
            }
            break;

            case 1:
            {
                const iterator_path_node& pathNode = m_it.pathNode();
                m_it.set(forward ? pathNode.get1()->end() : pathNode.get1()->rend().base(),pathNode.get1());
            }
            break;

            case 2:
            {
                const iterator_path_node& pathNode = m_it.pathNode();
                m_it.set(forward ? pathNode.get2()->end() : pathNode.get2()->rend().base(),pathNode.get2());
            }
            break;

            case 3:
            {
                const iterator_path_node& pathNode = m_it.pathNode();
                m_it.set(forward ? pathNode.get3()->end() : pathNode.get3()->rend().base(),pathNode.get3());
            }
            break;

            default:
                assert(0);
        }
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_path_iterator<C1,C2,C3,C4>::set(bool forward,
                                                    const compatible_iterator_path<C1,C2,C3,C4>& itPath)
    {
        assert(itPath.size());
        m_it.set(forward,forward ? itPath.front() : itPath.back());
        m_pItPath = &itPath;
        m_itPathNodeIndex = forward ? 0 : itPath.size()-1;
        m_asForward = forward;

        //Iterate to valid node.
        if(m_it.done())
        {
            step(forward);
        }
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_path_iterator<C1,C2,C3,C4>::clear()
    {
        m_it.clear();
        m_pItPath = 0;
        m_itPathNodeIndex = -1;
        m_asForward = true;
    }

    //compatible_path_const_iterator
    template<class C1,class C2,class C3,class C4>
    compatible_path_const_iterator<C1,C2,C3,C4>::compatible_path_const_iterator()
        : m_pItPath(0),
          m_itPathNodeIndex(-1),
          m_asForward(true)
    {
    }

    template<class C1,class C2,class C3,class C4>
    const compatible_const_iterator<C1,C2,C3,C4>& compatible_path_const_iterator<C1,C2,C3,C4>::get() const
    {
        return m_it;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_path_const_iterator<C1,C2,C3,C4>::start(bool forward)
    {
        if(!m_pItPath || m_itPathNodeIndex == -1)
        {
            assert(0);
            return;
        }

        const size_type numItConts = m_pItPath->size();
        if(!numItConts || numItConts <= m_itPathNodeIndex)
        {
            assert(0);
            return;
        }

        const iterator_path_node& itPathNode = forward ? *m_pItPath->begin() : *m_pItPath->back();
        switch(itPathNode.typeIndex())
        {
            case 0:
            {
                const C1* pCont = reinterpret_cast<const C1*>(itPathNode.get());
                m_it.start(forward,pCont);
            }
            break;

            case 1:
            {
                const C2* pCont = reinterpret_cast<const C2*>(itPathNode.get());
                m_it.start(forward,pCont);
            }
            break;

            case 2:
            {
                const C3* pCont = reinterpret_cast<const C3*>(itPathNode.get());
                m_it.start(forward,pCont);
            }
            break;

            case 3:
            {
                const C4* pCont = reinterpret_cast<const C4*>(itPathNode.get());
                m_it.start(forward,pCont);
            }
            break;

            default:
                assert(0);
        }
        m_asForward = forward;

        //Iterate to valid node.
        if(m_it.done())
        {
            step(forward);
        }
    }

    template<class C1,class C2,class C3,class C4>
    bool compatible_path_const_iterator<C1,C2,C3,C4>::done() const
    {
        if(!m_pItPath || m_itPathNodeIndex == -1)
        {
            assert(0);
            return true;
        }

        const size_type numItConts = m_pItPath->size();
        if(!numItConts || numItConts <= m_itPathNodeIndex)
        {
            assert(0);
            return true;
        }

        iterator it = m_it;
        size_type itPathNodeIndex = m_itPathNodeIndex;

        while(it.done())
        {
            if(m_asForward && itPathNodeIndex < numItConts-1 || !m_asForward && itPathNodeIndex > 0)
            {
                const iterator_path_node& nextItPathNode = (*m_pItPath)[itPathNodeIndex+(m_asForward ? +1 : -1)];
                switch(nextItPathNode.typeIndex())
                {
                    case 0:
                    {
                        const C1* pNextCont = reinterpret_cast<const C1*>(nextItPathNode.get());
                        it.start(m_asForward,pNextCont);
                        m_asForward ? itPathNodeIndex++ : itPathNodeIndex--;
                    }
                    break;

                    case 1:
                    {
                        const C2* pNextCont = reinterpret_cast<const C2*>(nextItPathNode.get());
                        it.start(m_asForward,pNextCont);
                        m_asForward ? itPathNodeIndex++ : itPathNodeIndex--;
                    }
                    break;

                    case 2:
                    {
                        const C3* pNextCont = reinterpret_cast<const C3*>(nextItPathNode.get());
                        it.start(m_asForward,pNextCont);
                        m_asForward ? itPathNodeIndex++ : itPathNodeIndex--;
                    }
                    break;

                    case 3:
                    {
                        const C4* pNextCont = reinterpret_cast<const C4*>(nextItPathNode.get());
                        it.start(m_asForward,pNextCont);
                        m_asForward ? itPathNodeIndex++ : itPathNodeIndex--;
                    }
                    break;

                    default:
                        assert(0);
                        return true;
                }

                continue;
            }

            return true;
        }

        return false;
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_path_const_iterator<C1,C2,C3,C4>::step(bool forward)
    {
        if(!m_pItPath || m_itPathNodeIndex == -1)
        {
            assert(0);
            return;
        }

        const size_type numItConts = m_pItPath->size();
        if(!numItConts || numItConts <= m_itPathNodeIndex)
        {
            assert(0);
            return;
        }

        m_it.step(forward);
        while(m_it.done())
        {
            if(forward && m_itPathNodeIndex < numItConts-1 || !forward && m_itPathNodeIndex > 0)
            {
                const iterator_path_node& nextItPathNode = (*m_pItPath)[m_itPathNodeIndex+(forward ? +1 : -1)];
                switch(nextItPathNode.typeIndex())
                {
                    case 0:
                    {
                        const C1* pNextCont = reinterpret_cast<const C1*>(nextItPathNode.get());
                        m_it.start(forward,pNextCont);
                        forward ? m_itPathNodeIndex++ : m_itPathNodeIndex--;
                    }
                    break;

                    case 1:
                    {
                        const C2* pNextCont = reinterpret_cast<const C2*>(nextItPathNode.get());
                        m_it.start(forward,pNextCont);
                        forward ? m_itPathNodeIndex++ : m_itPathNodeIndex--;
                    }
                    break;

                    case 2:
                    {
                        const C3* pNextCont = reinterpret_cast<const C3*>(nextItPathNode.get());
                        m_it.start(forward,pNextCont);
                        forward ? m_itPathNodeIndex++ : m_itPathNodeIndex--;
                    }
                    break;

                    case 3:
                    {
                        const C4* pNextCont = reinterpret_cast<const C4*>(nextItPathNode.get());
                        m_it.start(forward,pNextCont);
                        forward ? m_itPathNodeIndex++ : m_itPathNodeIndex--;
                    }
                    break;

                    default:
                        assert(0);
                        return;
                }

                continue;
            }

            return;
        }
    }

    template<class C1,class C2,class C3,class C4>
    bool compatible_path_const_iterator<C1,C2,C3,C4>::isForward() const
    {
        return m_it.isForward();
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_path_const_iterator<C1,C2,C3,C4>::seekBeginPathNode(bool forward)
    {
        if(!m_pItPath || m_itPathNodeIndex == -1)
        {
            assert(0);
            return;
        }

        const size_type numItConts = m_pItPath->size();
        if(!numItConts || numItConts <= m_itPathNodeIndex)
        {
            assert(0);
            return;
        }

        switch(m_it.typeIndex())
        {
            case 0:
            {
                const iterator_path_node& pathNode = m_it.pathNode();
                m_it.set(forward ? pathNode.get0()->begin() : pathNode.get0()->rbegin().base(),pathNode.get0());
            }
            break;

            case 1:
            {
                const iterator_path_node& pathNode = m_it.pathNode();
                m_it.set(forward ? pathNode.get1()->begin() : pathNode.get1()->rbegin().base(),pathNode.get1());
            }
            break;

            case 2:
            {
                const iterator_path_node& pathNode = m_it.pathNode();
                m_it.set(forward ? pathNode.get2()->begin() : pathNode.get2()->rbegin().base(),pathNode.get2());
            }
            break;

            case 3:
            {
                const iterator_path_node& pathNode = m_it.pathNode();
                m_it.set(forward ? pathNode.get3()->begin() : pathNode.get3()->rbegin().base(),pathNode.get3());
            }
            break;

            default:
                assert(0);
        }
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_path_const_iterator<C1,C2,C3,C4>::seekEndPathNode(bool forward)
    {
        if(!m_pItPath || m_itPathNodeIndex == -1)
        {
            assert(0);
            return;
        }

        const size_type numItConts = m_pItPath->size();
        if(!numItConts || numItConts <= m_itPathNodeIndex)
        {
            assert(0);
            return;
        }

        switch(m_it.typeIndex())
        {
            case 0:
            {
                const iterator_path_node& pathNode = m_it.pathNode();
                m_it.set(forward ? pathNode.get0()->end() : pathNode.get0()->rend().base(),pathNode.get0());
            }
            break;

            case 1:
            {
                const iterator_path_node& pathNode = m_it.pathNode();
                m_it.set(forward ? pathNode.get1()->end() : pathNode.get1()->rend().base(),pathNode.get1());
            }
            break;

            case 2:
            {
                const iterator_path_node& pathNode = m_it.pathNode();
                m_it.set(forward ? pathNode.get2()->end() : pathNode.get2()->rend().base(),pathNode.get2());
            }
            break;

            case 3:
            {
                const iterator_path_node& pathNode = m_it.pathNode();
                m_it.set(forward ? pathNode.get3()->end() : pathNode.get3()->rend().base(),pathNode.get3());
            }
            break;

            default:
                assert(0);
        }
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_path_const_iterator<C1,C2,C3,C4>::set(bool forward,
                                                          const compatible_const_iterator_path<C1,C2,C3,C4>& itPath)
    {
        assert(itPath.size());
        m_it.set(forward,forward ? itPath.front() : itPath.back());
        m_pItPath = &itPath;
        m_itPathNodeIndex = forward ? 0 : itPath.size()-1;
        m_asForward = forward;

        //Iterate to valid node.
        if(m_it.done())
        {
            step(forward);
        }
    }

    template<class C1,class C2,class C3,class C4>
    void compatible_path_const_iterator<C1,C2,C3,C4>::clear()
    {
        m_it.clear();
        m_pItPath = 0;
        m_itPathNodeIndex = -1;
        m_asForward = true;
    }
}
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: patch #1
От: Vain Россия google.ru
Дата: 14.05.10 19:16
Оценка:
Здравствуйте, Vain, Вы писали:

Забыл исправить, неправильно итерируется если контейнеры повторяются:
    my_compatible_const_it_path itPath;
    itPath.resize(5);
    {
        itPath[0] = &cont1;
        itPath[1] = &cont1;
        itPath[2] = &cont2;
        itPath[3] = &cont1;
        itPath[4] = &cont1;
    }


Исправленная версия здесь
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: v1.1
От: Vain Россия google.ru
Дата: 30.12.10 18:18
Оценка:
Здравствуйте, Vain, Вы писали:

Версия с услучшениями и исправлениями:
// v1.1
//  - Fixed bug with stepping out of container range in one case.
//  - Added reverse iterator adaptor for cases where reverse iterator not implemented or
//    implemented partially.
//  - Added internal availability to check iterators on singularity with several restrictions.
//  - Added functions "erase" to support erasing in container, "getContainerX" to read out
//    container address which uses by iterator and "isForward" to find out in which direction
//    iterator is operated.
//  - Now all 3 main functions - "start", "step" and "done" has the parameter "forward" to
//    explicitly qualify operational direction.
//  - Now iterator can afford setup of container pointer before iterator to container itself
//    for cases where container address known before container iterator. To update iterator
//    later then call to "set" function.
//    (for example: "my_compatible_iterator tmp(mycontainer::iterator(),&mycontainer);").
//  - Other fixes and changes.
//
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: Итератор по набору std контейнеров
От: Vain Россия google.ru
Дата: 31.07.11 15:43
Оценка:
Здравствуйте, Vain, Вы писали:

Исходники перехали на sourceforge
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.