From 585b3bca50325ed94babb248aa451f37dc42d1fc Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Wed, 27 May 2015 09:19:08 +0300 Subject: [PATCH] [iterators][segment iterator] fix for boost trac ticket #11346 Problem: segment iterator does not work with point iterators that return a value instead of a reference when dereferenced. Fix: check the if the reference type of the point iterator is indeed a reference or not and use a pointing_segment or a segment as the value type of the segment iterator, respectively. --- .../detail/segment_iterator/value_type.hpp | 38 ++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/include/boost/geometry/iterators/detail/segment_iterator/value_type.hpp b/include/boost/geometry/iterators/detail/segment_iterator/value_type.hpp index 0b3c66670..ff3267c88 100644 --- a/include/boost/geometry/iterators/detail/segment_iterator/value_type.hpp +++ b/include/boost/geometry/iterators/detail/segment_iterator/value_type.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014, Oracle and/or its affiliates. +// Copyright (c) 2014-2015, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -10,7 +10,14 @@ #ifndef BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_VALUE_TYPE_HPP #define BOOST_GEOMETRY_ITERATORS_DETAIL_SEGMENT_ITERATOR_VALUE_TYPE_HPP -#include +#include + +#include +#include + +#include +#include +#include #include @@ -24,15 +31,36 @@ namespace detail { namespace segment_iterator template struct value_type { + typedef typename std::iterator_traits + < + geometry::point_iterator + >::reference point_iterator_reference_type; + typedef typename detail::point_iterator::value_type < Geometry >::type point_iterator_value_type; - typedef geometry::model::pointing_segment + // If the reference type of the point iterator is not really a + // reference, then dereferencing a point iterator would create + // a temporary object. + // In this case using a pointing_segment to represent the + // dereferenced value of the segment iterator cannot be used, as + // it would store pointers to temporary objects. Instead we use a + // segment, which does a full copy of the temporary objects + // returned by the point iterator. + typedef typename boost::mpl::if_ < - point_iterator_value_type - > type; + boost::is_reference, + geometry::model::pointing_segment, + geometry::model::segment + < + typename geometry::util::bare_type + < + point_iterator_value_type + >::type + > + >::type type; }; }} // namespace detail::segment_iterator