Add support for ranges passed by rvalue in range utilities.

This allows to pass temporary ranges and proxies without the need to
explicitly create variables.
This commit is contained in:
Adam Wulkiewicz 2021-06-04 00:02:59 +02:00
parent 14aa054593
commit 2fc1a3fe8f
4 changed files with 287 additions and 220 deletions

View File

@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
// 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
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@ -104,7 +104,7 @@ struct disjoint_range_segment_or_box
point_type const
> range_segment;
view_type view(range);
view_type const view(range);
const size_type count = ::boost::size(view);
@ -117,9 +117,7 @@ struct disjoint_range_segment_or_box
return disjoint_point_segment_or_box
<
SegmentOrBox
>::apply(geometry::range::front<view_type const>(view),
segment_or_box,
strategy);
>::apply(range::front(view), segment_or_box, strategy);
}
else
{

View File

@ -442,11 +442,7 @@ struct polygon_parser
{
typename ring_type<Polygon>::type ring;
appender::apply(it, end, wkt, ring);
// This may be a proxy range and push_back needs lvalue
// TODO: Support rvalue ranges in util/range.hpp
typename traits::interior_mutable_type<Polygon>::type
rings = geometry::interior_rings(poly);
range::push_back(rings, std::move(ring));
range::push_back(geometry::interior_rings(poly), std::move(ring));
}
if (it != end && *it == ",")

View File

@ -1,15 +1,13 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Boost.Geometry
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// 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
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_UTIL_RANGE_HPP
#define BOOST_GEOMETRY_UTIL_RANGE_HPP
@ -29,7 +27,6 @@
#include <boost/range/difference_type.hpp>
#include <boost/range/has_range_iterator.hpp>
#include <boost/range/iterator.hpp>
#include <boost/range/rbegin.hpp>
#include <boost/range/reference.hpp>
#include <boost/range/size.hpp>
#include <boost/range/value_type.hpp>
@ -75,37 +72,16 @@ struct is_range
: is_range_impl<T>
{};
template <typename Range, typename T = void>
using enable_if_mutable_t = std::enable_if_t
<
(! std::is_const<std::remove_reference_t<Range>>::value),
T
>;
// NOTE: For SinglePassRanges pos could iterate over all elements until the i-th element was met.
template <typename RandomAccessRange>
struct pos
{
typedef typename boost::range_iterator<RandomAccessRange>::type iterator;
typedef typename boost::range_size<RandomAccessRange>::type size_type;
typedef typename boost::range_difference<RandomAccessRange>::type difference_type;
static inline iterator apply(RandomAccessRange & rng, size_type i)
{
BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<RandomAccessRange> ));
return boost::begin(rng) + static_cast<difference_type>(i);
}
};
} // namespace detail
/*!
\brief Short utility to conveniently return an iterator of a RandomAccessRange.
\ingroup utility
*/
template <typename RandomAccessRange>
inline typename boost::range_iterator<RandomAccessRange const>::type
pos(RandomAccessRange const& rng,
typename boost::range_size<RandomAccessRange const>::type i)
{
BOOST_GEOMETRY_ASSERT(i <= boost::size(rng));
return detail::pos<RandomAccessRange const>::apply(rng, i);
}
/*!
\brief Short utility to conveniently return an iterator of a RandomAccessRange.
@ -113,24 +89,13 @@ pos(RandomAccessRange const& rng,
*/
template <typename RandomAccessRange>
inline typename boost::range_iterator<RandomAccessRange>::type
pos(RandomAccessRange & rng,
pos(RandomAccessRange && rng,
typename boost::range_size<RandomAccessRange>::type i)
{
BOOST_RANGE_CONCEPT_ASSERT((boost::RandomAccessRangeConcept<RandomAccessRange>));
BOOST_GEOMETRY_ASSERT(i <= boost::size(rng));
return detail::pos<RandomAccessRange>::apply(rng, i);
}
/*!
\brief Short utility to conveniently return an element of a RandomAccessRange.
\ingroup utility
*/
template <typename RandomAccessRange>
inline typename boost::range_reference<RandomAccessRange const>::type
at(RandomAccessRange const& rng,
typename boost::range_size<RandomAccessRange const>::type i)
{
BOOST_GEOMETRY_ASSERT(i < boost::size(rng));
return * detail::pos<RandomAccessRange const>::apply(rng, i);
return boost::begin(rng)
+ static_cast<typename boost::range_difference<RandomAccessRange>::type>(i);
}
/*!
@ -139,23 +104,10 @@ at(RandomAccessRange const& rng,
*/
template <typename RandomAccessRange>
inline typename boost::range_reference<RandomAccessRange>::type
at(RandomAccessRange & rng,
at(RandomAccessRange && rng,
typename boost::range_size<RandomAccessRange>::type i)
{
BOOST_GEOMETRY_ASSERT(i < boost::size(rng));
return * detail::pos<RandomAccessRange>::apply(rng, i);
}
/*!
\brief Short utility to conveniently return the front element of a Range.
\ingroup utility
*/
template <typename Range>
inline typename boost::range_reference<Range const>::type
front(Range const& rng)
{
BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
return *boost::begin(rng);
return *pos(rng, i);
}
/*!
@ -164,38 +116,24 @@ front(Range const& rng)
*/
template <typename Range>
inline typename boost::range_reference<Range>::type
front(Range & rng)
front(Range && rng)
{
BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
return *boost::begin(rng);
}
// NOTE: For SinglePassRanges back() could iterate over all elements until the last element is met.
/*!
\brief Short utility to conveniently return the back element of a BidirectionalRange.
\ingroup utility
*/
template <typename BidirectionalRange>
inline typename boost::range_reference<BidirectionalRange const>::type
back(BidirectionalRange const& rng)
{
BOOST_RANGE_CONCEPT_ASSERT(( boost::BidirectionalRangeConcept<BidirectionalRange const> ));
BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
return *(boost::rbegin(rng));
}
/*!
\brief Short utility to conveniently return the back element of a BidirectionalRange.
\ingroup utility
*/
template <typename BidirectionalRange>
inline typename boost::range_reference<BidirectionalRange>::type
back(BidirectionalRange & rng)
back(BidirectionalRange && rng)
{
BOOST_RANGE_CONCEPT_ASSERT((boost::BidirectionalRangeConcept<BidirectionalRange>));
BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
return *(boost::rbegin(rng));
auto it = boost::end(rng);
return *(--it);
}
@ -204,11 +142,17 @@ back(BidirectionalRange & rng)
It uses traits::clear<>.
\ingroup utility
*/
template <typename Range>
inline void clear(Range & rng)
template
<
typename Range,
detail::enable_if_mutable_t<Range, int> = 0
>
inline void clear(Range && rng)
{
// NOTE: this trait is probably not needed since it could be implemented using resize()
geometry::traits::clear<Range>::apply(rng);
geometry::traits::clear
<
std::remove_reference_t<Range>
>::apply(rng);
}
/*!
@ -216,11 +160,18 @@ inline void clear(Range & rng)
It uses boost::geometry::traits::push_back<>.
\ingroup utility
*/
template <typename Range>
inline void push_back(Range & rng,
template
<
typename Range,
detail::enable_if_mutable_t<Range, int> = 0
>
inline void push_back(Range && rng,
typename boost::range_value<Range>::type const& value)
{
geometry::traits::push_back<Range>::apply(rng, value);
geometry::traits::push_back
<
std::remove_reference_t<Range>
>::apply(rng, value);
}
/*!
@ -228,11 +179,18 @@ inline void push_back(Range & rng,
It uses boost::geometry::traits::push_back<>.
\ingroup utility
*/
template <typename Range>
inline void push_back(Range & rng,
template
<
typename Range,
detail::enable_if_mutable_t<Range, int> = 0
>
inline void push_back(Range && rng,
typename boost::range_value<Range>::type && value)
{
geometry::traits::push_back<Range>::apply(rng, std::move(value));
geometry::traits::push_back
<
std::remove_reference_t<Range>
>::apply(rng, std::move(value));
}
/*!
@ -240,10 +198,18 @@ inline void push_back(Range & rng,
It uses boost::geometry::traits::emplace_back<>.
\ingroup utility
*/
template <typename Range, typename ...Args>
inline void emplace_back(Range & rng, Args&&... args)
template
<
typename Range,
typename ...Args,
detail::enable_if_mutable_t<Range, int> = 0
>
inline void emplace_back(Range && rng, Args &&... args)
{
geometry::traits::emplace_back<Range>::apply(rng, std::forward<Args>(args)...);
geometry::traits::emplace_back
<
std::remove_reference_t<Range>
>::apply(rng, std::forward<Args>(args)...);
}
/*!
@ -251,11 +217,18 @@ inline void emplace_back(Range & rng, Args&&... args)
It uses boost::geometry::traits::resize<>.
\ingroup utility
*/
template <typename Range>
inline void resize(Range & rng,
template
<
typename Range,
detail::enable_if_mutable_t<Range, int> = 0
>
inline void resize(Range && rng,
typename boost::range_size<Range>::type new_size)
{
geometry::traits::resize<Range>::apply(rng, new_size);
geometry::traits::resize
<
std::remove_reference_t<Range>
>::apply(rng, new_size);
}
/*!
@ -263,8 +236,12 @@ inline void resize(Range & rng,
It uses resize().
\ingroup utility
*/
template <typename Range>
inline void pop_back(Range & rng)
template
<
typename Range,
detail::enable_if_mutable_t<Range, int> = 0
>
inline void pop_back(Range && rng)
{
BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
range::resize(rng, boost::size(rng) - 1);
@ -272,12 +249,16 @@ inline void pop_back(Range & rng)
/*!
\brief Short utility to conveniently remove an element from a mutable range.
It uses std::copy() and resize(). Version taking mutable iterators.
It uses std::move() and resize(). Version taking mutable iterators.
\ingroup utility
*/
template <typename Range>
template
<
typename Range,
detail::enable_if_mutable_t<Range, int> = 0
>
inline typename boost::range_iterator<Range>::type
erase(Range & rng,
erase(Range && rng,
typename boost::range_iterator<Range>::type it)
{
BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
@ -304,13 +285,17 @@ erase(Range & rng,
/*!
\brief Short utility to conveniently remove an element from a mutable range.
It uses std::copy() and resize(). Version taking non-mutable iterators.
It uses std::move() and resize(). Version taking non-mutable iterators.
\ingroup utility
*/
template <typename Range>
template
<
typename Range,
detail::enable_if_mutable_t<Range, int> = 0
>
inline typename boost::range_iterator<Range>::type
erase(Range & rng,
typename boost::range_iterator<Range const>::type cit)
erase(Range && rng,
typename boost::range_iterator<std::remove_reference_t<Range> const>::type cit)
{
BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<Range> ));
@ -323,12 +308,16 @@ erase(Range & rng,
/*!
\brief Short utility to conveniently remove a range of elements from a mutable range.
It uses std::copy() and resize(). Version taking mutable iterators.
It uses std::move() and resize(). Version taking mutable iterators.
\ingroup utility
*/
template <typename Range>
template
<
typename Range,
detail::enable_if_mutable_t<Range, int> = 0
>
inline typename boost::range_iterator<Range>::type
erase(Range & rng,
erase(Range && rng,
typename boost::range_iterator<Range>::type first,
typename boost::range_iterator<Range>::type last)
{
@ -361,14 +350,18 @@ erase(Range & rng,
/*!
\brief Short utility to conveniently remove a range of elements from a mutable range.
It uses std::copy() and resize(). Version taking non-mutable iterators.
It uses std::move() and resize(). Version taking non-mutable iterators.
\ingroup utility
*/
template <typename Range>
template
<
typename Range,
detail::enable_if_mutable_t<Range, int> = 0
>
inline typename boost::range_iterator<Range>::type
erase(Range & rng,
typename boost::range_iterator<Range const>::type cfirst,
typename boost::range_iterator<Range const>::type clast)
erase(Range && rng,
typename boost::range_iterator<std::remove_reference_t<Range> const>::type cfirst,
typename boost::range_iterator<std::remove_reference_t<Range> const>::type clast)
{
BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<Range> ));

View File

@ -5,10 +5,8 @@
// Contributed and/or modified by Adam Wulkiewicz, 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
// http://www.boost.org/LICENSE_1_0.txt)
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#include <geometry_test_common.hpp>
@ -21,57 +19,15 @@
namespace bgt {
template <bool MutableIterator>
struct beginner
struct NonCopyable
{
template <typename Range>
typename boost::range_iterator<Range>::type
operator()(Range & rng)
{
return boost::begin(rng);
}
};
template <>
struct beginner<false>
{
template <typename Range>
typename boost::range_iterator<Range const>::type
operator()(Range & rng)
{
return boost::const_begin(rng);
}
};
template <bool MutableIterator>
struct ender
{
template <typename Range>
typename boost::range_iterator<Range>::type
operator()(Range & rng)
{
return boost::end(rng);
}
};
template <>
struct ender<false>
{
template <typename Range>
typename boost::range_iterator<Range const>::type
operator()(Range & rng)
{
return boost::const_end(rng);
}
};
struct NonMovable
{
NonMovable(int ii = 0) : i(ii) {}
NonMovable(NonMovable const& ii) : i(ii.i) {}
NonMovable & operator=(NonMovable const& ii) { i = ii.i; return *this; }
bool operator==(NonMovable const& ii) const { return i == ii.i; }
NonCopyable(int ii = 0) : i(ii) {}
NonCopyable(NonCopyable && ii) : i(ii.i) {}
NonCopyable & operator=(NonCopyable && ii) { i = ii.i; return *this; }
bool operator==(NonCopyable const& ii) const { return i == ii.i; }
int i;
NonMovable(NonMovable && ii) = delete;
NonMovable & operator=(NonMovable && ii) = delete;
NonCopyable(NonCopyable const& ii) = delete;
NonCopyable & operator=(NonCopyable const& ii) = delete;
};
struct CopyableAndMovable
@ -85,45 +41,154 @@ struct CopyableAndMovable
CopyableAndMovable & operator=(CopyableAndMovable && ii) { i = std::move(ii.i); return *this; }
};
template <typename Container>
struct proxy
{
using iterator = typename boost::range_iterator<Container>::type;
using const_iterator = typename boost::range_iterator<Container const>::type;
explicit proxy(Container & container) : m_ptr(&container) {}
template <typename T>
void push_back(T&& v) { m_ptr->push_back(std::forward<T>(v)); }
template <typename ...Ts>
void emplace_back(Ts&&... vs) { m_ptr->emplace_back(std::forward<Ts>(vs)...); }
void clear() { m_ptr->clear(); }
void resize(size_t n) { m_ptr->resize(n); }
iterator begin() { return m_ptr->begin(); }
const_iterator begin() const { return m_ptr->begin(); }
iterator end() { return m_ptr->end(); }
const_iterator end() const { return m_ptr->end(); }
private:
Container * m_ptr;
};
template <typename Container>
bgt::proxy<Container> make_proxy(Container & container)
{
return bgt::proxy<Container>(container);
}
} // namespace bgt
namespace bgr = bg::range;
template <typename T, bool MutableIterator>
void test_all()
template <typename T>
void fill(std::vector<T> & v, int n)
{
bgt::beginner<MutableIterator> begin;
bgt::ender<MutableIterator> end;
std::vector<T> v;
for (int i = 0 ; i < 20 ; ++i)
for (int i = 0; i < n; ++i)
{
bgr::push_back(v, i);
}
}
for (int i = 0 ; i < 20 ; ++i)
{
BOOST_CHECK(bgr::at(v, i) == i);
}
template <typename T>
void test_push_emplace(std::vector<T> & v)
{
bgr::push_back(v, 0);
bgr::push_back(bgt::make_proxy(v), 1);
bgr::emplace_back(v, 2);
bgr::emplace_back(bgt::make_proxy(v), 3);
typename std::vector<T>::value_type val = 4;
bgr::push_back(v, std::move(val));
val = 5;
bgr::push_back(bgt::make_proxy(v), std::move(val));
val = 6;
bgr::emplace_back(v, std::move(val));
val = 7;
bgr::emplace_back(bgt::make_proxy(v), std::move(val));
for (int i = (int)v.size(); i < 20; ++i)
{
std::vector<T> w;
std::copy(v.begin(), v.end(), bgr::back_inserter(w));
BOOST_CHECK(v.size() == w.size() && std::equal(v.begin(), v.end(), w.begin()));
bgr::push_back(v, i);
}
}
template <typename T>
void test_at_front_back(std::vector<T> const& v)
{
BOOST_CHECK(bgr::at(v, 1) == 1);
BOOST_CHECK(bgr::at(bgt::make_proxy(v), 2) == 2);
BOOST_CHECK(bgr::at(std::make_pair(v.begin(), v.end()), 3) == 3);
BOOST_CHECK(bgr::front(v) == 0);
BOOST_CHECK(bgr::back(v) == 19);
BOOST_CHECK(bgr::front(bgt::make_proxy(v)) == 0);
BOOST_CHECK(bgr::front(std::make_pair(v.begin(), v.end())) == 0);
BOOST_CHECK(bgr::back(v) == 19);
BOOST_CHECK(bgr::back(bgt::make_proxy(v)) == 19);
BOOST_CHECK(bgr::back(std::make_pair(v.begin(), v.end())) == 19);
}
template <typename T>
void test_at_front_back(std::vector<T> & v)
{
bgr::at(v, 1) = 101;
bgr::at(bgt::make_proxy(v), 2) = 102;
bgr::at(std::make_pair(v.begin(), v.end()), 3) = 103;
BOOST_CHECK(bgr::at(v, 1) == 101);
BOOST_CHECK(bgr::at(bgt::make_proxy(v), 2) == 102);
BOOST_CHECK(bgr::at(std::make_pair(v.begin(), v.end()), 3) == 103);
bgr::at(v, 1) = 1;
bgr::at(bgt::make_proxy(v), 2) = 2;
bgr::at(std::make_pair(v.begin(), v.end()), 3) = 3;
bgr::front(v) = 100;
BOOST_CHECK(bgr::front(v) == 100);
bgr::front(bgt::make_proxy(v)) = 200;
BOOST_CHECK(bgr::front(v) == 200);
bgr::front(std::make_pair(v.begin(), v.end())) = 0;
BOOST_CHECK(bgr::front(v) == 0);
bgr::back(v) = 119;
BOOST_CHECK(bgr::back(v) == 119);
bgr::back(bgt::make_proxy(v)) = 219;
BOOST_CHECK(bgr::back(v) == 219);
bgr::back(std::make_pair(v.begin(), v.end())) = 19;
BOOST_CHECK(bgr::back(v) == 19);
}
template <typename T>
void test_clear(std::vector<T> & v)
{
std::vector<T> w;
std::copy(v.begin(), v.end(), bgr::back_inserter(w));
BOOST_CHECK(w.size() == 20 && std::equal(v.begin(), v.end(), w.begin()));
bgr::clear(w);
BOOST_CHECK(w.size() == 0);
w = v;
BOOST_CHECK(w.size() == 20);
bgr::clear(bgt::make_proxy(w));
BOOST_CHECK(w.size() == 0);
}
void test_clear(std::vector<bgt::NonCopyable> & )
{}
template <typename T>
void test_resize_pop(std::vector<T> & v)
{
BOOST_CHECK(boost::size(v) == 20); // [0,19]
bgr::resize(v, 15);
BOOST_CHECK(boost::size(v) == 15); // [0,14]
BOOST_CHECK(bgr::back(v) == 14);
bgr::resize(v, 18);
BOOST_CHECK(boost::size(v) == 18); // [0,17]
bgr::resize(bgt::make_proxy(v), 16);
BOOST_CHECK(boost::size(v) == 16); // [0,15]
BOOST_CHECK(bgr::back(v) == 15);
bgr::pop_back(v);
BOOST_CHECK(boost::size(v) == 15); // [0,14]
bgr::pop_back(bgt::make_proxy(v));
BOOST_CHECK(boost::size(v) == 14); // [0,13]
BOOST_CHECK(bgr::back(v) == 13);
}
template <typename T, typename Begin, typename End>
void test_erase(std::vector<T> & v, Begin begin, End end)
{
typename std::vector<T>::iterator
it = bgr::erase(v, end(v) - 1);
BOOST_CHECK(boost::size(v) == 13); // [0,12]
@ -135,14 +200,14 @@ void test_all()
BOOST_CHECK(bgr::back(v) == 9);
BOOST_CHECK(it == end(v));
it = bgr::erase(v, begin(v) + 2);
it = bgr::erase(bgt::make_proxy(v), begin(v) + 2);
BOOST_CHECK(boost::size(v) == 9); // {0,1,3..9}
BOOST_CHECK(bgr::at(v, 1) == 1);
BOOST_CHECK(bgr::at(v, 2) == 3);
BOOST_CHECK(bgr::back(v) == 9);
BOOST_CHECK(it == bgr::pos(v, 2));
it = bgr::erase(v, begin(v) + 2, begin(v) + 2);
it = bgr::erase(bgt::make_proxy(v), begin(v) + 2, begin(v) + 2);
BOOST_CHECK(boost::size(v) == 9); // {0,1,3..9}
BOOST_CHECK(bgr::at(v, 1) == 1);
BOOST_CHECK(bgr::at(v, 2) == 3);
@ -175,6 +240,38 @@ void test_all()
BOOST_CHECK(it == end(v));
}
template <typename T, typename Begin, typename End>
void test_erase(std::vector<bgt::NonCopyable> & , Begin , End )
{}
template <typename T>
void test_all()
{
std::vector<T> v;
test_push_emplace(v);
BOOST_CHECK(boost::size(v) == 20);
test_at_front_back(v);
test_at_front_back(const_cast<std::vector<T> const&>(v));
test_clear(v);
test_resize_pop(v);
int n = (int)v.size();
test_erase(v, [](auto & rng) { return boost::begin(rng); },
[](auto & rng) { return boost::end(rng); });
bgr::clear(v);
fill(v, n);
test_erase(v, [](auto & rng) { return boost::const_begin(rng); },
[](auto & rng) { return boost::const_end(rng); });
}
void test_detail()
{
int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
@ -186,18 +283,6 @@ void test_detail()
BOOST_CHECK(boost::size(v) == 10);
bgr::erase(v, v.begin() + 1);
BOOST_CHECK(boost::size(v) == 9);
bgt::NonMovable * arr2[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
bgt::NonMovable foo;
arr2[1] = &foo;
std::move(arr2 + 1, arr2 + 10, arr2);
BOOST_CHECK(arr2[0] == &foo);
std::vector<bgt::NonMovable*> v2(10, (bgt::NonMovable*)NULL);
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);
}
template <class Iterator>
@ -218,17 +303,12 @@ void test_pointers()
int test_main(int, char* [])
{
test_all<int, true>();
test_all<int, false>();
// Storing non-movable elements in a std::vector is not possible in some implementations of STD lib
#ifdef BOOST_GEOMETRY_TEST_NONMOVABLE_ELEMENTS
test_all<bgt::NonMovable, true>();
test_all<bgt::NonMovable, false>();
#endif
test_all<bgt::CopyableAndMovable, true>();
test_all<bgt::CopyableAndMovable, false>();
test_all<int>();
test_all<bgt::CopyableAndMovable>();
test_all<bgt::NonCopyable>();
test_detail();
test_pointers<int*>();
test_pointers<int const*>();