annotate DEPENDENCIES/generic/include/boost/geometry/util/range.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents f46d142149f5
children
rev   line source
Chris@102 1 // Boost.Geometry (aka GGL, Generic Geometry Library)
Chris@102 2
Chris@102 3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
Chris@102 4
Chris@102 5 // This file was modified by Oracle on 2013, 2014, 2015.
Chris@102 6 // Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
Chris@102 7
Chris@102 8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
Chris@102 9
Chris@102 10 // Use, modification and distribution is subject to the Boost Software License,
Chris@102 11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@102 12 // http://www.boost.org/LICENSE_1_0.txt)
Chris@102 13
Chris@102 14 #ifndef BOOST_GEOMETRY_UTIL_RANGE_HPP
Chris@102 15 #define BOOST_GEOMETRY_UTIL_RANGE_HPP
Chris@102 16
Chris@102 17 #include <algorithm>
Chris@102 18
Chris@102 19 #include <boost/assert.hpp>
Chris@102 20 #include <boost/concept_check.hpp>
Chris@102 21 #include <boost/config.hpp>
Chris@102 22 #include <boost/range/concepts.hpp>
Chris@102 23 #include <boost/range/begin.hpp>
Chris@102 24 #include <boost/range/end.hpp>
Chris@102 25 #include <boost/range/empty.hpp>
Chris@102 26 #include <boost/range/size.hpp>
Chris@102 27 #include <boost/type_traits/is_convertible.hpp>
Chris@102 28
Chris@102 29 #include <boost/geometry/core/mutable_range.hpp>
Chris@102 30
Chris@102 31 namespace boost { namespace geometry { namespace range {
Chris@102 32
Chris@102 33 namespace detail {
Chris@102 34
Chris@102 35 // NOTE: For SinglePassRanges pos could iterate over all elements until the i-th element was met.
Chris@102 36
Chris@102 37 template <typename RandomAccessRange>
Chris@102 38 struct pos
Chris@102 39 {
Chris@102 40 typedef typename boost::range_iterator<RandomAccessRange>::type iterator;
Chris@102 41 typedef typename boost::range_size<RandomAccessRange>::type size_type;
Chris@102 42 typedef typename boost::range_difference<RandomAccessRange>::type difference_type;
Chris@102 43
Chris@102 44 static inline iterator apply(RandomAccessRange & rng, size_type i)
Chris@102 45 {
Chris@102 46 BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<RandomAccessRange> ));
Chris@102 47 return boost::begin(rng) + static_cast<difference_type>(i);
Chris@102 48 }
Chris@102 49 };
Chris@102 50
Chris@102 51 } // namespace detail
Chris@102 52
Chris@102 53 /*!
Chris@102 54 \brief Short utility to conveniently return an iterator of a RandomAccessRange.
Chris@102 55 \ingroup utility
Chris@102 56 */
Chris@102 57 template <typename RandomAccessRange>
Chris@102 58 inline typename boost::range_iterator<RandomAccessRange const>::type
Chris@102 59 pos(RandomAccessRange const& rng,
Chris@102 60 typename boost::range_size<RandomAccessRange const>::type i)
Chris@102 61 {
Chris@102 62 BOOST_ASSERT(i <= boost::size(rng));
Chris@102 63 return detail::pos<RandomAccessRange const>::apply(rng, i);
Chris@102 64 }
Chris@102 65
Chris@102 66 /*!
Chris@102 67 \brief Short utility to conveniently return an iterator of a RandomAccessRange.
Chris@102 68 \ingroup utility
Chris@102 69 */
Chris@102 70 template <typename RandomAccessRange>
Chris@102 71 inline typename boost::range_iterator<RandomAccessRange>::type
Chris@102 72 pos(RandomAccessRange & rng,
Chris@102 73 typename boost::range_size<RandomAccessRange>::type i)
Chris@102 74 {
Chris@102 75 BOOST_ASSERT(i <= boost::size(rng));
Chris@102 76 return detail::pos<RandomAccessRange>::apply(rng, i);
Chris@102 77 }
Chris@102 78
Chris@102 79 /*!
Chris@102 80 \brief Short utility to conveniently return an element of a RandomAccessRange.
Chris@102 81 \ingroup utility
Chris@102 82 */
Chris@102 83 template <typename RandomAccessRange>
Chris@102 84 inline typename boost::range_reference<RandomAccessRange const>::type
Chris@102 85 at(RandomAccessRange const& rng,
Chris@102 86 typename boost::range_size<RandomAccessRange const>::type i)
Chris@102 87 {
Chris@102 88 BOOST_ASSERT(i < boost::size(rng));
Chris@102 89 return * detail::pos<RandomAccessRange const>::apply(rng, i);
Chris@102 90 }
Chris@102 91
Chris@102 92 /*!
Chris@102 93 \brief Short utility to conveniently return an element of a RandomAccessRange.
Chris@102 94 \ingroup utility
Chris@102 95 */
Chris@102 96 template <typename RandomAccessRange>
Chris@102 97 inline typename boost::range_reference<RandomAccessRange>::type
Chris@102 98 at(RandomAccessRange & rng,
Chris@102 99 typename boost::range_size<RandomAccessRange>::type i)
Chris@102 100 {
Chris@102 101 BOOST_ASSERT(i < boost::size(rng));
Chris@102 102 return * detail::pos<RandomAccessRange>::apply(rng, i);
Chris@102 103 }
Chris@102 104
Chris@102 105 /*!
Chris@102 106 \brief Short utility to conveniently return the front element of a Range.
Chris@102 107 \ingroup utility
Chris@102 108 */
Chris@102 109 template <typename Range>
Chris@102 110 inline typename boost::range_reference<Range const>::type
Chris@102 111 front(Range const& rng)
Chris@102 112 {
Chris@102 113 BOOST_ASSERT(!boost::empty(rng));
Chris@102 114 return *boost::begin(rng);
Chris@102 115 }
Chris@102 116
Chris@102 117 /*!
Chris@102 118 \brief Short utility to conveniently return the front element of a Range.
Chris@102 119 \ingroup utility
Chris@102 120 */
Chris@102 121 template <typename Range>
Chris@102 122 inline typename boost::range_reference<Range>::type
Chris@102 123 front(Range & rng)
Chris@102 124 {
Chris@102 125 BOOST_ASSERT(!boost::empty(rng));
Chris@102 126 return *boost::begin(rng);
Chris@102 127 }
Chris@102 128
Chris@102 129 // NOTE: For SinglePassRanges back() could iterate over all elements until the last element is met.
Chris@102 130
Chris@102 131 /*!
Chris@102 132 \brief Short utility to conveniently return the back element of a BidirectionalRange.
Chris@102 133 \ingroup utility
Chris@102 134 */
Chris@102 135 template <typename BidirectionalRange>
Chris@102 136 inline typename boost::range_reference<BidirectionalRange const>::type
Chris@102 137 back(BidirectionalRange const& rng)
Chris@102 138 {
Chris@102 139 BOOST_RANGE_CONCEPT_ASSERT(( boost::BidirectionalRangeConcept<BidirectionalRange const> ));
Chris@102 140 BOOST_ASSERT(!boost::empty(rng));
Chris@102 141 return *(boost::rbegin(rng));
Chris@102 142 }
Chris@102 143
Chris@102 144 /*!
Chris@102 145 \brief Short utility to conveniently return the back element of a BidirectionalRange.
Chris@102 146 \ingroup utility
Chris@102 147 */
Chris@102 148 template <typename BidirectionalRange>
Chris@102 149 inline typename boost::range_reference<BidirectionalRange>::type
Chris@102 150 back(BidirectionalRange & rng)
Chris@102 151 {
Chris@102 152 BOOST_RANGE_CONCEPT_ASSERT((boost::BidirectionalRangeConcept<BidirectionalRange>));
Chris@102 153 BOOST_ASSERT(!boost::empty(rng));
Chris@102 154 return *(boost::rbegin(rng));
Chris@102 155 }
Chris@102 156
Chris@102 157
Chris@102 158 /*!
Chris@102 159 \brief Short utility to conveniently clear a mutable range.
Chris@102 160 It uses traits::clear<>.
Chris@102 161 \ingroup utility
Chris@102 162 */
Chris@102 163 template <typename Range>
Chris@102 164 inline void clear(Range & rng)
Chris@102 165 {
Chris@102 166 // NOTE: this trait is probably not needed since it could be implemented using resize()
Chris@102 167 geometry::traits::clear<Range>::apply(rng);
Chris@102 168 }
Chris@102 169
Chris@102 170 /*!
Chris@102 171 \brief Short utility to conveniently insert a new element at the end of a mutable range.
Chris@102 172 It uses boost::geometry::traits::push_back<>.
Chris@102 173 \ingroup utility
Chris@102 174 */
Chris@102 175 template <typename Range>
Chris@102 176 inline void push_back(Range & rng,
Chris@102 177 typename boost::range_value<Range>::type const& value)
Chris@102 178 {
Chris@102 179 geometry::traits::push_back<Range>::apply(rng, value);
Chris@102 180 }
Chris@102 181
Chris@102 182 /*!
Chris@102 183 \brief Short utility to conveniently resize a mutable range.
Chris@102 184 It uses boost::geometry::traits::resize<>.
Chris@102 185 \ingroup utility
Chris@102 186 */
Chris@102 187 template <typename Range>
Chris@102 188 inline void resize(Range & rng,
Chris@102 189 typename boost::range_size<Range>::type new_size)
Chris@102 190 {
Chris@102 191 geometry::traits::resize<Range>::apply(rng, new_size);
Chris@102 192 }
Chris@102 193
Chris@102 194
Chris@102 195 /*!
Chris@102 196 \brief Short utility to conveniently remove an element from the back of a mutable range.
Chris@102 197 It uses resize().
Chris@102 198 \ingroup utility
Chris@102 199 */
Chris@102 200 template <typename Range>
Chris@102 201 inline void pop_back(Range & rng)
Chris@102 202 {
Chris@102 203 BOOST_ASSERT(!boost::empty(rng));
Chris@102 204 range::resize(rng, boost::size(rng) - 1);
Chris@102 205 }
Chris@102 206
Chris@102 207 namespace detail {
Chris@102 208
Chris@102 209 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@102 210
Chris@102 211 template <typename It,
Chris@102 212 typename OutIt,
Chris@102 213 bool UseMove = boost::is_convertible
Chris@102 214 <
Chris@102 215 typename std::iterator_traits<It>::value_type &&,
Chris@102 216 typename std::iterator_traits<OutIt>::value_type
Chris@102 217 >::value>
Chris@102 218 struct copy_or_move_impl
Chris@102 219 {
Chris@102 220 static inline OutIt apply(It first, It last, OutIt out)
Chris@102 221 {
Chris@102 222 return std::move(first, last, out);
Chris@102 223 }
Chris@102 224 };
Chris@102 225
Chris@102 226 template <typename It, typename OutIt>
Chris@102 227 struct copy_or_move_impl<It, OutIt, false>
Chris@102 228 {
Chris@102 229 static inline OutIt apply(It first, It last, OutIt out)
Chris@102 230 {
Chris@102 231 return std::copy(first, last, out);
Chris@102 232 }
Chris@102 233 };
Chris@102 234
Chris@102 235 template <typename It, typename OutIt>
Chris@102 236 inline OutIt copy_or_move(It first, It last, OutIt out)
Chris@102 237 {
Chris@102 238 return copy_or_move_impl<It, OutIt>::apply(first, last, out);
Chris@102 239 }
Chris@102 240
Chris@102 241 #else
Chris@102 242
Chris@102 243 template <typename It, typename OutIt>
Chris@102 244 inline OutIt copy_or_move(It first, It last, OutIt out)
Chris@102 245 {
Chris@102 246 return std::copy(first, last, out);
Chris@102 247 }
Chris@102 248
Chris@102 249 #endif
Chris@102 250
Chris@102 251 } // namespace detail
Chris@102 252
Chris@102 253 /*!
Chris@102 254 \brief Short utility to conveniently remove an element from a mutable range.
Chris@102 255 It uses std::copy() and resize(). Version taking mutable iterators.
Chris@102 256 \ingroup utility
Chris@102 257 */
Chris@102 258 template <typename Range>
Chris@102 259 inline typename boost::range_iterator<Range>::type
Chris@102 260 erase(Range & rng,
Chris@102 261 typename boost::range_iterator<Range>::type it)
Chris@102 262 {
Chris@102 263 BOOST_ASSERT(!boost::empty(rng));
Chris@102 264 BOOST_ASSERT(it != boost::end(rng));
Chris@102 265
Chris@102 266 typename boost::range_difference<Range>::type const
Chris@102 267 d = std::distance(boost::begin(rng), it);
Chris@102 268
Chris@102 269 typename boost::range_iterator<Range>::type
Chris@102 270 next = it;
Chris@102 271 ++next;
Chris@102 272
Chris@102 273 detail::copy_or_move(next, boost::end(rng), it);
Chris@102 274 range::resize(rng, boost::size(rng) - 1);
Chris@102 275
Chris@102 276 // NOTE: In general this should be sufficient:
Chris@102 277 // return it;
Chris@102 278 // But in MSVC using the returned iterator causes
Chris@102 279 // assertion failures when iterator debugging is enabled
Chris@102 280 // Furthermore the code below should work in the case if resize()
Chris@102 281 // invalidates iterators when the container is resized down.
Chris@102 282 return boost::begin(rng) + d;
Chris@102 283 }
Chris@102 284
Chris@102 285 /*!
Chris@102 286 \brief Short utility to conveniently remove an element from a mutable range.
Chris@102 287 It uses std::copy() and resize(). Version taking non-mutable iterators.
Chris@102 288 \ingroup utility
Chris@102 289 */
Chris@102 290 template <typename Range>
Chris@102 291 inline typename boost::range_iterator<Range>::type
Chris@102 292 erase(Range & rng,
Chris@102 293 typename boost::range_iterator<Range const>::type cit)
Chris@102 294 {
Chris@102 295 BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<Range> ));
Chris@102 296
Chris@102 297 typename boost::range_iterator<Range>::type
Chris@102 298 it = boost::begin(rng)
Chris@102 299 + std::distance(boost::const_begin(rng), cit);
Chris@102 300
Chris@102 301 return erase(rng, it);
Chris@102 302 }
Chris@102 303
Chris@102 304 /*!
Chris@102 305 \brief Short utility to conveniently remove a range of elements from a mutable range.
Chris@102 306 It uses std::copy() and resize(). Version taking mutable iterators.
Chris@102 307 \ingroup utility
Chris@102 308 */
Chris@102 309 template <typename Range>
Chris@102 310 inline typename boost::range_iterator<Range>::type
Chris@102 311 erase(Range & rng,
Chris@102 312 typename boost::range_iterator<Range>::type first,
Chris@102 313 typename boost::range_iterator<Range>::type last)
Chris@102 314 {
Chris@102 315 typename boost::range_difference<Range>::type const
Chris@102 316 diff = std::distance(first, last);
Chris@102 317 BOOST_ASSERT(diff >= 0);
Chris@102 318
Chris@102 319 std::size_t const count = static_cast<std::size_t>(diff);
Chris@102 320 BOOST_ASSERT(count <= boost::size(rng));
Chris@102 321
Chris@102 322 if ( count > 0 )
Chris@102 323 {
Chris@102 324 typename boost::range_difference<Range>::type const
Chris@102 325 d = std::distance(boost::begin(rng), first);
Chris@102 326
Chris@102 327 detail::copy_or_move(last, boost::end(rng), first);
Chris@102 328 range::resize(rng, boost::size(rng) - count);
Chris@102 329
Chris@102 330 // NOTE: In general this should be sufficient:
Chris@102 331 // return first;
Chris@102 332 // But in MSVC using the returned iterator causes
Chris@102 333 // assertion failures when iterator debugging is enabled
Chris@102 334 // Furthermore the code below should work in the case if resize()
Chris@102 335 // invalidates iterators when the container is resized down.
Chris@102 336 return boost::begin(rng) + d;
Chris@102 337 }
Chris@102 338
Chris@102 339 return first;
Chris@102 340 }
Chris@102 341
Chris@102 342 /*!
Chris@102 343 \brief Short utility to conveniently remove a range of elements from a mutable range.
Chris@102 344 It uses std::copy() and resize(). Version taking non-mutable iterators.
Chris@102 345 \ingroup utility
Chris@102 346 */
Chris@102 347 template <typename Range>
Chris@102 348 inline typename boost::range_iterator<Range>::type
Chris@102 349 erase(Range & rng,
Chris@102 350 typename boost::range_iterator<Range const>::type cfirst,
Chris@102 351 typename boost::range_iterator<Range const>::type clast)
Chris@102 352 {
Chris@102 353 BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept<Range> ));
Chris@102 354
Chris@102 355 typename boost::range_iterator<Range>::type
Chris@102 356 first = boost::begin(rng)
Chris@102 357 + std::distance(boost::const_begin(rng), cfirst);
Chris@102 358 typename boost::range_iterator<Range>::type
Chris@102 359 last = boost::begin(rng)
Chris@102 360 + std::distance(boost::const_begin(rng), clast);
Chris@102 361
Chris@102 362 return erase(rng, first, last);
Chris@102 363 }
Chris@102 364
Chris@102 365 }}} // namespace boost::geometry::range
Chris@102 366
Chris@102 367 #endif // BOOST_GEOMETRY_UTIL_RANGE_HPP