From cad76bf9a0a9a89a16fba423d3dbf644401cf90a Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sat, 5 Jun 2021 00:35:47 +0200 Subject: [PATCH] Refactor iterators and views allowing to pass them as temporaries. Do not store pointers to ranges in iterators and views. Implement copy ctors in iterators allowing to convert compatible iterators. In copy ctors use enable_if instead of static_assert. --- .../geometry/iterators/closing_iterator.hpp | 62 +++++--- .../iterators/concatenate_iterator.hpp | 24 ++- .../iterators/ever_circling_iterator.hpp | 63 ++++++-- .../geometry/iterators/flatten_iterator.hpp | 31 ++-- .../geometry/iterators/point_iterator.hpp | 37 ++--- .../iterators/point_reverse_iterator.hpp | 34 ++-- .../geometry/iterators/segment_iterator.hpp | 34 ++-- .../boost/geometry/views/closeable_view.hpp | 25 +-- .../geometry/views/detail/normalized_view.hpp | 49 ++---- .../boost/geometry/views/identity_view.hpp | 26 ++-- test/iterators/closing_iterator.cpp | 147 ++++++++---------- 11 files changed, 273 insertions(+), 259 deletions(-) diff --git a/include/boost/geometry/iterators/closing_iterator.hpp b/include/boost/geometry/iterators/closing_iterator.hpp index fdb97977c..35fd1737c 100644 --- a/include/boost/geometry/iterators/closing_iterator.hpp +++ b/include/boost/geometry/iterators/closing_iterator.hpp @@ -4,7 +4,7 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// Copyright (c) 2020, Oracle and/or its affiliates. +// Copyright (c) 2020-2021, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -24,9 +24,10 @@ #include #include #include -#include #include +#include + namespace boost { namespace geometry { @@ -66,31 +67,52 @@ public: typedef typename base_type::difference_type difference_type; /// Constructor including the range it is based on - explicit inline closing_iterator(Range& range) - : m_range(&range) - , m_iterator(boost::begin(range)) + explicit inline closing_iterator(Range const& range) + : m_iterator(boost::begin(range)) + , m_begin(boost::begin(range)) , m_end(boost::end(range)) - , m_size(static_cast(boost::size(range))) + , m_size(m_end - m_begin) , m_index(0) {} /// Constructor to indicate the end of a range - explicit inline closing_iterator(Range& range, bool) - : m_range(&range) - , m_iterator(boost::end(range)) + explicit inline closing_iterator(Range const& range, bool) + : m_iterator(boost::end(range)) + , m_begin(boost::begin(range)) , m_end(boost::end(range)) - , m_size(static_cast(boost::size(range))) + , m_size(m_end - m_begin) , m_index((m_size == 0) ? 0 : m_size + 1) {} /// Default constructor - explicit inline closing_iterator() - : m_range(NULL) - , m_size(0) + inline closing_iterator() + : m_size(0) , m_index(0) {} + template + < + typename OtherRange, + std::enable_if_t + < + std::is_convertible + < + typename boost::range_iterator::type, + typename boost::range_iterator::type + >::value, + int + > = 0 + > + inline closing_iterator(closing_iterator const& other) + : m_iterator(other.m_iterator) + , m_begin(other.m_begin) + , m_end(other.m_end) + , m_size(other.m_size) + , m_index(other.m_index) + {} + private: + template friend struct closing_iterator; friend class boost::iterator_core_access; inline reference dereference() const @@ -105,8 +127,8 @@ private: inline bool equal(closing_iterator const& other) const { - return this->m_range == other.m_range - && this->m_index == other.m_index; + BOOST_GEOMETRY_ASSERT(m_begin == other.m_begin && m_end == other.m_end); + return this->m_index == other.m_index; } inline void increment() @@ -150,14 +172,14 @@ private: inline void update_iterator() { this->m_iterator = m_index <= m_size - ? boost::begin(*m_range) + (m_index % m_size) - : boost::end(*m_range) + ? m_begin + (m_index % m_size) + : m_end ; } - Range* m_range; - typename boost::range_iterator::type m_iterator; - typename boost::range_iterator::type m_end; + typename boost::range_iterator::type m_iterator; + typename boost::range_iterator::type m_begin; + typename boost::range_iterator::type m_end; difference_type m_size; difference_type m_index; }; diff --git a/include/boost/geometry/iterators/concatenate_iterator.hpp b/include/boost/geometry/iterators/concatenate_iterator.hpp index a6cfa8ee7..d3266e975 100644 --- a/include/boost/geometry/iterators/concatenate_iterator.hpp +++ b/include/boost/geometry/iterators/concatenate_iterator.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2020, Oracle and/or its affiliates. +// Copyright (c) 2014-2021, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -16,8 +16,6 @@ #include #include -#include - namespace boost { namespace geometry { @@ -49,7 +47,7 @@ public: typedef Iterator2 second_iterator_type; // default constructor - concatenate_iterator() {} + concatenate_iterator() = default; // for begin concatenate_iterator(Iterator1 it1, Iterator1 end1, @@ -67,7 +65,13 @@ public: typename OtherIt1, typename OtherIt2, typename OtherValue, - typename OtherReference + typename OtherReference, + std::enable_if_t + < + std::is_convertible::value + && std::is_convertible::value, + int + > = 0 > concatenate_iterator(concatenate_iterator < @@ -80,15 +84,7 @@ public: , m_end1(other.m_end1) , m_begin2(other.m_begin2) , m_it2(other.m_it2) - { - static const bool are_conv - = std::is_convertible::value - && std::is_convertible::value; - - BOOST_GEOMETRY_STATIC_ASSERT((are_conv), - "Other iterators have to be convertible to member iterators.", - OtherIt1, OtherIt2); - } + {} private: friend class boost::iterator_core_access; diff --git a/include/boost/geometry/iterators/ever_circling_iterator.hpp b/include/boost/geometry/iterators/ever_circling_iterator.hpp index 7492e1acc..ece1b6cdb 100644 --- a/include/boost/geometry/iterators/ever_circling_iterator.hpp +++ b/include/boost/geometry/iterators/ever_circling_iterator.hpp @@ -4,8 +4,8 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2020. -// Modifications copyright (c) 2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2020-2021. +// Modifications copyright (c) 2020-2021 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -18,6 +18,9 @@ #ifndef BOOST_GEOMETRY_ITERATORS_EVER_CIRCLING_ITERATOR_HPP #define BOOST_GEOMETRY_ITERATORS_EVER_CIRCLING_ITERATOR_HPP + +#include + #include #include #include @@ -26,8 +29,11 @@ #include #include +#include + #include + namespace boost { namespace geometry { @@ -49,7 +55,7 @@ struct ever_circling_iterator : Iterator > { - friend class boost::iterator_core_access; + ever_circling_iterator() = default; explicit inline ever_circling_iterator(Iterator begin, Iterator end, bool skip_first = false) @@ -69,6 +75,17 @@ struct ever_circling_iterator : this->base_reference() = start; } + template + < + typename OtherIterator, + std::enable_if_t::value, int> = 0 + > + inline ever_circling_iterator(ever_circling_iterator const& other) + : m_begin(other.m_begin) + , m_end(other.m_end) + , m_skip_first(other.m_skip_first) + {} + /// Navigate to a certain position, should be in [start .. end], if at end /// it will circle again. inline void moveto(Iterator it) @@ -78,6 +95,8 @@ struct ever_circling_iterator : } private: + template friend struct ever_circling_iterator; + friend class boost::iterator_core_access; inline void increment(bool possibly_skip = true) { @@ -125,8 +144,8 @@ private: public: /// Constructor including the range it is based on - explicit inline ever_circling_range_iterator(Range& range) - : m_range(&range) + explicit inline ever_circling_range_iterator(Range const& range) + : m_begin(boost::begin(range)) , m_iterator(boost::begin(range)) , m_size(boost::size(range)) , m_index(0) @@ -134,15 +153,35 @@ public: /// Default constructor explicit inline ever_circling_range_iterator() - : m_range(NULL) - , m_size(0) + : m_size(0) , m_index(0) {} + template + < + typename OtherRange, + std::enable_if_t + < + std::is_convertible + < + typename boost::range_iterator::type, + typename boost::range_iterator::type + >::value, + int + > = 0 + > + inline ever_circling_range_iterator(ever_circling_range_iterator const& other) + : m_begin(other.m_begin) + , m_iterator(other.m_iterator) + , m_size(other.m_size) + , m_index(other.m_index) + {} + typedef typename base_type::reference reference; typedef typename base_type::difference_type difference_type; private: + template friend struct ever_circling_range_iterator; friend class boost::iterator_core_access; inline reference dereference() const @@ -157,8 +196,8 @@ private: inline bool equal(ever_circling_range_iterator const& other) const { - return this->m_range == other.m_range - && this->m_index == other.m_index; + BOOST_GEOMETRY_ASSERT(m_begin == other.m_begin); + return this->m_index == other.m_index; } inline void increment() @@ -209,11 +248,11 @@ private: m_index += m_size; } m_index = m_index % m_size; - this->m_iterator = boost::begin(*m_range) + m_index; + this->m_iterator = m_begin + m_index; } - Range* m_range; - typename boost::range_iterator::type m_iterator; + typename boost::range_iterator::type m_begin; + typename boost::range_iterator::type m_iterator; difference_type m_size; difference_type m_index; }; diff --git a/include/boost/geometry/iterators/flatten_iterator.hpp b/include/boost/geometry/iterators/flatten_iterator.hpp index 190e59413..9b45d2efe 100644 --- a/include/boost/geometry/iterators/flatten_iterator.hpp +++ b/include/boost/geometry/iterators/flatten_iterator.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2020, Oracle and/or its affiliates. +// Copyright (c) 2014-2021, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -10,13 +10,14 @@ #ifndef BOOST_GEOMETRY_ITERATORS_FLATTEN_ITERATOR_HPP #define BOOST_GEOMETRY_ITERATORS_FLATTEN_ITERATOR_HPP + #include #include #include #include -#include + namespace boost { namespace geometry { @@ -58,7 +59,7 @@ public: typedef InnerIterator inner_iterator_type; // default constructor - flatten_iterator() {} + flatten_iterator() = default; // for begin flatten_iterator(OuterIterator outer_it, OuterIterator outer_end) @@ -77,7 +78,13 @@ public: typename OtherOuterIterator, typename OtherInnerIterator, typename OtherValue, typename OtherAccessInnerBegin, typename OtherAccessInnerEnd, - typename OtherReference + typename OtherReference, + std::enable_if_t + < + std::is_convertible::value + && std::is_convertible::value, + int + > = 0 > flatten_iterator(flatten_iterator < @@ -91,21 +98,7 @@ public: : m_outer_it(other.m_outer_it), m_outer_end(other.m_outer_end), m_inner_it(other.m_inner_it) - { - static const bool are_conv - = std::is_convertible - < - OtherOuterIterator, OuterIterator - >::value - && std::is_convertible - < - OtherInnerIterator, InnerIterator - >::value; - - BOOST_GEOMETRY_STATIC_ASSERT((are_conv), - "Other iterators have to be convertible to member iterators.", - OtherOuterIterator, OtherInnerIterator); - } + {} flatten_iterator& operator=(flatten_iterator const& other) { diff --git a/include/boost/geometry/iterators/point_iterator.hpp b/include/boost/geometry/iterators/point_iterator.hpp index 12e1d85c2..4168797cf 100644 --- a/include/boost/geometry/iterators/point_iterator.hpp +++ b/include/boost/geometry/iterators/point_iterator.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2020, Oracle and/or its affiliates. +// Copyright (c) 2014-2021, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -263,28 +262,24 @@ private: : point_iterator::iterator_adaptor_(base_it) {} public: - inline point_iterator() {} + inline point_iterator() = default; - template + template + < + typename OtherGeometry, + std::enable_if_t + < + std::is_convertible + < + typename detail::point_iterator::iterator_type::type, + typename detail::point_iterator::iterator_type::type + >::value, + int + > = 0 + > inline point_iterator(point_iterator const& other) : point_iterator::iterator_adaptor_(other.base()) - { - static const bool is_conv - = std::is_convertible< - typename detail::point_iterator::iterator_type - < - OtherGeometry - >::type, - typename detail::point_iterator::iterator_type - < - Geometry - >::type - >::value; - - BOOST_GEOMETRY_STATIC_ASSERT((is_conv), - "Other iterator has to be convertible to member iterator.", - point_iterator); - } + {} }; diff --git a/include/boost/geometry/iterators/point_reverse_iterator.hpp b/include/boost/geometry/iterators/point_reverse_iterator.hpp index f32dbf6ba..9c8cb492e 100644 --- a/include/boost/geometry/iterators/point_reverse_iterator.hpp +++ b/include/boost/geometry/iterators/point_reverse_iterator.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2020, Oracle and/or its affiliates. +// Copyright (c) 2014-2021, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -13,7 +13,6 @@ #include #include -#include #include namespace boost { namespace geometry @@ -39,23 +38,24 @@ private: : base_type(base_it) {} public: - inline point_reverse_iterator() {} + inline point_reverse_iterator() = default; - template - inline - point_reverse_iterator(point_reverse_iterator const& other) - : base_type(other.base()) - { - static const bool is_conv = std::is_convertible + template + < + typename OtherGeometry, + std::enable_if_t < - std::reverse_iterator >, - std::reverse_iterator > - >::value; - - BOOST_GEOMETRY_STATIC_ASSERT((is_conv), - "Other iterator has to be convertible to member iterator.", - point_reverse_iterator); - } + std::is_convertible + < + std::reverse_iterator >, + std::reverse_iterator > + >::value, + int + > = 0 + > + inline point_reverse_iterator(point_reverse_iterator const& other) + : base_type(other.base()) + {} }; diff --git a/include/boost/geometry/iterators/segment_iterator.hpp b/include/boost/geometry/iterators/segment_iterator.hpp index cd59321db..84af76e9c 100644 --- a/include/boost/geometry/iterators/segment_iterator.hpp +++ b/include/boost/geometry/iterators/segment_iterator.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2020, Oracle and/or its affiliates. +// Copyright (c) 2014-2021, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -18,7 +18,6 @@ #include #include -#include #include #include @@ -285,25 +284,24 @@ public: // correct iterator category. typedef std::bidirectional_iterator_tag iterator_category; - inline segment_iterator() {} + inline segment_iterator() = default; - template + template + < + typename OtherGeometry, + std::enable_if_t + < + std::is_convertible + < + typename detail::segment_iterator::iterator_type::type, + typename detail::segment_iterator::iterator_type::type + >::value, + int + > = 0 + > inline segment_iterator(segment_iterator const& other) : base(*other.base_ptr()) - { - static const bool is_conv - = std::is_convertible< - typename detail::segment_iterator::iterator_type - < - OtherGeometry - >::type, - typename detail::segment_iterator::iterator_type::type - >::value; - - BOOST_GEOMETRY_STATIC_ASSERT((is_conv), - "Other iterator has to be convertible to member iterator.", - segment_iterator); - } + {} inline segment_iterator& operator++() // prefix { diff --git a/include/boost/geometry/views/closeable_view.hpp b/include/boost/geometry/views/closeable_view.hpp index ba5bbd3f8..6114bc0e2 100644 --- a/include/boost/geometry/views/closeable_view.hpp +++ b/include/boost/geometry/views/closeable_view.hpp @@ -4,8 +4,8 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2020. -// Modifications copyright (c) 2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2020-2021. +// Modifications copyright (c) 2020-2021 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -43,21 +43,24 @@ namespace detail template struct closing_view { + using iterator = closing_iterator; + using const_iterator = closing_iterator; + // Keep this explicit, important for nested views/ranges explicit inline closing_view(Range& r) - : m_range(r) + : m_begin(r) + , m_end(r, true) {} - typedef closing_iterator iterator; - typedef closing_iterator const_iterator; + inline const_iterator begin() const { return m_begin; } + inline const_iterator end() const { return m_end; } - inline const_iterator begin() const { return const_iterator(m_range); } - inline const_iterator end() const { return const_iterator(m_range, true); } + inline iterator begin() { return m_begin; } + inline iterator end() { return m_end; } - inline iterator begin() { return iterator(m_range); } - inline iterator end() { return iterator(m_range, true); } -private : - Range& m_range; +private: + iterator m_begin; + iterator m_end; }; } diff --git a/include/boost/geometry/views/detail/normalized_view.hpp b/include/boost/geometry/views/detail/normalized_view.hpp index 2d3d4a8ba..e0063ca4f 100644 --- a/include/boost/geometry/views/detail/normalized_view.hpp +++ b/include/boost/geometry/views/detail/normalized_view.hpp @@ -4,8 +4,8 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2014-2020. -// Modifications copyright (c) 2014-2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014-2021. +// Modifications copyright (c) 2014-2021 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -28,6 +28,7 @@ #include #include #include +#include namespace boost { namespace geometry { @@ -39,53 +40,30 @@ namespace detail { template struct normalized_view { - static const bool is_const = std::is_const::value; + using range_type = typename detail::range_type::type; + using range = util::transcribe_const_t; - //typedef typename ring_type::type ring_type; - - typedef typename detail::range_type::type range_type; - - typedef std::conditional_t - < - is_const, - range_type const, - range_type - > range; - - typedef typename - reversible_view + using reversible_type = typename reversible_view < range, order_as_direction < geometry::point_order::value >::value - >::type reversible_type; + >::type; - typedef std::conditional_t - < - is_const, - reversible_type const, - reversible_type - > reversible; - - typedef typename - closeable_view + using reversible = util::transcribe_const_t; + + using closeable_type = typename closeable_view < reversible, geometry::closure::value - >::type closeable_type; + >::type; - typedef std::conditional_t - < - is_const, - closeable_type const, - closeable_type - > closeable; + using closeable = util::transcribe_const_t; explicit inline normalized_view(range & r) - : m_reversible(r) - , m_closeable(m_reversible) + : m_closeable(reversible_type(r)) {} typedef typename boost::range_iterator::type iterator; @@ -98,7 +76,6 @@ struct normalized_view inline iterator end() { return boost::end(m_closeable); } private: - reversible_type m_reversible; closeable_type m_closeable; }; diff --git a/include/boost/geometry/views/identity_view.hpp b/include/boost/geometry/views/identity_view.hpp index a05b54326..ebdb2ec75 100644 --- a/include/boost/geometry/views/identity_view.hpp +++ b/include/boost/geometry/views/identity_view.hpp @@ -4,8 +4,8 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2020. -// Modifications copyright (c) 2020 Oracle and/or its affiliates. +// This file was modified by Oracle on 2020-2021. +// Modifications copyright (c) 2020-2021 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -18,6 +18,7 @@ #ifndef BOOST_GEOMETRY_VIEWS_IDENTITY_VIEW_HPP #define BOOST_GEOMETRY_VIEWS_IDENTITY_VIEW_HPP +#include #include #include @@ -40,20 +41,23 @@ namespace boost { namespace geometry template struct identity_view { - typedef typename boost::range_iterator::type const_iterator; - typedef typename boost::range_iterator::type iterator; + using const_iterator = typename boost::range_iterator::type; + using iterator = typename boost::range_iterator::type; explicit inline identity_view(Range& r) - : m_range(r) + : m_begin(boost::begin(r)) + , m_end(boost::end(r)) {} - inline const_iterator begin() const { return boost::begin(m_range); } - inline const_iterator end() const { return boost::end(m_range); } + inline const_iterator begin() const { return m_begin; } + inline const_iterator end() const { return m_end; } - inline iterator begin() { return boost::begin(m_range); } - inline iterator end() { return boost::end(m_range); } -private : - Range& m_range; + inline iterator begin() { return m_begin; } + inline iterator end() { return m_end; } + +private: + iterator m_begin; + iterator m_end; }; #if defined(_MSC_VER) diff --git a/test/iterators/closing_iterator.cpp b/test/iterators/closing_iterator.cpp index 9ac43634b..a071b755f 100644 --- a/test/iterators/closing_iterator.cpp +++ b/test/iterators/closing_iterator.cpp @@ -5,6 +5,9 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// Copyright (c) 2021, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -14,21 +17,49 @@ #include #include -#include -#include #include #include -#include -#include -#include #include +#include #include +void test_concept() +{ + std::vector v = {1, 2, 3}; + + using iterator = bg::closing_iterator>; + using const_iterator = bg::closing_iterator const>; + + iterator it, it2(v); + const_iterator cit, cit2(v); + + BOOST_CHECK((std::is_same::value)); + BOOST_CHECK((std::is_same::value)); + + it = it2; + cit = cit2; + BOOST_CHECK_EQUAL(*it, 1); + BOOST_CHECK_EQUAL(*cit, 1); + cit = ++it; + BOOST_CHECK_EQUAL(*it, 2); + BOOST_CHECK_EQUAL(*cit, 2); + // This is ok because both of these iterators are in fact const iterators + it = ++cit; + BOOST_CHECK_EQUAL(*it, 3); + BOOST_CHECK_EQUAL(*cit, 3); + + // Check compilations, it is (since Oct 2010) random access + it--; + --it; + it += 2; + it -= 2; +} + // The closing iterator should also work on normal std:: containers void test_empty_non_geometry() { @@ -39,49 +70,33 @@ void test_empty_non_geometry() std::vector const > closing_iterator; - closing_iterator it(v); closing_iterator end(v, true); - std::ostringstream out; - for (; it != end; ++it) - { - out << *it; - } - BOOST_CHECK_EQUAL(out.str(), ""); + BOOST_CHECK(it == end); } void test_non_geometry() { - std::vector v; - v.push_back(1); - v.push_back(2); - v.push_back(3); - + std::vector v = {1, 2, 3}; + std::vector closed_v = { 1, 2, 3, 1 }; + typedef bg::closing_iterator < std::vector const > closing_iterator; - closing_iterator it(v); closing_iterator end(v, true); - - std::ostringstream out; - for (; it != end; ++it) - { - out << *it; - } - BOOST_CHECK_EQUAL(out.str(), "1231"); + + BOOST_CHECK(std::equal(it, end, closed_v.begin(), closed_v.end())); } void test_transformed_non_geometry() { - std::vector v; - v.push_back(-1); - v.push_back(-2); - v.push_back(-3); - + std::vector v = {-1, -2, -3}; + std::vector closed_v = { 1, 2, 3, 1 }; + typedef boost::transformed_range < std::negate, @@ -97,78 +112,50 @@ void test_transformed_non_geometry() closing_iterator it(v2); closing_iterator end(v2, true); - std::ostringstream out; - for (; it != end; ++it) - { - out << *it; - } - BOOST_CHECK_EQUAL(out.str(), "1231"); + BOOST_CHECK(std::equal(it, end, closed_v.begin(), closed_v.end())); } - - - - -template -void test_geometry(std::string const& wkt) +template +void test_geometry() { - Geometry geometry; - bg::read_wkt(wkt, geometry); - typedef bg::closing_iterator closing_iterator; + bg::model::ring

geometry = { {1, 1}, {1, 4}, {4, 4}, {4, 1} }; + bg::model::ring

closed = { {1, 1}, {1, 4}, {4, 4}, {4, 1}, {1, 1} }; + + using closing_iterator = bg::closing_iterator const>; + auto pred = [](P const& p1, P const& p2) + { + return bg::get<0>(p1) == bg::get<0>(p2) && bg::get<1>(p1) == bg::get<1>(p2); + }; // 1. Test normal behaviour { closing_iterator it(geometry); closing_iterator end(geometry, true); - std::ostringstream out; - for (; it != end; ++it) - { - out << " " << bg::get<0>(*it) << bg::get<1>(*it); - } - BOOST_CHECK_EQUAL(out.str(), " 11 14 44 41 11"); - - // Check compilations, it is (since Oct 2010) random access - it--; - --it; - it += 2; - it -= 2; + BOOST_CHECK((std::equal(it, end, closed.begin(), closed.end(), pred))); } // 2: check copy behaviour { - typedef typename boost::range_iterator::type normal_iterator; - Geometry copy; + bg::model::ring

copy; - std::copy( - closing_iterator(geometry), - closing_iterator(geometry, true), - std::back_inserter(copy)); + std::copy(closing_iterator(geometry), closing_iterator(geometry, true), + std::back_inserter(copy)); - std::ostringstream out; - for (normal_iterator cit = boost::begin(copy); cit != boost::end(copy); ++cit) - { - out << " " << bg::get<0>(*cit) << bg::get<1>(*cit); - } - BOOST_CHECK_EQUAL(out.str(), " 11 14 44 41 11"); + BOOST_CHECK((std::equal(copy.begin(), copy.end(), closed.begin(), closed.end(), pred))); } } -template -void test_all() -{ - test_empty_non_geometry(); - test_non_geometry(); - test_transformed_non_geometry(); - test_geometry >("POLYGON((1 1,1 4,4 4,4 1))"); -} - - int test_main(int, char* []) { - test_all >(); + test_concept(); + test_empty_non_geometry(); + test_non_geometry(); + test_transformed_non_geometry(); + + test_geometry>(); return 0; }