diff --git a/include/boost/geometry/algorithms/simplify.hpp b/include/boost/geometry/algorithms/simplify.hpp index e041a680e..0311d7eab 100644 --- a/include/boost/geometry/algorithms/simplify.hpp +++ b/include/boost/geometry/algorithms/simplify.hpp @@ -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)); } } } diff --git a/include/boost/geometry/core/mutable_range.hpp b/include/boost/geometry/core/mutable_range.hpp index 21596a235..dd0ff0c88 100644 --- a/include/boost/geometry/core/mutable_range.hpp +++ b/include/boost/geometry/core/mutable_range.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 @@ -22,6 +22,7 @@ #include #include +#include #include @@ -75,6 +76,12 @@ struct push_back { range.push_back(item); } + + static inline void apply(typename rvalue_type::type range, + item_type && item) + { + range.push_back(std::move(item)); + } }; @@ -85,8 +92,13 @@ struct push_back template struct resize { + typedef typename boost::range_size + < + typename std::remove_reference::type + >::type size_type; + static inline void apply(typename rvalue_type::type range, - std::size_t new_size) + size_type new_size) { range.resize(new_size); } diff --git a/include/boost/geometry/extensions/gis/io/shapefile/read.hpp b/include/boost/geometry/extensions/gis/io/shapefile/read.hpp index 62c2dbf35..d740338e4 100644 --- a/include/boost/geometry/extensions/gis/io/shapefile/read.hpp +++ b/include/boost/geometry/extensions/gis/io/shapefile/read.hpp @@ -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 diff --git a/include/boost/geometry/io/wkt/read.hpp b/include/boost/geometry/io/wkt/read.hpp index 7e136af83..10d4634c4 100644 --- a/include/boost/geometry/io/wkt/read.hpp +++ b/include/boost/geometry/io/wkt/read.hpp @@ -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 #include +#include #include namespace boost { namespace geometry @@ -438,13 +439,7 @@ struct polygon_parser { typename ring_type::type ring; appender::apply(it, end, wkt, ring); - traits::push_back - < - typename std::remove_reference - < - typename traits::interior_mutable_type::type - >::type - >::apply(interior_rings(poly), ring); + range::push_back(interior_rings(poly), std::move(ring)); } if (it != end && *it == ",") diff --git a/include/boost/geometry/util/range.hpp b/include/boost/geometry/util/range.hpp index 1abf617aa..d3265b83b 100644 --- a/include/boost/geometry/util/range.hpp +++ b/include/boost/geometry/util/range.hpp @@ -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::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 +inline void push_back(Range & rng, + typename boost::range_value::type && value) +{ + geometry::traits::push_back::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 ::value_type &&, - typename std::iterator_traits::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 -struct copy_or_move_impl -{ - static inline OutIt apply(It first, It last, OutIt out) - { - return std::copy(first, last, out); - } -}; - -template -inline OutIt copy_or_move(It first, It last, OutIt out) -{ - return copy_or_move_impl::apply(first, last, out); -} - -#else - -template -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::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; diff --git a/test/util/range.cpp b/test/util/range.cpp index 56cfdfb11..05a5e2f85 100644 --- a/test/util/range.cpp +++ b/test/util/range.cpp @@ -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 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 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