From 7abe47876b19831c399696ee197be4806f355d92 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Wed, 26 Mar 2014 10:22:31 +0200 Subject: [PATCH 01/20] [feature/point iterator] implementation of point iterator for most geometries (not yet for point, segment & box); --- .../geometry/core/dispatch/point_iterator.hpp | 47 +++ .../core/dispatch/point_iterator_type.hpp | 37 ++ .../boost/geometry/core/point_iterator.hpp | 242 +++++++++++++ .../geometry/core/point_iterator_type.hpp | 216 ++++++++++++ .../geometry/util/concatenate_iterator.hpp | 91 +++++ .../boost/geometry/util/flatten_iterator.hpp | 219 ++++++++++++ test/core/point_iterator.cpp | 331 ++++++++++++++++++ 7 files changed, 1183 insertions(+) create mode 100644 include/boost/geometry/core/dispatch/point_iterator.hpp create mode 100644 include/boost/geometry/core/dispatch/point_iterator_type.hpp create mode 100644 include/boost/geometry/core/point_iterator.hpp create mode 100644 include/boost/geometry/core/point_iterator_type.hpp create mode 100644 include/boost/geometry/util/concatenate_iterator.hpp create mode 100644 include/boost/geometry/util/flatten_iterator.hpp create mode 100644 test/core/point_iterator.cpp diff --git a/include/boost/geometry/core/dispatch/point_iterator.hpp b/include/boost/geometry/core/dispatch/point_iterator.hpp new file mode 100644 index 000000000..9d89ae737 --- /dev/null +++ b/include/boost/geometry/core/dispatch/point_iterator.hpp @@ -0,0 +1,47 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_CORE_DISPATCH_POINT_ITERATOR_HPP +#define BOOST_GEOMETRY_CORE_DISPATCH_POINT_ITERATOR_HPP + +#include +#include + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DISPATCH +namespace core_dispatch +{ + + +// dispatch for points_begin +template ::type> +struct points_begin + : not_implemented +{}; + + + +// dispatch for points_end +template ::type> +struct points_end + : not_implemented +{}; + + + +} // namespace core_dispatch +#endif // DOXYGEN_NO_DISPATCH + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_CORE_DISPATCH_POINT_ITERATOR_HPP diff --git a/include/boost/geometry/core/dispatch/point_iterator_type.hpp b/include/boost/geometry/core/dispatch/point_iterator_type.hpp new file mode 100644 index 000000000..abf91dd9a --- /dev/null +++ b/include/boost/geometry/core/dispatch/point_iterator_type.hpp @@ -0,0 +1,37 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_CORE_DISPATCH_POINT_ITERATOR_TYPE_HPP +#define BOOST_GEOMETRY_CORE_DISPATCH_POINT_ITERATOR_TYPE_HPP + +#include +#include + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DISPATCH +namespace core_dispatch +{ + +template ::type> +struct point_iterator_type + : not_implemented +{}; + + + +} // namespace core_dispatch +#endif // DOXYGEN_NO_DISPATCH + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_CORE_DISPATCH_POINT_ITERATOR_TYPE_HPP diff --git a/include/boost/geometry/core/point_iterator.hpp b/include/boost/geometry/core/point_iterator.hpp new file mode 100644 index 000000000..7339977c1 --- /dev/null +++ b/include/boost/geometry/core/point_iterator.hpp @@ -0,0 +1,242 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_CORE_POINT_ITERATOR_HPP +#define BOOST_GEOMETRY_CORE_POINT_ITERATOR_HPP + +#include +#include + + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DISPATCH +namespace core_dispatch +{ + + +// specializations for points_begin + + +// linestring +template +struct points_begin +{ + static inline typename point_iterator_type::type + apply(Linestring& linestring) + { + return boost::begin(linestring); + } +}; + + +// ring +template +struct points_begin +{ + static inline typename point_iterator_type::type + apply(Ring& ring) + { + return boost::begin(ring); + } +}; + + +// polygon +template +struct points_begin +{ + typedef typename point_iterator_type::type return_type; + + static inline return_type apply(Polygon& polygon) + { + typedef typename return_type::second_iterator_type flatten_iterator; + + return return_type + (boost::begin(geometry::exterior_ring(polygon)), + boost::end(geometry::exterior_ring(polygon)), + flatten_iterator(boost::begin(geometry::interior_rings(polygon)), + boost::end(geometry::interior_rings(polygon)) + ) + ); + } +}; + + +// multi-point +template +struct points_begin +{ + static inline typename point_iterator_type::type + apply(MultiPoint& multipoint) + { + return boost::begin(multipoint); + } +}; + + +// multi-linestring +template +struct points_begin +{ + static inline typename point_iterator_type::type + apply(MultiLinestring& multilinestring) + { + return typename point_iterator_type + < + MultiLinestring + >::type(boost::begin(multilinestring), boost::end(multilinestring)); + } +}; + + +// multi-polygon +template +struct points_begin +{ + static inline typename point_iterator_type::type + apply(MultiPolygon& multipolygon) + { + return typename point_iterator_type + < + MultiPolygon + >::type(boost::begin(multipolygon), boost::end(multipolygon)); + } +}; + +} // namespace core_dispatch +#endif // DOXYGEN_NO_DISPATCH + + + + + +#ifndef DOXYGEN_NO_DISPATCH +namespace core_dispatch +{ + + +// specializations for points_end + + +// linestring +template +struct points_end +{ + static inline typename point_iterator_type::type + apply(Linestring& linestring) + { + return boost::end(linestring); + } +}; + + +// ring +template +struct points_end +{ + static inline typename point_iterator_type::type + apply(Ring& ring) + { + return boost::end(ring); + } +}; + + +// polygon +template +struct points_end +{ + typedef typename point_iterator_type::type return_type; + + static inline return_type apply(Polygon& polygon) + { + typedef typename return_type::second_iterator_type flatten_iterator; + + return return_type + (boost::end(geometry::exterior_ring(polygon)), + flatten_iterator( boost::end(geometry::interior_rings(polygon)) ) + ); + } +}; + + +// multi-point +template +struct points_end +{ + static inline typename point_iterator_type::type + apply(MultiPoint& multipoint) + { + return boost::end(multipoint); + } +}; + + +// multi-linestring +template +struct points_end +{ + static inline typename point_iterator_type::type + apply(MultiLinestring& multilinestring) + { + return typename point_iterator_type + < + MultiLinestring + >::type(boost::end(multilinestring)); + } +}; + + +// multi-polygon +template +struct points_end +{ + static inline typename point_iterator_type::type + apply(MultiPolygon& multipolygon) + { + return typename point_iterator_type + < + MultiPolygon + >::type(boost::end(multipolygon)); + } +}; + + +} // namespace core_dispatch +#endif // DOXYGEN_NO_DISPATCH + + + + +// MK:: need to add doc here +template +typename point_iterator_type::type +points_begin(Geometry& geometry) +{ + return core_dispatch::points_begin::apply(geometry); +} + + +// MK:: need to add doc here +template +typename point_iterator_type::type +points_end(Geometry& geometry) +{ + return core_dispatch::points_end::apply(geometry); +} + + + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_CORE_POINT_ITERATOR_HPP diff --git a/include/boost/geometry/core/point_iterator_type.hpp b/include/boost/geometry/core/point_iterator_type.hpp new file mode 100644 index 000000000..51e409d66 --- /dev/null +++ b/include/boost/geometry/core/point_iterator_type.hpp @@ -0,0 +1,216 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_CORE_POINT_ITERATOR_TYPE_HPP +#define BOOST_GEOMETRY_CORE_POINT_ITERATOR_TYPE_HPP + +#include +#include + +#include +#include +#include +#include +#include +#include + + +namespace boost { namespace geometry +{ + + + +#ifndef DOXYGEN_NO_DETAIL +namespace core_detail +{ + + +template +struct point_iterator_value_type +{ + typedef typename boost::mpl::if_c + < + !boost::is_const::type::value, + typename geometry::point_type::type, + typename geometry::point_type::type const + >::type type; +}; + + + + +template +< + typename Geometry, + typename Tag = typename tag::type +> +struct point_iterator_inner_range_type +{ + typedef typename boost::mpl::if_c + < + !boost::is_const::type::value, + typename boost::range_value::type, + typename boost::range_value::type const + >::type type; +}; + + +template +struct point_iterator_inner_range_type +{ + typedef typename boost::mpl::if_c + < + !boost::is_const::type::value, + typename geometry::ring_type::type, + typename geometry::ring_type::type const + >::type type; +}; + + + +} // namespace core_detail +#endif // DOXYGEN_NO_DETAIL + + + + + +#ifndef DOXYGEN_NO_DISPATCH +namespace core_dispatch +{ + + +// linestring +template +struct point_iterator_type +{ + typedef typename boost::range_iterator::type type; +}; + + +// ring +template +struct point_iterator_type +{ + typedef typename boost::range_iterator::type type; +}; + + +// polygon +template +class point_iterator_type +{ +private: + typedef typename core_detail::point_iterator_inner_range_type + < + Polygon + >::type InnerRange; + +public: + typedef util::concatenate_iterator + < + typename boost::range_iterator::type, + util::flatten_iterator + < + typename boost::range_iterator + < + typename geometry::interior_type::type + >::type, + typename core_dispatch::point_iterator_type + < + InnerRange + >::type, + typename core_detail::point_iterator_value_type + < + Polygon + >::type, + core_dispatch::points_begin, + core_dispatch::points_end + >, + typename core_detail::point_iterator_value_type::type + > type; +}; + + +// multi-point +template +struct point_iterator_type +{ + typedef typename boost::range_iterator::type type; +}; + + +// multi-linestring +template +class point_iterator_type +{ +private: + typedef typename core_detail::point_iterator_inner_range_type + < + MultiLinestring + >::type InnerRange; + +public: + typedef util::flatten_iterator + < + typename boost::range_iterator::type, + typename core_dispatch::point_iterator_type::type, + typename core_detail::point_iterator_value_type + < + MultiLinestring + >::type, + core_dispatch::points_begin, + core_dispatch::points_end + > type; +}; + + +// multi-polygon +template +class point_iterator_type +{ +private: + typedef typename core_detail::point_iterator_inner_range_type + < + MultiPolygon + >::type InnerRange; + +public: + typedef util::flatten_iterator + < + typename boost::range_iterator::type, + typename core_dispatch::point_iterator_type::type, + typename core_detail::point_iterator_value_type::type, + core_dispatch::points_begin, + core_dispatch::points_end + > type; +}; + + + + + +} // namespace core_dispatch +#endif // DOXYGEN_NO_DISPATCH + + + +// MK::need to add doc here +template +struct point_iterator_type +{ + typedef typename core_dispatch::point_iterator_type::type type; +}; + + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_CORE_POINT_ITERATOR_TYPE_HPP diff --git a/include/boost/geometry/util/concatenate_iterator.hpp b/include/boost/geometry/util/concatenate_iterator.hpp new file mode 100644 index 000000000..7071cf87b --- /dev/null +++ b/include/boost/geometry/util/concatenate_iterator.hpp @@ -0,0 +1,91 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_UTIL_POINT_CONCATENATE_ITERATOR_HPP +#define BOOST_GEOMETRY_UTIL_POINT_CONCATENATE_ITERATOR_HPP + +#include + + +namespace boost { namespace geometry +{ + + +namespace util +{ + + +template +struct concatenate_iterator + : public boost::iterator_facade + < + concatenate_iterator, + Value, + boost::forward_traversal_tag + > +{ +private: + Iterator1 m_it1, m_end1; + Iterator2 m_it2; + +public: + typedef Iterator1 first_iterator_type; + typedef Iterator2 second_iterator_type; + + // default constructor + concatenate_iterator() {} + + // for begin + concatenate_iterator(Iterator1 it1, Iterator1 end1, + Iterator2 it2) + : m_it1(it1), m_end1(end1), m_it2(it2) + {} + + // for end + concatenate_iterator(Iterator1 end1, Iterator2 end2) + : m_it1(end1), m_end1(end1), m_it2(end2) + {} + +private: + friend class boost::iterator_core_access; + + Value& dereference() const + { + if ( m_it1 == m_end1 ) + { + return *m_it2; + } + return *m_it1; + } + + bool equal(concatenate_iterator const& other) const + { + return m_it1 == other.m_it1 && m_it2 == other.m_it2; + } + + void increment() + { + if ( m_it1 == m_end1 ) + { + ++m_it2; + } + else + { + ++m_it1; + } + } +}; + + +} // namespace util + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_UTIL_CONCATENATE_ITERATOR_HPP diff --git a/include/boost/geometry/util/flatten_iterator.hpp b/include/boost/geometry/util/flatten_iterator.hpp new file mode 100644 index 000000000..9b44370bc --- /dev/null +++ b/include/boost/geometry/util/flatten_iterator.hpp @@ -0,0 +1,219 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_UTIL_FLATTEN_ITERATOR_HPP +#define BOOST_GEOMETRY_UTIL_FLATTEN_ITERATOR_HPP + +#include +#include +#include + + +namespace boost { namespace geometry +{ + + +namespace util +{ + + +template +< + typename OuterIterator, + typename InnerIterator, + typename Value, + typename AccessInnerBegin, + typename AccessInnerEnd +> +struct flatten_iterator + : public boost::iterator_facade + < + flatten_iterator + < + OuterIterator, + InnerIterator, + Value, + AccessInnerBegin, + AccessInnerEnd>, + Value, + boost::forward_traversal_tag + > +{ +private: + OuterIterator m_outer_it, m_outer_end; + InnerIterator m_inner_it; + + struct enabler {}; + +public: + typedef OuterIterator outer_iterator_type; + typedef InnerIterator inner_iterator_type; + + // default constructor + flatten_iterator() {} + + // for begin + flatten_iterator(OuterIterator outer_it, OuterIterator outer_end) + : m_outer_it(outer_it), m_outer_end(outer_end) + { + if ( m_outer_it != m_outer_end ) + { + m_inner_it = AccessInnerBegin::apply(*m_outer_it); + // m_inner_it = AccessInnerBegin(*m_outer_it); + } + advance_through_empty(); + } + + // for end + flatten_iterator(OuterIterator outer_end) + : m_outer_it(outer_end), m_outer_end(outer_end) + {} + + template + < + typename OtherOuterIterator, + typename OtherInnerIterator, + typename OtherValue + > + explicit flatten_iterator(flatten_iterator + < + OtherOuterIterator, + OtherInnerIterator, + OtherValue, + AccessInnerBegin, + AccessInnerEnd + > const& other, + typename boost::enable_if + < + boost::is_convertible + < + OtherOuterIterator*, OuterIterator* + >, enabler + >::type = enabler() + ) + : m_outer_it(other.m_outer_it), + m_outer_end(other.m_outer_end), + m_inner_it(other.m_inner_it) + {} + + template + < + typename OtherOuterIterator, + typename OtherInnerIterator, + typename OtherValue + > + flatten_iterator operator=(flatten_iterator + < + OtherOuterIterator, + OtherInnerIterator, + OtherValue, + AccessInnerBegin, + AccessInnerEnd + > const& other) + { + m_outer_it = other.m_outer_it; + m_outer_end = other.m_outer_end; + m_inner_it = other.m_inner_it; + return *this; + } + +private: + friend class boost::iterator_core_access; + + template + < + typename OuterIterator1, + typename InnerIterator1, + typename Value1, + typename AccessInnerBegin1, + typename AccessInnerEnd1 + > + friend class flatten_iterator; + + static inline bool empty(OuterIterator outer_it) + { + return + AccessInnerBegin::apply(*outer_it) == AccessInnerEnd::apply(*outer_it); + // AccessInnerBegin(*outer_it) == AccessInnerEnd(*outer_it); + } + + void advance_through_empty() + { + while ( m_outer_it != m_outer_end && empty(m_outer_it) ) + { + ++m_outer_it; + } + + if ( m_outer_it != m_outer_end ) + { + m_inner_it = AccessInnerBegin::apply(*m_outer_it); + // m_inner_it = AccessInnerBegin(*m_outer_it); + } + } + + Value& dereference() const + { + BOOST_ASSERT( m_outer_it != m_outer_end ); + BOOST_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) ); + // BOOST_ASSERT( m_inner_it != AccessInnerEnd(*m_outer_it) ); + return *m_inner_it; + } + + + template + < + typename OtherOuterIterator, + typename OtherInnerIterator, + typename OtherValue + > + bool equal(flatten_iterator + < + OtherOuterIterator, + OtherInnerIterator, + OtherValue, + AccessInnerBegin, + AccessInnerEnd + > const& other) const + { + if ( this->m_outer_it != other.m_outer_it ) + { + return false; + } + + if ( this->m_outer_it == m_outer_end ) + { + return true; + } + + return this->m_inner_it == other.m_inner_it; + } + + void increment() + { + BOOST_ASSERT( m_outer_it != m_outer_end ); + BOOST_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) ); + // BOOST_ASSERT( m_inner_it != AccessInnerEnd(*m_outer_it) ); + + ++m_inner_it; + if ( m_inner_it == AccessInnerEnd::apply(*m_outer_it) ) + //if ( m_inner_it == AccessInnerEnd(*m_outer_it) ) + { + ++m_outer_it; + advance_through_empty(); + } + } +}; + + +} // namespace util + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_UTIL_FLATTEN_INTERATOR_HPP diff --git a/test/core/point_iterator.cpp b/test/core/point_iterator.cpp new file mode 100644 index 000000000..a88a79b7d --- /dev/null +++ b/test/core/point_iterator.cpp @@ -0,0 +1,331 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// Unit Test + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + + +#include + +#ifndef BOOST_TEST_MODULE +#define BOOST_TEST_MODULE test_point_iterator +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../algorithms/from_wkt.hpp" + +#include + + +namespace bg = ::boost::geometry; + +typedef bg::model::point point_type; +typedef bg::model::linestring linestring_type; +typedef bg::model::polygon polygon_type; //ccw, open + +// multi geometries +typedef bg::model::multi_point multi_point_type; +typedef bg::model::multi_linestring multi_linestring_type; +typedef bg::model::multi_polygon multi_polygon_type; + +struct equals +{ + template + static inline std::size_t number_of_elements(Iterator begin, + Iterator end) + { + std::size_t num_elems(0); + for (Iterator it = begin; it != end; ++it) + { + ++num_elems; + } + return num_elems; + } + + template + static inline bool apply(Iterator1 begin1, Iterator1 end1, + Iterator2 begin2, Iterator2 end2) + { + std::size_t num_points1 = number_of_elements(begin1, end1); + std::size_t num_points2 = number_of_elements(begin2, end2); + + if ( num_points1 != num_points2 ) + { + return false; + } + + Iterator1 it1 = begin1; + Iterator2 it2 = begin2; + for (; it1 != end1; ++it1, ++it2) + { + if ( !bg::equals(*it1, *it2) ) + { + return false; + } + } + return true; + } +}; + +template +struct test_point_iterator_of_geometry +{ + template + static inline void base_test(G& geometry, + PointRange const& point_range, + std::string const& header) + { + typedef typename bg::point_iterator_type + < + G + >::type point_iterator_type; + + point_iterator_type begin = bg::points_begin(geometry); + point_iterator_type end = bg::points_end(geometry); + + BOOST_CHECK( equals::apply(begin, end, + boost::begin(point_range), + boost::end(point_range)) + ); + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << header << " geometry: " << bg::wkt(geometry) << std::endl; + std::cout << "point range: ("; + for (point_iterator_type pit = begin; pit != end; ++pit) + { + std::cout << " " << bg::dsv(*pit); + } + std::cout << " )" << std::endl; + std::cout << "expected point range: " << bg::wkt(point_range) + << std::endl; +#endif + } + + static inline void apply(Geometry geometry, PointRange const& point_range) + { + base_test(geometry, point_range, "non-const"); + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl; +#endif + + base_test(geometry, point_range, "const"); + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl << std::endl; +#endif + } +}; + + +//====================================================================== +//====================================================================== + + +BOOST_AUTO_TEST_CASE( test_linestring_point_iterator ) +{ +#ifdef GEOMETRY_TEST_DEBUG + std::cout << "*** LINESTRING ***" << std::endl; +#endif + + typedef multi_point_type MP; + typedef linestring_type L; + + typedef test_point_iterator_of_geometry tester; + + tester::apply(from_wkt("LINESTRING()"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt("LINESTRING(3 3,4 4,5 5)"), + from_wkt("MULTIPOINT(3 3,4 4,5 5)") + ); + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl << std::endl << std::endl; +#endif +} + + +//====================================================================== +//====================================================================== + + +BOOST_AUTO_TEST_CASE( test_polygon_point_iterator ) +{ +#ifdef GEOMETRY_TEST_DEBUG + std::cout << "*** POLYGON ***" << std::endl; +#endif + + typedef multi_point_type MP; + typedef polygon_type P; + + typedef test_point_iterator_of_geometry tester; + + tester::apply(from_wkt

("POLYGON()"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt

("POLYGON(())"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt

("POLYGON((3 3,4 4,5 5),(),(),(),\ + (6 6,7 7,8 8),(),(),(9 9),())"), + from_wkt("MULTIPOINT(3 3,4 4,5 5,6 6,7 7,8 8,9 9)") + ); + + tester::apply(from_wkt

("POLYGON((),(3 3,4 4,5 5),(),(),\ + (6 6,7 7,8 8),(),(),(9 9),())"), + from_wkt("MULTIPOINT(3 3,4 4,5 5,6 6,7 7,8 8,9 9)") + ); + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl << std::endl; +#endif +} + + +//====================================================================== +//====================================================================== + + +BOOST_AUTO_TEST_CASE( test_multipoint_point_iterator ) +{ +#ifdef GEOMETRY_TEST_DEBUG + std::cout << "*** MULTIPOINT ***" << std::endl; +#endif + + typedef multi_point_type MP; + + typedef test_point_iterator_of_geometry tester; + + tester::apply(from_wkt("MULTIPOINT()"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt("MULTIPOINT(3 3,4 4,5 5)"), + from_wkt("MULTIPOINT(3 3,4 4,5 5)") + ); + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl << std::endl << std::endl; +#endif +} + + +//====================================================================== +//====================================================================== + + +BOOST_AUTO_TEST_CASE( test_multilinestring_point_iterator ) +{ +#ifdef GEOMETRY_TEST_DEBUG + std::cout << "*** MULTILINESTRING ***" << std::endl; +#endif + + typedef multi_point_type MP; + typedef linestring_type L; + typedef multi_linestring_type ML; + + typedef test_point_iterator_of_geometry tester; + + tester::apply(from_wkt("MULTILINESTRING()"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt("MULTILINESTRING(())"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt("MULTILINESTRING((),(),())"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt("MULTILINESTRING((),(),(0 0,1 1,2 2),(),(),\ + (3 3,4 4,5 5),(),(6 6),(),(),())"), + from_wkt("MULTIPOINT(0 0,1 1,2 2,3 3,4 4,5 5,6 6)") + ); + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl << std::endl; +#endif +} + + +//====================================================================== +//====================================================================== + + +BOOST_AUTO_TEST_CASE( test_multipolygon_point_iterator ) +{ +#ifdef GEOMETRY_TEST_DEBUG + std::cout << "*** MULTIPOLYGON ***" << std::endl; +#endif + + typedef multi_point_type MP; + typedef multi_polygon_type MPL; + + typedef test_point_iterator_of_geometry tester; + + tester::apply(from_wkt("MULTIPOLYGON()"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt("MULTIPOLYGON( () )"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt("MULTIPOLYGON( (()) )"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt("MULTIPOLYGON( ((),()) )"), + from_wkt("MULTIPOINT()") + ); + + tester::apply(from_wkt("MULTIPOLYGON(\ + ((3 3,4 4,5 5),(),(),(),\ + (6 6,7 7,8 8),(),(),(9 9),())\ + \ + ((),(1 1,2 2,10 10),(),(),(),\ + (11 11,12 12),(),(),(13 13),())\ + )"), + from_wkt("MULTIPOINT(3 3,4 4,5 5,6 6,7 7,8 8,9 9,\ + 1 1,2 2,10 10,11 11,12 12,13 13)") + ); + + tester::apply(from_wkt("MULTIPOLYGON(\ + (),\ + \ + ((3 3,4 4,5 5),(),(),(),\ + (6 6,7 7,8 8),(),(),(9 9),())\ + \ + ((),(1 1,2 2,10 10),(),(),(),\ + (11 11,12 12),(),(),(13 13),())\ + \ + ((),(),()),\ + )"), + from_wkt("MULTIPOINT(3 3,4 4,5 5,6 6,7 7,8 8,9 9,\ + 1 1,2 2,10 10,11 11,12 12,13 13)") + ); + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl << std::endl; +#endif +} + From bed33a7ee40880a11e4c9ef1ab9aceaac5a64f7c Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Wed, 26 Mar 2014 11:25:06 +0200 Subject: [PATCH 02/20] [point iterator] add missing definition of from_wkt in unit test; --- test/core/point_iterator.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/core/point_iterator.cpp b/test/core/point_iterator.cpp index a88a79b7d..f06aac273 100644 --- a/test/core/point_iterator.cpp +++ b/test/core/point_iterator.cpp @@ -26,7 +26,6 @@ #include #include #include -#include "../algorithms/from_wkt.hpp" #include @@ -42,6 +41,16 @@ typedef bg::model::multi_point multi_point_type; typedef bg::model::multi_linestring multi_linestring_type; typedef bg::model::multi_polygon multi_polygon_type; + +template +Geometry from_wkt(std::string const& wkt) +{ + Geometry res; + boost::geometry::read_wkt(wkt, res); + return res; +} + + struct equals { template From 555947d8e2017ecffa7a6a7b0f80f7ff7b144e18 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Thu, 27 Mar 2014 02:11:02 +0200 Subject: [PATCH 03/20] [point_iterator] define points_{begin,end} as inline free functions; --- include/boost/geometry/core/point_iterator.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/geometry/core/point_iterator.hpp b/include/boost/geometry/core/point_iterator.hpp index 7339977c1..9d5d13742 100644 --- a/include/boost/geometry/core/point_iterator.hpp +++ b/include/boost/geometry/core/point_iterator.hpp @@ -219,7 +219,7 @@ struct points_end // MK:: need to add doc here template -typename point_iterator_type::type +inline typename point_iterator_type::type points_begin(Geometry& geometry) { return core_dispatch::points_begin::apply(geometry); @@ -228,7 +228,7 @@ points_begin(Geometry& geometry) // MK:: need to add doc here template -typename point_iterator_type::type +inline typename point_iterator_type::type points_end(Geometry& geometry) { return core_dispatch::points_end::apply(geometry); From 64c11353be4fbdbdc19ab1cfba00d5aa936dd8ad Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Thu, 27 Mar 2014 02:25:38 +0200 Subject: [PATCH 04/20] [point_iterator] move flatten and concatenate iterator implementation in iterators/ directory; --- .../concatenate_iterator.hpp | 12 ++++------ .../{util => iterators}/flatten_iterator.hpp | 24 +++++-------------- 2 files changed, 11 insertions(+), 25 deletions(-) rename include/boost/geometry/{util => iterators}/concatenate_iterator.hpp (86%) rename include/boost/geometry/{util => iterators}/flatten_iterator.hpp (87%) diff --git a/include/boost/geometry/util/concatenate_iterator.hpp b/include/boost/geometry/iterators/concatenate_iterator.hpp similarity index 86% rename from include/boost/geometry/util/concatenate_iterator.hpp rename to include/boost/geometry/iterators/concatenate_iterator.hpp index 7071cf87b..da2e78986 100644 --- a/include/boost/geometry/util/concatenate_iterator.hpp +++ b/include/boost/geometry/iterators/concatenate_iterator.hpp @@ -7,18 +7,18 @@ // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html -#ifndef BOOST_GEOMETRY_UTIL_POINT_CONCATENATE_ITERATOR_HPP -#define BOOST_GEOMETRY_UTIL_POINT_CONCATENATE_ITERATOR_HPP +#ifndef BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP +#define BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP +#include #include +#include namespace boost { namespace geometry { -namespace util -{ template @@ -83,9 +83,7 @@ private: }; -} // namespace util - }} // namespace boost::geometry -#endif // BOOST_GEOMETRY_UTIL_CONCATENATE_ITERATOR_HPP +#endif // BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP diff --git a/include/boost/geometry/util/flatten_iterator.hpp b/include/boost/geometry/iterators/flatten_iterator.hpp similarity index 87% rename from include/boost/geometry/util/flatten_iterator.hpp rename to include/boost/geometry/iterators/flatten_iterator.hpp index 9b44370bc..67847593d 100644 --- a/include/boost/geometry/util/flatten_iterator.hpp +++ b/include/boost/geometry/iterators/flatten_iterator.hpp @@ -7,21 +7,20 @@ // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html -#ifndef BOOST_GEOMETRY_UTIL_FLATTEN_ITERATOR_HPP -#define BOOST_GEOMETRY_UTIL_FLATTEN_ITERATOR_HPP +#ifndef BOOST_GEOMETRY_ITERATORS_FLATTEN_ITERATOR_HPP +#define BOOST_GEOMETRY_ITERATORS_FLATTEN_ITERATOR_HPP #include #include +#include #include +#include namespace boost { namespace geometry { -namespace util -{ - template < @@ -62,11 +61,6 @@ public: flatten_iterator(OuterIterator outer_it, OuterIterator outer_end) : m_outer_it(outer_it), m_outer_end(outer_end) { - if ( m_outer_it != m_outer_end ) - { - m_inner_it = AccessInnerBegin::apply(*m_outer_it); - // m_inner_it = AccessInnerBegin(*m_outer_it); - } advance_through_empty(); } @@ -140,7 +134,6 @@ private: { return AccessInnerBegin::apply(*outer_it) == AccessInnerEnd::apply(*outer_it); - // AccessInnerBegin(*outer_it) == AccessInnerEnd(*outer_it); } void advance_through_empty() @@ -153,7 +146,6 @@ private: if ( m_outer_it != m_outer_end ) { m_inner_it = AccessInnerBegin::apply(*m_outer_it); - // m_inner_it = AccessInnerBegin(*m_outer_it); } } @@ -161,7 +153,6 @@ private: { BOOST_ASSERT( m_outer_it != m_outer_end ); BOOST_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) ); - // BOOST_ASSERT( m_inner_it != AccessInnerEnd(*m_outer_it) ); return *m_inner_it; } @@ -198,11 +189,9 @@ private: { BOOST_ASSERT( m_outer_it != m_outer_end ); BOOST_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) ); - // BOOST_ASSERT( m_inner_it != AccessInnerEnd(*m_outer_it) ); ++m_inner_it; if ( m_inner_it == AccessInnerEnd::apply(*m_outer_it) ) - //if ( m_inner_it == AccessInnerEnd(*m_outer_it) ) { ++m_outer_it; advance_through_empty(); @@ -211,9 +200,8 @@ private: }; -} // namespace util - }} // namespace boost::geometry -#endif // BOOST_GEOMETRY_UTIL_FLATTEN_INTERATOR_HPP + +#endif // BOOST_GEOMETRY_ITERATORS_FLATTEN_ITERATOR_HPP From 8a8132e6c02ad69d7f5fa5440c11162777d568ab Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Thu, 27 Mar 2014 23:23:51 +0200 Subject: [PATCH 05/20] [point_iterator] moved files to proper directories --- .../geometry/{core => iterators}/dispatch/point_iterator.hpp | 0 .../geometry/{core => iterators}/dispatch/point_iterator_type.hpp | 0 include/boost/geometry/{core => iterators}/point_iterator.hpp | 0 .../boost/geometry/{core => iterators}/point_iterator_type.hpp | 0 test/{core => iterators}/point_iterator.cpp | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename include/boost/geometry/{core => iterators}/dispatch/point_iterator.hpp (100%) rename include/boost/geometry/{core => iterators}/dispatch/point_iterator_type.hpp (100%) rename include/boost/geometry/{core => iterators}/point_iterator.hpp (100%) rename include/boost/geometry/{core => iterators}/point_iterator_type.hpp (100%) rename test/{core => iterators}/point_iterator.cpp (100%) diff --git a/include/boost/geometry/core/dispatch/point_iterator.hpp b/include/boost/geometry/iterators/dispatch/point_iterator.hpp similarity index 100% rename from include/boost/geometry/core/dispatch/point_iterator.hpp rename to include/boost/geometry/iterators/dispatch/point_iterator.hpp diff --git a/include/boost/geometry/core/dispatch/point_iterator_type.hpp b/include/boost/geometry/iterators/dispatch/point_iterator_type.hpp similarity index 100% rename from include/boost/geometry/core/dispatch/point_iterator_type.hpp rename to include/boost/geometry/iterators/dispatch/point_iterator_type.hpp diff --git a/include/boost/geometry/core/point_iterator.hpp b/include/boost/geometry/iterators/point_iterator.hpp similarity index 100% rename from include/boost/geometry/core/point_iterator.hpp rename to include/boost/geometry/iterators/point_iterator.hpp diff --git a/include/boost/geometry/core/point_iterator_type.hpp b/include/boost/geometry/iterators/point_iterator_type.hpp similarity index 100% rename from include/boost/geometry/core/point_iterator_type.hpp rename to include/boost/geometry/iterators/point_iterator_type.hpp diff --git a/test/core/point_iterator.cpp b/test/iterators/point_iterator.cpp similarity index 100% rename from test/core/point_iterator.cpp rename to test/iterators/point_iterator.cpp From f5d48b379834d5093b483fc1f87b6c7dc8e75429 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Thu, 27 Mar 2014 23:26:25 +0200 Subject: [PATCH 06/20] [point_iterator][concatenate_iterator] fix issues in copy constructor; --- .../iterators/concatenate_iterator.hpp | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/include/boost/geometry/iterators/concatenate_iterator.hpp b/include/boost/geometry/iterators/concatenate_iterator.hpp index da2e78986..7321f1c81 100644 --- a/include/boost/geometry/iterators/concatenate_iterator.hpp +++ b/include/boost/geometry/iterators/concatenate_iterator.hpp @@ -20,7 +20,6 @@ namespace boost { namespace geometry - template struct concatenate_iterator : public boost::iterator_facade @@ -34,6 +33,19 @@ private: Iterator1 m_it1, m_end1; Iterator2 m_it2; + struct enabler {}; + + template + struct is_convertible + : boost::mpl::if_c + < + boost::is_convertible::value + && boost::is_convertible::value, + boost::true_type, + boost::false_type + >::type + {}; + public: typedef Iterator1 first_iterator_type; typedef Iterator2 second_iterator_type; @@ -52,9 +64,25 @@ public: : m_it1(end1), m_end1(end1), m_it2(end2) {} + template + concatenate_iterator + (concatenate_iterator const& other, + typename boost::enable_if + < + is_convertible, + enabler + >::type = enabler()) + : m_it1(other.m_it1), m_end1(other.m_end1), m_it2(other.m_it2) + {} + + + private: friend class boost::iterator_core_access; + template + friend class concatenate_iterator; + Value& dereference() const { if ( m_it1 == m_end1 ) From 5d27f4f30120f1b68a5fe2d98772a081a8ff1c35 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Thu, 27 Mar 2014 23:27:23 +0200 Subject: [PATCH 07/20] [point_iterator][flatten_iterator] polish code a bit; fix problems with copy constructor; --- .../geometry/iterators/flatten_iterator.hpp | 79 ++++++++++--------- 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/include/boost/geometry/iterators/flatten_iterator.hpp b/include/boost/geometry/iterators/flatten_iterator.hpp index 67847593d..4a7c68a6d 100644 --- a/include/boost/geometry/iterators/flatten_iterator.hpp +++ b/include/boost/geometry/iterators/flatten_iterator.hpp @@ -71,26 +71,25 @@ public: template < - typename OtherOuterIterator, - typename OtherInnerIterator, - typename OtherValue + typename OtherOuterIterator, typename OtherInnerIterator, + typename OtherValue, + typename OtherAccessInnerBegin, typename OtherAccessInnerEnd > - explicit flatten_iterator(flatten_iterator - < - OtherOuterIterator, - OtherInnerIterator, - OtherValue, - AccessInnerBegin, - AccessInnerEnd - > const& other, - typename boost::enable_if - < - boost::is_convertible - < - OtherOuterIterator*, OuterIterator* - >, enabler - >::type = enabler() - ) + flatten_iterator(flatten_iterator + < + OtherOuterIterator, + OtherInnerIterator, + OtherValue, + OtherAccessInnerBegin, + OtherAccessInnerEnd + > const& other, + typename boost::enable_if + < + boost::is_convertible + < + OtherValue*, Value* + >, enabler + >::type = enabler()) : m_outer_it(other.m_outer_it), m_outer_end(other.m_outer_end), m_inner_it(other.m_inner_it) @@ -100,15 +99,17 @@ public: < typename OtherOuterIterator, typename OtherInnerIterator, - typename OtherValue + typename OtherValue, + typename OtherAccessInnerBegin, + typename OtherAccessInnerEnd > flatten_iterator operator=(flatten_iterator < OtherOuterIterator, OtherInnerIterator, OtherValue, - AccessInnerBegin, - AccessInnerEnd + OtherAccessInnerBegin, + OtherAccessInnerEnd > const& other) { m_outer_it = other.m_outer_it; @@ -122,11 +123,11 @@ private: template < - typename OuterIterator1, - typename InnerIterator1, - typename Value1, - typename AccessInnerBegin1, - typename AccessInnerEnd1 + typename Outer, + typename Inner, + typename V, + typename InnerBegin, + typename InnerEnd > friend class flatten_iterator; @@ -136,7 +137,7 @@ private: AccessInnerBegin::apply(*outer_it) == AccessInnerEnd::apply(*outer_it); } - void advance_through_empty() + inline void advance_through_empty() { while ( m_outer_it != m_outer_end && empty(m_outer_it) ) { @@ -161,16 +162,18 @@ private: < typename OtherOuterIterator, typename OtherInnerIterator, - typename OtherValue + typename OtherValue, + typename OtherAccessInnerBegin, + typename OtherAccessInnerEnd > - bool equal(flatten_iterator - < - OtherOuterIterator, - OtherInnerIterator, - OtherValue, - AccessInnerBegin, - AccessInnerEnd - > const& other) const + inline bool equal(flatten_iterator + < + OtherOuterIterator, + OtherInnerIterator, + OtherValue, + OtherAccessInnerBegin, + OtherAccessInnerEnd + > const& other) const { if ( this->m_outer_it != other.m_outer_it ) { @@ -185,7 +188,7 @@ private: return this->m_inner_it == other.m_inner_it; } - void increment() + inline void increment() { BOOST_ASSERT( m_outer_it != m_outer_end ); BOOST_ASSERT( m_inner_it != AccessInnerEnd::apply(*m_outer_it) ); From 88264401a1e8b7a81d651c260ce5b18ec4f45428 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Thu, 27 Mar 2014 23:28:07 +0200 Subject: [PATCH 08/20] [point_iterator] change namespace from core_dispatch to dispatch; fix macros of files due to new location; --- .../geometry/iterators/dispatch/point_iterator.hpp | 8 ++++---- .../iterators/dispatch/point_iterator_type.hpp | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/boost/geometry/iterators/dispatch/point_iterator.hpp b/include/boost/geometry/iterators/dispatch/point_iterator.hpp index 9d89ae737..c07f3a865 100644 --- a/include/boost/geometry/iterators/dispatch/point_iterator.hpp +++ b/include/boost/geometry/iterators/dispatch/point_iterator.hpp @@ -7,8 +7,8 @@ // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html -#ifndef BOOST_GEOMETRY_CORE_DISPATCH_POINT_ITERATOR_HPP -#define BOOST_GEOMETRY_CORE_DISPATCH_POINT_ITERATOR_HPP +#ifndef BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_HPP +#define BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_HPP #include #include @@ -18,7 +18,7 @@ namespace boost { namespace geometry #ifndef DOXYGEN_NO_DISPATCH -namespace core_dispatch +namespace dispatch { @@ -44,4 +44,4 @@ struct points_end }} // namespace boost::geometry -#endif // BOOST_GEOMETRY_CORE_DISPATCH_POINT_ITERATOR_HPP +#endif // BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_HPP diff --git a/include/boost/geometry/iterators/dispatch/point_iterator_type.hpp b/include/boost/geometry/iterators/dispatch/point_iterator_type.hpp index abf91dd9a..02c40acae 100644 --- a/include/boost/geometry/iterators/dispatch/point_iterator_type.hpp +++ b/include/boost/geometry/iterators/dispatch/point_iterator_type.hpp @@ -7,8 +7,8 @@ // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html -#ifndef BOOST_GEOMETRY_CORE_DISPATCH_POINT_ITERATOR_TYPE_HPP -#define BOOST_GEOMETRY_CORE_DISPATCH_POINT_ITERATOR_TYPE_HPP +#ifndef BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_TYPE_HPP +#define BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_TYPE_HPP #include #include @@ -18,7 +18,7 @@ namespace boost { namespace geometry #ifndef DOXYGEN_NO_DISPATCH -namespace core_dispatch +namespace dispatch { template ::type> @@ -28,10 +28,10 @@ struct point_iterator_type -} // namespace core_dispatch +} // namespace dispatch #endif // DOXYGEN_NO_DISPATCH }} // namespace boost::geometry -#endif // BOOST_GEOMETRY_CORE_DISPATCH_POINT_ITERATOR_TYPE_HPP +#endif // BOOST_GEOMETRY_ITERATORS_DISPATCH_POINT_ITERATOR_TYPE_HPP From 25e746cd2a122f974b423c78ea40d13f2d072405 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Thu, 27 Mar 2014 23:29:37 +0200 Subject: [PATCH 09/20] [point_iterator] move code to new namespace; remove comments; points_begin/point_end now return point_iterator class (suggested by Adam); --- .../geometry/iterators/point_iterator.hpp | 86 +++++++++++++------ 1 file changed, 59 insertions(+), 27 deletions(-) diff --git a/include/boost/geometry/iterators/point_iterator.hpp b/include/boost/geometry/iterators/point_iterator.hpp index 9d5d13742..192d75d57 100644 --- a/include/boost/geometry/iterators/point_iterator.hpp +++ b/include/boost/geometry/iterators/point_iterator.hpp @@ -7,11 +7,11 @@ // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html -#ifndef BOOST_GEOMETRY_CORE_POINT_ITERATOR_HPP -#define BOOST_GEOMETRY_CORE_POINT_ITERATOR_HPP +#ifndef BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP +#define BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP -#include -#include +#include +#include namespace boost { namespace geometry @@ -19,14 +19,13 @@ namespace boost { namespace geometry #ifndef DOXYGEN_NO_DISPATCH -namespace core_dispatch +namespace dispatch { // specializations for points_begin -// linestring template struct points_begin { @@ -38,7 +37,6 @@ struct points_begin }; -// ring template struct points_begin { @@ -50,7 +48,6 @@ struct points_begin }; -// polygon template struct points_begin { @@ -71,7 +68,6 @@ struct points_begin }; -// multi-point template struct points_begin { @@ -83,7 +79,6 @@ struct points_begin }; -// multi-linestring template struct points_begin { @@ -98,7 +93,6 @@ struct points_begin }; -// multi-polygon template struct points_begin { @@ -112,7 +106,7 @@ struct points_begin } }; -} // namespace core_dispatch +} // namespace dispatch #endif // DOXYGEN_NO_DISPATCH @@ -120,14 +114,13 @@ struct points_begin #ifndef DOXYGEN_NO_DISPATCH -namespace core_dispatch +namespace dispatch { // specializations for points_end -// linestring template struct points_end { @@ -139,7 +132,6 @@ struct points_end }; -// ring template struct points_end { @@ -151,7 +143,6 @@ struct points_end }; -// polygon template struct points_end { @@ -169,7 +160,6 @@ struct points_end }; -// multi-point template struct points_end { @@ -181,7 +171,6 @@ struct points_end }; -// multi-linestring template struct points_end { @@ -196,7 +185,6 @@ struct points_end }; -// multi-polygon template struct points_end { @@ -211,32 +199,76 @@ struct points_end }; -} // namespace core_dispatch +} // namespace dispatch #endif // DOXYGEN_NO_DISPATCH +// MK:: need to add doc here +template +class point_iterator + : public dispatch::point_iterator_type::type +{ +private: + typedef typename dispatch::point_iterator_type::type base; + + base* base_ptr() + { + return this; + } + + base const* base_ptr() const + { + return this; + } + + template + struct is_convertible + : boost::is_convertible + < + typename dispatch::point_iterator_type::type, + typename dispatch::point_iterator_type::type + > + {}; + + struct enabler {}; + + template friend class point_iterator; +public: + point_iterator() {} + + point_iterator(base const& base_it) : base(base_it) {} + + template + point_iterator(point_iterator const& other, + typename boost::enable_if + < + is_convertible, + enabler + >::type = enabler()) + + : base(*other.base_ptr()) + {} +}; // MK:: need to add doc here template -inline typename point_iterator_type::type +inline point_iterator points_begin(Geometry& geometry) { - return core_dispatch::points_begin::apply(geometry); + return dispatch::points_begin::apply(geometry); } // MK:: need to add doc here template -inline typename point_iterator_type::type +inline point_iterator points_end(Geometry& geometry) { - return core_dispatch::points_end::apply(geometry); + return dispatch::points_end::apply(geometry); } - - }} // namespace boost::geometry -#endif // BOOST_GEOMETRY_CORE_POINT_ITERATOR_HPP +#endif // BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP From c127c568716992e211f15b37a3d35619684bf11f Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Thu, 27 Mar 2014 23:32:05 +0200 Subject: [PATCH 10/20] [point_iterator] changes due to new location of files and namespaces used; --- .../iterators/point_iterator_type.hpp | 81 ++++++++----------- 1 file changed, 34 insertions(+), 47 deletions(-) diff --git a/include/boost/geometry/iterators/point_iterator_type.hpp b/include/boost/geometry/iterators/point_iterator_type.hpp index 51e409d66..4d50e42c4 100644 --- a/include/boost/geometry/iterators/point_iterator_type.hpp +++ b/include/boost/geometry/iterators/point_iterator_type.hpp @@ -7,18 +7,18 @@ // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html -#ifndef BOOST_GEOMETRY_CORE_POINT_ITERATOR_TYPE_HPP -#define BOOST_GEOMETRY_CORE_POINT_ITERATOR_TYPE_HPP +#ifndef BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_TYPE_HPP +#define BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_TYPE_HPP -#include -#include +#include +#include #include #include #include #include -#include -#include +#include +#include namespace boost { namespace geometry @@ -27,7 +27,7 @@ namespace boost { namespace geometry #ifndef DOXYGEN_NO_DETAIL -namespace core_detail +namespace detail_dispatch { @@ -74,7 +74,7 @@ struct point_iterator_inner_range_type -} // namespace core_detail +} // namespace detail_dispatch #endif // DOXYGEN_NO_DETAIL @@ -82,11 +82,10 @@ struct point_iterator_inner_range_type #ifndef DOXYGEN_NO_DISPATCH -namespace core_dispatch +namespace dispatch { -// linestring template struct point_iterator_type { @@ -94,7 +93,6 @@ struct point_iterator_type }; -// ring template struct point_iterator_type { @@ -102,43 +100,41 @@ struct point_iterator_type }; -// polygon template class point_iterator_type { private: - typedef typename core_detail::point_iterator_inner_range_type + typedef typename detail_dispatch::point_iterator_inner_range_type < Polygon >::type InnerRange; public: - typedef util::concatenate_iterator + typedef concatenate_iterator < typename boost::range_iterator::type, - util::flatten_iterator + flatten_iterator < typename boost::range_iterator < typename geometry::interior_type::type >::type, - typename core_dispatch::point_iterator_type + typename dispatch::point_iterator_type < InnerRange >::type, - typename core_detail::point_iterator_value_type + typename detail_dispatch::point_iterator_value_type < Polygon >::type, - core_dispatch::points_begin, - core_dispatch::points_end + dispatch::points_begin, + dispatch::points_end >, - typename core_detail::point_iterator_value_type::type + typename detail_dispatch::point_iterator_value_type::type > type; }; -// multi-point template struct point_iterator_type { @@ -146,49 +142,50 @@ struct point_iterator_type }; -// multi-linestring template class point_iterator_type { private: - typedef typename core_detail::point_iterator_inner_range_type + typedef typename detail_dispatch::point_iterator_inner_range_type < MultiLinestring >::type InnerRange; public: - typedef util::flatten_iterator + typedef flatten_iterator < typename boost::range_iterator::type, - typename core_dispatch::point_iterator_type::type, - typename core_detail::point_iterator_value_type + typename dispatch::point_iterator_type::type, + typename detail_dispatch::point_iterator_value_type < MultiLinestring >::type, - core_dispatch::points_begin, - core_dispatch::points_end + dispatch::points_begin, + dispatch::points_end > type; }; -// multi-polygon template class point_iterator_type { private: - typedef typename core_detail::point_iterator_inner_range_type + typedef typename detail_dispatch::point_iterator_inner_range_type < MultiPolygon >::type InnerRange; public: - typedef util::flatten_iterator + typedef flatten_iterator < typename boost::range_iterator::type, - typename core_dispatch::point_iterator_type::type, - typename core_detail::point_iterator_value_type::type, - core_dispatch::points_begin, - core_dispatch::points_end + typename dispatch::point_iterator_type::type, + typename detail_dispatch::point_iterator_value_type + < + MultiPolygon + >::type, + dispatch::points_begin, + dispatch::points_end > type; }; @@ -196,21 +193,11 @@ public: -} // namespace core_dispatch +} // namespace dispatch #endif // DOXYGEN_NO_DISPATCH - -// MK::need to add doc here -template -struct point_iterator_type -{ - typedef typename core_dispatch::point_iterator_type::type type; -}; - - - }} // namespace boost::geometry -#endif // BOOST_GEOMETRY_CORE_POINT_ITERATOR_TYPE_HPP +#endif // BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_TYPE_HPP From 8d09814c5090599456a6c67edaec27abec9f1ce3 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Thu, 27 Mar 2014 23:33:54 +0200 Subject: [PATCH 11/20] [point_iterator] adda bit more testing (dereference point iterator); now using boost::assign::tuple_list_of instead of multipoints for giving expected output; --- test/iterators/point_iterator.cpp | 271 ++++++++++++++++++++++-------- 1 file changed, 199 insertions(+), 72 deletions(-) diff --git a/test/iterators/point_iterator.cpp b/test/iterators/point_iterator.cpp index f06aac273..25e3a8421 100644 --- a/test/iterators/point_iterator.cpp +++ b/test/iterators/point_iterator.cpp @@ -17,6 +17,8 @@ #include +#include + #include #include #include @@ -27,27 +29,41 @@ #include #include -#include +#include +#include +#include namespace bg = ::boost::geometry; +namespace ba = ::boost::assign; typedef bg::model::point point_type; +typedef bg::model::point point_type_3d; typedef bg::model::linestring linestring_type; typedef bg::model::polygon polygon_type; //ccw, open // multi geometries typedef bg::model::multi_point multi_point_type; +typedef bg::model::multi_point multi_point_type_3d; typedef bg::model::multi_linestring multi_linestring_type; typedef bg::model::multi_polygon multi_polygon_type; +typedef boost::tuple tuple_point_type; +typedef boost::tuple tuple_point_type_3d; +typedef std::vector tuple_multi_point_type; +typedef std::vector tuple_multi_point_type_3d; + +BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian) +BOOST_GEOMETRY_REGISTER_MULTI_POINT(tuple_multi_point_type) +BOOST_GEOMETRY_REGISTER_MULTI_POINT(tuple_multi_point_type_3d) + template Geometry from_wkt(std::string const& wkt) { - Geometry res; - boost::geometry::read_wkt(wkt, res); - return res; + Geometry geometry; + boost::geometry::read_wkt(wkt, geometry); + return geometry; } @@ -90,6 +106,58 @@ struct equals } }; + +struct test_assignment +{ + template + static inline void apply(Iterator it, ConstIterator cit, + Value const& value1, Value const& value2) + { +#ifdef GEOMETRY_TEST_DEBUG + std::cout << "== before assignment ==" << std::endl; + std::cout << "value1: " << bg::wkt(value1) << std::endl; + std::cout << "value2: " << bg::wkt(value2) << std::endl; + std::cout << "*it : " << bg::wkt(*it) << std::endl; + std::cout << "*cit : " << bg::wkt(*cit) << std::endl; +#endif + + BOOST_CHECK( bg::equals(*it, value1) ); + BOOST_CHECK( !bg::equals(*it, value2) ); + BOOST_CHECK( bg::equals(*cit, value1) ); + BOOST_CHECK( !bg::equals(*cit, value2) ); + + *it = value2; + BOOST_CHECK( bg::equals(*it, value2) ); + BOOST_CHECK( !bg::equals(*it, value1) ); + BOOST_CHECK( bg::equals(*cit, value2) ); + BOOST_CHECK( !bg::equals(*cit, value1) ); + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << "== after 1st assignment ==" << std::endl; + std::cout << "value1: " << bg::wkt(value1) << std::endl; + std::cout << "value2: " << bg::wkt(value2) << std::endl; + std::cout << "*it : " << bg::wkt(*it) << std::endl; + std::cout << "*cit : " << bg::wkt(*cit) << std::endl; +#endif + + *it = value1; + BOOST_CHECK( bg::equals(*it, value1) ); + BOOST_CHECK( !bg::equals(*it, value2) ); + BOOST_CHECK( bg::equals(*cit, value1) ); + BOOST_CHECK( !bg::equals(*cit, value2) ); + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << "== after 2nd assignment ==" << std::endl; + std::cout << "value1: " << bg::wkt(value1) << std::endl; + std::cout << "value2: " << bg::wkt(value2) << std::endl; + std::cout << "*it : " << bg::wkt(*it) << std::endl; + std::cout << "*cit : " << bg::wkt(*cit) << std::endl; + std::cout << std::endl; +#endif + } +}; + + template struct test_point_iterator_of_geometry { @@ -98,29 +166,36 @@ struct test_point_iterator_of_geometry PointRange const& point_range, std::string const& header) { - typedef typename bg::point_iterator_type - < - G - >::type point_iterator_type; + typedef bg::point_iterator point_iterator; + typedef bg::point_iterator const_point_iterator; - point_iterator_type begin = bg::points_begin(geometry); - point_iterator_type end = bg::points_end(geometry); + point_iterator begin = bg::points_begin(geometry); + point_iterator end = bg::points_end(geometry); BOOST_CHECK( equals::apply(begin, end, - boost::begin(point_range), - boost::end(point_range)) + bg::points_begin(point_range), + bg::points_end(point_range)) ); #ifdef GEOMETRY_TEST_DEBUG std::cout << header << " geometry: " << bg::wkt(geometry) << std::endl; std::cout << "point range: ("; - for (point_iterator_type pit = begin; pit != end; ++pit) + for (point_iterator pit = begin; pit != end; ++pit) + { + std::cout << " " << bg::dsv(*pit); + } + std::cout << " )" << std::endl; + + typedef bg::point_iterator point_range_iterator; + + point_range_iterator rng_begin = bg::points_begin(point_range); + point_range_iterator rng_end = bg::points_end(point_range); + std::cout << "expected point range: ("; + for (point_range_iterator pit = rng_begin; pit != rng_end; ++pit) { std::cout << " " << bg::dsv(*pit); } std::cout << " )" << std::endl; - std::cout << "expected point range: " << bg::wkt(point_range) - << std::endl; #endif } @@ -129,14 +204,44 @@ struct test_point_iterator_of_geometry base_test(geometry, point_range, "non-const"); #ifdef GEOMETRY_TEST_DEBUG - std::cout << std::endl; + std::cout << std::endl; #endif base_test(geometry, point_range, "const"); #ifdef GEOMETRY_TEST_DEBUG - std::cout << std::endl << std::endl; + std::cout << std::endl << std::endl; #endif + + // testing construction of const and non-const iterator + typedef bg::point_iterator point_iterator; + typedef bg::point_iterator const_point_iterator; + + point_iterator begin = bg::points_begin(geometry); + point_iterator end = bg::points_end(geometry); + + const_point_iterator const_begin = bg::points_begin(geometry); + const_point_iterator const_end = bg::points_end(geometry); + + // testing assignment of non-const to const iterator + const_begin = begin; + const_end = end; + + // testing dereferencing/assignment + if ( begin != end ) + { + typedef typename bg::point_type::type point; + + point p = *begin; + point q = bg::make_zero(); + + test_assignment::apply(begin, const_begin, p, q); + test_assignment::apply(begin, const_begin, p, q); + + *begin = q; + test_assignment::apply(begin, const_begin, q, p); + *begin = p; + } } }; @@ -151,17 +256,17 @@ BOOST_AUTO_TEST_CASE( test_linestring_point_iterator ) std::cout << "*** LINESTRING ***" << std::endl; #endif - typedef multi_point_type MP; + typedef tuple_multi_point_type TMP; typedef linestring_type L; - typedef test_point_iterator_of_geometry tester; + typedef test_point_iterator_of_geometry tester; tester::apply(from_wkt("LINESTRING()"), - from_wkt("MULTIPOINT()") + TMP() ); tester::apply(from_wkt("LINESTRING(3 3,4 4,5 5)"), - from_wkt("MULTIPOINT(3 3,4 4,5 5)") + ba::tuple_list_of(3,3)(4,4)(5,5) ); #ifdef GEOMETRY_TEST_DEBUG @@ -180,27 +285,29 @@ BOOST_AUTO_TEST_CASE( test_polygon_point_iterator ) std::cout << "*** POLYGON ***" << std::endl; #endif - typedef multi_point_type MP; + typedef tuple_multi_point_type TMP; typedef polygon_type P; - typedef test_point_iterator_of_geometry tester; + typedef test_point_iterator_of_geometry tester; tester::apply(from_wkt

("POLYGON()"), - from_wkt("MULTIPOINT()") + TMP() ); tester::apply(from_wkt

("POLYGON(())"), - from_wkt("MULTIPOINT()") + TMP() ); - tester::apply(from_wkt

("POLYGON((3 3,4 4,5 5),(),(),(),\ - (6 6,7 7,8 8),(),(),(9 9),())"), - from_wkt("MULTIPOINT(3 3,4 4,5 5,6 6,7 7,8 8,9 9)") + tester::apply(from_wkt

("POLYGON((1 1,9 1,9 9,1 9),(5 5,6 5,6 6,5 6))"), + ba::tuple_list_of(1,1)(9,1)(9,9)(1,9)(5,5)(6,5)(6,6)(5,6) ); - tester::apply(from_wkt

("POLYGON((),(3 3,4 4,5 5),(),(),\ - (6 6,7 7,8 8),(),(),(9 9),())"), - from_wkt("MULTIPOINT(3 3,4 4,5 5,6 6,7 7,8 8,9 9)") + tester::apply(from_wkt

("POLYGON((3 3,4 4,5 5),(),(),(),(6 6,7 7,8 8),(),(),(9 9),())"), + ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9) + ); + + tester::apply(from_wkt

("POLYGON((),(3 3,4 4,5 5),(),(),(6 6,7 7,8 8),(),(),(9 9),())"), + ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9) ); #ifdef GEOMETRY_TEST_DEBUG @@ -219,16 +326,46 @@ BOOST_AUTO_TEST_CASE( test_multipoint_point_iterator ) std::cout << "*** MULTIPOINT ***" << std::endl; #endif + typedef tuple_multi_point_type TMP; typedef multi_point_type MP; - typedef test_point_iterator_of_geometry tester; + typedef test_point_iterator_of_geometry tester; tester::apply(from_wkt("MULTIPOINT()"), - from_wkt("MULTIPOINT()") + TMP() ); tester::apply(from_wkt("MULTIPOINT(3 3,4 4,5 5)"), - from_wkt("MULTIPOINT(3 3,4 4,5 5)") + ba::tuple_list_of(3,3)(4,4)(5,5) + ); + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl << std::endl << std::endl; +#endif +} + + +//====================================================================== +//====================================================================== + + +BOOST_AUTO_TEST_CASE( test_multipoint_3d_point_iterator ) +{ +#ifdef GEOMETRY_TEST_DEBUG + std::cout << "*** MULTIPOINT 3D ***" << std::endl; +#endif + + typedef tuple_multi_point_type_3d TMP; + typedef multi_point_type_3d MP; + + typedef test_point_iterator_of_geometry tester; + + tester::apply(from_wkt("MULTIPOINT()"), + TMP() + ); + + tester::apply(from_wkt("MULTIPOINT(3 3 3,4 4 4,5 5 5)"), + ba::tuple_list_of(3,3,3)(4,4,4)(5,5,5) ); #ifdef GEOMETRY_TEST_DEBUG @@ -247,27 +384,29 @@ BOOST_AUTO_TEST_CASE( test_multilinestring_point_iterator ) std::cout << "*** MULTILINESTRING ***" << std::endl; #endif - typedef multi_point_type MP; - typedef linestring_type L; + typedef tuple_multi_point_type TMP; typedef multi_linestring_type ML; - typedef test_point_iterator_of_geometry tester; + typedef test_point_iterator_of_geometry tester; tester::apply(from_wkt("MULTILINESTRING()"), - from_wkt("MULTIPOINT()") + TMP() ); tester::apply(from_wkt("MULTILINESTRING(())"), - from_wkt("MULTIPOINT()") + TMP() ); tester::apply(from_wkt("MULTILINESTRING((),(),())"), - from_wkt("MULTIPOINT()") + TMP() ); - tester::apply(from_wkt("MULTILINESTRING((),(),(0 0,1 1,2 2),(),(),\ - (3 3,4 4,5 5),(),(6 6),(),(),())"), - from_wkt("MULTIPOINT(0 0,1 1,2 2,3 3,4 4,5 5,6 6)") + tester::apply(from_wkt("MULTILINESTRING((1 1,2 2,3 3),(3 3,4 4,5 5),(6 6))"), + ba::tuple_list_of(1,1)(2,2)(3,3)(3,3)(4,4)(5,5)(6,6) + ); + + tester::apply(from_wkt("MULTILINESTRING((),(),(1 1,2 2,3 3),(),(),(3 3,4 4,5 5),(),(6 6),(),(),())"), + ba::tuple_list_of(1,1)(2,2)(3,3)(3,3)(4,4)(5,5)(6,6) ); #ifdef GEOMETRY_TEST_DEBUG @@ -286,55 +425,43 @@ BOOST_AUTO_TEST_CASE( test_multipolygon_point_iterator ) std::cout << "*** MULTIPOLYGON ***" << std::endl; #endif - typedef multi_point_type MP; + typedef tuple_multi_point_type TMP; typedef multi_polygon_type MPL; - typedef test_point_iterator_of_geometry tester; + typedef test_point_iterator_of_geometry tester; tester::apply(from_wkt("MULTIPOLYGON()"), - from_wkt("MULTIPOINT()") + TMP() ); tester::apply(from_wkt("MULTIPOLYGON( () )"), - from_wkt("MULTIPOINT()") + TMP() ); tester::apply(from_wkt("MULTIPOLYGON( (()) )"), - from_wkt("MULTIPOINT()") + TMP() ); tester::apply(from_wkt("MULTIPOLYGON( ((),()) )"), - from_wkt("MULTIPOINT()") + TMP() ); - tester::apply(from_wkt("MULTIPOLYGON(\ - ((3 3,4 4,5 5),(),(),(),\ - (6 6,7 7,8 8),(),(),(9 9),())\ - \ - ((),(1 1,2 2,10 10),(),(),(),\ - (11 11,12 12),(),(),(13 13),())\ - )"), - from_wkt("MULTIPOINT(3 3,4 4,5 5,6 6,7 7,8 8,9 9,\ - 1 1,2 2,10 10,11 11,12 12,13 13)") + tester::apply(from_wkt("MULTIPOLYGON(((3 3,4 4,5 5),(6 6,7 7,8 8),(9 9)),((1 1,2 2,10 10),(11 11,12 12)))"), + ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)\ + (1,1)(2,2)(10,10)(11,11)(12,12) ); - tester::apply(from_wkt("MULTIPOLYGON(\ - (),\ - \ - ((3 3,4 4,5 5),(),(),(),\ - (6 6,7 7,8 8),(),(),(9 9),())\ - \ - ((),(1 1,2 2,10 10),(),(),(),\ - (11 11,12 12),(),(),(13 13),())\ - \ - ((),(),()),\ - )"), - from_wkt("MULTIPOINT(3 3,4 4,5 5,6 6,7 7,8 8,9 9,\ - 1 1,2 2,10 10,11 11,12 12,13 13)") + tester::apply(from_wkt("MULTIPOLYGON(((3 3,4 4,5 5),(),(),(),(6 6,7 7,8 8),(),(),(9 9),()),((),(1 1,2 2,10 10),(),(),(),(11 11,12 12),(),(),(13 13),()))"), + ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)\ + (1,1)(2,2)(10,10)(11,11)(12,12)(13,13) + ); + + tester::apply(from_wkt("MULTIPOLYGON(((3 3,4 4,5 5),(),(),(),(6 6,7 7,8 8),(),(),(9 9),()),((),(1 1,2 2,10 10),(),(),(),(11 11,12 12),(),(),(13 13),()),((),(),()))"), + ba::tuple_list_of(3,3)(4,4)(5,5)(6,6)(7,7)(8,8)(9,9)\ + (1,1)(2,2)(10,10)(11,11)(12,12)(13,13) ); #ifdef GEOMETRY_TEST_DEBUG std::cout << std::endl << std::endl; #endif } - From 5e96c27c8492a73b24a6bc039ec06b85b9a45743 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Fri, 28 Mar 2014 00:11:16 +0200 Subject: [PATCH 12/20] [point_iterator] make private the constructor of point_iterator that takes the base class as argument; --- include/boost/geometry/iterators/point_iterator.hpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/boost/geometry/iterators/point_iterator.hpp b/include/boost/geometry/iterators/point_iterator.hpp index 192d75d57..50613fafc 100644 --- a/include/boost/geometry/iterators/point_iterator.hpp +++ b/include/boost/geometry/iterators/point_iterator.hpp @@ -233,11 +233,14 @@ private: struct enabler {}; template friend class point_iterator; -public: - point_iterator() {} + template friend inline point_iterator points_begin(G&); + template friend inline point_iterator points_end(G&); point_iterator(base const& base_it) : base(base_it) {} +public: + point_iterator() {} + template point_iterator(point_iterator const& other, typename boost::enable_if From e1f39cd0657f192fa1fa37f85ecd5494afdb871c Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Fri, 28 Mar 2014 00:30:50 +0200 Subject: [PATCH 13/20] [point_iterator] minor and stylistic changes; in concatenate_iterator use enable_if_c instead of enable_if (shorter code); --- .../iterators/concatenate_iterator.hpp | 18 +++++------------- .../geometry/iterators/flatten_iterator.hpp | 6 ++---- .../geometry/iterators/point_iterator.hpp | 1 + 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/include/boost/geometry/iterators/concatenate_iterator.hpp b/include/boost/geometry/iterators/concatenate_iterator.hpp index 7321f1c81..32a8b2332 100644 --- a/include/boost/geometry/iterators/concatenate_iterator.hpp +++ b/include/boost/geometry/iterators/concatenate_iterator.hpp @@ -10,6 +10,8 @@ #ifndef BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP #define BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP +#include +#include #include #include #include @@ -35,17 +37,6 @@ private: struct enabler {}; - template - struct is_convertible - : boost::mpl::if_c - < - boost::is_convertible::value - && boost::is_convertible::value, - boost::true_type, - boost::false_type - >::type - {}; - public: typedef Iterator1 first_iterator_type; typedef Iterator2 second_iterator_type; @@ -67,9 +58,10 @@ public: template concatenate_iterator (concatenate_iterator const& other, - typename boost::enable_if + typename boost::enable_if_c < - is_convertible, + boost::is_convertible::value + && boost::is_convertible::value, enabler >::type = enabler()) : m_it1(other.m_it1), m_end1(other.m_end1), m_it2(other.m_it2) diff --git a/include/boost/geometry/iterators/flatten_iterator.hpp b/include/boost/geometry/iterators/flatten_iterator.hpp index 4a7c68a6d..9e3983cc4 100644 --- a/include/boost/geometry/iterators/flatten_iterator.hpp +++ b/include/boost/geometry/iterators/flatten_iterator.hpp @@ -85,10 +85,8 @@ public: > const& other, typename boost::enable_if < - boost::is_convertible - < - OtherValue*, Value* - >, enabler + boost::is_convertible, + enabler >::type = enabler()) : m_outer_it(other.m_outer_it), m_outer_end(other.m_outer_end), diff --git a/include/boost/geometry/iterators/point_iterator.hpp b/include/boost/geometry/iterators/point_iterator.hpp index 50613fafc..07a70c4e0 100644 --- a/include/boost/geometry/iterators/point_iterator.hpp +++ b/include/boost/geometry/iterators/point_iterator.hpp @@ -10,6 +10,7 @@ #ifndef BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP #define BOOST_GEOMETRY_ITERATORS_POINT_ITERATOR_HPP +#include #include #include From 38682d9b41d479a5f516ff2889967258e8cea4b2 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Fri, 28 Mar 2014 00:45:06 +0200 Subject: [PATCH 14/20] [point_iterator] remove function call that is not meaningful; --- test/iterators/point_iterator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/iterators/point_iterator.cpp b/test/iterators/point_iterator.cpp index 25e3a8421..c144bf7dc 100644 --- a/test/iterators/point_iterator.cpp +++ b/test/iterators/point_iterator.cpp @@ -235,11 +235,11 @@ struct test_point_iterator_of_geometry point p = *begin; point q = bg::make_zero(); - test_assignment::apply(begin, const_begin, p, q); test_assignment::apply(begin, const_begin, p, q); *begin = q; test_assignment::apply(begin, const_begin, q, p); + *begin = p; } } From d5d4b08a0ce98621949adc82ac34f524bd87a7a3 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Fri, 28 Mar 2014 11:57:05 +0200 Subject: [PATCH 15/20] [point_iterator] minor stylistic changes; --- test/iterators/concatenate_iterator.cpp | 261 ++++++++++++++++++++++++ test/iterators/point_iterator.cpp | 9 +- 2 files changed, 266 insertions(+), 4 deletions(-) create mode 100644 test/iterators/concatenate_iterator.cpp diff --git a/test/iterators/concatenate_iterator.cpp b/test/iterators/concatenate_iterator.cpp new file mode 100644 index 000000000..9d0d3335a --- /dev/null +++ b/test/iterators/concatenate_iterator.cpp @@ -0,0 +1,261 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// Unit Test + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_TEST_MODULE +#define BOOST_TEST_MODULE test_concatenate_iterator +#endif + +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +using namespace boost::assign; + +template +std::ostream& print_container(std::ostream& os, + Iterator begin, Iterator end, + std::string const& header) +{ + std::cout << header; + for (Iterator it = begin; it != end; ++it) + { + os << " " << *it; + } + return os; +} + + +template +struct is_odd +{ + inline bool operator()(T const& t) const + { + return t % 2 != 0; + } +}; + +struct test_concat_iterator +{ + template + static inline void apply(Container1& c1, Container2& c2, + std::string const& case_id) + { +#ifdef GEOMETRY_TEST_DEBUG + std::cout << "case id: " << case_id << std::endl; +#endif + + typedef boost::geometry::concatenate_iterator + < + typename Container1::const_iterator, + typename Container2::const_iterator, + typename Container1::value_type const + > const_concat_iterator; + + typedef boost::geometry::concatenate_iterator + < + typename Container1::iterator, + typename Container2::iterator, + typename Container1::value_type + > concat_iterator; + + + concat_iterator begin(c1.begin(), c1.end(), c2.begin()); + concat_iterator end(c1.end(), c2.end()); + const_concat_iterator const_begin(begin); + const_concat_iterator const_end(end); + const_begin = begin; + const_end = end; + + std::size_t size(0); + for (const_concat_iterator it = const_begin; it != const_end; ++it) + { + ++size; + } + BOOST_CHECK( c1.size() + c2.size() == size ); + + size = 0; + for (concat_iterator it = begin; it != end; ++it) + { + ++size; + } + BOOST_CHECK( c1.size() + c2.size() == size ); + +#ifdef GEOMETRY_TEST_DEBUG + print_container(std::cout, c1.begin(), c1.end(), "first :") + << std::endl; + + print_container(std::cout, c2.begin(), c2.end(), "second :") + << std::endl; + + print_container(std::cout, begin, end, "combined:") + << std::endl; + + if ( begin != end ) + { + std::cout << "min element: " + << *std::min_element(begin, end) + << std::endl; + std::cout << "max element: " + << *std::max_element(const_begin, const_end) + << std::endl; + } +#endif + + { + typename Container1::const_iterator it1 = c1.begin(); + typename Container2::const_iterator it2 = c2.begin(); + for (const_concat_iterator it = const_begin; it != const_end; ++it) + { + if ( it1 != c1.end() ) + { + BOOST_CHECK( *it == *it1 ); + ++it1; + } + else + { + BOOST_CHECK( *it == *it2 ); + ++it2; + } + } + } + + typedef typename std::iterator_traits + < + concat_iterator + >::value_type value_type; + + if ( c1.size() != 0 ) + { + concat_iterator it_max = std::max_element(begin, end); + const_concat_iterator const_it_max = + std::max_element(const_begin, const_end); + + BOOST_CHECK( it_max == const_it_max ); + + value_type old_value = *const_begin; + value_type new_value = *it_max + 1; + + *begin = *it_max + 1; + BOOST_CHECK( *c1.begin() == new_value ); + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "modified element of 1st container:" << std::endl; + print_container(std::cout, c1.begin(), c1.end(), "first :") + << std::endl; + print_container(std::cout, begin, end, "combined:") + << std::endl; +#endif + + *begin = old_value; + BOOST_CHECK( *c1.begin() == old_value ); + } + + if ( c2.size() != 0 ) + { + concat_iterator begin2 = begin; + std::size_t counter(0); + while ( counter != c1.size() ) + { + ++counter; + begin2++; + } + + concat_iterator it_max = std::max_element(begin, end); + const_concat_iterator const_it_max = + std::max_element(const_begin, const_end); + + BOOST_CHECK( it_max == const_it_max ); + + value_type old_value = *begin2; + value_type new_value = *it_max + 1; + + *begin2 = *it_max + 1; + BOOST_CHECK( *c2.begin() == new_value ); + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "modified element of 2nd container:" << std::endl; + print_container(std::cout, c2.begin(), c2.end(), "second :") + << std::endl; + print_container(std::cout, begin, end, "combined:") + << std::endl; +#endif + + *begin2 = old_value; + BOOST_CHECK( *c2.begin() == old_value ); + } + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "odd elements removed:" << std::endl; + print_container(std::cout, begin, end, "before:") + << std::endl; +#endif + concat_iterator new_end = + std::remove_if(begin, end, is_odd()); + + for (const_concat_iterator it = const_begin; it != new_end; ++it) + { + BOOST_CHECK( !is_odd()(*it) ); + } + +#ifdef GEOMETRY_TEST_DEBUG + print_container(std::cout, begin, new_end, "after :") + << std::endl; +#endif + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << "====================" << std::endl << std::endl; +#endif + } +}; + + +BOOST_AUTO_TEST_CASE( test_concatenate_iterator ) +{ + { + std::vector v; + std::list l; + + test_concat_iterator::apply(v, l, "empty_both"); + } + { + std::vector v; + std::list l; + l += 10,11,12,13,14,15,16,17,18,19,20; + + test_concat_iterator::apply(v, l, "empty_first"); + } + { + std::vector v; + v += 0,1,2,3,4,5,6; + std::list l; + + test_concat_iterator::apply(v, l, "empty_second"); + } + { + std::vector v; + v += 0,1,2,3,4,5,6; + std::list l; + l += 10,11,12,13,14,15,16,17,18,19,20; + + test_concat_iterator::apply(l, v, "non_empty"); + } +} diff --git a/test/iterators/point_iterator.cpp b/test/iterators/point_iterator.cpp index c144bf7dc..13d77fdf8 100644 --- a/test/iterators/point_iterator.cpp +++ b/test/iterators/point_iterator.cpp @@ -20,8 +20,12 @@ #include #include -#include +#include #include +#include + +#include + #include #include #include @@ -29,9 +33,6 @@ #include #include -#include -#include - #include namespace bg = ::boost::geometry; From 5da4191c59ee99e7f466312c05aa8f2838c4f573 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Fri, 28 Mar 2014 11:57:35 +0200 Subject: [PATCH 16/20] [point_iterator][concatenate_iterator] add separate unit test; --- test/iterators/concatenate_iterator.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/test/iterators/concatenate_iterator.cpp b/test/iterators/concatenate_iterator.cpp index 9d0d3335a..941cf612d 100644 --- a/test/iterators/concatenate_iterator.cpp +++ b/test/iterators/concatenate_iterator.cpp @@ -59,19 +59,20 @@ struct test_concat_iterator #ifdef GEOMETRY_TEST_DEBUG std::cout << "case id: " << case_id << std::endl; #endif + typedef typename Container1::const_iterator const_iterator1; + typedef typename Container2::const_iterator const_iterator2; + typedef typename Container1::iterator iterator1; + typedef typename Container2::iterator iterator2; typedef boost::geometry::concatenate_iterator < - typename Container1::const_iterator, - typename Container2::const_iterator, + const_iterator1, const_iterator2, typename Container1::value_type const > const_concat_iterator; typedef boost::geometry::concatenate_iterator < - typename Container1::iterator, - typename Container2::iterator, - typename Container1::value_type + iterator1, iterator2, typename Container1::value_type > concat_iterator; @@ -99,10 +100,8 @@ struct test_concat_iterator #ifdef GEOMETRY_TEST_DEBUG print_container(std::cout, c1.begin(), c1.end(), "first :") << std::endl; - print_container(std::cout, c2.begin(), c2.end(), "second :") << std::endl; - print_container(std::cout, begin, end, "combined:") << std::endl; @@ -118,8 +117,8 @@ struct test_concat_iterator #endif { - typename Container1::const_iterator it1 = c1.begin(); - typename Container2::const_iterator it2 = c2.begin(); + const_iterator1 it1 = c1.begin(); + const_iterator2 it2 = c2.begin(); for (const_concat_iterator it = const_begin; it != const_end; ++it) { if ( it1 != c1.end() ) From 861e094b7cf7fb8680307013c749c0d6d63448c1 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Mon, 31 Mar 2014 09:33:23 +0300 Subject: [PATCH 17/20] [point_iterator] add separate unit test for flatten iterator; updated Jamfile to run the unit tests for point/concatenate/flatten iterator; --- test/iterators/Jamfile.v2 | 14 +- test/iterators/flatten_iterator.cpp | 430 ++++++++++++++++++++++++++++ 2 files changed, 441 insertions(+), 3 deletions(-) create mode 100644 test/iterators/flatten_iterator.cpp diff --git a/test/iterators/Jamfile.v2 b/test/iterators/Jamfile.v2 index 72091f21f..40273145d 100644 --- a/test/iterators/Jamfile.v2 +++ b/test/iterators/Jamfile.v2 @@ -1,8 +1,13 @@ # Boost.Geometry (aka GGL, Generic Geometry Library) # -# Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -# Copyright (c) 2008-2012 Bruno Lalande, Paris, France. -# Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +# Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. +# Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +# Copyright (c) 2009-2014 Mateusz Loskot, London, UK. +# +# This file was modified by Oracle on 2014. +# Modifications copyright (c) 2014, Oracle and/or its affiliates. +# +# Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle # # Use, modification and distribution is subject to the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -12,4 +17,7 @@ test-suite boost-geometry-iterators : [ run closing_iterator.cpp ] [ run ever_circling_iterator.cpp ] + [ run point_iterator.cpp ] + [ run concatenate_iterator.cpp ] + [ run flatten_iterator.cpp ] ; diff --git a/test/iterators/flatten_iterator.cpp b/test/iterators/flatten_iterator.cpp new file mode 100644 index 000000000..98e8643e2 --- /dev/null +++ b/test/iterators/flatten_iterator.cpp @@ -0,0 +1,430 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// Unit Test + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_TEST_MODULE +#define BOOST_TEST_MODULE test_flatten_iterator +#endif + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +using namespace boost::assign; + +template +std::ostream& print_container(std::ostream& os, + Iterator begin, Iterator end, + std::string const& header) +{ + std::cout << header; + for (Iterator it = begin; it != end; ++it) + { + os << " " << *it; + } + return os; +} + + +template +std::ostream& print_nested_container(std::ostream& os, + Iterator begin, Iterator end, + std::string const& header) +{ + std::cout << header; + for (Iterator outer = begin; outer != end; ++outer) + { + os << " ("; + for (BOOST_AUTO_TPL(inner, outer->begin()); + inner != outer->end(); ++inner) + { + if ( inner != outer->begin() ) + { + os << " "; + } + os << *inner; + } + os << ") "; + } + return os; +} + + +template +struct is_odd +{ + inline bool operator()(T const& t) const + { + return t % 2 != 0; + } +}; + + +template +struct is_even +{ + inline bool operator()(T const& t) const + { + return !is_odd()(t); + } +}; + + + +template +struct access_begin +{ + typedef typename boost::mpl::if_ + < + typename boost::is_const::type, + typename InnerContainer::const_iterator, + typename InnerContainer::iterator + >::type return_type; + + static inline return_type apply(InnerContainer& inner) + { + return inner.begin(); + } +}; + + +template +struct access_end +{ + typedef typename boost::mpl::if_ + < + typename boost::is_const::type, + typename InnerContainer::const_iterator, + typename InnerContainer::iterator + >::type return_type; + + static inline return_type apply(InnerContainer& inner) + { + return inner.end(); + } +}; + + +template +std::size_t number_of_elements(NestedContainer const& c) +{ + std::size_t num_elements(0); + for (typename NestedContainer::const_iterator outer = c.begin(); + outer != c.end(); ++outer) + { + num_elements += outer->size(); + } + return num_elements; +} + + +struct test_flatten_iterator +{ + template + static inline void apply(NestedContainer& c, + std::string const& case_id, + std::string const& container_id) + { +#ifdef GEOMETRY_TEST_DEBUG + std::stringstream sstream; + sstream << case_id << " " << "[" << container_id << "]"; + + std::cout << "case id: " << sstream.str() << std::endl; +#endif + typedef typename NestedContainer::const_iterator const_outer_iterator; + typedef typename NestedContainer::iterator outer_iterator; + typedef typename NestedContainer::value_type inner_container; + + typedef typename inner_container::const_iterator const_inner_iterator; + typedef typename inner_container::iterator inner_iterator; + + typedef boost::geometry::flatten_iterator + < + const_outer_iterator, + const_inner_iterator, + typename inner_container::value_type const, + access_begin, + access_end + > const_flatten_iterator; + + typedef boost::geometry::flatten_iterator + < + outer_iterator, + inner_iterator, + typename inner_container::value_type, + access_begin, + access_end + > flatten_iterator; + + + flatten_iterator begin(c.begin(), c.end()); + flatten_iterator end(c.end()); + const_flatten_iterator const_begin(begin); + const_flatten_iterator const_end(end); + const_begin = begin; + const_end = end; + + std::size_t size(0); + for (const_flatten_iterator it = const_begin; it != const_end; ++it) + { + ++size; + } + BOOST_CHECK( number_of_elements(c) == size ); + + size = 0; + for (flatten_iterator it = begin; it != end; ++it) + { + ++size; + } + BOOST_CHECK( number_of_elements(c) == size ); + +#ifdef GEOMETRY_TEST_DEBUG + print_nested_container(std::cout, c.begin(), c.end(), "nested :") + << std::endl; + print_container(std::cout, begin, end, "flattened :") + << std::endl; + + if ( begin != end ) + { + std::cout << "min element: " + << *std::min_element(begin, end) + << std::endl; + std::cout << "max element: " + << *std::max_element(const_begin, const_end) + << std::endl; + } +#endif + + { + const_flatten_iterator it = begin; + const_outer_iterator outer_begin = c.begin(); + const_outer_iterator outer_end = c.end(); + for (const_outer_iterator outer = outer_begin; + outer != outer_end; ++outer) + { + const_inner_iterator inner_begin = outer->begin(); + const_inner_iterator inner_end = outer->end(); + for (const_inner_iterator inner = inner_begin; + inner != inner_end; ++inner, it++) + // it++, instead of ++it, on purpose here + { + BOOST_CHECK( *it == *inner ); + } + } + } + + typedef typename std::iterator_traits + < + flatten_iterator + >::value_type value_type; + + if ( begin != end ) + { + flatten_iterator it_max = std::max_element(begin, end); + const_flatten_iterator const_it_max = + std::max_element(const_begin, const_end); + + BOOST_CHECK( it_max == const_it_max ); + BOOST_CHECK( *it_max == *const_it_max ); + + value_type old_value = *const_begin; + value_type new_value = *it_max + 1; + + *begin = *it_max + 1; + const_outer_iterator outer = c.begin(); + while ( outer->begin() == outer->end() ) + { + ++outer; + } + const_inner_iterator inner = outer->begin(); + + BOOST_CHECK( *inner == new_value ); + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "modified 1st element of 1st non-empty " + << "inner container:" << std::endl; + print_nested_container(std::cout, c.begin(), c.end(), "nested :") + << std::endl; + print_container(std::cout, begin, end, "flattened:") + << std::endl; +#endif + + *begin = old_value; + BOOST_CHECK( *inner == old_value ); + } + + + if ( begin != end ) + { +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "odd elements removed:" << std::endl; + print_nested_container(std::cout, c.begin(), c.end(), + "nested before:") + << std::endl; + print_container(std::cout, begin, end, + "flattended before:") + << std::endl; +#endif + typename std::iterator_traits::difference_type + num_even = std::count_if(begin, end, is_even()); + + flatten_iterator new_end = + std::remove_if(begin, end, is_odd()); + + std::size_t new_size(0); + for (const_flatten_iterator it = const_begin; it != new_end; ++it) + { + ++new_size; + BOOST_CHECK( !is_odd()(*it) ); + } + BOOST_CHECK( new_size == static_cast(num_even) ); + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl; + print_nested_container(std::cout, c.begin(), c.end(), + "nested after (all elements) :") + << std::endl; + print_container(std::cout, begin, new_end, "flattened after :") + << std::endl; +#endif + } + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << "====================" << std::endl << std::endl; +#endif + } +}; + + + +// the actual test cases -- START +template +struct test_case_per_container; + +template<> +struct test_case_per_container<0> +{ + template + static inline void apply(std::string const& case_id, + std::string const& container_id) + { + NestedContainer c; + test_flatten_iterator::apply(c, case_id, container_id); + } +}; + +template<> +struct test_case_per_container<1> +{ + template + static inline void apply(std::string const& case_id, + std::string const& container_id) + { + NestedContainer c; + for (int i = 0; i < 5; ++i) + { + c += typename NestedContainer::value_type(); + } + test_flatten_iterator::apply(c, case_id, container_id); + } +}; + +template<> +struct test_case_per_container<2> +{ + template + static inline void apply(std::string const& case_id, + std::string const& container_id) + { + NestedContainer c; + typename NestedContainer::value_type ic[4]; + + ic[0] += 5,4,3,2,1; + ic[1] += 6,7,8; + ic[2] += 9; + ic[3] += 9,8,7,6,5; + c += ic[0],ic[1],ic[2],ic[3]; + + test_flatten_iterator::apply(c, case_id, container_id); + } +}; + +template<> +struct test_case_per_container<3> +{ + template + static inline void apply(std::string const& case_id, + std::string const& container_id) + { + NestedContainer c; + typename NestedContainer::value_type ic[20]; + + ic[2] += 5,4,3,2,1; + ic[3] += 6,7,8; + ic[8] += 9; + ic[9] += 9,8,7,6,5; + ic[14] += 4,3,2,1; + for (std::size_t i = 0; i < 20; ++i) + { + c += ic[i]; + } + + test_flatten_iterator::apply(c, case_id, container_id); + } +}; +// the actual test cases -- END + + + +template +inline void test_case_all_containers(std::string const& case_id) +{ + typedef typename std::vector > VV; + typedef typename std::vector > VL; + typedef typename std::list > LV; + typedef typename std::list > LL; + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl << std::endl; +#endif + test_case_per_container::template apply(case_id, "VV"); + test_case_per_container::template apply(case_id, "VL"); + test_case_per_container::template apply(case_id, "LV"); + test_case_per_container::template apply(case_id, "LL"); + +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "********************************************************" + << std::endl << std::endl; +#endif +} + + + +BOOST_AUTO_TEST_CASE( test_flatten_iterator_all ) +{ + test_case_all_containers<0>("empty"); + test_case_all_containers<1>("case1"); + test_case_all_containers<2>("case2"); + test_case_all_containers<3>("case3"); +} From 415500955ab633270096618f6a4d983f3086332f Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Mon, 31 Mar 2014 14:52:03 +0300 Subject: [PATCH 18/20] [point iterator] minor staylistic changes in unit test for concatenate iterator; --- test/iterators/concatenate_iterator.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/iterators/concatenate_iterator.cpp b/test/iterators/concatenate_iterator.cpp index 941cf612d..6a488bcde 100644 --- a/test/iterators/concatenate_iterator.cpp +++ b/test/iterators/concatenate_iterator.cpp @@ -50,7 +50,7 @@ struct is_odd } }; -struct test_concat_iterator +struct test_concatenate_iterator { template static inline void apply(Container1& c1, Container2& c2, @@ -227,27 +227,27 @@ struct test_concat_iterator }; -BOOST_AUTO_TEST_CASE( test_concatenate_iterator ) +BOOST_AUTO_TEST_CASE( test_concatenate_iterator_all ) { { std::vector v; std::list l; - test_concat_iterator::apply(v, l, "empty_both"); + test_concatenate_iterator::apply(v, l, "empty_both"); } { std::vector v; std::list l; l += 10,11,12,13,14,15,16,17,18,19,20; - test_concat_iterator::apply(v, l, "empty_first"); + test_concatenate_iterator::apply(v, l, "empty_first"); } { std::vector v; v += 0,1,2,3,4,5,6; std::list l; - test_concat_iterator::apply(v, l, "empty_second"); + test_concatenate_iterator::apply(v, l, "empty_second"); } { std::vector v; @@ -255,6 +255,6 @@ BOOST_AUTO_TEST_CASE( test_concatenate_iterator ) std::list l; l += 10,11,12,13,14,15,16,17,18,19,20; - test_concat_iterator::apply(l, v, "non_empty"); + test_concatenate_iterator::apply(l, v, "non_empty"); } } From 2f9f45433430e799904b821ecf3deba28c995263 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 2 Apr 2014 20:21:32 +0200 Subject: [PATCH 19/20] [get_turns] fix for MultiLinestrings containing Ls with equal points In this case no sections were generated for those "empty" Linestrings but if there were some sections already generated they could be marked as last_non_duplicated. --- .../geometry/algorithms/detail/sections/sectionalize.hpp | 2 +- test/algorithms/overlay/get_turns_linear_linear.cpp | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/sections/sectionalize.hpp b/include/boost/geometry/algorithms/detail/sections/sectionalize.hpp index 71c3a9bb1..c4b6ac7c5 100644 --- a/include/boost/geometry/algorithms/detail/sections/sectionalize.hpp +++ b/include/boost/geometry/algorithms/detail/sections/sectionalize.hpp @@ -285,7 +285,7 @@ struct sectionalize_part section_type section; bool mark_first_non_duplicated = true; - std::size_t last_non_duplicate_index = 0; + std::size_t last_non_duplicate_index = sections.size(); iterator_type it = boost::begin(range); diff --git a/test/algorithms/overlay/get_turns_linear_linear.cpp b/test/algorithms/overlay/get_turns_linear_linear.cpp index ebaff5128..63dae1734 100644 --- a/test/algorithms/overlay/get_turns_linear_linear.cpp +++ b/test/algorithms/overlay/get_turns_linear_linear.cpp @@ -22,14 +22,15 @@ //TEST //#include -//#include -//#include +#include +#include template void test_all() { typedef bg::model::point pt; typedef bg::model::linestring ls; + typedef bg::model::multi_linestring mls; test_geometry("LINESTRING(0 0,2 0)", "LINESTRING(0 0,2 0)", "tii", "txx"); test_geometry("LINESTRING(0 0,2 0)", "LINESTRING(2 0,0 0)", "tix", "txi"); @@ -120,6 +121,10 @@ void test_all() // to_svg("LINESTRING(31 0,15 0,10 5,5 5,4 0,1 0,0 0,-1 1)", "LINESTRING(-1 -1,0 0,1 0,2 0,2.5 1,3 0,30 0)", "test33.svg"); // to_svg("LINESTRING(31 0,15 0,10 5,5 5,4 0,1 0,0 0,-1 1)", "LINESTRING(30 0,3 0,2.5 1,2 0,1 0,0 0,-1 -1)", "test34.svg"); //} + + test_geometry("MULTILINESTRING((0 0,10 0,30 0))", + "MULTILINESTRING((0 10,5 0,20 0,20 0,30 0),(2 0,2 0),(3 0,3 0,3 0))", + expected("mii")("ccc")("ccc")("txx")); } int test_main(int, char* []) From ca0c8b97df57f40eaf3cab9a2f4eed1ebc1aeaf7 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 3 Apr 2014 11:58:50 +0200 Subject: [PATCH 20/20] [get_turns] Fix turns dumplication for L/L. Change the ignoring check calculation in get_turn_info_for_endpoint. Add additional parameters to the second version of collinear_opposite<>::apply() defining if the pk and/or qk are valid (in other words current segment is NOT the last one). Also make ignoring check for last endpoint in L/A more clear. --- .../algorithms/detail/overlay/get_turn_info.hpp | 13 ++++++++----- .../detail/overlay/get_turn_info_for_endpoint.hpp | 15 ++++++--------- .../detail/overlay/get_turn_info_la.hpp | 9 ++++----- .../detail/overlay/get_turn_info_ll.hpp | 2 +- .../overlay/get_turns_linear_linear.cpp | 4 ++++ 5 files changed, 23 insertions(+), 20 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp index 5192b3aac..c038eb00c 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp @@ -821,15 +821,17 @@ public: IntersectionInfo const& intersection_info, DirInfo const& dir_info, SidePolicy const& side, - MethodAndOperationsReplacer method_and_operations_replacer) + MethodAndOperationsReplacer method_and_operations_replacer, + bool const is_pk_valid = true, bool const is_qk_valid = true) { TurnInfo tp = tp_model; tp.method = method_collinear; // If P arrives within Q, there is a turn dependent on P - if (dir_info.arrival[0] == 1 - && set_tp<0>(pi, pj, pk, side.pk_wrt_p1(), true, qi, qj, side.pk_wrt_q1(), tp, intersection_info)) + if ( dir_info.arrival[0] == 1 + && is_pk_valid + && set_tp<0>(pi, pj, pk, side.pk_wrt_p1(), true, qi, qj, side.pk_wrt_q1(), tp, intersection_info) ) { method_and_operations_replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation); @@ -838,8 +840,9 @@ public: } // If Q arrives within P, there is a turn dependent on Q - if (dir_info.arrival[1] == 1 - && set_tp<1>(qi, qj, qk, side.qk_wrt_q1(), false, pi, pj, side.qk_wrt_p1(), tp, intersection_info)) + if ( dir_info.arrival[1] == 1 + && is_qk_valid + && set_tp<1>(qi, qj, qk, side.qk_wrt_q1(), false, pi, pj, side.qk_wrt_p1(), tp, intersection_info) ) { method_and_operations_replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation); diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp index d960dd0aa..43a324c4f 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp @@ -184,10 +184,10 @@ struct get_turn_info_for_endpoint p_operation0, q_operation0, tp_model, result, out); - bool result_ignore_ip0 = !opposite ? // <=> ip_count == 1 || ip_count == 2 && !opposite - append0_last : - (append0_last && (p0j || (is_q_last && q0j && q1i))); - // NOTE: based on how collinear is calculated for opposite segments + // NOTE: opposite && ip_count == 1 may be true! + + // don't ignore only for collinear opposite + bool result_ignore_ip0 = append0_last && ( ip_count == 1 || !opposite ); if ( p_operation1 == operation_none ) return result_ignore_ip0; @@ -200,11 +200,8 @@ struct get_turn_info_for_endpoint p_operation1, q_operation1, tp_model, result, out); - bool result_ignore_ip1 = !opposite ? // <=> ip_count == 2 && !opposite - append1_last : - (append1_last && (q1j || (is_p_last && p1j && p0i))); - // NOTE: based on how collinear is calculated for opposite segments - // this condition is symmetric to the one above + // don't ignore only for collinear opposite + bool result_ignore_ip1 = append1_last && !opposite /*&& ip_count == 2*/; return result_ignore_ip0 || result_ignore_ip1; } diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp index 73b811aea..161f9237f 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp @@ -234,12 +234,13 @@ struct get_turn_info_linear_areal equal::apply(pi, pj, pk, qi, qj, qk, tp, result.template get<0>(), result.template get<1>(), side_calc); - spike_detector spike_detect(side_calc); + // TODO: This isn't correct handling, hence commented out + /*spike_detector spike_detect(side_calc); if ( tp.operations[0].operation == operation_union && spike_detect.is_spike_p()) { tp.operations[0].operation = operation_continue; - } + }*/ replacer_of_method_and_operations_ec replacer(method_touch); replacer(tp.method, tp.operations[0].operation, tp.operations[1].operation); @@ -506,9 +507,7 @@ struct get_turn_info_linear_areal // IP on the last point of Linear Geometry if ( EnableLast && is_p_last - && ( ip_count > 1 ? p1j : p0j ) - && (!q0i || (q0i && q1j)) // prevents duplication - && !q1i ) // prevents duplication + && ( ip_count > 1 ? (p1j && !q1i) : (p0j && !q0i) ) ) // prevents duplication { TurnInfo tp = tp_model; diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp index 586bc3f91..dbb2c4a11 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp @@ -351,7 +351,7 @@ struct get_turn_info_linear_linear AssignPolicy >::apply(pi, pj, pk, qi, qj, qk, tp, out, result.template get<0>(), result.template get<1>(), side_calc, - replacer); + replacer, !is_p_last, !is_q_last); } } } diff --git a/test/algorithms/overlay/get_turns_linear_linear.cpp b/test/algorithms/overlay/get_turns_linear_linear.cpp index 63dae1734..fdafbdae2 100644 --- a/test/algorithms/overlay/get_turns_linear_linear.cpp +++ b/test/algorithms/overlay/get_turns_linear_linear.cpp @@ -125,6 +125,10 @@ void test_all() test_geometry("MULTILINESTRING((0 0,10 0,30 0))", "MULTILINESTRING((0 10,5 0,20 0,20 0,30 0),(2 0,2 0),(3 0,3 0,3 0))", expected("mii")("ccc")("ccc")("txx")); + + test_geometry("LINESTRING(2 2,5 -1,15 2,18 0,20 0)", + "LINESTRING(30 0,19 0,18 0,0 0)", + expected("iuu")("iuu")("tiu")("mxi")); } int test_main(int, char* [])