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