mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-11 13:34:10 +00:00
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.
This commit is contained in:
parent
2fc1a3fe8f
commit
cad76bf9a0
@ -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 <boost/range/end.hpp>
|
||||
#include <boost/range/difference_type.hpp>
|
||||
#include <boost/range/reference.hpp>
|
||||
#include <boost/range/size.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
|
||||
#include <boost/geometry/core/assert.hpp>
|
||||
|
||||
|
||||
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<difference_type>(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<difference_type>(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<OtherRange const>::type,
|
||||
typename boost::range_iterator<Range const>::type
|
||||
>::value,
|
||||
int
|
||||
> = 0
|
||||
>
|
||||
inline closing_iterator(closing_iterator<OtherRange> 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 <typename OtherRange> friend struct closing_iterator;
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
inline reference dereference() const
|
||||
@ -105,8 +127,8 @@ private:
|
||||
|
||||
inline bool equal(closing_iterator<Range> 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<Range>::type m_iterator;
|
||||
typename boost::range_iterator<Range>::type m_end;
|
||||
typename boost::range_iterator<Range const>::type m_iterator;
|
||||
typename boost::range_iterator<Range const>::type m_begin;
|
||||
typename boost::range_iterator<Range const>::type m_end;
|
||||
difference_type m_size;
|
||||
difference_type m_index;
|
||||
};
|
||||
|
@ -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 <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
#include <boost/geometry/core/static_assert.hpp>
|
||||
|
||||
|
||||
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<OtherIt1, Iterator1>::value
|
||||
&& std::is_convertible<OtherIt2, Iterator2>::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<OtherIt1, Iterator1>::value
|
||||
&& std::is_convertible<OtherIt2, Iterator2>::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;
|
||||
|
@ -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 <type_traits>
|
||||
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
@ -26,8 +29,11 @@
|
||||
#include <boost/range/size.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
|
||||
#include <boost/geometry/core/assert.hpp>
|
||||
|
||||
#include <boost/geometry/iterators/base.hpp>
|
||||
|
||||
|
||||
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<std::is_convertible<OtherIterator, Iterator>::value, int> = 0
|
||||
>
|
||||
inline ever_circling_iterator(ever_circling_iterator<OtherIterator> 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 <typename OtherIterator> 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<OtherRange const>::type,
|
||||
typename boost::range_iterator<Range const>::type
|
||||
>::value,
|
||||
int
|
||||
> = 0
|
||||
>
|
||||
inline ever_circling_range_iterator(ever_circling_range_iterator<OtherRange> 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 <typename OtherRange> 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<Range> 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<Range>::type m_iterator;
|
||||
typename boost::range_iterator<Range const>::type m_begin;
|
||||
typename boost::range_iterator<Range const>::type m_iterator;
|
||||
difference_type m_size;
|
||||
difference_type m_index;
|
||||
};
|
||||
|
@ -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 <type_traits>
|
||||
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
#include <boost/geometry/core/assert.hpp>
|
||||
#include <boost/geometry/core/static_assert.hpp>
|
||||
|
||||
|
||||
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<OtherOuterIterator, OuterIterator>::value
|
||||
&& std::is_convertible<OtherInnerIterator, InnerIterator>::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)
|
||||
{
|
||||
|
@ -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 <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/static_assert.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/iterators/dispatch/point_iterator.hpp>
|
||||
@ -263,28 +262,24 @@ private:
|
||||
: point_iterator::iterator_adaptor_(base_it) {}
|
||||
|
||||
public:
|
||||
inline point_iterator() {}
|
||||
inline point_iterator() = default;
|
||||
|
||||
template <typename OtherGeometry>
|
||||
template
|
||||
<
|
||||
typename OtherGeometry,
|
||||
std::enable_if_t
|
||||
<
|
||||
std::is_convertible
|
||||
<
|
||||
typename detail::point_iterator::iterator_type<OtherGeometry>::type,
|
||||
typename detail::point_iterator::iterator_type<Geometry>::type
|
||||
>::value,
|
||||
int
|
||||
> = 0
|
||||
>
|
||||
inline point_iterator(point_iterator<OtherGeometry> 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<OtherGeometry>);
|
||||
}
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
|
@ -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 <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/geometry/core/static_assert.hpp>
|
||||
#include <boost/geometry/iterators/point_iterator.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@ -39,23 +38,24 @@ private:
|
||||
: base_type(base_it) {}
|
||||
|
||||
public:
|
||||
inline point_reverse_iterator() {}
|
||||
inline point_reverse_iterator() = default;
|
||||
|
||||
template <typename OtherGeometry>
|
||||
inline
|
||||
point_reverse_iterator(point_reverse_iterator<OtherGeometry> const& other)
|
||||
: base_type(other.base())
|
||||
{
|
||||
static const bool is_conv = std::is_convertible
|
||||
template
|
||||
<
|
||||
typename OtherGeometry,
|
||||
std::enable_if_t
|
||||
<
|
||||
std::reverse_iterator<point_iterator<Geometry> >,
|
||||
std::reverse_iterator<point_iterator<OtherGeometry> >
|
||||
>::value;
|
||||
|
||||
BOOST_GEOMETRY_STATIC_ASSERT((is_conv),
|
||||
"Other iterator has to be convertible to member iterator.",
|
||||
point_reverse_iterator<OtherGeometry>);
|
||||
}
|
||||
std::is_convertible
|
||||
<
|
||||
std::reverse_iterator<point_iterator<OtherGeometry> >,
|
||||
std::reverse_iterator<point_iterator<Geometry> >
|
||||
>::value,
|
||||
int
|
||||
> = 0
|
||||
>
|
||||
inline point_reverse_iterator(point_reverse_iterator<OtherGeometry> const& other)
|
||||
: base_type(other.base())
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
|
@ -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 <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/static_assert.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/iterators/detail/point_iterator/inner_range_type.hpp>
|
||||
@ -285,25 +284,24 @@ public:
|
||||
// correct iterator category.
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
|
||||
inline segment_iterator() {}
|
||||
inline segment_iterator() = default;
|
||||
|
||||
template <typename OtherGeometry>
|
||||
template
|
||||
<
|
||||
typename OtherGeometry,
|
||||
std::enable_if_t
|
||||
<
|
||||
std::is_convertible
|
||||
<
|
||||
typename detail::segment_iterator::iterator_type<OtherGeometry>::type,
|
||||
typename detail::segment_iterator::iterator_type<Geometry>::type
|
||||
>::value,
|
||||
int
|
||||
> = 0
|
||||
>
|
||||
inline segment_iterator(segment_iterator<OtherGeometry> 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<Geometry>::type
|
||||
>::value;
|
||||
|
||||
BOOST_GEOMETRY_STATIC_ASSERT((is_conv),
|
||||
"Other iterator has to be convertible to member iterator.",
|
||||
segment_iterator<OtherGeometry>);
|
||||
}
|
||||
{}
|
||||
|
||||
inline segment_iterator& operator++() // prefix
|
||||
{
|
||||
|
@ -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 <typename Range>
|
||||
struct closing_view
|
||||
{
|
||||
using iterator = closing_iterator<Range>;
|
||||
using const_iterator = closing_iterator<Range const>;
|
||||
|
||||
// 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<Range> iterator;
|
||||
typedef closing_iterator<Range const> 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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 <boost/geometry/views/reversible_view.hpp>
|
||||
#include <boost/geometry/views/closeable_view.hpp>
|
||||
#include <boost/geometry/util/order_as_direction.hpp>
|
||||
#include <boost/geometry/util/type_traits_std.hpp>
|
||||
|
||||
namespace boost { namespace geometry {
|
||||
|
||||
@ -39,53 +40,30 @@ namespace detail {
|
||||
template <typename Geometry>
|
||||
struct normalized_view
|
||||
{
|
||||
static const bool is_const = std::is_const<Geometry>::value;
|
||||
using range_type = typename detail::range_type<Geometry>::type;
|
||||
using range = util::transcribe_const_t<Geometry, range_type>;
|
||||
|
||||
//typedef typename ring_type<Geometry>::type ring_type;
|
||||
|
||||
typedef typename detail::range_type<Geometry>::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<Geometry>::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<Geometry, reversible_type>;
|
||||
|
||||
using closeable_type = typename closeable_view
|
||||
<
|
||||
reversible,
|
||||
geometry::closure<Geometry>::value
|
||||
>::type closeable_type;
|
||||
>::type;
|
||||
|
||||
typedef std::conditional_t
|
||||
<
|
||||
is_const,
|
||||
closeable_type const,
|
||||
closeable_type
|
||||
> closeable;
|
||||
using closeable = util::transcribe_const_t<Geometry, closeable_type>;
|
||||
|
||||
explicit inline normalized_view(range & r)
|
||||
: m_reversible(r)
|
||||
, m_closeable(m_reversible)
|
||||
: m_closeable(reversible_type(r))
|
||||
{}
|
||||
|
||||
typedef typename boost::range_iterator<closeable>::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;
|
||||
};
|
||||
|
||||
|
@ -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 <boost/range/iterator_range.hpp>
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
@ -40,20 +41,23 @@ namespace boost { namespace geometry
|
||||
template <typename Range>
|
||||
struct identity_view
|
||||
{
|
||||
typedef typename boost::range_iterator<Range const>::type const_iterator;
|
||||
typedef typename boost::range_iterator<Range>::type iterator;
|
||||
using const_iterator = typename boost::range_iterator<Range const>::type;
|
||||
using iterator = typename boost::range_iterator<Range>::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)
|
||||
|
@ -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 <algorithm>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <geometry_test_common.hpp>
|
||||
|
||||
#include <boost/geometry/iterators/closing_iterator.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
#include <boost/geometry/io/wkt/read.hpp>
|
||||
#include <boost/geometry/geometries/geometries.hpp>
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
#include <boost/geometry/geometries/ring.hpp>
|
||||
|
||||
#include <boost/range/adaptor/transformed.hpp>
|
||||
|
||||
|
||||
void test_concept()
|
||||
{
|
||||
std::vector<int> v = {1, 2, 3};
|
||||
|
||||
using iterator = bg::closing_iterator<std::vector<int>>;
|
||||
using const_iterator = bg::closing_iterator<std::vector<int> const>;
|
||||
|
||||
iterator it, it2(v);
|
||||
const_iterator cit, cit2(v);
|
||||
|
||||
BOOST_CHECK((std::is_same<decltype(*it2), const int&>::value));
|
||||
BOOST_CHECK((std::is_same<decltype(*cit2), const int&>::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<int> 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<int> v;
|
||||
v.push_back(1);
|
||||
v.push_back(2);
|
||||
v.push_back(3);
|
||||
|
||||
std::vector<int> v = {1, 2, 3};
|
||||
std::vector<int> closed_v = { 1, 2, 3, 1 };
|
||||
|
||||
typedef bg::closing_iterator
|
||||
<
|
||||
std::vector<int> 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<int> v;
|
||||
v.push_back(-1);
|
||||
v.push_back(-2);
|
||||
v.push_back(-3);
|
||||
|
||||
std::vector<int> v = {-1, -2, -3};
|
||||
std::vector<int> closed_v = { 1, 2, 3, 1 };
|
||||
|
||||
typedef boost::transformed_range
|
||||
<
|
||||
std::negate<int>,
|
||||
@ -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 <typename Geometry>
|
||||
void test_geometry(std::string const& wkt)
|
||||
template <typename P>
|
||||
void test_geometry()
|
||||
{
|
||||
Geometry geometry;
|
||||
bg::read_wkt(wkt, geometry);
|
||||
typedef bg::closing_iterator<Geometry const> closing_iterator;
|
||||
bg::model::ring<P> geometry = { {1, 1}, {1, 4}, {4, 4}, {4, 1} };
|
||||
bg::model::ring<P> closed = { {1, 1}, {1, 4}, {4, 4}, {4, 1}, {1, 1} };
|
||||
|
||||
using closing_iterator = bg::closing_iterator<bg::model::ring<P> 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<Geometry const>::type normal_iterator;
|
||||
Geometry copy;
|
||||
bg::model::ring<P> copy;
|
||||
|
||||
std::copy<closing_iterator>(
|
||||
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 <typename P>
|
||||
void test_all()
|
||||
{
|
||||
test_empty_non_geometry();
|
||||
test_non_geometry();
|
||||
test_transformed_non_geometry();
|
||||
test_geometry<bg::model::ring<P> >("POLYGON((1 1,1 4,4 4,4 1))");
|
||||
}
|
||||
|
||||
|
||||
int test_main(int, char* [])
|
||||
{
|
||||
test_all<bg::model::d2::point_xy<double> >();
|
||||
test_concept();
|
||||
test_empty_non_geometry();
|
||||
test_non_geometry();
|
||||
test_transformed_non_geometry();
|
||||
|
||||
test_geometry<bg::model::d2::point_xy<double>>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user