Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef RANGE_HPP
- #define RANGE_HPP
- #include <cstddef>
- #include <iterator>
- /**
- * Class should behave the same way as range in python.
- * @tparam T For simplicity T will be numeric type.
- */
- template<typename T>
- class Range {
- struct Iterator {
- using value_type = T;
- using iterator_category = std::forward_iterator_tag;
- using difference_type = ptrdiff_t;
- using pointer = const T *;
- using reference = const T &;
- Iterator(T from, T to, T step) : to_(to), step_(step), current_(from) {};
- Iterator() : Iterator(0, 0, 0) {};
- T &operator*() {
- return current_;
- }
- T *operator->() {
- return ¤t_;
- }
- bool operator==(Iterator const &that) const {
- return (that.current_ == current_ && that.step_ == step_ && to_ == that.to_) ||
- (!canDereference() && !that.canDereference());
- }
- bool operator!=(Iterator const &that) const {
- return !(that == *this);
- }
- Iterator &operator++() {
- current_ += step_;
- return *this;
- }
- Iterator operator++(int) {
- Iterator copy = *this;
- current_ += step_;
- return copy;
- }
- private:
- friend Range;
- T to_;
- T step_;
- T current_;
- bool canDereference() const {
- return current_ * sgn(step_) < to_ * sgn(step_);
- }
- T sgn(T val) const {
- return (T(0) < val) - (val < T(0));
- }
- };
- public:
- using iterator = Iterator;
- using const_iterator = Iterator;
- Range(T from, T to, T step) : from_(from), to_(to), step_(step) {};
- iterator begin() const { return Iterator(from_, to_, step_); }
- iterator end() const { return Iterator(0, 0, 0); }
- private:
- T from_, to_, step_;
- };
- template<typename T>
- auto range(T from, T to, T step) {
- return Range<T>(from, to, step);
- }
- template<typename T>
- auto range(T from, T to) {
- return Range<T>(from, to, 1);
- }
- template<typename T>
- auto range(T to) {
- return Range<T>(0, to, 1);
- }
- #endif // RANGE_HPP
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement