Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/circular_buffer/details.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // Helper classes and functions for the circular buffer. | |
2 | |
3 // Copyright (c) 2003-2008 Jan Gaspar | |
4 | |
5 // Use, modification, and distribution is subject to the Boost Software | |
6 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
7 // http://www.boost.org/LICENSE_1_0.txt) | |
8 | |
9 #if !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP) | |
10 #define BOOST_CIRCULAR_BUFFER_DETAILS_HPP | |
11 | |
12 #if defined(_MSC_VER) && _MSC_VER >= 1200 | |
13 #pragma once | |
14 #endif | |
15 | |
16 #include <boost/iterator.hpp> | |
17 #include <boost/throw_exception.hpp> | |
18 #include <boost/move/move.hpp> | |
19 #include <boost/type_traits/is_nothrow_move_constructible.hpp> | |
20 #include <boost/detail/no_exceptions_support.hpp> | |
21 #include <iterator> | |
22 | |
23 // Silence MS /W4 warnings like C4913: | |
24 // "user defined binary operator ',' exists but no overload could convert all operands, default built-in binary operator ',' used" | |
25 // This might happen when previously including some boost headers that overload the coma operator. | |
26 #if defined(_MSC_VER) | |
27 # pragma warning(push) | |
28 # pragma warning(disable:4913) | |
29 #endif | |
30 | |
31 namespace boost { | |
32 | |
33 namespace cb_details { | |
34 | |
35 template <class Traits> struct nonconst_traits; | |
36 | |
37 template<class ForwardIterator, class Diff, class T, class Alloc> | |
38 void uninitialized_fill_n_with_alloc( | |
39 ForwardIterator first, Diff n, const T& item, Alloc& alloc); | |
40 | |
41 template<class ValueType, class InputIterator, class ForwardIterator> | |
42 ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest); | |
43 | |
44 template<class ValueType, class InputIterator, class ForwardIterator> | |
45 ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest); | |
46 | |
47 /*! | |
48 \struct const_traits | |
49 \brief Defines the data types for a const iterator. | |
50 */ | |
51 template <class Traits> | |
52 struct const_traits { | |
53 // Basic types | |
54 typedef typename Traits::value_type value_type; | |
55 typedef typename Traits::const_pointer pointer; | |
56 typedef typename Traits::const_reference reference; | |
57 typedef typename Traits::size_type size_type; | |
58 typedef typename Traits::difference_type difference_type; | |
59 | |
60 // Non-const traits | |
61 typedef nonconst_traits<Traits> nonconst_self; | |
62 }; | |
63 | |
64 /*! | |
65 \struct nonconst_traits | |
66 \brief Defines the data types for a non-const iterator. | |
67 */ | |
68 template <class Traits> | |
69 struct nonconst_traits { | |
70 // Basic types | |
71 typedef typename Traits::value_type value_type; | |
72 typedef typename Traits::pointer pointer; | |
73 typedef typename Traits::reference reference; | |
74 typedef typename Traits::size_type size_type; | |
75 typedef typename Traits::difference_type difference_type; | |
76 | |
77 // Non-const traits | |
78 typedef nonconst_traits<Traits> nonconst_self; | |
79 }; | |
80 | |
81 /*! | |
82 \struct iterator_wrapper | |
83 \brief Helper iterator dereference wrapper. | |
84 */ | |
85 template <class Iterator> | |
86 struct iterator_wrapper { | |
87 mutable Iterator m_it; | |
88 explicit iterator_wrapper(Iterator it) : m_it(it) {} | |
89 Iterator operator () () const { return m_it++; } | |
90 private: | |
91 iterator_wrapper<Iterator>& operator = (const iterator_wrapper<Iterator>&); // do not generate | |
92 }; | |
93 | |
94 /*! | |
95 \struct item_wrapper | |
96 \brief Helper item dereference wrapper. | |
97 */ | |
98 template <class Pointer, class Value> | |
99 struct item_wrapper { | |
100 Value m_item; | |
101 explicit item_wrapper(Value item) : m_item(item) {} | |
102 Pointer operator () () const { return &m_item; } | |
103 private: | |
104 item_wrapper<Pointer, Value>& operator = (const item_wrapper<Pointer, Value>&); // do not generate | |
105 }; | |
106 | |
107 /*! | |
108 \struct assign_n | |
109 \brief Helper functor for assigning n items. | |
110 */ | |
111 template <class Value, class Alloc> | |
112 struct assign_n { | |
113 typedef typename Alloc::size_type size_type; | |
114 size_type m_n; | |
115 Value m_item; | |
116 Alloc& m_alloc; | |
117 assign_n(size_type n, Value item, Alloc& alloc) : m_n(n), m_item(item), m_alloc(alloc) {} | |
118 template <class Pointer> | |
119 void operator () (Pointer p) const { | |
120 uninitialized_fill_n_with_alloc(p, m_n, m_item, m_alloc); | |
121 } | |
122 private: | |
123 assign_n<Value, Alloc>& operator = (const assign_n<Value, Alloc>&); // do not generate | |
124 }; | |
125 | |
126 /*! | |
127 \struct assign_range | |
128 \brief Helper functor for assigning range of items. | |
129 */ | |
130 template <class ValueType, class Iterator> | |
131 struct assign_range { | |
132 Iterator m_first; | |
133 Iterator m_last; | |
134 | |
135 assign_range(const Iterator& first, const Iterator& last) BOOST_NOEXCEPT | |
136 : m_first(first), m_last(last) {} | |
137 | |
138 template <class Pointer> | |
139 void operator () (Pointer p) const { | |
140 boost::cb_details::uninitialized_copy<ValueType>(m_first, m_last, p); | |
141 } | |
142 }; | |
143 | |
144 template <class ValueType, class Iterator> | |
145 inline assign_range<ValueType, Iterator> make_assign_range(const Iterator& first, const Iterator& last) { | |
146 return assign_range<ValueType, Iterator>(first, last); | |
147 } | |
148 | |
149 /*! | |
150 \class capacity_control | |
151 \brief Capacity controller of the space optimized circular buffer. | |
152 */ | |
153 template <class Size> | |
154 class capacity_control { | |
155 | |
156 //! The capacity of the space-optimized circular buffer. | |
157 Size m_capacity; | |
158 | |
159 //! The lowest guaranteed or minimum capacity of the adapted space-optimized circular buffer. | |
160 Size m_min_capacity; | |
161 | |
162 public: | |
163 | |
164 //! Constructor. | |
165 capacity_control(Size buffer_capacity, Size min_buffer_capacity = 0) | |
166 : m_capacity(buffer_capacity), m_min_capacity(min_buffer_capacity) | |
167 { // Check for capacity lower than min_capacity. | |
168 BOOST_CB_ASSERT(buffer_capacity >= min_buffer_capacity); | |
169 } | |
170 | |
171 // Default copy constructor. | |
172 | |
173 // Default assign operator. | |
174 | |
175 //! Get the capacity of the space optimized circular buffer. | |
176 Size capacity() const { return m_capacity; } | |
177 | |
178 //! Get the minimal capacity of the space optimized circular buffer. | |
179 Size min_capacity() const { return m_min_capacity; } | |
180 | |
181 //! Size operator - returns the capacity of the space optimized circular buffer. | |
182 operator Size() const { return m_capacity; } | |
183 }; | |
184 | |
185 /*! | |
186 \struct iterator | |
187 \brief Random access iterator for the circular buffer. | |
188 \param Buff The type of the underlying circular buffer. | |
189 \param Traits Basic iterator types. | |
190 \note This iterator is not circular. It was designed | |
191 for iterating from begin() to end() of the circular buffer. | |
192 */ | |
193 template <class Buff, class Traits> | |
194 struct iterator : | |
195 public boost::iterator< | |
196 std::random_access_iterator_tag, | |
197 typename Traits::value_type, | |
198 typename Traits::difference_type, | |
199 typename Traits::pointer, | |
200 typename Traits::reference> | |
201 #if BOOST_CB_ENABLE_DEBUG | |
202 , public debug_iterator_base | |
203 #endif // #if BOOST_CB_ENABLE_DEBUG | |
204 { | |
205 // Helper types | |
206 | |
207 //! Base iterator. | |
208 typedef boost::iterator< | |
209 std::random_access_iterator_tag, | |
210 typename Traits::value_type, | |
211 typename Traits::difference_type, | |
212 typename Traits::pointer, | |
213 typename Traits::reference> base_iterator; | |
214 | |
215 //! Non-const iterator. | |
216 typedef iterator<Buff, typename Traits::nonconst_self> nonconst_self; | |
217 | |
218 // Basic types | |
219 | |
220 //! The type of the elements stored in the circular buffer. | |
221 typedef typename base_iterator::value_type value_type; | |
222 | |
223 //! Pointer to the element. | |
224 typedef typename base_iterator::pointer pointer; | |
225 | |
226 //! Reference to the element. | |
227 typedef typename base_iterator::reference reference; | |
228 | |
229 //! Size type. | |
230 typedef typename Traits::size_type size_type; | |
231 | |
232 //! Difference type. | |
233 typedef typename base_iterator::difference_type difference_type; | |
234 | |
235 // Member variables | |
236 | |
237 //! The circular buffer where the iterator points to. | |
238 const Buff* m_buff; | |
239 | |
240 //! An internal iterator. | |
241 pointer m_it; | |
242 | |
243 // Construction & assignment | |
244 | |
245 // Default copy constructor. | |
246 | |
247 //! Default constructor. | |
248 iterator() : m_buff(0), m_it(0) {} | |
249 | |
250 #if BOOST_CB_ENABLE_DEBUG | |
251 | |
252 //! Copy constructor (used for converting from a non-const to a const iterator). | |
253 iterator(const nonconst_self& it) : debug_iterator_base(it), m_buff(it.m_buff), m_it(it.m_it) {} | |
254 | |
255 //! Internal constructor. | |
256 /*! | |
257 \note This constructor is not intended to be used directly by the user. | |
258 */ | |
259 iterator(const Buff* cb, const pointer p) : debug_iterator_base(cb), m_buff(cb), m_it(p) {} | |
260 | |
261 #else | |
262 | |
263 iterator(const nonconst_self& it) : m_buff(it.m_buff), m_it(it.m_it) {} | |
264 | |
265 iterator(const Buff* cb, const pointer p) : m_buff(cb), m_it(p) {} | |
266 | |
267 #endif // #if BOOST_CB_ENABLE_DEBUG | |
268 | |
269 //! Assign operator. | |
270 iterator& operator = (const iterator& it) { | |
271 if (this == &it) | |
272 return *this; | |
273 #if BOOST_CB_ENABLE_DEBUG | |
274 debug_iterator_base::operator =(it); | |
275 #endif // #if BOOST_CB_ENABLE_DEBUG | |
276 m_buff = it.m_buff; | |
277 m_it = it.m_it; | |
278 return *this; | |
279 } | |
280 | |
281 // Random access iterator methods | |
282 | |
283 //! Dereferencing operator. | |
284 reference operator * () const { | |
285 BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator | |
286 BOOST_CB_ASSERT(m_it != 0); // check for iterator pointing to end() | |
287 return *m_it; | |
288 } | |
289 | |
290 //! Dereferencing operator. | |
291 pointer operator -> () const { return &(operator*()); } | |
292 | |
293 //! Difference operator. | |
294 template <class Traits0> | |
295 difference_type operator - (const iterator<Buff, Traits0>& it) const { | |
296 BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator | |
297 BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator | |
298 return linearize_pointer(*this) - linearize_pointer(it); | |
299 } | |
300 | |
301 //! Increment operator (prefix). | |
302 iterator& operator ++ () { | |
303 BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator | |
304 BOOST_CB_ASSERT(m_it != 0); // check for iterator pointing to end() | |
305 m_buff->increment(m_it); | |
306 if (m_it == m_buff->m_last) | |
307 m_it = 0; | |
308 return *this; | |
309 } | |
310 | |
311 //! Increment operator (postfix). | |
312 iterator operator ++ (int) { | |
313 iterator<Buff, Traits> tmp = *this; | |
314 ++*this; | |
315 return tmp; | |
316 } | |
317 | |
318 //! Decrement operator (prefix). | |
319 iterator& operator -- () { | |
320 BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator | |
321 BOOST_CB_ASSERT(m_it != m_buff->m_first); // check for iterator pointing to begin() | |
322 if (m_it == 0) | |
323 m_it = m_buff->m_last; | |
324 m_buff->decrement(m_it); | |
325 return *this; | |
326 } | |
327 | |
328 //! Decrement operator (postfix). | |
329 iterator operator -- (int) { | |
330 iterator<Buff, Traits> tmp = *this; | |
331 --*this; | |
332 return tmp; | |
333 } | |
334 | |
335 //! Iterator addition. | |
336 iterator& operator += (difference_type n) { | |
337 BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator | |
338 if (n > 0) { | |
339 BOOST_CB_ASSERT(m_buff->end() - *this >= n); // check for too large n | |
340 m_it = m_buff->add(m_it, n); | |
341 if (m_it == m_buff->m_last) | |
342 m_it = 0; | |
343 } else if (n < 0) { | |
344 *this -= -n; | |
345 } | |
346 return *this; | |
347 } | |
348 | |
349 //! Iterator addition. | |
350 iterator operator + (difference_type n) const { return iterator<Buff, Traits>(*this) += n; } | |
351 | |
352 //! Iterator subtraction. | |
353 iterator& operator -= (difference_type n) { | |
354 BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator | |
355 if (n > 0) { | |
356 BOOST_CB_ASSERT(*this - m_buff->begin() >= n); // check for too large n | |
357 m_it = m_buff->sub(m_it == 0 ? m_buff->m_last : m_it, n); | |
358 } else if (n < 0) { | |
359 *this += -n; | |
360 } | |
361 return *this; | |
362 } | |
363 | |
364 //! Iterator subtraction. | |
365 iterator operator - (difference_type n) const { return iterator<Buff, Traits>(*this) -= n; } | |
366 | |
367 //! Element access operator. | |
368 reference operator [] (difference_type n) const { return *(*this + n); } | |
369 | |
370 // Equality & comparison | |
371 | |
372 //! Equality. | |
373 template <class Traits0> | |
374 bool operator == (const iterator<Buff, Traits0>& it) const { | |
375 BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator | |
376 BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator | |
377 return m_it == it.m_it; | |
378 } | |
379 | |
380 //! Inequality. | |
381 template <class Traits0> | |
382 bool operator != (const iterator<Buff, Traits0>& it) const { | |
383 BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator | |
384 BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator | |
385 return m_it != it.m_it; | |
386 } | |
387 | |
388 //! Less. | |
389 template <class Traits0> | |
390 bool operator < (const iterator<Buff, Traits0>& it) const { | |
391 BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator | |
392 BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator | |
393 return linearize_pointer(*this) < linearize_pointer(it); | |
394 } | |
395 | |
396 //! Greater. | |
397 template <class Traits0> | |
398 bool operator > (const iterator<Buff, Traits0>& it) const { return it < *this; } | |
399 | |
400 //! Less or equal. | |
401 template <class Traits0> | |
402 bool operator <= (const iterator<Buff, Traits0>& it) const { return !(it < *this); } | |
403 | |
404 //! Greater or equal. | |
405 template <class Traits0> | |
406 bool operator >= (const iterator<Buff, Traits0>& it) const { return !(*this < it); } | |
407 | |
408 // Helpers | |
409 | |
410 //! Get a pointer which would point to the same element as the iterator in case the circular buffer is linearized. | |
411 template <class Traits0> | |
412 typename Traits0::pointer linearize_pointer(const iterator<Buff, Traits0>& it) const { | |
413 return it.m_it == 0 ? m_buff->m_buff + m_buff->size() : | |
414 (it.m_it < m_buff->m_first ? it.m_it + (m_buff->m_end - m_buff->m_first) | |
415 : m_buff->m_buff + (it.m_it - m_buff->m_first)); | |
416 } | |
417 }; | |
418 | |
419 //! Iterator addition. | |
420 template <class Buff, class Traits> | |
421 inline iterator<Buff, Traits> | |
422 operator + (typename Traits::difference_type n, const iterator<Buff, Traits>& it) { | |
423 return it + n; | |
424 } | |
425 | |
426 #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) | |
427 | |
428 //! Iterator category. | |
429 template <class Buff, class Traits> | |
430 inline std::random_access_iterator_tag iterator_category(const iterator<Buff, Traits>&) { | |
431 return std::random_access_iterator_tag(); | |
432 } | |
433 | |
434 //! The type of the elements stored in the circular buffer. | |
435 template <class Buff, class Traits> | |
436 inline typename Traits::value_type* value_type(const iterator<Buff, Traits>&) { return 0; } | |
437 | |
438 //! Distance type. | |
439 template <class Buff, class Traits> | |
440 inline typename Traits::difference_type* distance_type(const iterator<Buff, Traits>&) { return 0; } | |
441 | |
442 #endif // #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) | |
443 | |
444 /*! | |
445 \fn ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest) | |
446 \brief Equivalent of <code>std::uninitialized_copy</code> but with explicit specification of value type. | |
447 */ | |
448 template<class ValueType, class InputIterator, class ForwardIterator> | |
449 inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest) { | |
450 typedef ValueType value_type; | |
451 | |
452 // We do not use allocator.construct and allocator.destroy | |
453 // because C++03 requires to take parameter by const reference but | |
454 // Boost.move requires nonconst reference | |
455 ForwardIterator next = dest; | |
456 BOOST_TRY { | |
457 for (; first != last; ++first, ++dest) | |
458 ::new (dest) value_type(*first); | |
459 } BOOST_CATCH(...) { | |
460 for (; next != dest; ++next) | |
461 next->~value_type(); | |
462 BOOST_RETHROW | |
463 } | |
464 BOOST_CATCH_END | |
465 return dest; | |
466 } | |
467 | |
468 template<class ValueType, class InputIterator, class ForwardIterator> | |
469 ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, | |
470 true_type) { | |
471 for (; first != last; ++first, ++dest) | |
472 ::new (dest) ValueType(boost::move(*first)); | |
473 return dest; | |
474 } | |
475 | |
476 template<class ValueType, class InputIterator, class ForwardIterator> | |
477 ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, | |
478 false_type) { | |
479 return uninitialized_copy<ValueType>(first, last, dest); | |
480 } | |
481 | |
482 /*! | |
483 \fn ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest) | |
484 \brief Equivalent of <code>std::uninitialized_copy</code> but with explicit specification of value type and moves elements if they have noexcept move constructors. | |
485 */ | |
486 template<class ValueType, class InputIterator, class ForwardIterator> | |
487 ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest) { | |
488 typedef typename boost::is_nothrow_move_constructible<ValueType>::type tag_t; | |
489 return uninitialized_move_if_noexcept_impl<ValueType>(first, last, dest, tag_t()); | |
490 } | |
491 | |
492 /*! | |
493 \fn void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const T& item, Alloc& alloc) | |
494 \brief Equivalent of <code>std::uninitialized_fill_n</code> with allocator. | |
495 */ | |
496 template<class ForwardIterator, class Diff, class T, class Alloc> | |
497 inline void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const T& item, Alloc& alloc) { | |
498 ForwardIterator next = first; | |
499 BOOST_TRY { | |
500 for (; n > 0; ++first, --n) | |
501 alloc.construct(first, item); | |
502 } BOOST_CATCH(...) { | |
503 for (; next != first; ++next) | |
504 alloc.destroy(next); | |
505 BOOST_RETHROW | |
506 } | |
507 BOOST_CATCH_END | |
508 } | |
509 | |
510 } // namespace cb_details | |
511 | |
512 } // namespace boost | |
513 | |
514 #if defined(_MSC_VER) | |
515 # pragma warning(pop) | |
516 #endif | |
517 | |
518 #endif // #if !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP) |