Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <algorithm>
- namespace Views
- {
- template <typename It, typename Pred> class FilterIterator
- {
- It mCur;
- It mEnd;
- Pred mPred;
- void satisfy() noexcept
- {
- while (mCur != mEnd && !mPred(*mCur))
- ++mCur;
- }
- public:
- using iterator_category = std::forward_iterator_tag;
- using value_type = typename std::iterator_traits<It>::value_type;
- using difference_type =
- typename std::iterator_traits<It>::difference_type;
- using pointer = typename std::iterator_traits<It>::pointer;
- using reference = typename std::iterator_traits<It>::reference;
- FilterIterator(It first, It last, Pred p)
- : mCur(first), mEnd(last), mPred(std::move(p))
- {
- satisfy();
- }
- reference operator*() const
- {
- return *mCur;
- }
- pointer operator->() const
- {
- return &*mCur;
- }
- FilterIterator& operator++()
- {
- ++mCur;
- satisfy();
- return *this;
- }
- FilterIterator operator++(int)
- {
- auto tmp = *this;
- ++*this;
- return tmp;
- }
- friend bool operator==(const FilterIterator& a,
- const FilterIterator& b)
- {
- return a.mCur == b.mCur;
- }
- friend bool operator!=(const FilterIterator& a,
- const FilterIterator& b)
- {
- return !(a == b);
- }
- };
- template <typename Range, typename F> class TransformView;
- template <typename It, typename F> class TransformIterator
- {
- It mIt;
- F mF;
- public:
- using iterator_category = std::forward_iterator_tag;
- using value_type = decltype(mF(*mIt));
- using difference_type =
- typename std::iterator_traits<It>::difference_type;
- // no pointer/reference aliases: --> returns by value
- TransformIterator(It it, F fun) : mIt(it), mF(std::move(fun))
- {
- }
- auto operator*() const
- {
- return mF(*mIt);
- }
- auto operator->() const = delete;
- TransformIterator& operator++()
- {
- ++mIt;
- return *this;
- }
- TransformIterator operator++(int)
- {
- auto tmp = *this;
- ++*this;
- return tmp;
- }
- friend bool operator==(const TransformIterator& a,
- const TransformIterator& b)
- {
- return a.mIt == b.mIt;
- }
- friend bool operator!=(const TransformIterator& a,
- const TransformIterator& b)
- {
- return !(a == b);
- }
- };
- template <typename Range, typename Pred> class FilterView
- {
- Range* mRange;
- Pred mPred;
- public:
- FilterView(Range& r, Pred p) : mRange(&r), mPred(std::move(p))
- {
- }
- auto begin()
- {
- return FilterIterator(mRange->begin(), mRange->end(), mPred);
- }
- auto end()
- {
- return FilterIterator(mRange->end(), mRange->end(), mPred);
- }
- template <typename T> T First()
- {
- if (begin() == end())
- {
- return T{};
- }
- return *begin();
- }
- // chaining
- template <typename P2> auto Where(P2 p2)
- {
- return FilterView<FilterView, P2>(*this, std::move(p2));
- }
- template <typename F> auto Select(F f)
- {
- return TransformView<FilterView, F>(*this, std::move(f));
- }
- };
- template <typename Range, typename F> class TransformView
- {
- Range* mRange;
- F mF;
- public:
- TransformView(Range& r, F fun) : mRange(&r), mF(std::move(fun))
- {
- }
- auto begin()
- {
- return TransformIterator(mRange->begin(), mF);
- }
- auto end()
- {
- return TransformIterator(mRange->end(), mF);
- }
- template <typename T> T First()
- {
- if (begin() == end())
- {
- return T{};
- }
- return *begin();
- }
- template <typename P2> auto Where(P2 p2)
- {
- return FilterView<TransformView, P2>(*this, std::move(p2));
- }
- template <typename F2> auto Select(F2 f2)
- {
- return TransformView<TransformView, F2>(*this, std::move(f2));
- }
- };
- template <typename Range, typename Pred>
- auto MakeFilterView(Range& r, Pred p)
- {
- return FilterView<Range, Pred>(r, std::move(p));
- }
- template <typename Range, typename F> auto MakeTransformView(Range& r, F f)
- {
- return TransformView<Range, F>(r, std::move(f));
- }
- } // namespace Views
Advertisement
Add Comment
Please, Sign In to add comment