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