mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-09 15:14:02 +00:00
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:
parent
14aa054593
commit
2fc1a3fe8f
@ -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
|
||||
{
|
||||
|
@ -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 == ",")
|
||||
|
@ -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> ));
|
||||
|
||||
|
@ -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*>();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user