/usr/include/boost/geometry/util
Edit: /usr/include/boost/geometry/util/range.hpp (12445B)
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013, 2014, 2015, 2016, 2019.
// Modifications copyright (c) 2013-2019 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)
#ifndef BOOST_GEOMETRY_UTIL_RANGE_HPP
#define BOOST_GEOMETRY_UTIL_RANGE_HPP
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace boost { namespace geometry { namespace range {
namespace detail {
// NOTE: For SinglePassRanges pos could iterate over all elements until the i-th element was met.
template
struct pos
{
typedef typename boost::range_iterator::type iterator;
typedef typename boost::range_size::type size_type;
typedef typename boost::range_difference::type difference_type;
static inline iterator apply(RandomAccessRange & rng, size_type i)
{
BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept ));
return boost::begin(rng) + static_cast(i);
}
};
} // namespace detail
/*!
\brief Short utility to conveniently return an iterator of a RandomAccessRange.
\ingroup utility
*/
template
inline typename boost::range_iterator::type
pos(RandomAccessRange const& rng,
typename boost::range_size::type i)
{
BOOST_GEOMETRY_ASSERT(i <= boost::size(rng));
return detail::pos::apply(rng, i);
}
/*!
\brief Short utility to conveniently return an iterator of a RandomAccessRange.
\ingroup utility
*/
template
inline typename boost::range_iterator::type
pos(RandomAccessRange & rng,
typename boost::range_size::type i)
{
BOOST_GEOMETRY_ASSERT(i <= boost::size(rng));
return detail::pos::apply(rng, i);
}
/*!
\brief Short utility to conveniently return an element of a RandomAccessRange.
\ingroup utility
*/
template
inline typename boost::range_reference::type
at(RandomAccessRange const& rng,
typename boost::range_size::type i)
{
BOOST_GEOMETRY_ASSERT(i < boost::size(rng));
return * detail::pos::apply(rng, i);
}
/*!
\brief Short utility to conveniently return an element of a RandomAccessRange.
\ingroup utility
*/
template
inline typename boost::range_reference::type
at(RandomAccessRange & rng,
typename boost::range_size::type i)
{
BOOST_GEOMETRY_ASSERT(i < boost::size(rng));
return * detail::pos::apply(rng, i);
}
/*!
\brief Short utility to conveniently return the front element of a Range.
\ingroup utility
*/
template
inline typename boost::range_reference::type
front(Range const& rng)
{
BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
return *boost::begin(rng);
}
/*!
\brief Short utility to conveniently return the front element of a Range.
\ingroup utility
*/
template
inline typename boost::range_reference::type
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
inline typename boost::range_reference::type
back(BidirectionalRange const& rng)
{
BOOST_RANGE_CONCEPT_ASSERT(( boost::BidirectionalRangeConcept ));
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
inline typename boost::range_reference::type
back(BidirectionalRange & rng)
{
BOOST_RANGE_CONCEPT_ASSERT((boost::BidirectionalRangeConcept));
BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
return *(boost::rbegin(rng));
}
/*!
\brief Short utility to conveniently clear a mutable range.
It uses traits::clear<>.
\ingroup utility
*/
template
inline void clear(Range & rng)
{
// NOTE: this trait is probably not needed since it could be implemented using resize()
geometry::traits::clear::apply(rng);
}
/*!
\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 const& value)
{
geometry::traits::push_back::apply(rng, value);
}
/*!
\brief Short utility to conveniently resize a mutable range.
It uses boost::geometry::traits::resize<>.
\ingroup utility
*/
template
inline void resize(Range & rng,
typename boost::range_size::type new_size)
{
geometry::traits::resize::apply(rng, new_size);
}
/*!
\brief Short utility to conveniently remove an element from the back of a mutable range.
It uses resize().
\ingroup utility
*/
template
inline void pop_back(Range & rng)
{
BOOST_GEOMETRY_ASSERT(!boost::empty(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.
\ingroup utility
*/
template
inline typename boost::range_iterator::type
erase(Range & rng,
typename boost::range_iterator::type it)
{
BOOST_GEOMETRY_ASSERT(!boost::empty(rng));
BOOST_GEOMETRY_ASSERT(it != boost::end(rng));
typename boost::range_difference::type const
d = std::distance(boost::begin(rng), it);
typename boost::range_iterator::type
next = it;
++next;
detail::copy_or_move(next, boost::end(rng), it);
range::resize(rng, boost::size(rng) - 1);
// NOTE: In general this should be sufficient:
// return it;
// But in MSVC using the returned iterator causes
// assertion failures when iterator debugging is enabled
// Furthermore the code below should work in the case if resize()
// invalidates iterators when the container is resized down.
return boost::begin(rng) + d;
}
/*!
\brief Short utility to conveniently remove an element from a mutable range.
It uses std::copy() and resize(). Version taking non-mutable iterators.
\ingroup utility
*/
template
inline typename boost::range_iterator::type
erase(Range & rng,
typename boost::range_iterator::type cit)
{
BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept ));
typename boost::range_iterator::type
it = boost::begin(rng)
+ std::distance(boost::const_begin(rng), cit);
return range::erase(rng, it);
}
/*!
\brief Short utility to conveniently remove a range of elements from a mutable range.
It uses std::copy() and resize(). Version taking mutable iterators.
\ingroup utility
*/
template
inline typename boost::range_iterator::type
erase(Range & rng,
typename boost::range_iterator::type first,
typename boost::range_iterator::type last)
{
typename boost::range_difference::type const
diff = std::distance(first, last);
BOOST_GEOMETRY_ASSERT(diff >= 0);
std::size_t const count = static_cast(diff);
BOOST_GEOMETRY_ASSERT(count <= boost::size(rng));
if ( count > 0 )
{
typename boost::range_difference::type const
d = std::distance(boost::begin(rng), first);
detail::copy_or_move(last, boost::end(rng), first);
range::resize(rng, boost::size(rng) - count);
// NOTE: In general this should be sufficient:
// return first;
// But in MSVC using the returned iterator causes
// assertion failures when iterator debugging is enabled
// Furthermore the code below should work in the case if resize()
// invalidates iterators when the container is resized down.
return boost::begin(rng) + d;
}
return first;
}
/*!
\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.
\ingroup utility
*/
template
inline typename boost::range_iterator::type
erase(Range & rng,
typename boost::range_iterator::type cfirst,
typename boost::range_iterator::type clast)
{
BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept ));
typename boost::range_iterator::type
first = boost::begin(rng)
+ std::distance(boost::const_begin(rng), cfirst);
typename boost::range_iterator::type
last = boost::begin(rng)
+ std::distance(boost::const_begin(rng), clast);
return range::erase(rng, first, last);
}
// back_inserter
template
class back_insert_iterator
{
public:
typedef std::output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
typedef Container container_type;
explicit back_insert_iterator(Container & c)
: container(boost::addressof(c))
{}
back_insert_iterator & operator=(typename Container::value_type const& value)
{
range::push_back(*container, value);
return *this;
}
back_insert_iterator & operator* ()
{
return *this;
}
back_insert_iterator & operator++ ()
{
return *this;
}
back_insert_iterator operator++(int)
{
return *this;
}
private:
Container * container;
};
template
inline back_insert_iterator back_inserter(Range & rng)
{
return back_insert_iterator(rng);
}
}}} // namespace boost::geometry::range
#endif // BOOST_GEOMETRY_UTIL_RANGE_HPP