You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

56 lines
1.5 KiB

/**
* Copyright (c) 2018 Niklas Rosenstein
* MIT licensed.
*
* @description Provides a #range() iterator.
*/
#pragma once
#include <cstddef>
#include "iterator.hpp"
namespace niklasrosenstein {
/**
* An implementation of a range iterator using the #iterator interface.
* Supports an arbitrary integer dataype that can be specified with the
* template parameter #T.
*/
template <class T = std::size_t>
class _range : public iterator<_range<T>> {
T _curr, _max, _step;
static inline int sign(T const& val) { return (T(0) < val) - (val < T(0)); }
public:
/**
* Create a range iterator starting from zero up excluding #max.
*/
inline _range(T max) : _curr(0), _max(max), _step(1) { }
/**
* Create a range iterator starting from #min up to excluding #max
* taking the specified #step each turn (must not be zero and the
* sign must match the direction of the iteration).
*/
inline _range(T min, T max, T step = 1) : _curr(min), _max(max), _step(step) {
assert(step != 0 && sign(step) == sign(max - min));
}
// niklasrosenstein::iterator
typedef T yield_type;
inline bool has_next() const { return this->_curr < this->_max; }
inline T next() { T temp = _curr; _curr += _step; return temp; }
};
template <class T = std::size_t>
_range<T> range(T max) { return {max}; }
template <class T = std::size_t>
_range<T> range(T min, T max, T step = 1) { return {min, max, step}; }
} // namespace niklasrosenstein