// Copyright (c) 2014 // INRIA Saclay-Ile de France (France) // // This file is part of CGAL (www.cgal.org) // // $URL: https://github.com/CGAL/cgal/blob/v5.2/STL_Extension/include/CGAL/transforming_pair_iterator.h $ // $Id: transforming_pair_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) : Marc Glisse #ifndef CGAL_TRANSFORMING_PAIR_ITERATOR_H #define CGAL_TRANSFORMING_PAIR_ITERATOR_H // Should be a combination of transform_iterator and zip_iterator, // but boost's iterator_category games are a pain. #include #include #include namespace CGAL { namespace internal { template ::value> struct Min_category { CGAL_static_assertion((boost::is_convertible::value)); typedef Cat1 type; }; template struct Min_category { typedef Cat2 type; }; template class transforming_pair_iterator_helper { typedef typename Min_category< typename std::iterator_traits::iterator_category, typename std::iterator_traits::iterator_category> ::type iterator_category; typedef typename Default::Get()(std::declval::reference>(),std::declval::reference>())) >::type reference; typedef typename Default::Get::type>::type>::type value_type; public: typedef boost::iterator_facade< Derived, value_type, iterator_category, reference // expect ptrdiff_t is good enough for difference > type; }; } template class transforming_pair_iterator : public internal::transforming_pair_iterator_helper,F,It1,It2,Ref,Val>::type, private internal::Functor_as_base { It1 iter1; It2 iter2; friend class boost::iterator_core_access; typedef typename internal::transforming_pair_iterator_helper::type Base; typedef internal::Functor_as_base Functor_base; typename Base::reference dereference()const{ return functor()(*iter1,*iter2); } bool equal(transforming_pair_iterator const&i)const{ bool b=(iter1==i.iter1); CGAL_assertion(b==(iter2==i.iter2)); //FIXME: or do we want only one driving iterator return b; } void increment(){ ++iter1; ++iter2; } void decrement(){ --iter1; --iter2; } void advance(std::ptrdiff_t n){ std::advance(iter1,n); std::advance(iter2,n); } std::ptrdiff_t distance_to(transforming_pair_iterator const&i)const{ std::ptrdiff_t dist=std::distance(iter1,i.iter1); CGAL_assertion(dist==std::distance(iter2,i.iter2)); return dist; } public: using Functor_base::functor; transforming_pair_iterator(){} explicit transforming_pair_iterator(It1 i1,It2 i2,F const& f=F()) :Functor_base(f),iter1(i1),iter2(i2){} template transforming_pair_iterator( transforming_pair_iterator const&i, typename boost::enable_if_convertible::type* = 0, typename boost::enable_if_convertible::type* = 0, typename boost::enable_if_convertible::type* = 0) : Functor_base(i.functor()),iter1(i.iter1),iter2(i.iter2) {} }; template inline transforming_pair_iterator make_transforming_pair_iterator(It1 i1, It2 i2, F const&f=F()) { return transforming_pair_iterator(i1,i2,f); } } #endif // CGAL_TRANSFORMING_PAIR_ITERATOR_H