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
|