annotate DEPENDENCIES/generic/include/boost/geometry/index/detail/varray.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
rev   line source
Chris@16 1 // Boost.Container varray
Chris@16 2 //
Chris@16 3 // Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
Chris@16 4 // Copyright (c) 2011-2013 Andrew Hundt.
Chris@16 5 //
Chris@16 6 // Use, modification and distribution is subject to the Boost Software License,
Chris@16 7 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 8 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 9
Chris@16 10 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_HPP
Chris@16 11 #define BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_HPP
Chris@16 12
Chris@16 13 // TODO - REMOVE/CHANGE
Chris@16 14 #include <boost/container/detail/config_begin.hpp>
Chris@16 15 #include <boost/container/detail/workaround.hpp>
Chris@16 16 #include <boost/container/detail/preprocessor.hpp>
Chris@16 17
Chris@16 18 #include <boost/config.hpp>
Chris@16 19 #include <boost/swap.hpp>
Chris@16 20 #include <boost/integer.hpp>
Chris@16 21
Chris@16 22 #include <boost/mpl/assert.hpp>
Chris@16 23
Chris@16 24 #include <boost/type_traits/is_unsigned.hpp>
Chris@16 25 #include <boost/type_traits/alignment_of.hpp>
Chris@16 26 #include <boost/type_traits/aligned_storage.hpp>
Chris@16 27
Chris@16 28 // TODO - use std::reverse_iterator and std::iterator_traits
Chris@16 29 // instead Boost.Iterator to remove dependency?
Chris@16 30 // or boost/detail/iterator.hpp ?
Chris@16 31 #include <boost/iterator/reverse_iterator.hpp>
Chris@16 32 #include <boost/iterator/iterator_concepts.hpp>
Chris@16 33
Chris@16 34 #include <boost/geometry/index/detail/assert.hpp>
Chris@16 35
Chris@16 36 #include <boost/geometry/index/detail/assert.hpp>
Chris@16 37 #include <boost/geometry/index/detail/varray_detail.hpp>
Chris@16 38
Chris@16 39 #include <boost/concept_check.hpp>
Chris@16 40 #include <boost/throw_exception.hpp>
Chris@16 41
Chris@16 42 /*!
Chris@16 43 \defgroup varray_non_member varray non-member functions
Chris@16 44 */
Chris@16 45
Chris@16 46 namespace boost { namespace geometry { namespace index { namespace detail {
Chris@16 47
Chris@16 48 namespace varray_detail {
Chris@16 49
Chris@16 50 template <typename Value, std::size_t Capacity>
Chris@16 51 struct varray_traits
Chris@16 52 {
Chris@16 53 typedef Value value_type;
Chris@16 54 typedef std::size_t size_type;
Chris@16 55 typedef std::ptrdiff_t difference_type;
Chris@16 56 typedef Value * pointer;
Chris@16 57 typedef const Value * const_pointer;
Chris@16 58 typedef Value & reference;
Chris@16 59 typedef const Value & const_reference;
Chris@16 60
Chris@16 61 typedef boost::false_type use_memop_in_swap_and_move;
Chris@16 62 typedef boost::false_type use_optimized_swap;
Chris@16 63 typedef boost::false_type disable_trivial_init;
Chris@16 64 };
Chris@16 65
Chris@16 66 template <typename Varray>
Chris@16 67 struct checker
Chris@16 68 {
Chris@16 69 typedef typename Varray::size_type size_type;
Chris@16 70 typedef typename Varray::const_iterator const_iterator;
Chris@16 71
Chris@16 72 static inline void check_capacity(Varray const& v, size_type s)
Chris@16 73 {
Chris@16 74 BOOST_GEOMETRY_INDEX_ASSERT(s <= v.capacity(), "size too big");
Chris@16 75
Chris@16 76 ::boost::ignore_unused_variable_warning(v);
Chris@16 77 ::boost::ignore_unused_variable_warning(s);
Chris@16 78 }
Chris@16 79
Chris@16 80 static inline void throw_out_of_bounds(Varray const& v, size_type i)
Chris@16 81 {
Chris@16 82 //#ifndef BOOST_NO_EXCEPTIONS
Chris@16 83 if ( v.size() <= i )
Chris@16 84 BOOST_THROW_EXCEPTION(std::out_of_range("index out of bounds"));
Chris@16 85 //#else // BOOST_NO_EXCEPTIONS
Chris@16 86 // BOOST_GEOMETRY_INDEX_ASSERT(i < v.size(), "index out of bounds");
Chris@16 87 //#endif // BOOST_NO_EXCEPTIONS
Chris@16 88
Chris@16 89 ::boost::ignore_unused_variable_warning(v);
Chris@16 90 ::boost::ignore_unused_variable_warning(i);
Chris@16 91 }
Chris@16 92
Chris@16 93 static inline void check_index(Varray const& v, size_type i)
Chris@16 94 {
Chris@16 95 BOOST_GEOMETRY_INDEX_ASSERT(i < v.size(), "index out of bounds");
Chris@16 96
Chris@16 97 ::boost::ignore_unused_variable_warning(v);
Chris@16 98 ::boost::ignore_unused_variable_warning(i);
Chris@16 99 }
Chris@16 100
Chris@16 101 static inline void check_not_empty(Varray const& v)
Chris@16 102 {
Chris@16 103 BOOST_GEOMETRY_INDEX_ASSERT(!v.empty(), "the container is empty");
Chris@16 104
Chris@16 105 ::boost::ignore_unused_variable_warning(v);
Chris@16 106 }
Chris@16 107
Chris@16 108 static inline void check_iterator_end_neq(Varray const& v, const_iterator position)
Chris@16 109 {
Chris@16 110 BOOST_GEOMETRY_INDEX_ASSERT(v.begin() <= position && position < v.end(), "iterator out of bounds");
Chris@16 111
Chris@16 112 ::boost::ignore_unused_variable_warning(v);
Chris@16 113 ::boost::ignore_unused_variable_warning(position);
Chris@16 114 }
Chris@16 115
Chris@16 116 static inline void check_iterator_end_eq(Varray const& v, const_iterator position)
Chris@16 117 {
Chris@16 118 BOOST_GEOMETRY_INDEX_ASSERT(v.begin() <= position && position <= v.end(), "iterator out of bounds");
Chris@16 119
Chris@16 120 ::boost::ignore_unused_variable_warning(v);
Chris@16 121 ::boost::ignore_unused_variable_warning(position);
Chris@16 122 }
Chris@16 123 };
Chris@16 124
Chris@16 125 } // namespace varray_detail
Chris@16 126
Chris@16 127 /*!
Chris@16 128 \brief A variable-size array container with fixed capacity.
Chris@16 129
Chris@16 130 varray is a sequence container like boost::container::vector with contiguous storage that can
Chris@16 131 change in size, along with the static allocation, low overhead, and fixed capacity of boost::array.
Chris@16 132
Chris@16 133 A varray is a sequence that supports random access to elements, constant time insertion and
Chris@16 134 removal of elements at the end, and linear time insertion and removal of elements at the beginning or
Chris@16 135 in the middle. The number of elements in a varray may vary dynamically up to a fixed capacity
Chris@16 136 because elements are stored within the object itself similarly to an array. However, objects are
Chris@16 137 initialized as they are inserted into varray unlike C arrays or std::array which must construct
Chris@16 138 all elements on instantiation. The behavior of varray enables the use of statically allocated
Chris@16 139 elements in cases with complex object lifetime requirements that would otherwise not be trivially
Chris@16 140 possible.
Chris@16 141
Chris@16 142 \par Error Handling
Chris@16 143 Insertion beyond the capacity and out of bounds errors result in undefined behavior unless
Chris@16 144 otherwise specified. In this respect if size() == capacity(), then varray::push_back()
Chris@16 145 behaves like std::vector pop_front() if size() == empty(). The reason for this difference
Chris@16 146 is because unlike vectors, varray does not perform allocation.
Chris@16 147
Chris@16 148 \par Advanced Usage
Chris@16 149 Error handling behavior can be modified to more closely match std::vector exception behavior
Chris@16 150 when exceeding bounds by providing an alternate Strategy and varray_traits instantiation.
Chris@16 151
Chris@16 152 \tparam Value The type of element that will be stored.
Chris@16 153 \tparam Capacity The maximum number of elements varray can store, fixed at compile time.
Chris@16 154 \tparam Strategy Defines the public typedefs and error handlers,
Chris@16 155 implements StaticVectorStrategy and has some similarities
Chris@16 156 to an Allocator.
Chris@16 157 */
Chris@16 158 template <typename Value, std::size_t Capacity>
Chris@16 159 class varray
Chris@16 160 {
Chris@16 161 typedef varray_detail::varray_traits<Value, Capacity> vt;
Chris@16 162 typedef varray_detail::checker<varray> errh;
Chris@16 163
Chris@16 164 BOOST_MPL_ASSERT_MSG(
Chris@16 165 ( boost::is_unsigned<typename vt::size_type>::value &&
Chris@16 166 sizeof(typename boost::uint_value_t<Capacity>::least) <= sizeof(typename vt::size_type) ),
Chris@16 167 SIZE_TYPE_IS_TOO_SMALL_FOR_SPECIFIED_CAPACITY,
Chris@16 168 (varray)
Chris@16 169 );
Chris@16 170
Chris@16 171 typedef boost::aligned_storage<
Chris@16 172 sizeof(Value[Capacity]),
Chris@16 173 boost::alignment_of<Value[Capacity]>::value
Chris@16 174 > aligned_storage_type;
Chris@16 175
Chris@16 176 template <typename V, std::size_t C>
Chris@16 177 friend class varray;
Chris@16 178
Chris@16 179 BOOST_COPYABLE_AND_MOVABLE(varray)
Chris@16 180
Chris@16 181 #ifdef BOOST_NO_RVALUE_REFERENCES
Chris@16 182 public:
Chris@16 183 template <std::size_t C>
Chris@16 184 varray & operator=(varray<Value, C> & sv)
Chris@16 185 {
Chris@16 186 typedef varray<Value, C> other;
Chris@16 187 this->operator=(static_cast<const ::boost::rv<other> &>(const_cast<const other &>(sv)));
Chris@16 188 return *this;
Chris@16 189 }
Chris@16 190 #endif
Chris@16 191
Chris@16 192 public:
Chris@16 193 //! @brief The type of elements stored in the container.
Chris@16 194 typedef typename vt::value_type value_type;
Chris@16 195 //! @brief The unsigned integral type used by the container.
Chris@16 196 typedef typename vt::size_type size_type;
Chris@16 197 //! @brief The pointers difference type.
Chris@16 198 typedef typename vt::difference_type difference_type;
Chris@16 199 //! @brief The pointer type.
Chris@16 200 typedef typename vt::pointer pointer;
Chris@16 201 //! @brief The const pointer type.
Chris@16 202 typedef typename vt::const_pointer const_pointer;
Chris@16 203 //! @brief The value reference type.
Chris@16 204 typedef typename vt::reference reference;
Chris@16 205 //! @brief The value const reference type.
Chris@16 206 typedef typename vt::const_reference const_reference;
Chris@16 207
Chris@16 208 //! @brief The iterator type.
Chris@16 209 typedef pointer iterator;
Chris@16 210 //! @brief The const iterator type.
Chris@16 211 typedef const_pointer const_iterator;
Chris@16 212 //! @brief The reverse iterator type.
Chris@16 213 typedef boost::reverse_iterator<iterator> reverse_iterator;
Chris@16 214 //! @brief The const reverse iterator.
Chris@16 215 typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
Chris@16 216
Chris@16 217 //! @brief Constructs an empty varray.
Chris@16 218 //!
Chris@16 219 //! @par Throws
Chris@16 220 //! Nothing.
Chris@16 221 //!
Chris@16 222 //! @par Complexity
Chris@16 223 //! Constant O(1).
Chris@16 224 varray()
Chris@16 225 : m_size(0)
Chris@16 226 {}
Chris@16 227
Chris@16 228 //! @pre <tt>count <= capacity()</tt>
Chris@16 229 //!
Chris@16 230 //! @brief Constructs a varray containing count default constructed Values.
Chris@16 231 //!
Chris@16 232 //! @param count The number of values which will be contained in the container.
Chris@16 233 //!
Chris@16 234 //! @par Throws
Chris@16 235 //! If Value's default constructor throws.
Chris@16 236 //! @internal
Chris@16 237 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 238 //! @endinternal
Chris@16 239 //!
Chris@16 240 //! @par Complexity
Chris@16 241 //! Linear O(N).
Chris@16 242 explicit varray(size_type count)
Chris@16 243 : m_size(0)
Chris@16 244 {
Chris@16 245 this->resize(count); // may throw
Chris@16 246 }
Chris@16 247
Chris@16 248 //! @pre <tt>count <= capacity()</tt>
Chris@16 249 //!
Chris@16 250 //! @brief Constructs a varray containing count copies of value.
Chris@16 251 //!
Chris@16 252 //! @param count The number of copies of a values that will be contained in the container.
Chris@16 253 //! @param value The value which will be used to copy construct values.
Chris@16 254 //!
Chris@16 255 //! @par Throws
Chris@16 256 //! If Value's copy constructor throws.
Chris@16 257 //! @internal
Chris@16 258 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 259 //! @endinternal
Chris@16 260 //!
Chris@16 261 //! @par Complexity
Chris@16 262 //! Linear O(N).
Chris@16 263 varray(size_type count, value_type const& value)
Chris@16 264 : m_size(0)
Chris@16 265 {
Chris@16 266 this->resize(count, value); // may throw
Chris@16 267 }
Chris@16 268
Chris@16 269 //! @pre
Chris@16 270 //! @li <tt>distance(first, last) <= capacity()</tt>
Chris@16 271 //! @li Iterator must meet the \c ForwardTraversalIterator concept.
Chris@16 272 //!
Chris@16 273 //! @brief Constructs a varray containing copy of a range <tt>[first, last)</tt>.
Chris@16 274 //!
Chris@16 275 //! @param first The iterator to the first element in range.
Chris@16 276 //! @param last The iterator to the one after the last element in range.
Chris@16 277 //!
Chris@16 278 //! @par Throws
Chris@16 279 //! If Value's constructor taking a dereferenced Iterator throws.
Chris@16 280 //! @internal
Chris@16 281 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 282 //! @endinternal
Chris@16 283 //!
Chris@16 284 //! @par Complexity
Chris@16 285 //! Linear O(N).
Chris@16 286 template <typename Iterator>
Chris@16 287 varray(Iterator first, Iterator last)
Chris@16 288 : m_size(0)
Chris@16 289 {
Chris@16 290 BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
Chris@16 291
Chris@16 292 this->assign(first, last); // may throw
Chris@16 293 }
Chris@16 294
Chris@16 295 //! @brief Constructs a copy of other varray.
Chris@16 296 //!
Chris@16 297 //! @param other The varray which content will be copied to this one.
Chris@16 298 //!
Chris@16 299 //! @par Throws
Chris@16 300 //! If Value's copy constructor throws.
Chris@16 301 //!
Chris@16 302 //! @par Complexity
Chris@16 303 //! Linear O(N).
Chris@16 304 varray(varray const& other)
Chris@16 305 : m_size(other.size())
Chris@16 306 {
Chris@16 307 namespace sv = varray_detail;
Chris@16 308 sv::uninitialized_copy(other.begin(), other.end(), this->begin()); // may throw
Chris@16 309 }
Chris@16 310
Chris@16 311 //! @pre <tt>other.size() <= capacity()</tt>.
Chris@16 312 //!
Chris@16 313 //! @brief Constructs a copy of other varray.
Chris@16 314 //!
Chris@16 315 //! @param other The varray which content will be copied to this one.
Chris@16 316 //!
Chris@16 317 //! @par Throws
Chris@16 318 //! If Value's copy constructor throws.
Chris@16 319 //! @internal
Chris@16 320 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 321 //! @endinternal
Chris@16 322 //!
Chris@16 323 //! @par Complexity
Chris@16 324 //! Linear O(N).
Chris@16 325 template <std::size_t C>
Chris@16 326 varray(varray<value_type, C> const& other)
Chris@16 327 : m_size(other.size())
Chris@16 328 {
Chris@16 329 errh::check_capacity(*this, other.size()); // may throw
Chris@16 330
Chris@16 331 namespace sv = varray_detail;
Chris@16 332 sv::uninitialized_copy(other.begin(), other.end(), this->begin()); // may throw
Chris@16 333 }
Chris@16 334
Chris@16 335 //! @brief Copy assigns Values stored in the other varray to this one.
Chris@16 336 //!
Chris@16 337 //! @param other The varray which content will be copied to this one.
Chris@16 338 //!
Chris@16 339 //! @par Throws
Chris@16 340 //! If Value's copy constructor or copy assignment throws.
Chris@16 341 //!
Chris@16 342 //! @par Complexity
Chris@16 343 //! Linear O(N).
Chris@16 344 varray & operator=(BOOST_COPY_ASSIGN_REF(varray) other)
Chris@16 345 {
Chris@16 346 this->assign(other.begin(), other.end()); // may throw
Chris@16 347
Chris@16 348 return *this;
Chris@16 349 }
Chris@16 350
Chris@16 351 //! @pre <tt>other.size() <= capacity()</tt>
Chris@16 352 //!
Chris@16 353 //! @brief Copy assigns Values stored in the other varray to this one.
Chris@16 354 //!
Chris@16 355 //! @param other The varray which content will be copied to this one.
Chris@16 356 //!
Chris@16 357 //! @par Throws
Chris@16 358 //! If Value's copy constructor or copy assignment throws.
Chris@16 359 //! @internal
Chris@16 360 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 361 //! @endinternal
Chris@16 362 //!
Chris@16 363 //! @par Complexity
Chris@16 364 //! Linear O(N).
Chris@16 365 template <std::size_t C>
Chris@16 366 // TEMPORARY WORKAROUND
Chris@16 367 #if defined(BOOST_NO_RVALUE_REFERENCES)
Chris@16 368 varray & operator=(::boost::rv< varray<value_type, C> > const& other)
Chris@16 369 #else
Chris@16 370 varray & operator=(varray<value_type, C> const& other)
Chris@16 371 #endif
Chris@16 372 {
Chris@16 373 this->assign(other.begin(), other.end()); // may throw
Chris@16 374
Chris@16 375 return *this;
Chris@16 376 }
Chris@16 377
Chris@16 378 //! @brief Move constructor. Moves Values stored in the other varray to this one.
Chris@16 379 //!
Chris@16 380 //! @param other The varray which content will be moved to this one.
Chris@16 381 //!
Chris@16 382 //! @par Throws
Chris@16 383 //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
Chris@16 384 //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
Chris@16 385 //! @internal
Chris@16 386 //! @li It throws only if \c use_memop_in_swap_and_move is \c false_type - default.
Chris@16 387 //! @endinternal
Chris@16 388 //!
Chris@16 389 //! @par Complexity
Chris@16 390 //! Linear O(N).
Chris@16 391 varray(BOOST_RV_REF(varray) other)
Chris@16 392 {
Chris@16 393 typedef typename
Chris@16 394 vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
Chris@16 395
Chris@16 396 this->move_ctor_dispatch(other, use_memop_in_swap_and_move());
Chris@16 397 }
Chris@16 398
Chris@16 399 //! @pre <tt>other.size() <= capacity()</tt>
Chris@16 400 //!
Chris@16 401 //! @brief Move constructor. Moves Values stored in the other varray to this one.
Chris@16 402 //!
Chris@16 403 //! @param other The varray which content will be moved to this one.
Chris@16 404 //!
Chris@16 405 //! @par Throws
Chris@16 406 //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
Chris@16 407 //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
Chris@16 408 //! @internal
Chris@16 409 //! @li It throws only if \c use_memop_in_swap_and_move is false_type - default.
Chris@16 410 //! @endinternal
Chris@16 411 //! @internal
Chris@16 412 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 413 //! @endinternal
Chris@16 414 //!
Chris@16 415 //! @par Complexity
Chris@16 416 //! Linear O(N).
Chris@16 417 template <std::size_t C>
Chris@16 418 varray(BOOST_RV_REF_2_TEMPL_ARGS(varray, value_type, C) other)
Chris@16 419 : m_size(other.m_size)
Chris@16 420 {
Chris@16 421 errh::check_capacity(*this, other.size()); // may throw
Chris@16 422
Chris@16 423 typedef typename
Chris@16 424 vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
Chris@16 425
Chris@16 426 this->move_ctor_dispatch(other, use_memop_in_swap_and_move());
Chris@16 427 }
Chris@16 428
Chris@16 429 //! @brief Move assignment. Moves Values stored in the other varray to this one.
Chris@16 430 //!
Chris@16 431 //! @param other The varray which content will be moved to this one.
Chris@16 432 //!
Chris@16 433 //! @par Throws
Chris@16 434 //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
Chris@16 435 //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
Chris@16 436 //! @internal
Chris@16 437 //! @li It throws only if \c use_memop_in_swap_and_move is \c false_type - default.
Chris@16 438 //! @endinternal
Chris@16 439 //!
Chris@16 440 //! @par Complexity
Chris@16 441 //! Linear O(N).
Chris@16 442 varray & operator=(BOOST_RV_REF(varray) other)
Chris@16 443 {
Chris@16 444 if ( &other == this )
Chris@16 445 return *this;
Chris@16 446
Chris@16 447 typedef typename
Chris@16 448 vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
Chris@16 449
Chris@16 450 this->move_assign_dispatch(other, use_memop_in_swap_and_move());
Chris@16 451
Chris@16 452 return *this;
Chris@16 453 }
Chris@16 454
Chris@16 455 //! @pre <tt>other.size() <= capacity()</tt>
Chris@16 456 //!
Chris@16 457 //! @brief Move assignment. Moves Values stored in the other varray to this one.
Chris@16 458 //!
Chris@16 459 //! @param other The varray which content will be moved to this one.
Chris@16 460 //!
Chris@16 461 //! @par Throws
Chris@16 462 //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
Chris@16 463 //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
Chris@16 464 //! @internal
Chris@16 465 //! @li It throws only if \c use_memop_in_swap_and_move is \c false_type - default.
Chris@16 466 //! @endinternal
Chris@16 467 //! @internal
Chris@16 468 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 469 //! @endinternal
Chris@16 470 //!
Chris@16 471 //! @par Complexity
Chris@16 472 //! Linear O(N).
Chris@16 473 template <std::size_t C>
Chris@16 474 varray & operator=(BOOST_RV_REF_2_TEMPL_ARGS(varray, value_type, C) other)
Chris@16 475 {
Chris@16 476 errh::check_capacity(*this, other.size()); // may throw
Chris@16 477
Chris@16 478 typedef typename
Chris@16 479 vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
Chris@16 480
Chris@16 481 this->move_assign_dispatch(other, use_memop_in_swap_and_move());
Chris@16 482
Chris@16 483 return *this;
Chris@16 484 }
Chris@16 485
Chris@16 486 //! @brief Destructor. Destroys Values stored in this container.
Chris@16 487 //!
Chris@16 488 //! @par Throws
Chris@16 489 //! Nothing
Chris@16 490 //!
Chris@16 491 //! @par Complexity
Chris@16 492 //! Linear O(N).
Chris@16 493 ~varray()
Chris@16 494 {
Chris@16 495 namespace sv = varray_detail;
Chris@16 496 sv::destroy(this->begin(), this->end());
Chris@16 497 }
Chris@16 498
Chris@16 499 //! @brief Swaps contents of the other varray and this one.
Chris@16 500 //!
Chris@16 501 //! @param other The varray which content will be swapped with this one's content.
Chris@16 502 //!
Chris@16 503 //! @par Throws
Chris@16 504 //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
Chris@16 505 //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
Chris@16 506 //! @internal
Chris@16 507 //! @li It throws only if \c use_memop_in_swap_and_move and \c use_optimized_swap are \c false_type - default.
Chris@16 508 //! @endinternal
Chris@16 509 //!
Chris@16 510 //! @par Complexity
Chris@16 511 //! Linear O(N).
Chris@16 512 void swap(varray & other)
Chris@16 513 {
Chris@16 514 typedef typename
Chris@16 515 vt::use_optimized_swap use_optimized_swap;
Chris@16 516
Chris@16 517 this->swap_dispatch(other, use_optimized_swap());
Chris@16 518 }
Chris@16 519
Chris@16 520 //! @pre <tt>other.size() <= capacity() && size() <= other.capacity()</tt>
Chris@16 521 //!
Chris@16 522 //! @brief Swaps contents of the other varray and this one.
Chris@16 523 //!
Chris@16 524 //! @param other The varray which content will be swapped with this one's content.
Chris@16 525 //!
Chris@16 526 //! @par Throws
Chris@16 527 //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
Chris@16 528 //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
Chris@16 529 //! @internal
Chris@16 530 //! @li It throws only if \c use_memop_in_swap_and_move and \c use_optimized_swap are \c false_type - default.
Chris@16 531 //! @endinternal
Chris@16 532 //! @internal
Chris@16 533 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 534 //! @endinternal
Chris@16 535 //!
Chris@16 536 //! @par Complexity
Chris@16 537 //! Linear O(N).
Chris@16 538 template <std::size_t C>
Chris@16 539 void swap(varray<value_type, C> & other)
Chris@16 540 {
Chris@16 541 errh::check_capacity(*this, other.size());
Chris@16 542 errh::check_capacity(other, this->size());
Chris@16 543
Chris@16 544 typedef typename
Chris@16 545 vt::use_optimized_swap use_optimized_swap;
Chris@16 546
Chris@16 547 this->swap_dispatch(other, use_optimized_swap());
Chris@16 548 }
Chris@16 549
Chris@16 550 //! @pre <tt>count <= capacity()</tt>
Chris@16 551 //!
Chris@16 552 //! @brief Inserts or erases elements at the end such that
Chris@16 553 //! the size becomes count. New elements are default constructed.
Chris@16 554 //!
Chris@16 555 //! @param count The number of elements which will be stored in the container.
Chris@16 556 //!
Chris@16 557 //! @par Throws
Chris@16 558 //! If Value's default constructor throws.
Chris@16 559 //! @internal
Chris@16 560 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 561 //! @endinternal
Chris@16 562 //!
Chris@16 563 //! @par Complexity
Chris@16 564 //! Linear O(N).
Chris@16 565 void resize(size_type count)
Chris@16 566 {
Chris@16 567 namespace sv = varray_detail;
Chris@16 568 typedef typename vt::disable_trivial_init dti;
Chris@16 569
Chris@16 570 if ( count < m_size )
Chris@16 571 {
Chris@16 572 sv::destroy(this->begin() + count, this->end());
Chris@16 573 }
Chris@16 574 else
Chris@16 575 {
Chris@16 576 errh::check_capacity(*this, count); // may throw
Chris@16 577
Chris@16 578 sv::uninitialized_fill(this->end(), this->begin() + count, dti()); // may throw
Chris@16 579 }
Chris@16 580 m_size = count; // update end
Chris@16 581 }
Chris@16 582
Chris@16 583 //! @pre <tt>count <= capacity()</tt>
Chris@16 584 //!
Chris@16 585 //! @brief Inserts or erases elements at the end such that
Chris@16 586 //! the size becomes count. New elements are copy constructed from value.
Chris@16 587 //!
Chris@16 588 //! @param count The number of elements which will be stored in the container.
Chris@16 589 //! @param value The value used to copy construct the new element.
Chris@16 590 //!
Chris@16 591 //! @par Throws
Chris@16 592 //! If Value's copy constructor throws.
Chris@16 593 //! @internal
Chris@16 594 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 595 //! @endinternal
Chris@16 596 //!
Chris@16 597 //! @par Complexity
Chris@16 598 //! Linear O(N).
Chris@16 599 void resize(size_type count, value_type const& value)
Chris@16 600 {
Chris@16 601 if ( count < m_size )
Chris@16 602 {
Chris@16 603 namespace sv = varray_detail;
Chris@16 604 sv::destroy(this->begin() + count, this->end());
Chris@16 605 }
Chris@16 606 else
Chris@16 607 {
Chris@16 608 errh::check_capacity(*this, count); // may throw
Chris@16 609
Chris@16 610 std::uninitialized_fill(this->end(), this->begin() + count, value); // may throw
Chris@16 611 }
Chris@16 612 m_size = count; // update end
Chris@16 613 }
Chris@16 614
Chris@16 615 //! @pre <tt>count <= capacity()</tt>
Chris@16 616 //!
Chris@16 617 //! @brief This call has no effect because the Capacity of this container is constant.
Chris@16 618 //!
Chris@16 619 //! @param count The number of elements which the container should be able to contain.
Chris@16 620 //!
Chris@16 621 //! @par Throws
Chris@16 622 //! Nothing.
Chris@16 623 //! @internal
Chris@16 624 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 625 //! @endinternal
Chris@16 626 //!
Chris@16 627 //! @par Complexity
Chris@16 628 //! Linear O(N).
Chris@16 629 void reserve(size_type count)
Chris@16 630 {
Chris@16 631 errh::check_capacity(*this, count); // may throw
Chris@16 632 }
Chris@16 633
Chris@16 634 //! @pre <tt>size() < capacity()</tt>
Chris@16 635 //!
Chris@16 636 //! @brief Adds a copy of value at the end.
Chris@16 637 //!
Chris@16 638 //! @param value The value used to copy construct the new element.
Chris@16 639 //!
Chris@16 640 //! @par Throws
Chris@16 641 //! If Value's copy constructor throws.
Chris@16 642 //! @internal
Chris@16 643 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 644 //! @endinternal
Chris@16 645 //!
Chris@16 646 //! @par Complexity
Chris@16 647 //! Constant O(1).
Chris@16 648 void push_back(value_type const& value)
Chris@16 649 {
Chris@16 650 typedef typename vt::disable_trivial_init dti;
Chris@16 651
Chris@16 652 errh::check_capacity(*this, m_size + 1); // may throw
Chris@16 653
Chris@16 654 namespace sv = varray_detail;
Chris@16 655 sv::construct(dti(), this->end(), value); // may throw
Chris@16 656 ++m_size; // update end
Chris@16 657 }
Chris@16 658
Chris@16 659 //! @pre <tt>size() < capacity()</tt>
Chris@16 660 //!
Chris@16 661 //! @brief Moves value to the end.
Chris@16 662 //!
Chris@16 663 //! @param value The value to move construct the new element.
Chris@16 664 //!
Chris@16 665 //! @par Throws
Chris@16 666 //! If Value's move constructor throws.
Chris@16 667 //! @internal
Chris@16 668 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 669 //! @endinternal
Chris@16 670 //!
Chris@16 671 //! @par Complexity
Chris@16 672 //! Constant O(1).
Chris@16 673 void push_back(BOOST_RV_REF(value_type) value)
Chris@16 674 {
Chris@16 675 typedef typename vt::disable_trivial_init dti;
Chris@16 676
Chris@16 677 errh::check_capacity(*this, m_size + 1); // may throw
Chris@16 678
Chris@16 679 namespace sv = varray_detail;
Chris@16 680 sv::construct(dti(), this->end(), ::boost::move(value)); // may throw
Chris@16 681 ++m_size; // update end
Chris@16 682 }
Chris@16 683
Chris@16 684 //! @pre <tt>!empty()</tt>
Chris@16 685 //!
Chris@16 686 //! @brief Destroys last value and decreases the size.
Chris@16 687 //!
Chris@16 688 //! @par Throws
Chris@16 689 //! Nothing by default.
Chris@16 690 //!
Chris@16 691 //! @par Complexity
Chris@16 692 //! Constant O(1).
Chris@16 693 void pop_back()
Chris@16 694 {
Chris@16 695 errh::check_not_empty(*this);
Chris@16 696
Chris@16 697 namespace sv = varray_detail;
Chris@16 698 sv::destroy(this->end() - 1);
Chris@16 699 --m_size; // update end
Chris@16 700 }
Chris@16 701
Chris@16 702 //! @pre
Chris@16 703 //! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
Chris@16 704 //! @li <tt>size() < capacity()</tt>
Chris@16 705 //!
Chris@16 706 //! @brief Inserts a copy of element at position.
Chris@16 707 //!
Chris@16 708 //! @param position The position at which the new value will be inserted.
Chris@16 709 //! @param value The value used to copy construct the new element.
Chris@16 710 //!
Chris@16 711 //! @par Throws
Chris@16 712 //! @li If Value's copy constructor or copy assignment throws
Chris@16 713 //! @li If Value's move constructor or move assignment throws.
Chris@16 714 //! @internal
Chris@16 715 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 716 //! @endinternal
Chris@16 717 //!
Chris@16 718 //! @par Complexity
Chris@16 719 //! Constant or linear.
Chris@16 720 iterator insert(iterator position, value_type const& value)
Chris@16 721 {
Chris@16 722 typedef typename vt::disable_trivial_init dti;
Chris@16 723 namespace sv = varray_detail;
Chris@16 724
Chris@16 725 errh::check_iterator_end_eq(*this, position);
Chris@16 726 errh::check_capacity(*this, m_size + 1); // may throw
Chris@16 727
Chris@16 728 if ( position == this->end() )
Chris@16 729 {
Chris@16 730 sv::construct(dti(), position, value); // may throw
Chris@16 731 ++m_size; // update end
Chris@16 732 }
Chris@16 733 else
Chris@16 734 {
Chris@16 735 // TODO - should move be used only if it's nonthrowing?
Chris@16 736 value_type & r = *(this->end() - 1);
Chris@16 737 sv::construct(dti(), this->end(), boost::move(r)); // may throw
Chris@16 738 ++m_size; // update end
Chris@16 739 sv::move_backward(position, this->end() - 2, this->end() - 1); // may throw
Chris@16 740 sv::assign(position, value); // may throw
Chris@16 741 }
Chris@16 742
Chris@16 743 return position;
Chris@16 744 }
Chris@16 745
Chris@16 746 //! @pre
Chris@16 747 //! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
Chris@16 748 //! @li <tt>size() < capacity()</tt>
Chris@16 749 //!
Chris@16 750 //! @brief Inserts a move-constructed element at position.
Chris@16 751 //!
Chris@16 752 //! @param position The position at which the new value will be inserted.
Chris@16 753 //! @param value The value used to move construct the new element.
Chris@16 754 //!
Chris@16 755 //! @par Throws
Chris@16 756 //! If Value's move constructor or move assignment throws.
Chris@16 757 //! @internal
Chris@16 758 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 759 //! @endinternal
Chris@16 760 //!
Chris@16 761 //! @par Complexity
Chris@16 762 //! Constant or linear.
Chris@16 763 iterator insert(iterator position, BOOST_RV_REF(value_type) value)
Chris@16 764 {
Chris@16 765 typedef typename vt::disable_trivial_init dti;
Chris@16 766 namespace sv = varray_detail;
Chris@16 767
Chris@16 768 errh::check_iterator_end_eq(*this, position);
Chris@16 769 errh::check_capacity(*this, m_size + 1); // may throw
Chris@16 770
Chris@16 771 if ( position == this->end() )
Chris@16 772 {
Chris@16 773 sv::construct(dti(), position, boost::move(value)); // may throw
Chris@16 774 ++m_size; // update end
Chris@16 775 }
Chris@16 776 else
Chris@16 777 {
Chris@16 778 // TODO - should move be used only if it's nonthrowing?
Chris@16 779 value_type & r = *(this->end() - 1);
Chris@16 780 sv::construct(dti(), this->end(), boost::move(r)); // may throw
Chris@16 781 ++m_size; // update end
Chris@16 782 sv::move_backward(position, this->end() - 2, this->end() - 1); // may throw
Chris@16 783 sv::assign(position, boost::move(value)); // may throw
Chris@16 784 }
Chris@16 785
Chris@16 786 return position;
Chris@16 787 }
Chris@16 788
Chris@16 789 //! @pre
Chris@16 790 //! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
Chris@16 791 //! @li <tt>size() + count <= capacity()</tt>
Chris@16 792 //!
Chris@16 793 //! @brief Inserts a count copies of value at position.
Chris@16 794 //!
Chris@16 795 //! @param position The position at which new elements will be inserted.
Chris@16 796 //! @param count The number of new elements which will be inserted.
Chris@16 797 //! @param value The value used to copy construct new elements.
Chris@16 798 //!
Chris@16 799 //! @par Throws
Chris@16 800 //! @li If Value's copy constructor or copy assignment throws.
Chris@16 801 //! @li If Value's move constructor or move assignment throws.
Chris@16 802 //! @internal
Chris@16 803 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 804 //! @endinternal
Chris@16 805 //!
Chris@16 806 //! @par Complexity
Chris@16 807 //! Linear O(N).
Chris@16 808 iterator insert(iterator position, size_type count, value_type const& value)
Chris@16 809 {
Chris@16 810 errh::check_iterator_end_eq(*this, position);
Chris@16 811 errh::check_capacity(*this, m_size + count); // may throw
Chris@16 812
Chris@16 813 if ( position == this->end() )
Chris@16 814 {
Chris@16 815 std::uninitialized_fill(position, position + count, value); // may throw
Chris@16 816 m_size += count; // update end
Chris@16 817 }
Chris@16 818 else
Chris@16 819 {
Chris@16 820 namespace sv = varray_detail;
Chris@16 821
Chris@16 822 difference_type to_move = std::distance(position, this->end());
Chris@16 823
Chris@16 824 // TODO - should following lines check for exception and revert to the old size?
Chris@16 825
Chris@16 826 if ( count < static_cast<size_type>(to_move) )
Chris@16 827 {
Chris@16 828 sv::uninitialized_move(this->end() - count, this->end(), this->end()); // may throw
Chris@16 829 m_size += count; // update end
Chris@16 830 sv::move_backward(position, position + to_move - count, this->end() - count); // may throw
Chris@16 831 std::fill_n(position, count, value); // may throw
Chris@16 832 }
Chris@16 833 else
Chris@16 834 {
Chris@16 835 std::uninitialized_fill(this->end(), position + count, value); // may throw
Chris@16 836 m_size += count - to_move; // update end
Chris@16 837 sv::uninitialized_move(position, position + to_move, position + count); // may throw
Chris@16 838 m_size += to_move; // update end
Chris@16 839 std::fill_n(position, to_move, value); // may throw
Chris@16 840 }
Chris@16 841 }
Chris@16 842
Chris@16 843 return position;
Chris@16 844 }
Chris@16 845
Chris@16 846 //! @pre
Chris@16 847 //! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
Chris@16 848 //! @li <tt>distance(first, last) <= capacity()</tt>
Chris@16 849 //! @li \c Iterator must meet the \c ForwardTraversalIterator concept.
Chris@16 850 //!
Chris@16 851 //! @brief Inserts a copy of a range <tt>[first, last)</tt> at position.
Chris@16 852 //!
Chris@16 853 //! @param position The position at which new elements will be inserted.
Chris@16 854 //! @param first The iterator to the first element of a range used to construct new elements.
Chris@16 855 //! @param last The iterator to the one after the last element of a range used to construct new elements.
Chris@16 856 //!
Chris@16 857 //! @par Throws
Chris@16 858 //! @li If Value's constructor and assignment taking a dereferenced \c Iterator.
Chris@16 859 //! @li If Value's move constructor or move assignment throws.
Chris@16 860 //! @internal
Chris@16 861 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 862 //! @endinternal
Chris@16 863 //!
Chris@16 864 //! @par Complexity
Chris@16 865 //! Linear O(N).
Chris@16 866 template <typename Iterator>
Chris@16 867 iterator insert(iterator position, Iterator first, Iterator last)
Chris@16 868 {
Chris@16 869 BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
Chris@16 870
Chris@16 871 typedef typename boost::iterator_traversal<Iterator>::type traversal;
Chris@16 872 this->insert_dispatch(position, first, last, traversal());
Chris@16 873
Chris@16 874 return position;
Chris@16 875 }
Chris@16 876
Chris@16 877 //! @pre \c position must be a valid iterator of \c *this in range <tt>[begin(), end())</tt>
Chris@16 878 //!
Chris@16 879 //! @brief Erases Value from position.
Chris@16 880 //!
Chris@16 881 //! @param position The position of the element which will be erased from the container.
Chris@16 882 //!
Chris@16 883 //! @par Throws
Chris@16 884 //! If Value's move assignment throws.
Chris@16 885 //!
Chris@16 886 //! @par Complexity
Chris@16 887 //! Linear O(N).
Chris@16 888 iterator erase(iterator position)
Chris@16 889 {
Chris@16 890 namespace sv = varray_detail;
Chris@16 891
Chris@16 892 errh::check_iterator_end_neq(*this, position);
Chris@16 893
Chris@16 894 //TODO - add empty check?
Chris@16 895 //errh::check_empty(*this);
Chris@16 896
Chris@16 897 sv::move(position + 1, this->end(), position); // may throw
Chris@16 898 sv::destroy(this->end() - 1);
Chris@16 899 --m_size;
Chris@16 900
Chris@16 901 return position;
Chris@16 902 }
Chris@16 903
Chris@16 904 //! @pre
Chris@16 905 //! @li \c first and \c last must define a valid range
Chris@16 906 //! @li iterators must be in range <tt>[begin(), end()]</tt>
Chris@16 907 //!
Chris@16 908 //! @brief Erases Values from a range <tt>[first, last)</tt>.
Chris@16 909 //!
Chris@16 910 //! @param first The position of the first element of a range which will be erased from the container.
Chris@16 911 //! @param last The position of the one after the last element of a range which will be erased from the container.
Chris@16 912 //!
Chris@16 913 //! @par Throws
Chris@16 914 //! If Value's move assignment throws.
Chris@16 915 //!
Chris@16 916 //! @par Complexity
Chris@16 917 //! Linear O(N).
Chris@16 918 iterator erase(iterator first, iterator last)
Chris@16 919 {
Chris@16 920 namespace sv = varray_detail;
Chris@16 921
Chris@16 922 errh::check_iterator_end_eq(*this, first);
Chris@16 923 errh::check_iterator_end_eq(*this, last);
Chris@16 924
Chris@16 925 difference_type n = std::distance(first, last);
Chris@16 926
Chris@16 927 //TODO - add invalid range check?
Chris@16 928 //BOOST_ASSERT_MSG(0 <= n, "invalid range");
Chris@16 929 //TODO - add this->size() check?
Chris@16 930 //BOOST_ASSERT_MSG(n <= this->size(), "invalid range");
Chris@16 931
Chris@16 932 sv::move(last, this->end(), first); // may throw
Chris@16 933 sv::destroy(this->end() - n, this->end());
Chris@16 934 m_size -= n;
Chris@16 935
Chris@16 936 return first;
Chris@16 937 }
Chris@16 938
Chris@16 939 //! @pre <tt>distance(first, last) <= capacity()</tt>
Chris@16 940 //!
Chris@16 941 //! @brief Assigns a range <tt>[first, last)</tt> of Values to this container.
Chris@16 942 //!
Chris@16 943 //! @param first The iterator to the first element of a range used to construct new content of this container.
Chris@16 944 //! @param last The iterator to the one after the last element of a range used to construct new content of this container.
Chris@16 945 //!
Chris@16 946 //! @par Throws
Chris@16 947 //! If Value's copy constructor or copy assignment throws,
Chris@16 948 //!
Chris@16 949 //! @par Complexity
Chris@16 950 //! Linear O(N).
Chris@16 951 template <typename Iterator>
Chris@16 952 void assign(Iterator first, Iterator last)
Chris@16 953 {
Chris@16 954 BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
Chris@16 955
Chris@16 956 typedef typename boost::iterator_traversal<Iterator>::type traversal;
Chris@16 957 this->assign_dispatch(first, last, traversal()); // may throw
Chris@16 958 }
Chris@16 959
Chris@16 960 //! @pre <tt>count <= capacity()</tt>
Chris@16 961 //!
Chris@16 962 //! @brief Assigns a count copies of value to this container.
Chris@16 963 //!
Chris@16 964 //! @param count The new number of elements which will be container in the container.
Chris@16 965 //! @param value The value which will be used to copy construct the new content.
Chris@16 966 //!
Chris@16 967 //! @par Throws
Chris@16 968 //! If Value's copy constructor or copy assignment throws.
Chris@16 969 //!
Chris@16 970 //! @par Complexity
Chris@16 971 //! Linear O(N).
Chris@16 972 void assign(size_type count, value_type const& value)
Chris@16 973 {
Chris@16 974 if ( count < m_size )
Chris@16 975 {
Chris@16 976 namespace sv = varray_detail;
Chris@16 977
Chris@16 978 std::fill_n(this->begin(), count, value); // may throw
Chris@16 979 sv::destroy(this->begin() + count, this->end());
Chris@16 980 }
Chris@16 981 else
Chris@16 982 {
Chris@16 983 errh::check_capacity(*this, count); // may throw
Chris@16 984
Chris@16 985 std::fill_n(this->begin(), m_size, value); // may throw
Chris@16 986 std::uninitialized_fill(this->end(), this->begin() + count, value); // may throw
Chris@16 987 }
Chris@16 988 m_size = count; // update end
Chris@16 989 }
Chris@16 990
Chris@16 991 #if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE)
Chris@16 992 #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 993 //! @pre <tt>size() < capacity()</tt>
Chris@16 994 //!
Chris@16 995 //! @brief Inserts a Value constructed with
Chris@16 996 //! \c std::forward<Args>(args)... in the end of the container.
Chris@16 997 //!
Chris@16 998 //! @param args The arguments of the constructor of the new element which will be created at the end of the container.
Chris@16 999 //!
Chris@16 1000 //! @par Throws
Chris@16 1001 //! If in-place constructor throws or Value's move constructor throws.
Chris@16 1002 //! @internal
Chris@16 1003 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 1004 //! @endinternal
Chris@16 1005 //!
Chris@16 1006 //! @par Complexity
Chris@16 1007 //! Constant O(1).
Chris@16 1008 template<class ...Args>
Chris@16 1009 void emplace_back(BOOST_FWD_REF(Args) ...args)
Chris@16 1010 {
Chris@16 1011 typedef typename vt::disable_trivial_init dti;
Chris@16 1012
Chris@16 1013 errh::check_capacity(*this, m_size + 1); // may throw
Chris@16 1014
Chris@16 1015 namespace sv = varray_detail;
Chris@16 1016 sv::construct(dti(), this->end(), ::boost::forward<Args>(args)...); // may throw
Chris@16 1017 ++m_size; // update end
Chris@16 1018 }
Chris@16 1019
Chris@16 1020 //! @pre
Chris@16 1021 //! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>
Chris@16 1022 //! @li <tt>size() < capacity()</tt>
Chris@16 1023 //!
Chris@16 1024 //! @brief Inserts a Value constructed with
Chris@16 1025 //! \c std::forward<Args>(args)... before position
Chris@16 1026 //!
Chris@16 1027 //! @param position The position at which new elements will be inserted.
Chris@16 1028 //! @param args The arguments of the constructor of the new element.
Chris@16 1029 //!
Chris@16 1030 //! @par Throws
Chris@16 1031 //! If in-place constructor throws or if Value's move constructor or move assignment throws.
Chris@16 1032 //! @internal
Chris@16 1033 //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
Chris@16 1034 //! @endinternal
Chris@16 1035 //!
Chris@16 1036 //! @par Complexity
Chris@16 1037 //! Constant or linear.
Chris@16 1038 template<class ...Args>
Chris@16 1039 iterator emplace(iterator position, BOOST_FWD_REF(Args) ...args)
Chris@16 1040 {
Chris@16 1041 typedef typename vt::disable_trivial_init dti;
Chris@16 1042
Chris@16 1043 namespace sv = varray_detail;
Chris@16 1044
Chris@16 1045 errh::check_iterator_end_eq(*this, position);
Chris@16 1046 errh::check_capacity(*this, m_size + 1); // may throw
Chris@16 1047
Chris@16 1048 if ( position == this->end() )
Chris@16 1049 {
Chris@16 1050 sv::construct(dti(), position, ::boost::forward<Args>(args)...); // may throw
Chris@16 1051 ++m_size; // update end
Chris@16 1052 }
Chris@16 1053 else
Chris@16 1054 {
Chris@16 1055 // TODO - should following lines check for exception and revert to the old size?
Chris@16 1056
Chris@16 1057 // TODO - should move be used only if it's nonthrowing?
Chris@16 1058 value_type & r = *(this->end() - 1);
Chris@16 1059 sv::construct(dti(), this->end(), boost::move(r)); // may throw
Chris@16 1060 ++m_size; // update end
Chris@16 1061 sv::move_backward(position, this->end() - 2, this->end() - 1); // may throw
Chris@16 1062
Chris@16 1063 aligned_storage<sizeof(value_type), alignment_of<value_type>::value> temp_storage;
Chris@16 1064 value_type * val_p = static_cast<value_type *>(temp_storage.address());
Chris@16 1065 sv::construct(dti(), val_p, ::boost::forward<Args>(args)...); // may throw
Chris@16 1066 sv::scoped_destructor<value_type> d(val_p);
Chris@16 1067 sv::assign(position, ::boost::move(*val_p)); // may throw
Chris@16 1068 }
Chris@16 1069
Chris@16 1070 return position;
Chris@16 1071 }
Chris@16 1072
Chris@16 1073 #else // BOOST_CONTAINER_PERFECT_FORWARDING || BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@16 1074
Chris@16 1075 #define BOOST_PP_LOCAL_MACRO(n) \
Chris@16 1076 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
Chris@16 1077 void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
Chris@16 1078 { \
Chris@16 1079 typedef typename vt::disable_trivial_init dti; \
Chris@16 1080 \
Chris@16 1081 errh::check_capacity(*this, m_size + 1); /*may throw*/\
Chris@16 1082 \
Chris@16 1083 namespace sv = varray_detail; \
Chris@16 1084 sv::construct(dti(), this->end() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\
Chris@16 1085 ++m_size; /*update end*/ \
Chris@16 1086 } \
Chris@16 1087 //
Chris@16 1088 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
Chris@16 1089 #include BOOST_PP_LOCAL_ITERATE()
Chris@16 1090
Chris@16 1091 #define BOOST_PP_LOCAL_MACRO(n) \
Chris@16 1092 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
Chris@16 1093 iterator emplace(iterator position BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
Chris@16 1094 { \
Chris@16 1095 typedef typename vt::disable_trivial_init dti; \
Chris@16 1096 namespace sv = varray_detail; \
Chris@16 1097 \
Chris@16 1098 errh::check_iterator_end_eq(*this, position); \
Chris@16 1099 errh::check_capacity(*this, m_size + 1); /*may throw*/\
Chris@16 1100 \
Chris@16 1101 if ( position == this->end() ) \
Chris@16 1102 { \
Chris@16 1103 sv::construct(dti(), position BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\
Chris@16 1104 ++m_size; /*update end*/ \
Chris@16 1105 } \
Chris@16 1106 else \
Chris@16 1107 { \
Chris@16 1108 /* TODO - should following lines check for exception and revert to the old size? */ \
Chris@16 1109 /* TODO - should move be used only if it's nonthrowing? */ \
Chris@16 1110 \
Chris@16 1111 value_type & r = *(this->end() - 1); \
Chris@16 1112 sv::construct(dti(), this->end(), boost::move(r)); /*may throw*/\
Chris@16 1113 ++m_size; /*update end*/ \
Chris@16 1114 sv::move_backward(position, this->end() - 2, this->end() - 1); /*may throw*/\
Chris@16 1115 \
Chris@16 1116 aligned_storage<sizeof(value_type), alignment_of<value_type>::value> temp_storage; \
Chris@16 1117 value_type * val_p = static_cast<value_type *>(temp_storage.address()); \
Chris@16 1118 sv::construct(dti(), val_p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\
Chris@16 1119 sv::scoped_destructor<value_type> d(val_p); \
Chris@16 1120 sv::assign(position, ::boost::move(*val_p)); /*may throw*/\
Chris@16 1121 } \
Chris@16 1122 \
Chris@16 1123 return position; \
Chris@16 1124 } \
Chris@16 1125 //
Chris@16 1126 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
Chris@16 1127 #include BOOST_PP_LOCAL_ITERATE()
Chris@16 1128
Chris@16 1129 #endif // BOOST_CONTAINER_PERFECT_FORWARDING || BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@16 1130 #endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE
Chris@16 1131
Chris@16 1132 //! @brief Removes all elements from the container.
Chris@16 1133 //!
Chris@16 1134 //! @par Throws
Chris@16 1135 //! Nothing.
Chris@16 1136 //!
Chris@16 1137 //! @par Complexity
Chris@16 1138 //! Constant O(1).
Chris@16 1139 void clear()
Chris@16 1140 {
Chris@16 1141 namespace sv = varray_detail;
Chris@16 1142 sv::destroy(this->begin(), this->end());
Chris@16 1143 m_size = 0; // update end
Chris@16 1144 }
Chris@16 1145
Chris@16 1146 //! @pre <tt>i < size()</tt>
Chris@16 1147 //!
Chris@16 1148 //! @brief Returns reference to the i-th element.
Chris@16 1149 //!
Chris@16 1150 //! @param i The element's index.
Chris@16 1151 //!
Chris@16 1152 //! @return reference to the i-th element
Chris@16 1153 //! from the beginning of the container.
Chris@16 1154 //!
Chris@16 1155 //! @par Throws
Chris@16 1156 //! \c std::out_of_range exception by default.
Chris@16 1157 //!
Chris@16 1158 //! @par Complexity
Chris@16 1159 //! Constant O(1).
Chris@16 1160 reference at(size_type i)
Chris@16 1161 {
Chris@16 1162 errh::throw_out_of_bounds(*this, i); // may throw
Chris@16 1163 return *(this->begin() + i);
Chris@16 1164 }
Chris@16 1165
Chris@16 1166 //! @pre <tt>i < size()</tt>
Chris@16 1167 //!
Chris@16 1168 //! @brief Returns const reference to the i-th element.
Chris@16 1169 //!
Chris@16 1170 //! @param i The element's index.
Chris@16 1171 //!
Chris@16 1172 //! @return const reference to the i-th element
Chris@16 1173 //! from the beginning of the container.
Chris@16 1174 //!
Chris@16 1175 //! @par Throws
Chris@16 1176 //! \c std::out_of_range exception by default.
Chris@16 1177 //!
Chris@16 1178 //! @par Complexity
Chris@16 1179 //! Constant O(1).
Chris@16 1180 const_reference at(size_type i) const
Chris@16 1181 {
Chris@16 1182 errh::throw_out_of_bounds(*this, i); // may throw
Chris@16 1183 return *(this->begin() + i);
Chris@16 1184 }
Chris@16 1185
Chris@16 1186 //! @pre <tt>i < size()</tt>
Chris@16 1187 //!
Chris@16 1188 //! @brief Returns reference to the i-th element.
Chris@16 1189 //!
Chris@16 1190 //! @param i The element's index.
Chris@16 1191 //!
Chris@16 1192 //! @return reference to the i-th element
Chris@16 1193 //! from the beginning of the container.
Chris@16 1194 //!
Chris@16 1195 //! @par Throws
Chris@16 1196 //! Nothing by default.
Chris@16 1197 //!
Chris@16 1198 //! @par Complexity
Chris@16 1199 //! Constant O(1).
Chris@16 1200 reference operator[](size_type i)
Chris@16 1201 {
Chris@16 1202 // TODO: Remove bounds check? std::vector and std::array operator[] don't check.
Chris@16 1203 errh::check_index(*this, i);
Chris@16 1204 return *(this->begin() + i);
Chris@16 1205 }
Chris@16 1206
Chris@16 1207 //! @pre <tt>i < size()</tt>
Chris@16 1208 //!
Chris@16 1209 //! @brief Returns const reference to the i-th element.
Chris@16 1210 //!
Chris@16 1211 //! @param i The element's index.
Chris@16 1212 //!
Chris@16 1213 //! @return const reference to the i-th element
Chris@16 1214 //! from the beginning of the container.
Chris@16 1215 //!
Chris@16 1216 //! @par Throws
Chris@16 1217 //! Nothing by default.
Chris@16 1218 //!
Chris@16 1219 //! @par Complexity
Chris@16 1220 //! Constant O(1).
Chris@16 1221 const_reference operator[](size_type i) const
Chris@16 1222 {
Chris@16 1223 errh::check_index(*this, i);
Chris@16 1224 return *(this->begin() + i);
Chris@16 1225 }
Chris@16 1226
Chris@16 1227 //! @pre \c !empty()
Chris@16 1228 //!
Chris@16 1229 //! @brief Returns reference to the first element.
Chris@16 1230 //!
Chris@16 1231 //! @return reference to the first element
Chris@16 1232 //! from the beginning of the container.
Chris@16 1233 //!
Chris@16 1234 //! @par Throws
Chris@16 1235 //! Nothing by default.
Chris@16 1236 //!
Chris@16 1237 //! @par Complexity
Chris@16 1238 //! Constant O(1).
Chris@16 1239 reference front()
Chris@16 1240 {
Chris@16 1241 errh::check_not_empty(*this);
Chris@16 1242 return *(this->begin());
Chris@16 1243 }
Chris@16 1244
Chris@16 1245 //! @pre \c !empty()
Chris@16 1246 //!
Chris@16 1247 //! @brief Returns const reference to the first element.
Chris@16 1248 //!
Chris@16 1249 //! @return const reference to the first element
Chris@16 1250 //! from the beginning of the container.
Chris@16 1251 //!
Chris@16 1252 //! @par Throws
Chris@16 1253 //! Nothing by default.
Chris@16 1254 //!
Chris@16 1255 //! @par Complexity
Chris@16 1256 //! Constant O(1).
Chris@16 1257 const_reference front() const
Chris@16 1258 {
Chris@16 1259 errh::check_not_empty(*this);
Chris@16 1260 return *(this->begin());
Chris@16 1261 }
Chris@16 1262
Chris@16 1263 //! @pre \c !empty()
Chris@16 1264 //!
Chris@16 1265 //! @brief Returns reference to the last element.
Chris@16 1266 //!
Chris@16 1267 //! @return reference to the last element
Chris@16 1268 //! from the beginning of the container.
Chris@16 1269 //!
Chris@16 1270 //! @par Throws
Chris@16 1271 //! Nothing by default.
Chris@16 1272 //!
Chris@16 1273 //! @par Complexity
Chris@16 1274 //! Constant O(1).
Chris@16 1275 reference back()
Chris@16 1276 {
Chris@16 1277 errh::check_not_empty(*this);
Chris@16 1278 return *(this->end() - 1);
Chris@16 1279 }
Chris@16 1280
Chris@16 1281 //! @pre \c !empty()
Chris@16 1282 //!
Chris@16 1283 //! @brief Returns const reference to the first element.
Chris@16 1284 //!
Chris@16 1285 //! @return const reference to the last element
Chris@16 1286 //! from the beginning of the container.
Chris@16 1287 //!
Chris@16 1288 //! @par Throws
Chris@16 1289 //! Nothing by default.
Chris@16 1290 //!
Chris@16 1291 //! @par Complexity
Chris@16 1292 //! Constant O(1).
Chris@16 1293 const_reference back() const
Chris@16 1294 {
Chris@16 1295 errh::check_not_empty(*this);
Chris@16 1296 return *(this->end() - 1);
Chris@16 1297 }
Chris@16 1298
Chris@16 1299 //! @brief Pointer such that <tt>[data(), data() + size())</tt> is a valid range.
Chris@16 1300 //! For a non-empty vector <tt>data() == &front()</tt>.
Chris@16 1301 //!
Chris@16 1302 //! @par Throws
Chris@16 1303 //! Nothing.
Chris@16 1304 //!
Chris@16 1305 //! @par Complexity
Chris@16 1306 //! Constant O(1).
Chris@16 1307 Value * data()
Chris@16 1308 {
Chris@16 1309 return boost::addressof(*(this->ptr()));
Chris@16 1310 }
Chris@16 1311
Chris@16 1312 //! @brief Const pointer such that <tt>[data(), data() + size())</tt> is a valid range.
Chris@16 1313 //! For a non-empty vector <tt>data() == &front()</tt>.
Chris@16 1314 //!
Chris@16 1315 //! @par Throws
Chris@16 1316 //! Nothing.
Chris@16 1317 //!
Chris@16 1318 //! @par Complexity
Chris@16 1319 //! Constant O(1).
Chris@16 1320 const Value * data() const
Chris@16 1321 {
Chris@16 1322 return boost::addressof(*(this->ptr()));
Chris@16 1323 }
Chris@16 1324
Chris@16 1325
Chris@16 1326 //! @brief Returns iterator to the first element.
Chris@16 1327 //!
Chris@16 1328 //! @return iterator to the first element contained in the vector.
Chris@16 1329 //!
Chris@16 1330 //! @par Throws
Chris@16 1331 //! Nothing.
Chris@16 1332 //!
Chris@16 1333 //! @par Complexity
Chris@16 1334 //! Constant O(1).
Chris@16 1335 iterator begin() { return this->ptr(); }
Chris@16 1336
Chris@16 1337 //! @brief Returns const iterator to the first element.
Chris@16 1338 //!
Chris@16 1339 //! @return const_iterator to the first element contained in the vector.
Chris@16 1340 //!
Chris@16 1341 //! @par Throws
Chris@16 1342 //! Nothing.
Chris@16 1343 //!
Chris@16 1344 //! @par Complexity
Chris@16 1345 //! Constant O(1).
Chris@16 1346 const_iterator begin() const { return this->ptr(); }
Chris@16 1347
Chris@16 1348 //! @brief Returns const iterator to the first element.
Chris@16 1349 //!
Chris@16 1350 //! @return const_iterator to the first element contained in the vector.
Chris@16 1351 //!
Chris@16 1352 //! @par Throws
Chris@16 1353 //! Nothing.
Chris@16 1354 //!
Chris@16 1355 //! @par Complexity
Chris@16 1356 //! Constant O(1).
Chris@16 1357 const_iterator cbegin() const { return this->ptr(); }
Chris@16 1358
Chris@16 1359 //! @brief Returns iterator to the one after the last element.
Chris@16 1360 //!
Chris@16 1361 //! @return iterator pointing to the one after the last element contained in the vector.
Chris@16 1362 //!
Chris@16 1363 //! @par Throws
Chris@16 1364 //! Nothing.
Chris@16 1365 //!
Chris@16 1366 //! @par Complexity
Chris@16 1367 //! Constant O(1).
Chris@16 1368 iterator end() { return this->begin() + m_size; }
Chris@16 1369
Chris@16 1370 //! @brief Returns const iterator to the one after the last element.
Chris@16 1371 //!
Chris@16 1372 //! @return const_iterator pointing to the one after the last element contained in the vector.
Chris@16 1373 //!
Chris@16 1374 //! @par Throws
Chris@16 1375 //! Nothing.
Chris@16 1376 //!
Chris@16 1377 //! @par Complexity
Chris@16 1378 //! Constant O(1).
Chris@16 1379 const_iterator end() const { return this->begin() + m_size; }
Chris@16 1380
Chris@16 1381 //! @brief Returns const iterator to the one after the last element.
Chris@16 1382 //!
Chris@16 1383 //! @return const_iterator pointing to the one after the last element contained in the vector.
Chris@16 1384 //!
Chris@16 1385 //! @par Throws
Chris@16 1386 //! Nothing.
Chris@16 1387 //!
Chris@16 1388 //! @par Complexity
Chris@16 1389 //! Constant O(1).
Chris@16 1390 const_iterator cend() const { return this->cbegin() + m_size; }
Chris@16 1391
Chris@16 1392 //! @brief Returns reverse iterator to the first element of the reversed container.
Chris@16 1393 //!
Chris@16 1394 //! @return reverse_iterator pointing to the beginning
Chris@16 1395 //! of the reversed varray.
Chris@16 1396 //!
Chris@16 1397 //! @par Throws
Chris@16 1398 //! Nothing.
Chris@16 1399 //!
Chris@16 1400 //! @par Complexity
Chris@16 1401 //! Constant O(1).
Chris@16 1402 reverse_iterator rbegin() { return reverse_iterator(this->end()); }
Chris@16 1403
Chris@16 1404 //! @brief Returns const reverse iterator to the first element of the reversed container.
Chris@16 1405 //!
Chris@16 1406 //! @return const_reverse_iterator pointing to the beginning
Chris@16 1407 //! of the reversed varray.
Chris@16 1408 //!
Chris@16 1409 //! @par Throws
Chris@16 1410 //! Nothing.
Chris@16 1411 //!
Chris@16 1412 //! @par Complexity
Chris@16 1413 //! Constant O(1).
Chris@16 1414 const_reverse_iterator rbegin() const { return reverse_iterator(this->end()); }
Chris@16 1415
Chris@16 1416 //! @brief Returns const reverse iterator to the first element of the reversed container.
Chris@16 1417 //!
Chris@16 1418 //! @return const_reverse_iterator pointing to the beginning
Chris@16 1419 //! of the reversed varray.
Chris@16 1420 //!
Chris@16 1421 //! @par Throws
Chris@16 1422 //! Nothing.
Chris@16 1423 //!
Chris@16 1424 //! @par Complexity
Chris@16 1425 //! Constant O(1).
Chris@16 1426 const_reverse_iterator crbegin() const { return reverse_iterator(this->end()); }
Chris@16 1427
Chris@16 1428 //! @brief Returns reverse iterator to the one after the last element of the reversed container.
Chris@16 1429 //!
Chris@16 1430 //! @return reverse_iterator pointing to the one after the last element
Chris@16 1431 //! of the reversed varray.
Chris@16 1432 //!
Chris@16 1433 //! @par Throws
Chris@16 1434 //! Nothing.
Chris@16 1435 //!
Chris@16 1436 //! @par Complexity
Chris@16 1437 //! Constant O(1).
Chris@16 1438 reverse_iterator rend() { return reverse_iterator(this->begin()); }
Chris@16 1439
Chris@16 1440 //! @brief Returns const reverse iterator to the one after the last element of the reversed container.
Chris@16 1441 //!
Chris@16 1442 //! @return const_reverse_iterator pointing to the one after the last element
Chris@16 1443 //! of the reversed varray.
Chris@16 1444 //!
Chris@16 1445 //! @par Throws
Chris@16 1446 //! Nothing.
Chris@16 1447 //!
Chris@16 1448 //! @par Complexity
Chris@16 1449 //! Constant O(1).
Chris@16 1450 const_reverse_iterator rend() const { return reverse_iterator(this->begin()); }
Chris@16 1451
Chris@16 1452 //! @brief Returns const reverse iterator to the one after the last element of the reversed container.
Chris@16 1453 //!
Chris@16 1454 //! @return const_reverse_iterator pointing to the one after the last element
Chris@16 1455 //! of the reversed varray.
Chris@16 1456 //!
Chris@16 1457 //! @par Throws
Chris@16 1458 //! Nothing.
Chris@16 1459 //!
Chris@16 1460 //! @par Complexity
Chris@16 1461 //! Constant O(1).
Chris@16 1462 const_reverse_iterator crend() const { return reverse_iterator(this->begin()); }
Chris@16 1463
Chris@16 1464 //! @brief Returns container's capacity.
Chris@16 1465 //!
Chris@16 1466 //! @return container's capacity.
Chris@16 1467 //!
Chris@16 1468 //! @par Throws
Chris@16 1469 //! Nothing.
Chris@16 1470 //!
Chris@16 1471 //! @par Complexity
Chris@16 1472 //! Constant O(1).
Chris@16 1473 static size_type capacity() { return Capacity; }
Chris@16 1474
Chris@16 1475 //! @brief Returns container's capacity.
Chris@16 1476 //!
Chris@16 1477 //! @return container's capacity.
Chris@16 1478 //!
Chris@16 1479 //! @par Throws
Chris@16 1480 //! Nothing.
Chris@16 1481 //!
Chris@16 1482 //! @par Complexity
Chris@16 1483 //! Constant O(1).
Chris@16 1484 static size_type max_size() { return Capacity; }
Chris@16 1485
Chris@16 1486 //! @brief Returns the number of stored elements.
Chris@16 1487 //!
Chris@16 1488 //! @return Number of elements contained in the container.
Chris@16 1489 //!
Chris@16 1490 //! @par Throws
Chris@16 1491 //! Nothing.
Chris@16 1492 //!
Chris@16 1493 //! @par Complexity
Chris@16 1494 //! Constant O(1).
Chris@16 1495 size_type size() const { return m_size; }
Chris@16 1496
Chris@16 1497 //! @brief Queries if the container contains elements.
Chris@16 1498 //!
Chris@16 1499 //! @return true if the number of elements contained in the
Chris@16 1500 //! container is equal to 0.
Chris@16 1501 //!
Chris@16 1502 //! @par Throws
Chris@16 1503 //! Nothing.
Chris@16 1504 //!
Chris@16 1505 //! @par Complexity
Chris@16 1506 //! Constant O(1).
Chris@16 1507 bool empty() const { return 0 == m_size; }
Chris@16 1508
Chris@16 1509 private:
Chris@16 1510
Chris@16 1511 // @par Throws
Chris@16 1512 // Nothing.
Chris@16 1513 // @par Complexity
Chris@16 1514 // Linear O(N).
Chris@16 1515 template <std::size_t C>
Chris@16 1516 void move_ctor_dispatch(varray<value_type, C> & other, boost::true_type /*use_memop*/)
Chris@16 1517 {
Chris@16 1518 ::memcpy(this->data(), other.data(), sizeof(Value) * other.m_size);
Chris@16 1519 m_size = other.m_size;
Chris@16 1520 }
Chris@16 1521
Chris@16 1522 // @par Throws
Chris@16 1523 // @li If boost::has_nothrow_move<Value>::value is true and Value's move constructor throws
Chris@16 1524 // @li If boost::has_nothrow_move<Value>::value is false and Value's copy constructor throws.
Chris@16 1525 // @par Complexity
Chris@16 1526 // Linear O(N).
Chris@16 1527 template <std::size_t C>
Chris@16 1528 void move_ctor_dispatch(varray<value_type, C> & other, boost::false_type /*use_memop*/)
Chris@16 1529 {
Chris@16 1530 namespace sv = varray_detail;
Chris@16 1531 sv::uninitialized_move_if_noexcept(other.begin(), other.end(), this->begin()); // may throw
Chris@16 1532 m_size = other.m_size;
Chris@16 1533 }
Chris@16 1534
Chris@16 1535 // @par Throws
Chris@16 1536 // Nothing.
Chris@16 1537 // @par Complexity
Chris@16 1538 // Linear O(N).
Chris@16 1539 template <std::size_t C>
Chris@16 1540 void move_assign_dispatch(varray<value_type, C> & other, boost::true_type /*use_memop*/)
Chris@16 1541 {
Chris@16 1542 this->clear();
Chris@16 1543
Chris@16 1544 ::memcpy(this->data(), other.data(), sizeof(Value) * other.m_size);
Chris@16 1545 std::swap(m_size, other.m_size);
Chris@16 1546 }
Chris@16 1547
Chris@16 1548 // @par Throws
Chris@16 1549 // @li If boost::has_nothrow_move<Value>::value is true and Value's move constructor or move assignment throws
Chris@16 1550 // @li If boost::has_nothrow_move<Value>::value is false and Value's copy constructor or move assignment throws.
Chris@16 1551 // @par Complexity
Chris@16 1552 // Linear O(N).
Chris@16 1553 template <std::size_t C>
Chris@16 1554 void move_assign_dispatch(varray<value_type, C> & other, boost::false_type /*use_memop*/)
Chris@16 1555 {
Chris@16 1556 namespace sv = varray_detail;
Chris@16 1557 if ( m_size <= static_cast<size_type>(other.size()) )
Chris@16 1558 {
Chris@16 1559 sv::move_if_noexcept(other.begin(), other.begin() + m_size, this->begin()); // may throw
Chris@16 1560 // TODO - perform uninitialized_copy first?
Chris@16 1561 sv::uninitialized_move_if_noexcept(other.begin() + m_size, other.end(), this->end()); // may throw
Chris@16 1562 }
Chris@16 1563 else
Chris@16 1564 {
Chris@16 1565 sv::move_if_noexcept(other.begin(), other.end(), this->begin()); // may throw
Chris@16 1566 sv::destroy(this->begin() + other.size(), this->end());
Chris@16 1567 }
Chris@16 1568 m_size = other.size(); // update end
Chris@16 1569 }
Chris@16 1570
Chris@16 1571 // @par Throws
Chris@16 1572 // Nothing.
Chris@16 1573 // @par Complexity
Chris@16 1574 // Linear O(N).
Chris@16 1575 template <std::size_t C>
Chris@16 1576 void swap_dispatch(varray<value_type, C> & other, boost::true_type const& /*use_optimized_swap*/)
Chris@16 1577 {
Chris@16 1578 typedef typename
Chris@16 1579 boost::mpl::if_c<
Chris@16 1580 Capacity < C,
Chris@16 1581 aligned_storage_type,
Chris@16 1582 typename varray<value_type, C>::aligned_storage_type
Chris@16 1583 >::type
Chris@16 1584 storage_type;
Chris@16 1585
Chris@16 1586 storage_type temp;
Chris@16 1587 Value * temp_ptr = reinterpret_cast<Value*>(temp.address());
Chris@16 1588
Chris@16 1589 ::memcpy(temp_ptr, this->data(), sizeof(Value) * this->size());
Chris@16 1590 ::memcpy(this->data(), other.data(), sizeof(Value) * other.size());
Chris@16 1591 ::memcpy(other.data(), temp_ptr, sizeof(Value) * this->size());
Chris@16 1592
Chris@16 1593 std::swap(m_size, other.m_size);
Chris@16 1594 }
Chris@16 1595
Chris@16 1596 // @par Throws
Chris@16 1597 // If Value's move constructor or move assignment throws
Chris@16 1598 // but only if use_memop_in_swap_and_move is false_type - default.
Chris@16 1599 // @par Complexity
Chris@16 1600 // Linear O(N).
Chris@16 1601 template <std::size_t C>
Chris@16 1602 void swap_dispatch(varray<value_type, C> & other, boost::false_type const& /*use_optimized_swap*/)
Chris@16 1603 {
Chris@16 1604 namespace sv = varray_detail;
Chris@16 1605
Chris@16 1606 typedef typename
Chris@16 1607 vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
Chris@16 1608
Chris@16 1609 if ( this->size() < other.size() )
Chris@16 1610 swap_dispatch_impl(this->begin(), this->end(), other.begin(), other.end(), use_memop_in_swap_and_move()); // may throw
Chris@16 1611 else
Chris@16 1612 swap_dispatch_impl(other.begin(), other.end(), this->begin(), this->end(), use_memop_in_swap_and_move()); // may throw
Chris@16 1613 std::swap(m_size, other.m_size);
Chris@16 1614 }
Chris@16 1615
Chris@16 1616 // @par Throws
Chris@16 1617 // Nothing.
Chris@16 1618 // @par Complexity
Chris@16 1619 // Linear O(N).
Chris@16 1620 void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, boost::true_type const& /*use_memop*/)
Chris@16 1621 {
Chris@16 1622 //BOOST_ASSERT_MSG(std::distance(first_sm, last_sm) <= std::distance(first_la, last_la));
Chris@16 1623
Chris@16 1624 namespace sv = varray_detail;
Chris@16 1625 for (; first_sm != last_sm ; ++first_sm, ++first_la)
Chris@16 1626 {
Chris@16 1627 boost::aligned_storage<
Chris@16 1628 sizeof(value_type),
Chris@16 1629 boost::alignment_of<value_type>::value
Chris@16 1630 > temp_storage;
Chris@16 1631 value_type * temp_ptr = reinterpret_cast<value_type*>(temp_storage.address());
Chris@16 1632
Chris@16 1633 ::memcpy(temp_ptr, boost::addressof(*first_sm), sizeof(value_type));
Chris@16 1634 ::memcpy(boost::addressof(*first_sm), boost::addressof(*first_la), sizeof(value_type));
Chris@16 1635 ::memcpy(boost::addressof(*first_la), temp_ptr, sizeof(value_type));
Chris@16 1636 }
Chris@16 1637
Chris@16 1638 ::memcpy(first_sm, first_la, sizeof(value_type) * std::distance(first_la, last_la));
Chris@16 1639 }
Chris@16 1640
Chris@16 1641 // @par Throws
Chris@16 1642 // If Value's move constructor or move assignment throws.
Chris@16 1643 // @par Complexity
Chris@16 1644 // Linear O(N).
Chris@16 1645 void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, boost::false_type const& /*use_memop*/)
Chris@16 1646 {
Chris@16 1647 //BOOST_ASSERT_MSG(std::distance(first_sm, last_sm) <= std::distance(first_la, last_la));
Chris@16 1648
Chris@16 1649 namespace sv = varray_detail;
Chris@16 1650 for (; first_sm != last_sm ; ++first_sm, ++first_la)
Chris@16 1651 {
Chris@16 1652 //boost::swap(*first_sm, *first_la); // may throw
Chris@16 1653 value_type temp(boost::move(*first_sm)); // may throw
Chris@16 1654 *first_sm = boost::move(*first_la); // may throw
Chris@16 1655 *first_la = boost::move(temp); // may throw
Chris@16 1656 }
Chris@16 1657 sv::uninitialized_move(first_la, last_la, first_sm); // may throw
Chris@16 1658 sv::destroy(first_la, last_la);
Chris@16 1659 }
Chris@16 1660
Chris@16 1661 // insert
Chris@16 1662
Chris@16 1663 // @par Throws
Chris@16 1664 // If Value's move constructor, move assignment throws
Chris@16 1665 // or if Value's copy constructor or copy assignment throws.
Chris@16 1666 // @par Complexity
Chris@16 1667 // Linear O(N).
Chris@16 1668 template <typename Iterator>
Chris@16 1669 void insert_dispatch(iterator position, Iterator first, Iterator last, boost::random_access_traversal_tag const&)
Chris@16 1670 {
Chris@16 1671 BOOST_CONCEPT_ASSERT((boost_concepts::RandomAccessTraversal<Iterator>)); // Make sure you passed a RandomAccessIterator
Chris@16 1672
Chris@16 1673 errh::check_iterator_end_eq(*this, position);
Chris@16 1674
Chris@16 1675 typename boost::iterator_difference<Iterator>::type
Chris@16 1676 count = std::distance(first, last);
Chris@16 1677
Chris@16 1678 errh::check_capacity(*this, m_size + count); // may throw
Chris@16 1679
Chris@16 1680 if ( position == this->end() )
Chris@16 1681 {
Chris@16 1682 namespace sv = varray_detail;
Chris@16 1683
Chris@16 1684 sv::uninitialized_copy(first, last, position); // may throw
Chris@16 1685 m_size += count; // update end
Chris@16 1686 }
Chris@16 1687 else
Chris@16 1688 {
Chris@16 1689 this->insert_in_the_middle(position, first, last, count); // may throw
Chris@16 1690 }
Chris@16 1691 }
Chris@16 1692
Chris@16 1693 // @par Throws
Chris@16 1694 // If Value's move constructor, move assignment throws
Chris@16 1695 // or if Value's copy constructor or copy assignment throws.
Chris@16 1696 // @par Complexity
Chris@16 1697 // Linear O(N).
Chris@16 1698 template <typename Iterator, typename Traversal>
Chris@16 1699 void insert_dispatch(iterator position, Iterator first, Iterator last, Traversal const& /*not_random_access*/)
Chris@16 1700 {
Chris@16 1701 errh::check_iterator_end_eq(*this, position);
Chris@16 1702
Chris@16 1703 if ( position == this->end() )
Chris@16 1704 {
Chris@16 1705 namespace sv = varray_detail;
Chris@16 1706
Chris@16 1707 std::ptrdiff_t d = std::distance(position, this->begin() + Capacity);
Chris@16 1708 std::size_t count = sv::uninitialized_copy_s(first, last, position, d); // may throw
Chris@16 1709
Chris@16 1710 errh::check_capacity(*this, count <= static_cast<std::size_t>(d) ? m_size + count : Capacity + 1); // may throw
Chris@16 1711
Chris@16 1712 m_size += count;
Chris@16 1713 }
Chris@16 1714 else
Chris@16 1715 {
Chris@16 1716 typename boost::iterator_difference<Iterator>::type
Chris@16 1717 count = std::distance(first, last);
Chris@16 1718
Chris@16 1719 errh::check_capacity(*this, m_size + count); // may throw
Chris@16 1720
Chris@16 1721 this->insert_in_the_middle(position, first, last, count); // may throw
Chris@16 1722 }
Chris@16 1723 }
Chris@16 1724
Chris@16 1725 // @par Throws
Chris@16 1726 // If Value's move constructor, move assignment throws
Chris@16 1727 // or if Value's copy constructor or copy assignment throws.
Chris@16 1728 // @par Complexity
Chris@16 1729 // Linear O(N).
Chris@16 1730 template <typename Iterator>
Chris@16 1731 void insert_in_the_middle(iterator position, Iterator first, Iterator last, difference_type count)
Chris@16 1732 {
Chris@16 1733 namespace sv = varray_detail;
Chris@16 1734
Chris@16 1735 difference_type to_move = std::distance(position, this->end());
Chris@16 1736
Chris@16 1737 // TODO - should following lines check for exception and revert to the old size?
Chris@16 1738
Chris@16 1739 if ( count < to_move )
Chris@16 1740 {
Chris@16 1741 sv::uninitialized_move(this->end() - count, this->end(), this->end()); // may throw
Chris@16 1742 m_size += count; // update end
Chris@16 1743 sv::move_backward(position, position + to_move - count, this->end() - count); // may throw
Chris@16 1744 sv::copy(first, last, position); // may throw
Chris@16 1745 }
Chris@16 1746 else
Chris@16 1747 {
Chris@16 1748 Iterator middle_iter = first;
Chris@16 1749 std::advance(middle_iter, to_move);
Chris@16 1750
Chris@16 1751 sv::uninitialized_copy(middle_iter, last, this->end()); // may throw
Chris@16 1752 m_size += count - to_move; // update end
Chris@16 1753 sv::uninitialized_move(position, position + to_move, position + count); // may throw
Chris@16 1754 m_size += to_move; // update end
Chris@16 1755 sv::copy(first, middle_iter, position); // may throw
Chris@16 1756 }
Chris@16 1757 }
Chris@16 1758
Chris@16 1759 // assign
Chris@16 1760
Chris@16 1761 // @par Throws
Chris@16 1762 // If Value's constructor or assignment taking dereferenced Iterator throws.
Chris@16 1763 // @par Complexity
Chris@16 1764 // Linear O(N).
Chris@16 1765 template <typename Iterator>
Chris@16 1766 void assign_dispatch(Iterator first, Iterator last, boost::random_access_traversal_tag const& /*not_random_access*/)
Chris@16 1767 {
Chris@16 1768 namespace sv = varray_detail;
Chris@16 1769
Chris@16 1770 typename boost::iterator_difference<Iterator>::type
Chris@16 1771 s = std::distance(first, last);
Chris@16 1772
Chris@16 1773 errh::check_capacity(*this, s); // may throw
Chris@16 1774
Chris@16 1775 if ( m_size <= static_cast<size_type>(s) )
Chris@16 1776 {
Chris@16 1777 sv::copy(first, first + m_size, this->begin()); // may throw
Chris@16 1778 // TODO - perform uninitialized_copy first?
Chris@16 1779 sv::uninitialized_copy(first + m_size, last, this->end()); // may throw
Chris@16 1780 }
Chris@16 1781 else
Chris@16 1782 {
Chris@16 1783 sv::copy(first, last, this->begin()); // may throw
Chris@16 1784 sv::destroy(this->begin() + s, this->end());
Chris@16 1785 }
Chris@16 1786 m_size = s; // update end
Chris@16 1787 }
Chris@16 1788
Chris@16 1789 // @par Throws
Chris@16 1790 // If Value's constructor or assignment taking dereferenced Iterator throws.
Chris@16 1791 // @par Complexity
Chris@16 1792 // Linear O(N).
Chris@16 1793 template <typename Iterator, typename Traversal>
Chris@16 1794 void assign_dispatch(Iterator first, Iterator last, Traversal const& /*not_random_access*/)
Chris@16 1795 {
Chris@16 1796 namespace sv = varray_detail;
Chris@16 1797
Chris@16 1798 size_type s = 0;
Chris@16 1799 iterator it = this->begin();
Chris@16 1800
Chris@16 1801 for ( ; it != this->end() && first != last ; ++it, ++first, ++s )
Chris@16 1802 *it = *first; // may throw
Chris@16 1803
Chris@16 1804 sv::destroy(it, this->end());
Chris@16 1805
Chris@16 1806 std::ptrdiff_t d = std::distance(it, this->begin() + Capacity);
Chris@16 1807 std::size_t count = sv::uninitialized_copy_s(first, last, it, d); // may throw
Chris@16 1808 s += count;
Chris@16 1809
Chris@16 1810 errh::check_capacity(*this, count <= static_cast<std::size_t>(d) ? s : Capacity + 1); // may throw
Chris@16 1811
Chris@16 1812 m_size = s; // update end
Chris@16 1813 }
Chris@16 1814
Chris@16 1815 pointer ptr()
Chris@16 1816 {
Chris@16 1817 return pointer(static_cast<Value*>(m_storage.address()));
Chris@16 1818 }
Chris@16 1819
Chris@16 1820 const_pointer ptr() const
Chris@16 1821 {
Chris@16 1822 return const_pointer(static_cast<const Value*>(m_storage.address()));
Chris@16 1823 }
Chris@16 1824
Chris@16 1825 size_type m_size;
Chris@16 1826 aligned_storage_type m_storage;
Chris@16 1827 };
Chris@16 1828
Chris@16 1829 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 1830
Chris@16 1831 template<typename Value>
Chris@16 1832 class varray<Value, 0>
Chris@16 1833 {
Chris@16 1834 typedef varray_detail::varray_traits<Value, 0> vt;
Chris@16 1835 typedef varray_detail::checker<varray> errh;
Chris@16 1836
Chris@16 1837 public:
Chris@16 1838 typedef typename vt::value_type value_type;
Chris@16 1839 typedef typename vt::size_type size_type;
Chris@16 1840 typedef typename vt::difference_type difference_type;
Chris@16 1841 typedef typename vt::pointer pointer;
Chris@16 1842 typedef typename vt::const_pointer const_pointer;
Chris@16 1843 typedef typename vt::reference reference;
Chris@16 1844 typedef typename vt::const_reference const_reference;
Chris@16 1845
Chris@16 1846 typedef pointer iterator;
Chris@16 1847 typedef const_pointer const_iterator;
Chris@16 1848 typedef boost::reverse_iterator<iterator> reverse_iterator;
Chris@16 1849 typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
Chris@16 1850
Chris@16 1851 // nothrow
Chris@16 1852 varray() {}
Chris@16 1853
Chris@16 1854 // strong
Chris@16 1855 explicit varray(size_type count)
Chris@16 1856 {
Chris@16 1857 errh::check_capacity(*this, count); // may throw
Chris@16 1858 }
Chris@16 1859
Chris@16 1860 // strong
Chris@16 1861 varray(size_type count, value_type const&)
Chris@16 1862 {
Chris@16 1863 errh::check_capacity(*this, count); // may throw
Chris@16 1864 }
Chris@16 1865
Chris@16 1866 // strong
Chris@16 1867 varray(varray const& /*other*/)
Chris@16 1868 {
Chris@16 1869 //errh::check_capacity(*this, count);
Chris@16 1870 }
Chris@16 1871
Chris@16 1872 // strong
Chris@16 1873 template <std::size_t C>
Chris@16 1874 varray(varray<value_type, C> const& other)
Chris@16 1875 {
Chris@16 1876 errh::check_capacity(*this, other.size()); // may throw
Chris@16 1877 }
Chris@16 1878
Chris@16 1879 // strong
Chris@16 1880 template <typename Iterator>
Chris@16 1881 varray(Iterator first, Iterator last)
Chris@16 1882 {
Chris@16 1883 errh::check_capacity(*this, std::distance(first, last)); // may throw
Chris@16 1884 }
Chris@16 1885
Chris@16 1886 // basic
Chris@16 1887 varray & operator=(varray const& /*other*/)
Chris@16 1888 {
Chris@16 1889 //errh::check_capacity(*this, other.size());
Chris@16 1890 return *this;
Chris@16 1891 }
Chris@16 1892
Chris@16 1893 // basic
Chris@16 1894 template <size_t C>
Chris@16 1895 varray & operator=(varray<value_type, C> const& other)
Chris@16 1896 {
Chris@16 1897 errh::check_capacity(*this, other.size()); // may throw
Chris@16 1898 return *this;
Chris@16 1899 }
Chris@16 1900
Chris@16 1901 // nothrow
Chris@16 1902 ~varray() {}
Chris@16 1903
Chris@16 1904 // strong
Chris@16 1905 void resize(size_type count)
Chris@16 1906 {
Chris@16 1907 errh::check_capacity(*this, count); // may throw
Chris@16 1908 }
Chris@16 1909
Chris@16 1910 // strong
Chris@16 1911 void resize(size_type count, value_type const&)
Chris@16 1912 {
Chris@16 1913 errh::check_capacity(*this, count); // may throw
Chris@16 1914 }
Chris@16 1915
Chris@16 1916
Chris@16 1917 // nothrow
Chris@16 1918 void reserve(size_type count)
Chris@16 1919 {
Chris@16 1920 errh::check_capacity(*this, count); // may throw
Chris@16 1921 }
Chris@16 1922
Chris@16 1923 // strong
Chris@16 1924 void push_back(value_type const&)
Chris@16 1925 {
Chris@16 1926 errh::check_capacity(*this, 1); // may throw
Chris@16 1927 }
Chris@16 1928
Chris@16 1929 // nothrow
Chris@16 1930 void pop_back()
Chris@16 1931 {
Chris@16 1932 errh::check_not_empty(*this);
Chris@16 1933 }
Chris@16 1934
Chris@16 1935 // basic
Chris@16 1936 void insert(iterator position, value_type const&)
Chris@16 1937 {
Chris@16 1938 errh::check_iterator_end_eq(*this, position);
Chris@16 1939 errh::check_capacity(*this, 1); // may throw
Chris@16 1940 }
Chris@16 1941
Chris@16 1942 // basic
Chris@16 1943 void insert(iterator position, size_type count, value_type const&)
Chris@16 1944 {
Chris@16 1945 errh::check_iterator_end_eq(*this, position);
Chris@16 1946 errh::check_capacity(*this, count); // may throw
Chris@16 1947 }
Chris@16 1948
Chris@16 1949 // basic
Chris@16 1950 template <typename Iterator>
Chris@16 1951 void insert(iterator, Iterator first, Iterator last)
Chris@16 1952 {
Chris@16 1953 // TODO - add MPL_ASSERT, check if Iterator is really an iterator
Chris@16 1954 typedef typename boost::iterator_traversal<Iterator>::type traversal;
Chris@16 1955 errh::check_capacity(*this, std::distance(first, last)); // may throw
Chris@16 1956 }
Chris@16 1957
Chris@16 1958 // basic
Chris@16 1959 void erase(iterator position)
Chris@16 1960 {
Chris@16 1961 errh::check_iterator_end_neq(*this, position);
Chris@16 1962 }
Chris@16 1963
Chris@16 1964 // basic
Chris@16 1965 void erase(iterator first, iterator last)
Chris@16 1966 {
Chris@16 1967 errh::check_iterator_end_eq(*this, first);
Chris@16 1968 errh::check_iterator_end_eq(*this, last);
Chris@16 1969
Chris@16 1970 //BOOST_ASSERT_MSG(0 <= n, "invalid range");
Chris@16 1971 }
Chris@16 1972
Chris@16 1973 // basic
Chris@16 1974 template <typename Iterator>
Chris@16 1975 void assign(Iterator first, Iterator last)
Chris@16 1976 {
Chris@16 1977 // TODO - add MPL_ASSERT, check if Iterator is really an iterator
Chris@16 1978 typedef typename boost::iterator_traversal<Iterator>::type traversal;
Chris@16 1979 errh::check_capacity(*this, std::distance(first, last)); // may throw
Chris@16 1980 }
Chris@16 1981
Chris@16 1982 // basic
Chris@16 1983 void assign(size_type count, value_type const&)
Chris@16 1984 {
Chris@16 1985 errh::check_capacity(*this, count); // may throw
Chris@16 1986 }
Chris@16 1987
Chris@16 1988 // nothrow
Chris@16 1989 void clear() {}
Chris@16 1990
Chris@16 1991 // strong
Chris@16 1992 reference at(size_type i)
Chris@16 1993 {
Chris@16 1994 errh::throw_out_of_bounds(*this, i); // may throw
Chris@16 1995 return *(this->begin() + i);
Chris@16 1996 }
Chris@16 1997
Chris@16 1998 // strong
Chris@16 1999 const_reference at(size_type i) const
Chris@16 2000 {
Chris@16 2001 errh::throw_out_of_bounds(*this, i); // may throw
Chris@16 2002 return *(this->begin() + i);
Chris@16 2003 }
Chris@16 2004
Chris@16 2005 // nothrow
Chris@16 2006 reference operator[](size_type i)
Chris@16 2007 {
Chris@16 2008 errh::check_index(*this, i);
Chris@16 2009 return *(this->begin() + i);
Chris@16 2010 }
Chris@16 2011
Chris@16 2012 // nothrow
Chris@16 2013 const_reference operator[](size_type i) const
Chris@16 2014 {
Chris@16 2015 errh::check_index(*this, i);
Chris@16 2016 return *(this->begin() + i);
Chris@16 2017 }
Chris@16 2018
Chris@16 2019 // nothrow
Chris@16 2020 reference front()
Chris@16 2021 {
Chris@16 2022 errh::check_not_empty(*this);
Chris@16 2023 return *(this->begin());
Chris@16 2024 }
Chris@16 2025
Chris@16 2026 // nothrow
Chris@16 2027 const_reference front() const
Chris@16 2028 {
Chris@16 2029 errh::check_not_empty(*this);
Chris@16 2030 return *(this->begin());
Chris@16 2031 }
Chris@16 2032
Chris@16 2033 // nothrow
Chris@16 2034 reference back()
Chris@16 2035 {
Chris@16 2036 errh::check_not_empty(*this);
Chris@16 2037 return *(this->end() - 1);
Chris@16 2038 }
Chris@16 2039
Chris@16 2040 // nothrow
Chris@16 2041 const_reference back() const
Chris@16 2042 {
Chris@16 2043 errh::check_not_empty(*this);
Chris@16 2044 return *(this->end() - 1);
Chris@16 2045 }
Chris@16 2046
Chris@16 2047 // nothrow
Chris@16 2048 Value * data() { return boost::addressof(*(this->ptr())); }
Chris@16 2049 const Value * data() const { return boost::addressof(*(this->ptr())); }
Chris@16 2050
Chris@16 2051 // nothrow
Chris@16 2052 iterator begin() { return this->ptr(); }
Chris@16 2053 const_iterator begin() const { return this->ptr(); }
Chris@16 2054 const_iterator cbegin() const { return this->ptr(); }
Chris@16 2055 iterator end() { return this->begin(); }
Chris@16 2056 const_iterator end() const { return this->begin(); }
Chris@16 2057 const_iterator cend() const { return this->cbegin(); }
Chris@16 2058 // nothrow
Chris@16 2059 reverse_iterator rbegin() { return reverse_iterator(this->end()); }
Chris@16 2060 const_reverse_iterator rbegin() const { return reverse_iterator(this->end()); }
Chris@16 2061 const_reverse_iterator crbegin() const { return reverse_iterator(this->end()); }
Chris@16 2062 reverse_iterator rend() { return reverse_iterator(this->begin()); }
Chris@16 2063 const_reverse_iterator rend() const { return reverse_iterator(this->begin()); }
Chris@16 2064 const_reverse_iterator crend() const { return reverse_iterator(this->begin()); }
Chris@16 2065
Chris@16 2066 // nothrow
Chris@16 2067 size_type capacity() const { return 0; }
Chris@16 2068 size_type max_size() const { return 0; }
Chris@16 2069 size_type size() const { return 0; }
Chris@16 2070 bool empty() const { return true; }
Chris@16 2071
Chris@16 2072 private:
Chris@16 2073 pointer ptr()
Chris@16 2074 {
Chris@16 2075 return pointer(reinterpret_cast<Value*>(this));
Chris@16 2076 }
Chris@16 2077
Chris@16 2078 const_pointer ptr() const
Chris@16 2079 {
Chris@16 2080 return const_pointer(reinterpret_cast<const Value*>(this));
Chris@16 2081 }
Chris@16 2082 };
Chris@16 2083
Chris@16 2084 #endif // !BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@16 2085
Chris@16 2086 //! @brief Checks if contents of two varrays are equal.
Chris@16 2087 //!
Chris@16 2088 //! @ingroup varray_non_member
Chris@16 2089 //!
Chris@16 2090 //! @param x The first varray.
Chris@16 2091 //! @param y The second varray.
Chris@16 2092 //!
Chris@16 2093 //! @return \c true if containers have the same size and elements in both containers are equal.
Chris@16 2094 //!
Chris@16 2095 //! @par Complexity
Chris@16 2096 //! Linear O(N).
Chris@16 2097 template<typename V, std::size_t C1, std::size_t C2>
Chris@16 2098 bool operator== (varray<V, C1> const& x, varray<V, C2> const& y)
Chris@16 2099 {
Chris@16 2100 return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin());
Chris@16 2101 }
Chris@16 2102
Chris@16 2103 //! @brief Checks if contents of two varrays are not equal.
Chris@16 2104 //!
Chris@16 2105 //! @ingroup varray_non_member
Chris@16 2106 //!
Chris@16 2107 //! @param x The first varray.
Chris@16 2108 //! @param y The second varray.
Chris@16 2109 //!
Chris@16 2110 //! @return \c true if containers have different size or elements in both containers are not equal.
Chris@16 2111 //!
Chris@16 2112 //! @par Complexity
Chris@16 2113 //! Linear O(N).
Chris@16 2114 template<typename V, std::size_t C1, std::size_t C2>
Chris@16 2115 bool operator!= (varray<V, C1> const& x, varray<V, C2> const& y)
Chris@16 2116 {
Chris@16 2117 return !(x==y);
Chris@16 2118 }
Chris@16 2119
Chris@16 2120 //! @brief Lexicographically compares varrays.
Chris@16 2121 //!
Chris@16 2122 //! @ingroup varray_non_member
Chris@16 2123 //!
Chris@16 2124 //! @param x The first varray.
Chris@16 2125 //! @param y The second varray.
Chris@16 2126 //!
Chris@16 2127 //! @return \c true if x compares lexicographically less than y.
Chris@16 2128 //!
Chris@16 2129 //! @par Complexity
Chris@16 2130 //! Linear O(N).
Chris@16 2131 template<typename V, std::size_t C1, std::size_t C2>
Chris@16 2132 bool operator< (varray<V, C1> const& x, varray<V, C2> const& y)
Chris@16 2133 {
Chris@16 2134 return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
Chris@16 2135 }
Chris@16 2136
Chris@16 2137 //! @brief Lexicographically compares varrays.
Chris@16 2138 //!
Chris@16 2139 //! @ingroup varray_non_member
Chris@16 2140 //!
Chris@16 2141 //! @param x The first varray.
Chris@16 2142 //! @param y The second varray.
Chris@16 2143 //!
Chris@16 2144 //! @return \c true if y compares lexicographically less than x.
Chris@16 2145 //!
Chris@16 2146 //! @par Complexity
Chris@16 2147 //! Linear O(N).
Chris@16 2148 template<typename V, std::size_t C1, std::size_t C2>
Chris@16 2149 bool operator> (varray<V, C1> const& x, varray<V, C2> const& y)
Chris@16 2150 {
Chris@16 2151 return y<x;
Chris@16 2152 }
Chris@16 2153
Chris@16 2154 //! @brief Lexicographically compares varrays.
Chris@16 2155 //!
Chris@16 2156 //! @ingroup varray_non_member
Chris@16 2157 //!
Chris@16 2158 //! @param x The first varray.
Chris@16 2159 //! @param y The second varray.
Chris@16 2160 //!
Chris@16 2161 //! @return \c true if y don't compare lexicographically less than x.
Chris@16 2162 //!
Chris@16 2163 //! @par Complexity
Chris@16 2164 //! Linear O(N).
Chris@16 2165 template<typename V, std::size_t C1, std::size_t C2>
Chris@16 2166 bool operator<= (varray<V, C1> const& x, varray<V, C2> const& y)
Chris@16 2167 {
Chris@16 2168 return !(y<x);
Chris@16 2169 }
Chris@16 2170
Chris@16 2171 //! @brief Lexicographically compares varrays.
Chris@16 2172 //!
Chris@16 2173 //! @ingroup varray_non_member
Chris@16 2174 //!
Chris@16 2175 //! @param x The first varray.
Chris@16 2176 //! @param y The second varray.
Chris@16 2177 //!
Chris@16 2178 //! @return \c true if x don't compare lexicographically less than y.
Chris@16 2179 //!
Chris@16 2180 //! @par Complexity
Chris@16 2181 //! Linear O(N).
Chris@16 2182 template<typename V, std::size_t C1, std::size_t C2>
Chris@16 2183 bool operator>= (varray<V, C1> const& x, varray<V, C2> const& y)
Chris@16 2184 {
Chris@16 2185 return !(x<y);
Chris@16 2186 }
Chris@16 2187
Chris@16 2188 //! @brief Swaps contents of two varrays.
Chris@16 2189 //!
Chris@16 2190 //! This function calls varray::swap().
Chris@16 2191 //!
Chris@16 2192 //! @ingroup varray_non_member
Chris@16 2193 //!
Chris@16 2194 //! @param x The first varray.
Chris@16 2195 //! @param y The second varray.
Chris@16 2196 //!
Chris@16 2197 //! @par Complexity
Chris@16 2198 //! Linear O(N).
Chris@16 2199 template<typename V, std::size_t C1, std::size_t C2>
Chris@16 2200 inline void swap(varray<V, C1> & x, varray<V, C2> & y)
Chris@16 2201 {
Chris@16 2202 x.swap(y);
Chris@16 2203 }
Chris@16 2204
Chris@16 2205 }}}} // namespace boost::geometry::index::detail
Chris@16 2206
Chris@16 2207 // TODO - REMOVE/CHANGE
Chris@16 2208 #include <boost/container/detail/config_end.hpp>
Chris@16 2209
Chris@16 2210 #endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_HPP