dust3d/thirdparty/cgal/CGAL-5.1/include/CGAL/Nested_iterator.h

247 lines
5.6 KiB
C++

// Copyright (c) 2003
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel). All rights reserved.
//
// This file is part of CGAL (www.cgal.org)
//
// $URL: https://github.com/CGAL/cgal/blob/v5.1/STL_Extension/include/CGAL/Nested_iterator.h $
// $Id: Nested_iterator.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@cse.nd.edu>
#ifndef CGAL_NESTED_ITERATOR_H
#define CGAL_NESTED_ITERATOR_H
#include <CGAL/iterator.h>
#include <iterator>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable:4396)
#endif
namespace CGAL {
template<class It>
struct Nested_iterator_traits
{
typedef It Base_iterator;
typedef typename std::iterator_traits<It>::value_type::iterator Iterator;
Iterator begin(It it) const { return it->begin(); }
Iterator end(It it) const { return it->end(); }
};
namespace internal {
template<class Tr>
struct Emptyness_predicate : public Tr
{
typedef Tr Traits;
bool operator()(typename Traits::Base_iterator base_it) const
{
return this->begin(base_it) == this->end(base_it);
}
};
template<class F_iterator>
class FI_w_begin_end : public F_iterator
{
private:
typedef typename F_iterator::Predicate Predicate;
typedef typename Predicate::Traits::Iterator Iterator;
typedef typename Predicate::Traits::Base_iterator Base_iterator;
public:
FI_w_begin_end() : F_iterator() {}
FI_w_begin_end(Base_iterator it2,
Base_iterator it3)
: F_iterator(it2, Predicate(), it3) {}
Iterator begin(Base_iterator it)
{
return this->predicate().begin(it);
}
Iterator end(Base_iterator it)
{
return this->predicate().end(it);
}
};
}
template<class Base_it, class Tr> class Nested_iterator;
template<class Base_it, class Tr>
bool operator==(const Nested_iterator<Base_it,Tr>&,
const Nested_iterator<Base_it,Tr>&);
template <typename Base_it,
typename Tr = Nested_iterator_traits<Base_it> >
class Nested_iterator
: private internal::FI_w_begin_end<
Filter_iterator<Base_it, internal::Emptyness_predicate<Tr> > >
{
typedef Nested_iterator<Base_it,Tr> Self;
public:
typedef Base_it Base_iterator;
typedef Tr Traits;
typedef typename Tr::Iterator Iterator;
protected:
typedef internal::
FI_w_begin_end< Filter_iterator<Base_iterator,
internal::Emptyness_predicate<Tr> > >
Filter_base_iterator;
private:
typedef std::iterator_traits<Iterator> ItTraits;
public:
typedef typename ItTraits::reference reference;
typedef typename ItTraits::pointer pointer;
typedef typename ItTraits::value_type value_type;
typedef typename ItTraits::difference_type difference_type;
typedef typename ItTraits::iterator_category iterator_category;
public:
Nested_iterator() : Filter_base_iterator(), nested_it_() {}
Nested_iterator(Base_iterator base_it_end,
Base_iterator base_it_cur)
: Filter_base_iterator(base_it_end, base_it_cur), nested_it_()
{
if ( !this->is_end() ) {
nested_it_ = this->begin( this->base() );
}
}
Nested_iterator(const Self& other)
: Filter_base_iterator(other)
{
if ( !other.is_end() )
nested_it_ = other.nested_it_;
}
Self& operator=(const Self& other)
{
copy_from(other);
return *this;
}
Self& operator++()
{
if ( nested_it_ != this->end( this->base() ) ) {
++nested_it_;
if ( nested_it_ == this->end( this->base() ) ) {
Filter_base_iterator::operator++();
if ( !this->is_end() ) {
nested_it_ = this->begin( this->base() );
}
}
}
return *this;
}
Self operator++(int)
{
Self tmp = *this;
++(*this);
return tmp;
}
Self& operator--()
{
if ( this->is_end() ) {
Filter_base_iterator::operator--();
nested_it_ = this->end(this->base());
--nested_it_;
} else {
if ( nested_it_ != this->begin( this->base() ) ) {
--nested_it_;
} else {
Filter_base_iterator::operator--();
nested_it_ = this->end( this->base() );
--nested_it_;
}
}
return *this;
}
Self operator--(int)
{
Self tmp = *this;
--(*this);
return tmp;
}
reference operator*() const
{
return *nested_it_;
}
pointer operator->() const
{
return nested_it_.operator->();
}
friend bool operator==<>(const Self&, const Self&);
protected:
void copy_from(const Self& other)
{
Filter_base_iterator::operator=(other);
if ( !other.is_end() ) {
nested_it_ = other.nested_it_;
}
}
protected:
Iterator nested_it_;
};
template<class Base_it, class Traits>
inline
bool operator==(const Nested_iterator<Base_it,Traits>& it1,
const Nested_iterator<Base_it,Traits>& it2)
{
// CGAL_precondition( it1.b_ == it2.b_ && it1.e_ == it2.e_ );
if ( it1.base() != it2.base() ) { return false; }
return it1.is_end() || ( it1.nested_it_ == it2.nested_it_ );
}
template<class Base_it, class Traits>
inline
bool operator!=(const Nested_iterator<Base_it,Traits>& it1,
const Nested_iterator<Base_it,Traits>& it2)
{
return !(it1 == it2);
}
} //namespace CGAL
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif // CGAL_NESTED_ITERATOR_H