annotate DEPENDENCIES/generic/include/boost/circular_buffer/details.hpp @ 125:34e428693f5d vext

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