iterator/counting: allow copying of iterator

This commit is contained in:
Danny Robson 2023-07-13 06:45:47 +10:00
parent e7a2c18481
commit fffd584c93
2 changed files with 31 additions and 8 deletions

View File

@ -8,9 +8,14 @@
#pragma once
#include <memory>
namespace cruft::iterator {
///////////////////////////////////////////////////////////////////////////
/// Counts the number of times the iterator is assigned to.
///
/// It currently uses a shared_ptr to allow for value copying of the iterator
/// (as tends to often happen in places such as <algorithm>)
struct counting_output_iterator {
// An internal proxy value which is returned when the iterator is
// dereferenced. It increments the assignment value in the host
@ -37,13 +42,17 @@ namespace cruft::iterator {
using iterator_category = std::output_iterator_tag;
using reference = assignable&;
counting_output_iterator ()
: m_count (std::make_shared<std::size_t> (0))
{ ; }
counting_output_iterator& operator++ () { return *this; }
assignable operator* () { return assignable (m_count); }
assignable operator* () { return assignable (*m_count); }
/// Returns the number of times the iterator has been assigned to.
auto count (void) const { return m_count; }
std::size_t count (void) const { return *m_count; }
private:
std::size_t m_count = 0;
std::shared_ptr<std::size_t> m_count;
};
}

View File

@ -8,17 +8,31 @@
#include <vector>
#include <array>
#include <iostream>
///////////////////////////////////////////////////////////////////////////////
static void
test_counting_output_iterator (cruft::TAP::logger &tap)
{
cruft::iterator::counting_output_iterator out;
*out = 0; ++out;
*out = 1; ++out;
*out = 2; ++out;
{
cruft::iterator::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");
tap.expect_eq (out.count (), 3u, "counting_output_iterator simple manual assignment");
}
{
std::vector<int> numbers (100);
std::iota (std::begin (numbers), std::end (numbers), 0);
cruft::iterator::counting_output_iterator out;
std::copy (std::begin (numbers), std::end (numbers), out);
tap.expect_eq (out.count (), 100u, "counting_output_iterator, std::copy over a vector");
}
}