/* * 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 */ #pragma once #include 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 ) 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 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 (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 m_count; }; }