On Saturday, March 28, 2020 at 2:04:11 PM UTC-4, red floyd wrote:
> I was looking for a way to use standard algorithms with a range of
> integers.
Option 1:
#include <iterator>
#include <algorithm>
template <class Iterator,class Enable = void>
class integer_iterator
{
};
template <class T>
class integer_iterator<T,typename std::enable_if<std::is_integral<T>::value
>::type>
{
T value_;
T step_;
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = T;
using difference_type = std::ptrdiff_t;
using pointer = typename std::conditional<std::is_const<T>::value,
value_type*,
const value_type*>::type;
using reference = typename std::conditional<std::is_const<T>::value,
value_type&,
const value_type&>::type;
public:
explicit integer_iterator(T n = 0, T step = 1) : value_(n), step_(step)
{
}
integer_iterator(const integer_iterator&) = default;
integer_iterator(integer_iterator&&) = default;
integer_iterator& operator=(const integer_iterator&) = default;
integer_iterator& operator=(integer_iterator&&) = default;
template <class U,
class=typename std::enable_if<!std::is_same<U,T>::value &&
std::is_convertible<U,T>::value>::type>
integer_iterator(const integer_iterator<U>& other)
: value_(other.value_)
{
}
reference operator*() const
{
return value_;
}
T operator->() const
{
return &value_;
}
integer_iterator& operator++()
{
value_ += step_;
return *this;
}
integer_iterator operator++(int)
{
integer_iterator temp = *this;
++*this;
return temp;
}
integer_iterator& operator--()
{
value_ -= step_;
return *this;
}
integer_iterator operator--(int)
{
integer_iterator temp = *this;
--*this;
return temp;
}
integer_iterator& operator+=(const difference_type offset)
{
value_ += offset;
return *this;
}
integer_iterator operator+(const difference_type offset) const
{
integer_iterator temp = *this;
return temp += offset;
}
integer_iterator& operator-=(const difference_type offset)
{
return *this += -offset;
}
integer_iterator operator-(const difference_type offset) const
{
integer_iterator temp = *this;
return temp -= offset;
}
difference_type operator-(const integer_iterator& rhs) const
{
return value_ - rhs.value_;
}
reference operator[](const difference_type offset) const
{
return *(*this + offset);
}
bool operator==(const integer_iterator& rhs) const
{
return value_ == rhs.value_;
}
bool operator!=(const integer_iterator& rhs) const
{
return !(*this == rhs);
}
bool operator<(const integer_iterator& rhs) const
{
return value_ < rhs.value_;
}
bool operator>(const integer_iterator& rhs) const
{
return rhs < *this;
}
bool operator<=(const integer_iterator& rhs) const
{
return !(rhs < *this);
}
bool operator>=(const integer_iterator& rhs) const
{
return !(*this < rhs);
}
inline
friend integer_iterator<T> operator+(
difference_type offset, integer_iterator<T> next)
{
return next += offset;
}
};
int main(int argc, char** argv)
{
integer_iterator<int> first(1,10);
integer_iterator<int> last(100000001, 10);
int n = 0;
auto f = [&n](int i) {n += i;};
std::for_each(first, last, f);
}
Option 2
int main(int argc, char** argv)
{
int n = 0;
auto f = [&n](int i) {n += i;};
for (int i = 1; i < 100000001; i += 10)
{
f(i);
}
}
Decisions, decisions ...
Daniel