Skip to content

Instantly share code, notes, and snippets.

@upsuper
Last active August 29, 2015 14:23
Show Gist options
  • Save upsuper/bce38e7d40b9d4414712 to your computer and use it in GitHub Desktop.
Save upsuper/bce38e7d40b9d4414712 to your computer and use it in GitHub Desktop.

Revisions

  1. upsuper revised this gist Jun 17, 2015. 1 changed file with 0 additions and 84 deletions.
    84 changes: 0 additions & 84 deletions gistfile1.cpp
    Original file line number Diff line number Diff line change
    @@ -61,18 +61,6 @@ class ReverseIterator
    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);
    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);
    template<typename Iterator1, typename Iterator2>
    friend bool operator>=(const ReverseIterator<Iterator1>& aIter1,
    const ReverseIterator<Iterator2>& aIter2);

    private:
    IteratorT mCurrent;
    @@ -94,38 +82,6 @@ operator!=(const ReverseIterator<Iterator1>& aIter1,
    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;
    }

    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;
    }

    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>
    @@ -214,18 +170,6 @@ class IntegerIterator
    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);
    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);
    template<typename IntType1, typename IntType2>
    friend bool operator>=(const IntegerIterator<IntType1>& aIter1,
    const IntegerIterator<IntType2>& aIter2);

    private:
    IntTypeT mCurrent;
    @@ -245,34 +189,6 @@ bool operator!=(const IntegerIterator<IntType1>& aIter1,
    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 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 IntType1, typename IntType2>
    bool operator>=(const IntegerIterator<IntType1>& aIter1,
    const IntegerIterator<IntType2>& aIter2)
    {
    return aIter1.mCurrent >= aIter2.mCurrent;
    }

    template<typename IntTypeT>
    class IntegerRange
    {
  2. upsuper created this gist Jun 17, 2015.
    335 changes: 335 additions & 0 deletions gistfile1.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,335 @@
    #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);
    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);
    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;
    }

    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;
    }

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