iterator: add counting_output_iterator

This commit is contained in:
Danny Robson 2018-10-05 14:55:29 +10:00
parent 179c8bead4
commit 0e5a084a9b
2 changed files with 54 additions and 0 deletions

View File

@ -606,6 +606,45 @@ namespace cruft {
std::forward<Args> (src)... std::forward<Args> (src)...
); );
} }
///////////////////////////////////////////////////////////////////////////
/// Counts the number of times the iterator is assigned to.
struct counting_output_iterator {
// An internal proxy value which is returned when the iterator is
// dereferenced. It increments the assignment value in the host
// iterator.
//
// The internals of this object are not a stable interface.
struct assignable {
assignable (std::size_t &_count)
: m_count (_count)
{ ; }
template <typename Arg>
void
operator= (Arg&&)
{
++m_count;
}
private:
std::size_t &m_count;
};
using value_type = assignable;
using iterator_category = std::output_iterator_tag;
using reference = assignable&;
counting_output_iterator& operator++ () { return *this; }
assignable operator* () { return assignable (m_count); }
/// Returns the number of times the iterator has been assigned to.
auto count (void) const { return m_count; }
private:
std::size_t m_count = 0;
};
}; };
#endif #endif

View File

@ -6,6 +6,19 @@
#include <array> #include <array>
///////////////////////////////////////////////////////////////////////////////
void
test_counting_output_iterator (cruft::TAP::logger &tap)
{
cruft::counting_output_iterator out;
*out = 0; ++out;
*out = 1; ++out;
*out = 2; ++out;
tap.expect_eq (out.count (), 3u, "counting_output_iterator simple manual assignment");
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
int int
main (int, char**) main (int, char**)
@ -49,5 +62,7 @@ main (int, char**)
tap.expect_eq (src, dst, "copy using structured bindings"); tap.expect_eq (src, dst, "copy using structured bindings");
} }
test_counting_output_iterator (tap);
return tap.status (); return tap.status ();
} }