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