Support rvalue refs in range utils and use it.

This commit is contained in:
Adam Wulkiewicz 2021-05-15 03:08:45 +02:00
parent 7cbae4d68d
commit 50d1bfedc9
6 changed files with 58 additions and 91 deletions

View File

@ -294,7 +294,7 @@ private:
simplify_ring::apply(*it, out, max_distance, strategy);
if (! geometry::is_empty(out))
{
range::push_back(interior_rings_out, out);
range::push_back(interior_rings_out, std::move(out));
}
}
}
@ -354,7 +354,7 @@ struct simplify_multi
Policy::apply(*it, single_out, max_distance, strategy);
if (! geometry::is_empty(single_out))
{
range::push_back(out, single_out);
range::push_back(out, std::move(single_out));
}
}
}

View File

@ -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
@ -22,6 +22,7 @@
#include <cstddef>
#include <type_traits>
#include <boost/range/size_type.hpp>
#include <boost/range/value_type.hpp>
@ -75,6 +76,12 @@ struct push_back
{
range.push_back(item);
}
static inline void apply(typename rvalue_type<Range>::type range,
item_type && item)
{
range.push_back(std::move(item));
}
};
@ -85,8 +92,13 @@ struct push_back
template <typename Range>
struct resize
{
typedef typename boost::range_size
<
typename std::remove_reference<Range>::type
>::type size_type;
static inline void apply(typename rvalue_type<Range>::type range,
std::size_t new_size)
size_type new_size)
{
range.resize(new_size);
}

View File

@ -614,18 +614,14 @@ struct read_polygon_policy
std::reverse(++b, is_open ? e : (--e));
}
// TODO: support rval references in range::push_back()
// and/or implement range::emplace_back()
// implement and call move_or_copy(ring)
// assume outer ring
if (num_parts == 1)
range::push_back(outer_rings, ring); // order could be checked here too
range::push_back(outer_rings, std::move(ring)); // order could be checked here too
// check order
else if ( is_outer_ring(ring, order_strategy) )
range::push_back(outer_rings, ring);
range::push_back(outer_rings, std::move(ring));
else
range::push_back(inner_rings, ring);
range::push_back(inner_rings, std::move(ring));
}
if (inner_rings.empty()) // no inner rings
@ -633,8 +629,8 @@ struct read_polygon_policy
for (size_t i = 0; i < outer_rings.size(); ++i)
{
poly_type poly;
geometry::exterior_ring(poly) = outer_rings[i]; // TODO: move
range::push_back(polygons, poly); // TODO: move
geometry::exterior_ring(poly) = std::move(outer_rings[i]);
range::push_back(polygons, std::move(poly));
}
}
else if (! outer_rings.empty()) // outer and inner rings
@ -644,7 +640,7 @@ struct read_polygon_policy
for (size_t i = 0; i < outer_rings.size(); ++i)
{
poly_type poly;
geometry::exterior_ring(poly) = outer_rings[i]; // TODO: move
geometry::exterior_ring(poly) = std::move(outer_rings[i]);
for (size_t j = 0; j < inner_rings.size(); ++j)
{
if (! assigned[j])
@ -653,7 +649,7 @@ struct read_polygon_policy
geometry::exterior_ring(poly),
within_strategy))
{
range::push_back(geometry::interior_rings(poly), inner_rings[j]); // TODO: move
range::push_back(geometry::interior_rings(poly), std::move(inner_rings[j]));
++assigned_count;
assigned[j] = true;
}
@ -665,7 +661,7 @@ struct read_polygon_policy
}
}
}
range::push_back(polygons, poly); // TODO: move
range::push_back(polygons, std::move(poly));
}
// check if all interior rings were assigned

View File

@ -6,8 +6,8 @@
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2020 Baidyanath Kundu, Haldia, India
// 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
@ -59,6 +59,7 @@
#include <boost/geometry/strategies/io/spherical.hpp>
#include <boost/geometry/util/coordinate_cast.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/util/type_traits.hpp>
namespace boost { namespace geometry
@ -438,13 +439,7 @@ struct polygon_parser
{
typename ring_type<Polygon>::type ring;
appender::apply(it, end, wkt, ring);
traits::push_back
<
typename std::remove_reference
<
typename traits::interior_mutable_type<Polygon>::type
>::type
>::apply(interior_rings(poly), ring);
range::push_back(interior_rings(poly), std::move(ring));
}
if (it != end && *it == ",")

View File

@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013-2020.
// Modifications copyright (c) 2013-2020 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013-2021.
// Modifications copyright (c) 2013-2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -223,6 +223,18 @@ inline void push_back(Range & rng,
geometry::traits::push_back<Range>::apply(rng, value);
}
/*!
\brief Short utility to conveniently insert a new element at the end of a mutable range.
It uses boost::geometry::traits::push_back<>.
\ingroup utility
*/
template <typename Range>
inline void push_back(Range & rng,
typename boost::range_value<Range>::type && value)
{
geometry::traits::push_back<Range>::apply(rng, std::move(value));
}
/*!
\brief Short utility to conveniently resize a mutable range.
It uses boost::geometry::traits::resize<>.
@ -248,52 +260,6 @@ inline void pop_back(Range & rng)
range::resize(rng, boost::size(rng) - 1);
}
namespace detail {
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <typename It,
typename OutIt,
bool UseMove = std::is_convertible
<
typename std::iterator_traits<It>::value_type &&,
typename std::iterator_traits<OutIt>::value_type
>::value>
struct copy_or_move_impl
{
static inline OutIt apply(It first, It last, OutIt out)
{
return std::move(first, last, out);
}
};
template <typename It, typename OutIt>
struct copy_or_move_impl<It, OutIt, false>
{
static inline OutIt apply(It first, It last, OutIt out)
{
return std::copy(first, last, out);
}
};
template <typename It, typename OutIt>
inline OutIt copy_or_move(It first, It last, OutIt out)
{
return copy_or_move_impl<It, OutIt>::apply(first, last, out);
}
#else
template <typename It, typename OutIt>
inline OutIt copy_or_move(It first, It last, OutIt out)
{
return std::copy(first, last, out);
}
#endif
} // namespace detail
/*!
\brief Short utility to conveniently remove an element from a mutable range.
It uses std::copy() and resize(). Version taking mutable iterators.
@ -314,7 +280,7 @@ erase(Range & rng,
next = it;
++next;
detail::copy_or_move(next, boost::end(rng), it);
std::move(next, boost::end(rng), it);
range::resize(rng, boost::size(rng) - 1);
// NOTE: In general this should be sufficient:
@ -368,7 +334,7 @@ erase(Range & rng,
typename boost::range_difference<Range>::type const
d = std::distance(boost::begin(rng), first);
detail::copy_or_move(last, boost::end(rng), first);
std::move(last, boost::end(rng), first);
range::resize(rng, boost::size(rng) - count);
// NOTE: In general this should be sufficient:
@ -430,6 +396,12 @@ public:
return *this;
}
back_insert_iterator & operator=(typename Container::value_type && value)
{
range::push_back(*container, std::move(value));
return *this;
}
back_insert_iterator & operator* ()
{
return *this;

View File

@ -1,7 +1,7 @@
// Boost.Geometry
// Unit Test
// Copyright (c) 2014-2015 Oracle and/or its affiliates.
// Copyright (c) 2014-2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -70,11 +70,8 @@ struct NonMovable
NonMovable & operator=(NonMovable const& ii) { i = ii.i; return *this; }
bool operator==(NonMovable const& ii) const { return i == ii.i; }
int i;
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
private:
NonMovable(NonMovable && ii);
NonMovable & operator=(NonMovable && ii);
#endif
NonMovable(NonMovable && ii) = delete;
NonMovable & operator=(NonMovable && ii) = delete;
};
struct CopyableAndMovable
@ -84,10 +81,8 @@ struct CopyableAndMovable
CopyableAndMovable & operator=(CopyableAndMovable const& ii) { i = ii.i; return *this; }
bool operator==(CopyableAndMovable const& ii) const { return i == ii.i; }
int i;
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
CopyableAndMovable(CopyableAndMovable && ii) : i(std::move(ii.i)) {}
CopyableAndMovable & operator=(CopyableAndMovable && ii) { i = std::move(ii.i); return *this; }
#endif
};
} // namespace bgt
@ -183,11 +178,11 @@ void test_all()
void test_detail()
{
int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
bgr::detail::copy_or_move(arr + 1, arr + 10, arr);
std::move(arr + 1, arr + 10, arr);
BOOST_CHECK(arr[0] == 1);
std::vector<int> v(10, 0);
bgr::detail::copy_or_move(v.begin() + 1, v.begin() + 10, v.begin());
std::move(v.begin() + 1, v.begin() + 10, v.begin());
BOOST_CHECK(boost::size(v) == 10);
bgr::erase(v, v.begin() + 1);
BOOST_CHECK(boost::size(v) == 9);
@ -195,17 +190,14 @@ void test_detail()
bgt::NonMovable * arr2[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
bgt::NonMovable foo;
arr2[1] = &foo;
bgr::detail::copy_or_move(arr2 + 1, arr2 + 10, arr2);
std::move(arr2 + 1, arr2 + 10, arr2);
BOOST_CHECK(arr2[0] == &foo);
// Storing pointers in a std::vector is not possible in MinGW C++98
#if __cplusplus >= 201103L
std::vector<bgt::NonMovable*> v2(10, (bgt::NonMovable*)NULL);
bgr::detail::copy_or_move(v2.begin() + 1, v2.begin() + 10, v2.begin());
std::move(v2.begin() + 1, v2.begin() + 10, v2.begin());
BOOST_CHECK(boost::size(v2) == 10);
bgr::erase(v2, v2.begin() + 1);
BOOST_CHECK(boost::size(v2) == 9);
#endif
}
template <class Iterator>