// Copyright (c) 2020 GeometryFactory (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // Author(s) : Simon Giraudot // #ifndef CGAL_PCA_SUBITERATOR_H #define CGAL_PCA_SUBITERATOR_H #include #include namespace CGAL { template class Subiterator : public boost::iterator_facade, ValueType, std::input_iterator_tag> { public: using Self = Subiterator; using Facade = boost::iterator_facade; using Input_type = typename std::iterator_traits::value_type; using Output_type = ValueType; using Converter = std::function; private: Converter m_converter; int m_next_index; InputIterator m_base; mutable Output_type m_current; public: Subiterator() { } Subiterator(InputIterator begin, const Converter& converter) : m_converter(converter), m_next_index(0), m_base(begin) { } Subiterator(InputIterator end) : m_next_index(0), m_base(end) { } private: friend class boost::iterator_core_access; void increment() { ++ m_next_index; if (m_next_index == Size) { ++ m_base; m_next_index = 0; } } bool equal(const Self& other) const { return this->m_base == other.m_base && this->m_next_index == other.m_next_index; } Output_type& dereference() const { m_current = m_converter (*m_base, m_next_index); return const_cast(m_current); } }; template Subiterator make_subiterator (InputIterator begin, const typename Subiterator::Converter& converter) { return Subiterator(begin, converter); } template Subiterator make_subiterator (InputIterator end) { return Subiterator(end); } } // namespace CGAL #endif // CGAL_PCA_SUBITERATOR_H