Instantly share code, notes, and snippets.
Last activeAugust 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> | |
namespacemozilla { | |
template<typename Iterator> | |
structIteratorTraits | |
{ | |
typedeftypename Iterator::ValueType ValueType; | |
}; | |
template<typename T> | |
structIteratorTraits<T*> | |
{ | |
typedef T ValueType; | |
}; | |
template<typename T> | |
structIteratorTraits<const T*> | |
{ | |
typedefconst T ValueType; | |
}; | |
}// namespace mozilla | |
namespacemozilla { | |
template<typename IteratorT> | |
classReverseIterator | |
{ | |
public: | |
typedeftypename IteratorTraits<IteratorT>::ValueType ValueType; | |
template<typename Iterator> | |
explicitReverseIterator(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; } | |
ReverseIteratoroperator++(int) {auto ret = *this;mCurrent--;return ret; } | |
ReverseIteratoroperator--(int) {auto ret = *this;mCurrent++;return ret; } | |
/* Comparison operators*/ | |
template<typename Iterator1,typename Iterator2> | |
friendbooloperator==(const ReverseIterator<Iterator1>& aIter1, | |
const ReverseIterator<Iterator2>& aIter2); | |
template<typename Iterator1,typename Iterator2> | |
friendbooloperator!=(const ReverseIterator<Iterator1>& aIter1, | |
const ReverseIterator<Iterator2>& aIter2); | |
private: | |
IteratorTmCurrent; | |
}; | |
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; | |
} | |
namespacedetail { | |
template<typename IteratorT> | |
classIteratorRange | |
{ | |
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) { } | |
iteratorbegin()const {returnmIterBegin; } | |
const_iteratorcbegin()const {returnbegin(); } | |
iteratorend()const {returnmIterEnd; } | |
const_iteratorcend()const {returnend(); } | |
reverse_iteratorrbegin()const {returnreverse_iterator(mIterEnd); } | |
const_reverse_iteratorcrbegin()const {returnrbegin(); } | |
reverse_iteratorrend()const {returnreverse_iterator(mIterBegin); } | |
const_reverse_iteratorcrend()const {returnrend(); } | |
private: | |
IteratorTmIterBegin; | |
IteratorTmIterEnd; | |
}; | |
}// 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 | |
namespacemozilla { | |
namespacedetail { | |
template<typename IntTypeT> | |
classIntegerIterator | |
{ | |
public: | |
typedefconst IntTypeT ValueType; | |
template<typename IntType> | |
explicitIntegerIterator(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 {returnmCurrent; } | |
/* Increment and decrement operators*/ | |
IntegerIterator&operator++() { ++mCurrent;return *this; } | |
IntegerIterator&operator--() { --mCurrent;return *this; } | |
IntegerIteratoroperator++(int) {auto ret = *this; ++mCurrent;return ret; } | |
IntegerIteratoroperator--(int) {auto ret = *this; --mCurrent;return ret; } | |
/* Comparison operators*/ | |
template<typename IntType1,typename IntType2> | |
friendbooloperator==(const IntegerIterator<IntType1>& aIter1, | |
const IntegerIterator<IntType2>& aIter2); | |
template<typename IntType1,typename IntType2> | |
friendbooloperator!=(const IntegerIterator<IntType1>& aIter1, | |
const IntegerIterator<IntType2>& aIter2); | |
private: | |
IntTypeTmCurrent; | |
}; | |
template<typename IntType1,typename IntType2> | |
booloperator==(const IntegerIterator<IntType1>& aIter1, | |
const IntegerIterator<IntType2>& aIter2) | |
{ | |
return aIter1.mCurrent == aIter2.mCurrent; | |
} | |
template<typename IntType1,typename IntType2> | |
booloperator!=(const IntegerIterator<IntType1>& aIter1, | |
const IntegerIterator<IntType2>& aIter2) | |
{ | |
return aIter1.mCurrent != aIter2.mCurrent; | |
} | |
template<typename IntTypeT> | |
classIntegerRange | |
{ | |
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> | |
explicitIntegerRange(IntType aEnd) | |
: mBegin(0), mEnd(aEnd) { } | |
template<typename IntType1,typename IntType2> | |
IntegerRange(IntType1 aBegin, IntType2 aEnd) | |
:mBegin(aBegin),mEnd(aEnd) { } | |
iteratorbegin()const {returniterator(mBegin); } | |
const_iteratorcbegin()const {returnbegin(); } | |
iteratorend()const {returniterator(mEnd); } | |
const_iteratorcend()const {returnend(); } | |
reverse_iteratorrbegin()const {returnreverse_iterator(mEnd); } | |
const_reverse_iteratorcrbegin()const {returnrbegin(); } | |
reverse_iteratorrend()const {returnreverse_iterator(mBegin); } | |
const_reverse_iteratorcrend()const {returnrend(); } | |
private: | |
IntTypeTmBegin; | |
IntTypeTmEnd; | |
}; | |
}// 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 | |
usingnamespacemozilla; | |
intmain() | |
{ | |
size_t n; | |
std::cin >> n; | |
for (auto i :Reversed(MakeRange(n))) { | |
std::cout << i << std::endl; | |
} | |
} |
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment