From 16aaf4cda5fd97da12a7f1da8b0a5168fac2e289 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 11 Oct 2016 13:57:03 +0000 Subject: Problem of merge with tangentialcomplex branch. Redo in an integration branch git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/tangential_integration@1701 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: fa029e8e90b3e203ea675f02098ec6fe95596f9f --- .../gudhi_patches/CGAL/transforming_iterator.h | 123 +++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 src/common/include/gudhi_patches/CGAL/transforming_iterator.h (limited to 'src/common/include/gudhi_patches/CGAL/transforming_iterator.h') diff --git a/src/common/include/gudhi_patches/CGAL/transforming_iterator.h b/src/common/include/gudhi_patches/CGAL/transforming_iterator.h new file mode 100644 index 00000000..15ea19a5 --- /dev/null +++ b/src/common/include/gudhi_patches/CGAL/transforming_iterator.h @@ -0,0 +1,123 @@ +// 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 +#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 std::iterator_traits Iter_traits; + typedef typename Iter_traits::reference Iter_ref; + typedef typename Default::Get()(std::declval())) +#else + typename boost::result_of::type + // should be reference instead of value_type +#endif + >::type reference_; + + typedef typename Default::Get::type>::type>::type value_type; + + // Crappy heuristic. If we have *it that returns a Weighted_point and F that returns a reference to the Point contained in the Weighted_point it takes as argument, we do NOT want the transformed iterator to return a reference to the temporary *it. On the other hand, if *it returns an int n, and F returns a reference to array[n] it is not so good to lose the reference. This probably should be done elsewhere and should at least be made optional... + typedef typename boost::mpl::if_< + boost::mpl::or_, + boost::is_integral >, + reference_, value_type>::type reference; + + public: + typedef boost::iterator_adaptor< + Derived, + Iter, + value_type, + typename Iter_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 -- cgit v1.2.3