// Copyright (c) 2014 // INRIA Saclay-Ile de France (France) // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 3 of the License, // or (at your option) any later version. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // // Author(s) : Marc Glisse #ifndef CGAL_TRANSFORMING_ITERATOR_H #define CGAL_TRANSFORMING_ITERATOR_H #include #include #include #include #include // Inspired by the boost version, but more compact and // without any iterator_category games. namespace CGAL { namespace internal { // non-empty case template::value> struct Functor_as_base { Functor_as_base(){} Functor_as_base(T const& t):f(t){} //template Functor_as_base(Functor_as_base const&g):f(g.functor()){} T const& functor()const{return f;} T & functor() {return f;} private: T f; }; // empty case template struct Functor_as_base : public T { Functor_as_base(){} Functor_as_base(T const& t):T(t){} //template Functor_as_base(Functor_as_base const&g):T(g.functor()){} T const& functor()const{return *this;} T & functor() {return *this;} }; template class transforming_iterator_helper { typedef typename Default::Get()(std::declval::reference>())) #else typename boost::result_of::value_type)>::type // should be reference instead of value_type #endif >::type reference; typedef typename Default::Get::type>::type>::type value_type; public: typedef boost::iterator_adaptor< Derived, Iter, value_type, typename std::iterator_traits::iterator_category, reference > type; }; } template class transforming_iterator : public internal::transforming_iterator_helper,F,Iter,Ref,Val>::type, private internal::Functor_as_base { friend class boost::iterator_core_access; typedef typename internal::transforming_iterator_helper::type Base; typedef internal::Functor_as_base Functor_base; typename Base::reference dereference()const{ return functor()(*this->base_reference()); } public: using Functor_base::functor; transforming_iterator(){} explicit transforming_iterator(Iter i,F const& f=F()) :Base(i),Functor_base(f){} template transforming_iterator( transforming_iterator const&i, typename boost::enable_if_convertible::type* = 0, typename boost::enable_if_convertible::type* = 0) : Base(i.base()),Functor_base(i.functor()) {} }; template inline transforming_iterator make_transforming_iterator(Iter i, F const&f=F()) { return transforming_iterator(i,f); } } #endif // CGAL_TRANSFORMING_ITERATOR_H