#include <iostream> 
#include <iterator> 
#include <stdexcept> 
#include <utility> 
#include <vector> 
  
using namespace std::rel_ops; 
  
template<typename T> 
class Fibonacci_Sequence 
{ 
        static std::vector<T> mSequence; 
  
public: 
  
        typedef T value_type; 
        typedef typename std::vector<T>::size_type size_type; 
  
        Fibonacci_Sequence(): 
                mBegin(0), 
                mEnd(0) 
        { 
                if(mSequence.empty()) 
                { 
                        mSequence.push_back(0); 
  
                        T before_last = 0, last = 1; 
  
                        while(last >= before_last) 
                        { 
                                mSequence.push_back(last); 
                                last += before_last; 
                                before_last = last - before_last; 
                        } 
  
                        mEnd.mN = mSequence.size(); 
                } 
        } 
  
        class iterator : public std::iterator<std::random_access_iterator_tag, 
                                              T, 
                                              size_type, 
                                              T*, 
                                              T> 
        { 
                friend class Fibonacci_Sequence; 
  
                mutable size_type mN; 
  
                iterator(size_type n): 
                        mN(n) {} 
  
        public: 
  
                iterator(iterator const& i): 
                        mN(i.mN) {} 
  
                T operator*() const 
                { 
                        if(mN >= mSequence.size()) 
                                throw std::out_of_range("Fibonacci_Sequence::iterator::operator*() : Cannot dereference iterator! To high!"); 
                        return mSequence[mN]; 
                } 
  
                iterator operator++() const 
                { 
                        return ++mN; 
                } 
  
                iterator operator++(int) const 
                { 
                        ++*this; 
                        return mN - 1; 
                } 
  
                iterator operator+(size_type a) const 
                { 
                        return mN + a; 
                } 
  
                iterator operator+=(size_type a) const 
                { 
                        return mN += a; 
                } 
  
                iterator operator--() const 
                { 
                        if(!mN) 
                                throw std::out_of_range("Fibonacci_Sequence::iterator::operator--() : The lower end of the sequence was reached! Invalid decrement!"); 
                        return --mN; 
                } 
  
                iterator operator--(int) const 
                { 
                        --*this; 
                        return mN + 1; 
                } 
  
                iterator operator-(size_type a) const 
                { 
                        if(mN - a > mN) 
                                throw std::out_of_range("Fibonacci_Sequence::iterator::operator-() : The lower end of the sequence was reached! Invalid subtraction!"); 
                        return mN - a; 
                } 
  
                int operator-(iterator a) const 
                { 
                        return mN - a.mN; 
                } 
  
                iterator operator-=(size_type a) const 
                { 
                        return (*this = *this - a); 
                } 
  
                friend bool operator<(iterator a, iterator b) 
                { 
                        return a.mN < b.mN; 
                } 
  
                friend bool operator==(iterator a, iterator b) 
                { 
                        return a.mN == b.mN; 
                } 
        }; 
  
        typedef std::reverse_iterator<iterator> reverse_iterator; 
  
        iterator begin() const 
        { 
                return mBegin; 
        } 
  
        iterator end() const 
        { 
                return mEnd; 
        } 
        reverse_iterator rbegin() const 
        { 
                return reverse_iterator(mSequence.size()); 
        } 
  
        reverse_iterator rend() const 
        { 
                return reverse_iterator(0); 
        } 
  
        T operator[](size_type n) const 
        { 
                return mSequence[n]; 
        } 
  
        size_type size() const 
        { 
                return mSequence.size(); 
        } 
  
        T at(size_type n) const 
        { 
                if(n >= mSequence.size()) 
                        throw std::out_of_range("Fibonacci_Sequence::at() : Index to high!"); 
  
                return mSequence[n]; 
        } 
  
private: 
  
        iterator const mBegin, mEnd; 
}; 
  
template<typename T> 
std::vector<T> Fibonacci_Sequence<T>::mSequence; 
  
int main() 
{ 
        Fibonacci_Sequence<unsigned> sequence; 
        std::copy(sequence.rbegin(), sequence.rend(), std::ostream_iterator<unsigned>(std::cout, "\n")); 
}