1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| #include <utility> #include <iterator> #include <algorithm> #include <numeric> namespace franges { using std::begin;using std::end;using std::cbegin;using std::cend;using std::reverse_iterator; template<typename Iter> struct base_view { Iter l, r; typedef Iter iterator; base_view(Iter _l, Iter _r) : l(_l), r(_r) {} Iter begin() const {return l;} Iter end() const {return r;} Iter cbegin() const {return l;} Iter cend() const {return r;} reverse_iterator<Iter> rbegin() const {return reverse_iterator<Iter>(l);} reverse_iterator<Iter> rend() const {return reverse_iterator<Iter>(r);} }; namespace vw { template<typename Container> base_view<typename Container::iterator> view(Container& con) { return base_view<decltype(begin(con))>(begin(con), end(con)); } template<typename Container> base_view<typename Container::iterator> view(const Container& con) { return base_view<decltype(cbegin(con))>(cbegin(con), cend(con)); } struct cut { int l, r; cut(int _l, int _r) : l(_l), r(_r) {} cut(int _r) : l(0), r(_r) {} template<typename Range> decltype(auto) operator() (Range& range) const { auto itl = begin(range), itr = begin(range); std::advance(itl, l), std::advance(itr, r); return base_view<decltype(itl)>(itl, itr); } template<typename Range> decltype(auto) operator() (const Range& range) const { auto itl = cbegin(range), itr = cbegin(range); std::advance(itl, l), std::advance(itr, r); return base_view<decltype(itl)>(itl, itr); } }; struct drop { int x; drop(int _x) : x(_x) {} template<typename Range> decltype(auto) operator() (Range& range) const { auto itl = begin(range); std::advance(itl, x); return base_view<decltype(itl)>(itl, end(range)); } template<typename Range> decltype(auto) operator() (const Range& range) const { auto itl = cbegin(range); std::advance(itl, x); return base_view<decltype(itl)>(itl, cend(range)); } }; template<typename Value> class value_iterator : public std::iterator<std::random_access_iterator_tag, Value> { Value x; using this_iterator = value_iterator<Value>; public: value_iterator() = default; value_iterator(int _x) : x(_x) {} value_iterator(const this_iterator&) = default; value_iterator(this_iterator&&) = default; friend bool operator==(const this_iterator&lhs, const this_iterator& rhs) {return lhs.x == rhs.x;} friend bool operator!=(const this_iterator&lhs, const this_iterator& rhs) {return lhs.x != rhs.x;} friend bool operator<(const this_iterator&lhs, const this_iterator& rhs) {return lhs.x < rhs.x;} int operator-(const this_iterator& oth) const {return x - oth.x;} this_iterator operator+(int oth) const {return x + oth;} this_iterator operator-(int oth) const {return x - oth;} this_iterator& operator+=(int oth) {x += oth; return *this;} this_iterator& operator-=(int oth) {x -= oth; return *this;} this_iterator& operator++() {++x;return *this;} this_iterator& operator--() {--x;return *this;} int& operator*() {return x;} }; using num_iterator = value_iterator<int>; base_view<num_iterator> range(int l, int r) { return base_view<num_iterator>(l, r); } struct reverse_t { template<typename Range> auto operator()(const Range& v) const {return base_view<decltype(rbegin(v))>(rbegin(v), rend(v));} template<typename Range> auto operator()(Range& v) const {return base_view<decltype(rbegin(v))>(rbegin(v), rend(v));} } reverse; } namespace fn { # define movefunc(funcname) const auto funcname = [](auto& cont, auto... args) {return std::funcname(begin(cont), end(cont), args...);} movefunc(sort); movefunc(reverse); movefunc(fill); movefunc(iota); movefunc(partial_sum); # undef movefunc } } template<typename Value, typename Func> auto operator|(Value&& l, Func r) { return r(std::forward<Value>(l)); } template<typename Value, typename Func> Value& operator|=(Value& l, Func r) { return l = r(l); } #define molambda(expr) ([&](const auto& _) {return expr;}) #define bilambda(expr) ([&](const auto& a, const auto& b) {return expr;})
|