Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <iostream>
- #include <set>
- #include <vector>
- template <class T>
- class Range {
- public:
- Range(const T upper) : Range(0, upper, 1) {}
- Range(const T lower, const T upper) : Range(lower, upper, 1) {}
- Range(const T lower, const T upper, const T step)
- : lower_(lower), upper_(upper), step_(step) {}
- class iterator {
- public:
- iterator(const Range &r, const T val) : owner_(r), val_(val) {}
- T operator*() const { return val_; }
- bool operator!=(const iterator &other) const { return val_ < other.val_; }
- iterator operator++() {
- val_ += owner_.step_;
- return *this;
- }
- iterator reset() {
- val_ = lower_;
- return *this;
- }
- private:
- const Range &owner_;
- T val_;
- };
- iterator begin() const { return iterator(*this, lower_); }
- iterator end() const { return iterator(*this, upper_); }
- private:
- T lower_, upper_, step_;
- };
- template <class T>
- Range<T> range(T low, T up, T step) {
- return Range<T>(low, up, step);
- }
- template <class T>
- class Range3D {
- public:
- Range3D(const T max) : Range3D({max, max}, {max, max}, {max, max}) {}
- Range3D(std::pair<T, T> xbounds, std::pair<T, T> ybounds,
- std::pair<T, T> zbounds)
- : xbounds_{xbounds}, ybounds_{ybounds}, zbounds_{zbounds} {}
- class iterator {
- public:
- iterator(const Range3D &r, const T x, const T y, const T z)
- : owner_{r}, x_{x}, y_{y}, z_{z} {}
- const iterator &operator*() const { return *this; }
- bool operator!=(const iterator &other) const {
- return x_ != other.x_ && y_ != other.y_ && z_ != other.z_;
- }
- iterator operator++() {
- ++z_;
- if (z_ == owner_.zbounds_.second) {
- z_ = owner_.zbounds_.first;
- ++y_;
- if (y_ == owner_.ybounds_.second) {
- y_ = owner_.ybounds_.first;
- ++x_;
- }
- }
- return *this;
- }
- T x() const { return x_; }
- T y() const { return y_; }
- T z() const { return z_; }
- private:
- const Range3D &owner_;
- T x_, y_, z_;
- };
- iterator begin() const {
- return iterator{*this, xbounds_.first, ybounds_.first, zbounds_.first};
- }
- iterator end() const {
- return iterator{*this, xbounds_.second, ybounds_.second, zbounds_.second};
- }
- private:
- std::pair<T, T> xbounds_, ybounds_, zbounds_;
- };
- template <class T, class U>
- class Enumeration {
- public:
- Enumeration(const T &begin, const T &end) : Enumeration(begin, end, 0) {}
- Enumeration(const T &begin, const T &end, int start_idx)
- : begin_{begin}, end_{end}, start_idx_{start_idx} {};
- class iterator {
- public:
- iterator(const Enumeration &e, const T val)
- : owner_(e), val_(val), idx_(e.start_idx_) {}
- iterator operator*() const { return *this; }
- bool operator!=(const iterator &other) const { return val_ != other.val_; }
- iterator operator++() {
- ++val_;
- ++idx_;
- return *this;
- }
- int idx() const { return idx_; }
- U value() const { return *val_; }
- private:
- const Enumeration &owner_;
- T val_;
- int idx_;
- };
- iterator begin() { return iterator{*this, begin_}; }
- iterator end() { return iterator{*this, end_}; }
- private:
- T begin_, end_;
- int start_idx_;
- };
- template <class T>
- auto enumerate(const T &begin, const T &end, int i0 = 0) {
- return Enumeration<T, decltype(*begin)>(begin, end, i0);
- }
- int main() {
- std::vector<int> x{10, 20, 30, 40, 50};
- for (const auto &e : enumerate(x.begin(), x.end())) {
- std::cout << e.idx() << " " << e.value() << std::endl;
- }
- std::cout << std::endl;
- std::set<int> y{10, 20, 3, 3, 40, 10, 50};
- for (const auto &e : enumerate(y.begin(), y.end())) {
- std::cout << e.idx() << " " << e.value() << std::endl;
- }
- std::cout << std::endl;
- std::string s{"The cake is a lie!"};
- for (const auto &e : enumerate(s.begin(), s.end())) {
- std::cout << e.idx() << " " << e.value() << std::endl;
- }
- for(const auto &i : Range3D<int>({0, 3}, {0, 3}, {0, 3})) {
- std::cout << i.x() << " " << i.y() << " " << i.z() << std::endl;
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment