iterator: flesh out the iota container
This commit is contained in:
parent
94d891c973
commit
4d91db760c
48
iterator.hpp
48
iterator.hpp
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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 ();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user