iterator: flesh out the iota container

This commit is contained in:
Danny Robson 2019-03-18 13:52:00 +11:00
parent 94d891c973
commit 4d91db760c
2 changed files with 53 additions and 12 deletions

View File

@ -222,36 +222,64 @@ namespace cruft {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
/// 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> template <typename ValueT = std::size_t>
class iota { class iota {
public: public:
using value_type = ValueT; using value_type = ValueT;
iota (ValueT _total) iota (value_type _total)
: m_total (_total) : m_total (_total)
{ ; } { ; }
struct iterator { class iterator {
iterator (ValueT _value) 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) : m_value (_value)
{ ; } { ; }
ValueT const* operator-> () const noexcept { return &m_value; } pointer operator-> () const& noexcept { return &m_value; }
ValueT const& 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; }
iterator& operator-- () noexcept { --m_value; return *this; }
bool operator!= (iterator const &rhs) const noexcept { return m_value != rhs.m_value; } 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; ValueT m_value;
}; };
iterator begin (void) const { return iterator( 0); } iterator begin (void) const { return iterator {}; }
iterator end (void) const { return iterator(m_total); } iterator end (void) const { return iterator {m_total}; }
ValueT size (void) const { return m_total; } value_type size (void) const { return m_total; }
private: private:
ValueT m_total; value_type m_total;
}; };

View File

@ -7,7 +7,7 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
void static void
test_counting_output_iterator (cruft::TAP::logger &tap) test_counting_output_iterator (cruft::TAP::logger &tap)
{ {
cruft::counting_output_iterator out; cruft::counting_output_iterator out;
@ -19,7 +19,8 @@ test_counting_output_iterator (cruft::TAP::logger &tap)
} }
void //-----------------------------------------------------------------------------
static void
test_dereference_iterator (cruft::TAP::logger &tap) test_dereference_iterator (cruft::TAP::logger &tap)
{ {
int values[4] { 0, 1, 2, 3 }; int values[4] { 0, 1, 2, 3 };
@ -35,6 +36,16 @@ test_dereference_iterator (cruft::TAP::logger &tap)
} }
//-----------------------------------------------------------------------------
static void
test_iota (cruft::TAP::logger &tap)
{
cruft::iota seq (5);
auto const sum = std::accumulate (std::begin (seq), std::end (seq), 0u);
tap.expect_eq (sum, 4u+3u+2u+1u+0u, "iota summation %!", sum);
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
int int
main (int, char**) main (int, char**)
@ -79,6 +90,8 @@ main (int, char**)
} }
test_counting_output_iterator (tap); test_counting_output_iterator (tap);
test_dereference_iterator (tap);
test_iota (tap);
return tap.status (); return tap.status ();
} }