#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"));
}