Last active
August 29, 2015 14:23
-
-
Save upsuper/bce38e7d40b9d4414712 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <stddef.h> | |
namespace mozilla { | |
template<typename Iterator> | |
struct IteratorTraits | |
{ | |
typedef typename Iterator::ValueType ValueType; | |
}; | |
template<typename T> | |
struct IteratorTraits<T*> | |
{ | |
typedef T ValueType; | |
}; | |
template<typename T> | |
struct IteratorTraits<const T*> | |
{ | |
typedef const T ValueType; | |
}; | |
} // namespace mozilla | |
namespace mozilla { | |
template<typename IteratorT> | |
class ReverseIterator | |
{ | |
public: | |
typedef typename IteratorTraits<IteratorT>::ValueType ValueType; | |
template<typename Iterator> | |
explicit ReverseIterator(Iterator aIter) | |
: mCurrent(aIter) { } | |
template<typename Iterator> | |
ReverseIterator(const ReverseIterator<Iterator>& aOther) | |
: mCurrent(aOther.mCurrent) { } | |
ValueType& operator*() const | |
{ | |
IteratorT tmp = mCurrent; | |
return *--tmp; | |
} | |
/* Increments and decrements operators */ | |
ReverseIterator& operator++() { --mCurrent; return *this; } | |
ReverseIterator& operator--() { ++mCurrent; return *this; } | |
ReverseIterator operator++(int) { auto ret = *this; mCurrent--; return ret; } | |
ReverseIterator operator--(int) { auto ret = *this; mCurrent++; return ret; } | |
/* Comparison operators */ | |
template<typename Iterator1, typename Iterator2> | |
friend bool operator==(const ReverseIterator<Iterator1>& aIter1, | |
const ReverseIterator<Iterator2>& aIter2); | |
template<typename Iterator1, typename Iterator2> | |
friend bool operator!=(const ReverseIterator<Iterator1>& aIter1, | |
const ReverseIterator<Iterator2>& aIter2); | |
private: | |
IteratorT mCurrent; | |
}; | |
template<typename Iterator1, typename Iterator2> | |
bool | |
operator==(const ReverseIterator<Iterator1>& aIter1, | |
const ReverseIterator<Iterator2>& aIter2) | |
{ | |
return aIter1.mCurrent == aIter2.mCurrent; | |
} | |
template<typename Iterator1, typename Iterator2> | |
bool | |
operator!=(const ReverseIterator<Iterator1>& aIter1, | |
const ReverseIterator<Iterator2>& aIter2) | |
{ | |
return aIter1.mCurrent != aIter2.mCurrent; | |
} | |
namespace detail { | |
template<typename IteratorT> | |
class IteratorRange | |
{ | |
public: | |
typedef IteratorT iterator; | |
typedef IteratorT const_iterator; | |
typedef ReverseIterator<IteratorT> reverse_iterator; | |
typedef ReverseIterator<IteratorT> const_reverse_iterator; | |
template<typename Iterator1, typename Iterator2> | |
IteratorRange(Iterator1 aIterBegin, Iterator2 aIterEnd) | |
: mIterBegin(aIterBegin), mIterEnd(aIterEnd) { } | |
template<typename Iterator> | |
IteratorRange(const IteratorRange<Iterator>& aOther) | |
: mIterBegin(aOther.mIterBegin), mIterEnd(aOther.mIterEnd) { } | |
iterator begin() const { return mIterBegin; } | |
const_iterator cbegin() const { return begin(); } | |
iterator end() const { return mIterEnd; } | |
const_iterator cend() const { return end(); } | |
reverse_iterator rbegin() const { return reverse_iterator(mIterEnd); } | |
const_reverse_iterator crbegin() const { return rbegin(); } | |
reverse_iterator rend() const { return reverse_iterator(mIterBegin); } | |
const_reverse_iterator crend() const { return rend(); } | |
private: | |
IteratorT mIterBegin; | |
IteratorT mIterEnd; | |
}; | |
} // namespace detail | |
template<typename Range> | |
detail::IteratorRange<typename Range::reverse_iterator> | |
Reversed(Range& aRange) | |
{ | |
return {aRange.rbegin(), aRange.rend()}; | |
} | |
template<typename Range> | |
detail::IteratorRange<typename Range::const_reverse_iterator> | |
Reversed(const Range& aRange) | |
{ | |
return {aRange.rbegin(), aRange.rend()}; | |
} | |
} // namespace mozilla | |
namespace mozilla { | |
namespace detail { | |
template<typename IntTypeT> | |
class IntegerIterator | |
{ | |
public: | |
typedef const IntTypeT ValueType; | |
template<typename IntType> | |
explicit IntegerIterator(IntType aCurrent) | |
: mCurrent(aCurrent) { } | |
template<typename IntType> | |
IntegerIterator(const IntegerIterator<IntType>& aOther) | |
: mCurrent(aOther.mCurrent) { } | |
// Since operator* is required to return a reference, we return | |
// a reference to our member here. | |
const IntTypeT& operator*() const { return mCurrent; } | |
/* Increment and decrement operators */ | |
IntegerIterator& operator++() { ++mCurrent; return *this; } | |
IntegerIterator& operator--() { --mCurrent; return *this; } | |
IntegerIterator operator++(int) { auto ret = *this; ++mCurrent; return ret; } | |
IntegerIterator operator--(int) { auto ret = *this; --mCurrent; return ret; } | |
/* Comparison operators */ | |
template<typename IntType1, typename IntType2> | |
friend bool operator==(const IntegerIterator<IntType1>& aIter1, | |
const IntegerIterator<IntType2>& aIter2); | |
template<typename IntType1, typename IntType2> | |
friend bool operator!=(const IntegerIterator<IntType1>& aIter1, | |
const IntegerIterator<IntType2>& aIter2); | |
private: | |
IntTypeT mCurrent; | |
}; | |
template<typename IntType1, typename IntType2> | |
bool operator==(const IntegerIterator<IntType1>& aIter1, | |
const IntegerIterator<IntType2>& aIter2) | |
{ | |
return aIter1.mCurrent == aIter2.mCurrent; | |
} | |
template<typename IntType1, typename IntType2> | |
bool operator!=(const IntegerIterator<IntType1>& aIter1, | |
const IntegerIterator<IntType2>& aIter2) | |
{ | |
return aIter1.mCurrent != aIter2.mCurrent; | |
} | |
template<typename IntTypeT> | |
class IntegerRange | |
{ | |
public: | |
typedef IntegerIterator<IntTypeT> iterator; | |
typedef IntegerIterator<IntTypeT> const_iterator; | |
typedef ReverseIterator<IntegerIterator<IntTypeT>> reverse_iterator; | |
typedef ReverseIterator<IntegerIterator<IntTypeT>> const_reverse_iterator; | |
template<typename IntType> | |
explicit IntegerRange(IntType aEnd) | |
: mBegin(0), mEnd(aEnd) { } | |
template<typename IntType1, typename IntType2> | |
IntegerRange(IntType1 aBegin, IntType2 aEnd) | |
: mBegin(aBegin), mEnd(aEnd) { } | |
iterator begin() const { return iterator(mBegin); } | |
const_iterator cbegin() const { return begin(); } | |
iterator end() const { return iterator(mEnd); } | |
const_iterator cend() const { return end(); } | |
reverse_iterator rbegin() const { return reverse_iterator(mEnd); } | |
const_reverse_iterator crbegin() const { return rbegin(); } | |
reverse_iterator rend() const { return reverse_iterator(mBegin); } | |
const_reverse_iterator crend() const { return rend(); } | |
private: | |
IntTypeT mBegin; | |
IntTypeT mEnd; | |
}; | |
} // namespace detail | |
template<typename IntType> | |
detail::IntegerRange<IntType> | |
MakeRange(IntType aEnd) | |
{ | |
return detail::IntegerRange<IntType>(aEnd); | |
} | |
template<typename IntType1, typename IntType2> | |
detail::IntegerRange<IntType2> | |
MakeRange(IntType1 aBegin, IntType2 aEnd) | |
{ | |
return detail::IntegerRange<IntType2>(aBegin, aEnd); | |
} | |
} // namespace mozilla | |
using namespace mozilla; | |
int main() | |
{ | |
size_t n; | |
std::cin >> n; | |
for (auto i : Reversed(MakeRange(n))) { | |
std::cout << i << std::endl; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment