// Copyright (c) 2016 CNRS and LIRIS' Establishments (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL: https://github.com/CGAL/cgal/blob/v5.1/Generalized_map/include/CGAL/GMap_cell_iterators.h $ // $Id: GMap_cell_iterators.h 52164b1 2019-10-19T15:34:59+02:00 Sébastien Loriot // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // Author(s) : Guillaume Damiand // #ifndef CGAL_GMAP_CELL_ITERATORS_H #define CGAL_GMAP_CELL_ITERATORS_H 1 #include #include // TODO do all the orbit iterator of any orbit ? namespace CGAL { /** @file Cell_iterators.h * Cell iterators. There are 3 classes: * - GMap_cell_iterator: one dart per each i-cell * - GMap_one_dart_per_incident_cell_iterator * - GMap_one_dart_per_cell_iterator * - one specialisation of the CMap_cell_iterator for the * GMap_dart_iterator_basic_of_all iterator */ //**************************************************************************** /* Class CMap_cell_iterator, i,dim,Tag_false>: specialization to iterate onto * all the cells of the gmap. */ template class CMap_cell_iterator, i,dim,Const,Tag_false>: public GMap_dart_iterator_basic_of_all { public: typedef GMap_dart_iterator_basic_of_all Base; typedef CMap_cell_iterator Self; typedef typename Base::Dart_handle Dart_handle; typedef typename Base::Map Map; protected: /// Unmark all the marked darts during the iterator. void unmark_treated_darts() { if (this->mmap->is_whole_map_unmarked(mmark_number)) return; this->mmap->negate_mark(mmark_number); if (this->mmap->is_whole_map_unmarked(mmark_number)) return; Base::rewind(); mark_cell(*this->mmap, (*this), mmark_number); while (this->mmap->number_of_unmarked_darts(mmark_number) > 0) this->operator++(); this->mmap->negate_mark(mmark_number); CGAL_assertion(this->mmap->is_whole_map_unmarked(mmark_number)); } public: /// Main constructor. CMap_cell_iterator(Map& amap): Base(amap), mmark_number(amap.get_new_mark()) { CGAL_static_assertion( (boost::is_same::value) ); CGAL_assertion(amap.is_whole_map_unmarked(mmark_number)); mark_cell(amap, (*this), mmark_number); } /// Constructor with a dart in parameter (for end iterator). CMap_cell_iterator(Map& amap, Dart_handle adart): Base(amap, adart), mmark_number(amap.get_new_mark()) { if (adart!=this->mmap->null_handle) mark_cell(amap, (*this), mmark_number); } /// Destructor. ~CMap_cell_iterator() { if (this->mmap->get_number_of_times_mark_reserved(mmark_number)==1) unmark_treated_darts(); this->mmap->free_mark(mmark_number); this->mmark_number = Map::INVALID_MARK; // To avoid basic class to try to unmark darts. } /// Copy constructor. CMap_cell_iterator(const Self& aiterator): Base(aiterator), mmark_number(aiterator.mmark_number) { this->mmap->share_a_mark(mmark_number); } /// Assignment operator. Self& operator=(const Self& aiterator) { if (this != &aiterator) { Base::operator=(aiterator); mmark_number = aiterator.mmark_number; this->mmap->share_a_mark(mmark_number); } return *this; } /// Rewind of the iterator to its beginning. void rewind() { unmark_treated_darts(); Base::rewind(); mark_cell(*this->mmap, (*this), mmark_number); } /// Postfix ++ operator. Self operator++(int) { Self res=*this; operator ++(); return res; } /// Prefix ++ operator. Self& operator++() { CGAL_assertion(this->cont()); do { Base::operator++(); } while (this->cont() && this->mmap->is_marked((*this), mmark_number)); if (this->cont()) mark_cell(*this->mmap, (*this), mmark_number); return *this; } private: /// A mark used to mark treated cells. typename Map::size_type mmark_number; }; //**************************************************************************** /* Class GMap_cell_iterator: to iterate onto * all the cells of the gmap. */ template class GMap_cell_iterator: public GMap_dart_iterator_basic_of_all { public: typedef GMap_dart_iterator_basic_of_all Base; typedef GMap_cell_iterator Self; typedef typename Base::Dart_handle Dart_handle; typedef typename Base::Map Map; protected: /// Unmark all the marked darts during the iterator. void unmark_treated_darts() { if (this->mmap->is_whole_map_unmarked(mmark_number)) return; this->mmap->negate_mark(mmark_number); if (this->mmap->is_whole_map_unmarked(mmark_number)) return; Base::rewind(); mark_cell(*this->mmap, (*this), mmark_number); while (this->mmap->number_of_unmarked_darts(mmark_number) > 0) this->operator++(); this->mmap->negate_mark(mmark_number); CGAL_assertion(this->mmap->is_whole_map_unmarked(mmark_number)); } public: /// Main constructor. GMap_cell_iterator(Map& amap): Base(amap), mmark_number(amap.get_new_mark()) { CGAL_static_assertion( (boost::is_same::value) ); CGAL_assertion(amap.is_whole_map_unmarked(mmark_number)); mark_cell(amap, (*this), mmark_number); } /// Constructor with a dart in parameter (for end iterator). GMap_cell_iterator(Map& amap, Dart_handle adart): Base(amap, adart), mmark_number(amap.get_new_mark()) { if (adart!=this->mmap->null_handle) mark_cell(amap, (*this), mmark_number); } /// Destructor. ~GMap_cell_iterator() { if (this->mmap->get_number_of_times_mark_reserved(mmark_number)==1) unmark_treated_darts(); this->mmap->free_mark(mmark_number); this->mmark_number = Map::INVALID_MARK; // To avoid basic class to try to unmark darts. } /// Copy constructor. GMap_cell_iterator(const Self& aiterator): Base(aiterator), mmark_number(aiterator.mmark_number) { this->mmap->share_a_mark(mmark_number); } /// Assignment operator. Self& operator=(const Self& aiterator) { if (this != &aiterator) { Base::operator=(aiterator); mmark_number = aiterator.mmark_number; this->mmap->share_a_mark(mmark_number); } return *this; } /// Rewind of the iterator to its beginning. void rewind() { unmark_treated_darts(); Base::rewind(); mark_cell(*this->mmap, (*this), mmark_number); } /// Postfix ++ operator. Self operator++(int) { Self res=*this; operator ++(); return res; } /// Prefix ++ operator. Self& operator++() { CGAL_assertion(this->cont()); do { Base::operator++(); } while (this->cont() && this->mmap->is_marked((*this), mmark_number)); if (this->cont()) mark_cell(*this->mmap, (*this), mmark_number); return *this; } private: /// A mark used to mark treated cells. typename Map::size_type mmark_number; }; //**************************************************************************** /* Class GMap_one_dart_per_incident_cell_iterator: to iterate * onto one dart per i-cell incident to the given j-cell. */ template class GMap_one_dart_per_incident_cell_iterator: public CMap_cell_iterator, i,dim,Const> { public: typedef GMap_one_dart_per_incident_cell_iterator Self; typedef CMap_cell_iterator, i,dim,Const> Base; typedef typename Base::Dart_handle Dart_handle; typedef typename Base::Map Map; typedef Tag_false Use_mark; typedef Tag_false Basic_iterator; /// Main constructor. GMap_one_dart_per_incident_cell_iterator(Map& amap, Dart_handle adart): Base(amap, adart) {} }; //**************************************************************************** /* Class GMap_one_dart_per_cell_iterator: to iterate onto the * i-cells of the map (one dart by each i-cell). */ template class GMap_one_dart_per_cell_iterator: public CMap_cell_iterator, i,dim,Const> { public: typedef GMap_one_dart_per_cell_iterator Self; typedef CMap_cell_iterator, i,dim,Const> Base; typedef typename Base::Dart_handle Dart_handle; typedef typename Base::Map Map; typedef Tag_false Use_mark; typedef Tag_false Basic_iterator; /// Main constructor. GMap_one_dart_per_cell_iterator(Map& amap): Base(amap) {} /// Constructor with a dart in parameter (for end iterator). GMap_one_dart_per_cell_iterator(Map& amap, Dart_handle adart): Base(amap, adart) {} }; //**************************************************************************** //**************************************************************************** } // namespace CGAL //****************************************************************************** #endif // CGAL_GMAP_CELL_ITERATORS_H //******************************************************************************