libcruft-util/iterator/iota.hpp

77 lines
2.5 KiB
C++

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright 2010-2018 Danny Robson <danny@nerdcruft.net>
*/
#pragma once
namespace cruft::iterator {
///////////////////////////////////////////////////////////////////////////
/// A numeric range that supplies a sequence of values.
///
/// The value range is specified as [closed-open). ie, The last value will
/// never be output by an iterator. This makes the object suitable as a
/// means of iterating over the indices of an integrable indexed container
/// (like std::vector)
///
/// Primarily used for integrating into other utilities (like izip).
template <typename ValueT = std::size_t>
class iota {
public:
using value_type = ValueT;
iota (value_type _total)
: m_total (_total)
{ ; }
class iterator {
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = ValueT const;
using difference_type = decltype (std::declval<value_type> () - std::declval<value_type> ());
using pointer = value_type*;
using reference = value_type&;
explicit iterator ()
: m_value {}
{ ; }
explicit iterator (value_type _value)
: m_value (_value)
{ ; }
pointer operator-> () const& noexcept { return &m_value; }
reference operator* () const& noexcept { return m_value; }
iterator& operator++ () noexcept { ++m_value; return *this; }
iterator& operator-- () noexcept { --m_value; return *this; }
constexpr difference_type
operator- (iterator const &rhs) const noexcept
{
return m_value - rhs.m_value;
}
constexpr bool operator!= (iterator const &rhs) const noexcept { return m_value != rhs.m_value; }
constexpr bool operator== (iterator const &rhs) const noexcept { return m_value == rhs.m_value; }
private:
ValueT m_value;
};
iterator begin (void) const { return iterator {}; }
iterator end (void) const { return iterator {m_total}; }
value_type size (void) const { return m_total; }
private:
value_type m_total;
};
template <typename ValueT>
iota (ValueT) -> iota<ValueT>;
}