libcruft-util/cruft/util/iterator/counting.hpp

59 lines
1.8 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
#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
// 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 ()
: m_count (std::make_shared<std::size_t> (0))
{ ; }
counting_output_iterator& operator++ () { return *this; }
assignable operator* () { return assignable (*m_count); }
/// Returns the number of times the iterator has been assigned to.
std::size_t count (void) const { return *m_count; }
private:
std::shared_ptr<std::size_t> m_count;
};
}