Ticket #9334: 9334.patch
File 9334.patch, 22.6 KB (added by , 9 years ago) |
---|
-
include/boost/circular_buffer/base.hpp
From 0f66798d1decb6b25bdee27eafebbb3915500831 Mon Sep 17 00:00:00 2001 From: Antony Polukhin <antoshkka@gmail.com> Date: Tue, 3 Dec 2013 13:40:58 +0400 Subject: [PATCH 1/2] Fixed issues with allocators that do not return pointers, added tes case for such situations (refs #9334) --- include/boost/circular_buffer/base.hpp | 40 +++++++------- include/boost/circular_buffer/details.hpp | 89 ++++++++++++++++++++----------- test/common.ipp | 89 ++++++++++++++++++++++++++++++- 3 files changed, 166 insertions(+), 52 deletions(-) diff --git a/include/boost/circular_buffer/base.hpp b/include/boost/circular_buffer/base.hpp index b3cdf88..a80a103 100644
a b public: 690 690 break; 691 691 } 692 692 if (is_uninitialized(dest)) { 693 ::new (dest) value_type(this_type::move_if_noexcept(*src));693 cb_details::do_construct<value_type>(dest, this_type::move_if_noexcept(*src), m_alloc); 694 694 ++constructed; 695 695 } else { 696 696 value_type tmp = this_type::move_if_noexcept(*src); … … public: 902 902 iterator b = begin(); 903 903 BOOST_TRY { 904 904 reset(buff, 905 cb_details::uninitialized_move_if_noexcept <value_type>(b, b + (std::min)(new_capacity, size()), buff),905 cb_details::uninitialized_move_if_noexcept(b, b + (std::min)(new_capacity, size()), buff, m_alloc), 906 906 new_capacity); 907 907 } BOOST_CATCH(...) { 908 908 deallocate(buff, new_capacity); … … public: 977 977 pointer buff = allocate(new_capacity); 978 978 iterator e = end(); 979 979 BOOST_TRY { 980 reset(buff, cb_details::uninitialized_move_if_noexcept <value_type>(e - (std::min)(new_capacity, size()),981 e, buff ), new_capacity);980 reset(buff, cb_details::uninitialized_move_if_noexcept(e - (std::min)(new_capacity, size()), 981 e, buff, m_alloc), new_capacity); 982 982 } BOOST_CATCH(...) { 983 983 deallocate(buff, new_capacity); 984 984 BOOST_RETHROW … … public: 1125 1125 initialize_buffer(cb.capacity()); 1126 1126 m_first = m_buff; 1127 1127 BOOST_TRY { 1128 m_last = cb_details::uninitialized_copy <value_type>(cb.begin(), cb.end(), m_buff);1128 m_last = cb_details::uninitialized_copy(cb.begin(), cb.end(), m_buff, m_alloc); 1129 1129 } BOOST_CATCH(...) { 1130 1130 deallocate(m_buff, cb.capacity()); 1131 1131 BOOST_RETHROW … … public: 1249 1249 return *this; 1250 1250 pointer buff = allocate(cb.capacity()); 1251 1251 BOOST_TRY { 1252 reset(buff, cb_details::uninitialized_copy <value_type>(cb.begin(), cb.end(), buff), cb.capacity());1252 reset(buff, cb_details::uninitialized_copy(cb.begin(), cb.end(), buff, m_alloc), cb.capacity()); 1253 1253 } BOOST_CATCH(...) { 1254 1254 deallocate(buff, cb.capacity()); 1255 1255 BOOST_RETHROW … … private: 1446 1446 increment(m_last); 1447 1447 m_first = m_last; 1448 1448 } else { 1449 ::new (m_last) value_type(static_cast<ValT>(item));1449 cb_details::do_construct<value_type>(m_last, static_cast<ValT>(item), m_alloc); 1450 1450 increment(m_last); 1451 1451 ++m_size; 1452 1452 } … … private: 1463 1463 m_last = m_first; 1464 1464 } else { 1465 1465 decrement(m_first); 1466 ::new (m_first) value_type(static_cast<ValT>(item));1466 cb_details::do_construct<value_type>(m_first, static_cast<ValT>(item), m_alloc); 1467 1467 ++m_size; 1468 1468 } 1469 1469 } BOOST_CATCH(...) { … … private: 2397 2397 throw_exception(std::length_error("circular_buffer")); 2398 2398 #if BOOST_CB_ENABLE_DEBUG 2399 2399 pointer p = (n == 0) ? 0 : m_alloc.allocate(n, 0); 2400 std::memset( p, cb_details::UNINITIALIZED, sizeof(value_type) * n);2400 std::memset(boost::addressof(*p), cb_details::UNINITIALIZED, sizeof(value_type) * n); 2401 2401 return p; 2402 2402 #else 2403 2403 return (n == 0) ? 0 : m_alloc.allocate(n, 0); … … private: 2438 2438 */ 2439 2439 void construct_or_replace(bool construct, pointer pos, param_value_type item) { 2440 2440 if (construct) 2441 ::new (pos) value_type(item);2441 cb_details::do_construct<value_type>(pos, item, m_alloc); 2442 2442 else 2443 2443 replace(pos, item); 2444 2444 } … … private: 2450 2450 */ 2451 2451 void construct_or_replace(bool construct, pointer pos, rvalue_type item) { 2452 2452 if (construct) 2453 ::new (pos) value_type(boost::move(item));2453 cb_details::do_construct<value_type>(pos, boost::move(item), m_alloc); 2454 2454 else 2455 2455 replace(pos, boost::move(item)); 2456 2456 } … … private: 2460 2460 m_alloc.destroy(p); 2461 2461 #if BOOST_CB_ENABLE_DEBUG 2462 2462 invalidate_iterators(iterator(this, p)); 2463 std::memset( p, cb_details::UNINITIALIZED, sizeof(value_type));2463 std::memset(boost::addressof(*p), cb_details::UNINITIALIZED, sizeof(value_type)); 2464 2464 #endif 2465 2465 } 2466 2466 … … private: 2590 2590 if (buffer_capacity == 0) 2591 2591 return; 2592 2592 while (first != last && !full()) { 2593 ::new (m_last) value_type(*first++);2593 cb_details::do_construct<value_type>(m_last, *first++, m_alloc); 2594 2594 increment(m_last); 2595 2595 ++m_size; 2596 2596 } … … private: 2626 2626 m_size = distance; 2627 2627 } 2628 2628 BOOST_TRY { 2629 m_last = cb_details::uninitialized_copy <value_type>(first, last, m_buff);2629 m_last = cb_details::uninitialized_copy(first, last, m_buff, m_alloc); 2630 2630 } BOOST_CATCH(...) { 2631 2631 deallocate(m_buff, buffer_capacity); 2632 2632 BOOST_RETHROW … … private: 2680 2680 std::deque<value_type, allocator_type> tmp(first, last, m_alloc); 2681 2681 size_type distance = tmp.size(); 2682 2682 assign_n(distance, distance, 2683 cb_details::make_assign_range <value_type>2684 (boost::make_move_iterator(tmp.begin()), boost::make_move_iterator(tmp.end()) ));2683 cb_details::make_assign_range 2684 (boost::make_move_iterator(tmp.begin()), boost::make_move_iterator(tmp.end()), m_alloc)); 2685 2685 } 2686 2686 2687 2687 //! Specialized assign method. … … private: 2689 2689 void assign(ForwardIterator first, ForwardIterator last, const std::forward_iterator_tag&) { 2690 2690 BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range 2691 2691 size_type distance = std::distance(first, last); 2692 assign_n(distance, distance, cb_details::make_assign_range <value_type>(first, last));2692 assign_n(distance, distance, cb_details::make_assign_range(first, last, m_alloc)); 2693 2693 } 2694 2694 2695 2695 //! Specialized assign method. … … private: 2732 2732 distance = new_capacity; 2733 2733 } 2734 2734 assign_n(new_capacity, distance, 2735 cb_details::make_assign_range <value_type>(first, last));2735 cb_details::make_assign_range(first, last, m_alloc)); 2736 2736 } 2737 2737 2738 2738 //! Helper assign method. … … private: 2855 2855 pointer p = m_last; 2856 2856 BOOST_TRY { 2857 2857 for (; ii < construct; ++ii, increment(p)) 2858 ::new (p) value_type(*wrapper());2858 cb_details::do_construct<value_type>(p, *wrapper(), m_alloc); 2859 2859 for (;ii < n; ++ii, increment(p)) 2860 2860 replace(p, *wrapper()); 2861 2861 } BOOST_CATCH(...) { … … private: 2949 2949 for (;ii > construct; --ii, increment(p)) 2950 2950 replace(p, *wrapper()); 2951 2951 for (; ii > 0; --ii, increment(p)) 2952 ::new (p) value_type(*wrapper());2952 cb_details::do_construct<value_type>(p, *wrapper(), m_alloc); 2953 2953 } BOOST_CATCH(...) { 2954 2954 size_type constructed = ii < construct ? construct - ii : 0; 2955 2955 m_last = add(m_last, constructed); -
include/boost/circular_buffer/details.hpp
diff --git a/include/boost/circular_buffer/details.hpp b/include/boost/circular_buffer/details.hpp index 2ab1789..5d9c9b4 100644
a b template<class ForwardIterator, class Diff, class T, class Alloc> 38 38 void uninitialized_fill_n_with_alloc( 39 39 ForwardIterator first, Diff n, const T& item, Alloc& alloc); 40 40 41 template<class ValueType, class InputIterator, class ForwardIterator> 42 ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest); 41 template<class InputIterator, class ForwardIterator, class Alloc> 42 ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a); 43 44 template<class InputIterator, class ForwardIterator, class Alloc> 45 ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a); 46 47 48 //! Those `do_construct` methods are required because in C++03 default allocators 49 //! have `construct` method that accepts second parameter in as a const reference; 50 //! while move-only types emulated by Boost.Move require constructor that accepts 51 //! a non-const reference. 52 //! 53 //! So when we need to call `construct` and pointer to value_type is provided, we 54 //! assume that it is safe to call placement new instead of Alloc::construct. 55 //! Otherwise we are asume that user has made his own allocator or uses allocator 56 //! from other libraries. In that case it's users ability to provide Alloc::construct 57 //! with non-const reference parameter or just do not use move-only types. 58 template <class ValueType, class Alloc> 59 inline void do_construct(ValueType* p, BOOST_RV_REF(ValueType) item, Alloc&) { 60 ::new (p) ValueType(boost::move(item)); 61 } 62 63 template <class ValueType, class Alloc> 64 inline void do_construct(ValueType* p, const ValueType& item, Alloc&) { 65 ::new (p) ValueType(item); 66 } 43 67 44 template<class ValueType, class InputIterator, class ForwardIterator> 45 ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest); 68 template <class ValueType, class Alloc, class PointerT> 69 inline void do_construct(PointerT& p, BOOST_RV_REF(ValueType) item, Alloc& a) { 70 a.construct(p, boost::move(item)); 71 } 72 73 template <class ValueType, class Alloc, class PointerT> 74 inline void do_construct(PointerT& p, const ValueType& item, Alloc& a) { 75 a.construct(p, item); 76 } 46 77 47 78 /*! 48 79 \struct const_traits … … private: 127 158 \struct assign_range 128 159 \brief Helper functor for assigning range of items. 129 160 */ 130 template <class ValueType, class Iterator>161 template <class Iterator, class Alloc> 131 162 struct assign_range { 132 163 Iterator m_first; 133 164 Iterator m_last; 165 Alloc& m_alloc; 134 166 135 assign_range(const Iterator& first, const Iterator& last ) BOOST_NOEXCEPT136 : m_first(first), m_last(last) {}167 assign_range(const Iterator& first, const Iterator& last, Alloc& alloc) 168 : m_first(first), m_last(last), m_alloc(alloc) {} 137 169 138 170 template <class Pointer> 139 171 void operator () (Pointer p) const { 140 boost::cb_details::uninitialized_copy <ValueType>(m_first, m_last, p);172 boost::cb_details::uninitialized_copy(m_first, m_last, p, m_alloc); 141 173 } 142 174 }; 143 175 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);176 template <class Iterator, class Alloc> 177 inline assign_range<Iterator, Alloc> make_assign_range(const Iterator& first, const Iterator& last, Alloc& a) { 178 return assign_range<Iterator, Alloc>(first, last, a); 147 179 } 148 180 149 181 /*! … … operator + (typename Traits::difference_type n, const iterator<Buff, Traits>& it 427 459 \fn ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest) 428 460 \brief Equivalent of <code>std::uninitialized_copy</code> but with explicit specification of value type. 429 461 */ 430 template<class ValueType, class InputIterator, class ForwardIterator> 431 inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest) { 432 typedef ValueType value_type; 433 434 // We do not use allocator.construct and allocator.destroy 435 // because C++03 requires to take parameter by const reference but 436 // Boost.move requires nonconst reference 462 template<class InputIterator, class ForwardIterator, class Alloc> 463 inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a) { 437 464 ForwardIterator next = dest; 438 465 BOOST_TRY { 439 466 for (; first != last; ++first, ++dest) 440 ::new (dest) value_type(*first);467 do_construct<typename Alloc::value_type>(dest, *first, a); 441 468 } BOOST_CATCH(...) { 442 469 for (; next != dest; ++next) 443 next->~value_type();470 a.destroy(next); 444 471 BOOST_RETHROW 445 472 } 446 473 BOOST_CATCH_END 447 474 return dest; 448 475 } 449 476 450 template<class ValueType, class InputIterator, class ForwardIterator>451 ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, 477 template<class InputIterator, class ForwardIterator, class Alloc> 478 ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a, 452 479 true_type) { 453 480 for (; first != last; ++first, ++dest) 454 ::new (dest) ValueType(boost::move(*first));481 do_construct<typename Alloc::value_type>(dest, boost::move(*first), a); 455 482 return dest; 456 483 } 457 484 458 template<class ValueType, class InputIterator, class ForwardIterator>459 ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, 485 template<class InputIterator, class ForwardIterator, class Alloc> 486 ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a, 460 487 false_type) { 461 return uninitialized_copy <ValueType>(first, last, dest);488 return uninitialized_copy(first, last, dest, a); 462 489 } 463 490 464 491 /*! 465 492 \fn ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest) 466 493 \brief Equivalent of <code>std::uninitialized_copy</code> but with explicit specification of value type and moves elements if they have noexcept move constructors. 467 494 */ 468 template<class ValueType, class InputIterator, class ForwardIterator>469 ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest ) {470 typedef typename boost::is_nothrow_move_constructible< ValueType>::type tag_t;471 return uninitialized_move_if_noexcept_impl <ValueType>(first, last, dest, tag_t());495 template<class InputIterator, class ForwardIterator, class Alloc> 496 ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a) { 497 typedef typename boost::is_nothrow_move_constructible<typename Alloc::value_type>::type tag_t; 498 return uninitialized_move_if_noexcept_impl(first, last, dest, a, tag_t()); 472 499 } 473 500 474 501 /*! … … inline void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const 480 507 ForwardIterator next = first; 481 508 BOOST_TRY { 482 509 for (; n > 0; ++first, --n) 483 alloc.construct(first, item);510 do_construct<typename Alloc::value_type>(first, item, alloc); 484 511 } BOOST_CATCH(...) { 485 512 for (; next != first; ++next) 486 513 alloc.destroy(next); -
test/common.ipp
diff --git a/test/common.ipp b/test/common.ipp index 772b74f..67dd464 100644
a b 11 11 #include <boost/type_traits/is_nothrow_move_assignable.hpp> 12 12 #include <boost/type_traits/has_nothrow_constructor.hpp> 13 13 14 void generic_test(CB_CONTAINER<MyInteger>& cb) { 14 template <class Alloc> 15 void generic_test(CB_CONTAINER<MyInteger, Alloc>& cb) { 15 16 16 17 vector<int> v; 17 18 v.push_back(11); … … void size_test() { 149 150 generic_test(cb2); 150 151 } 151 152 153 template<class T> 154 class my_allocator { 155 typedef std::allocator<T> base_t; 156 base_t base_; 157 public: 158 typedef T value_type; 159 160 161 typedef value_type& reference; 162 typedef const value_type& const_reference; 163 typedef typename base_t::size_type size_type; 164 typedef typename base_t::difference_type difference_type; 165 166 struct const_pointer; 167 struct pointer { 168 pointer(){} 169 pointer(void* p) : hidden_ptr_((T*)p) {} 170 difference_type operator-(const const_pointer& rhs) const { return hidden_ptr_ - rhs.hidden_ptr_; } 171 difference_type operator-(pointer rhs) const { return hidden_ptr_ - rhs.hidden_ptr_; } 172 pointer operator-(size_type rhs) const { return hidden_ptr_ - rhs; } 173 bool operator == (pointer rhs) const { return hidden_ptr_ == rhs.hidden_ptr_; } 174 bool operator != (pointer rhs) const { return hidden_ptr_ != rhs.hidden_ptr_; } 175 bool operator < (pointer rhs) const { return hidden_ptr_ < rhs.hidden_ptr_; } 176 bool operator >= (pointer rhs) const { return hidden_ptr_ >= rhs.hidden_ptr_; } 177 pointer& operator++() { ++hidden_ptr_; return *this; } 178 pointer& operator--() { --hidden_ptr_; return *this; } 179 pointer& operator+=(size_type s) { hidden_ptr_ += s; return *this; } 180 pointer operator+(size_type s) const { return hidden_ptr_ + s; } 181 pointer operator++(int) { pointer p = *this; ++hidden_ptr_; return p; } 182 pointer operator--(int) { pointer p = *this; --hidden_ptr_; return p; } 183 T& operator*() const { return *hidden_ptr_; } 184 185 T* hidden_ptr_; 186 }; 187 188 struct const_pointer { 189 const_pointer(){} 190 const_pointer(pointer p) : hidden_ptr_(p.hidden_ptr_) {} 191 const_pointer(const void* p) : hidden_ptr_((const T*)p) {} 192 difference_type operator-(pointer rhs) const { return hidden_ptr_ - rhs.hidden_ptr_; } 193 difference_type operator-(const_pointer rhs) const { return hidden_ptr_ - rhs.hidden_ptr_; } 194 const_pointer operator-(size_type rhs) const { return hidden_ptr_ - rhs; } 195 bool operator == (const_pointer rhs) const { return hidden_ptr_ == rhs.hidden_ptr_; } 196 bool operator != (const_pointer rhs) const { return hidden_ptr_ != rhs.hidden_ptr_; } 197 bool operator < (const_pointer rhs) const { return hidden_ptr_ < rhs.hidden_ptr_; } 198 bool operator >= (const_pointer rhs) const { return hidden_ptr_ >= rhs.hidden_ptr_; } 199 const_pointer& operator++() { ++hidden_ptr_; return *this; } 200 const_pointer& operator--() { --hidden_ptr_; return *this; } 201 const_pointer& operator+=(size_type s) { hidden_ptr_ += s; return hidden_ptr_; } 202 const_pointer operator+(size_type s) const { return hidden_ptr_ + s; } 203 const_pointer operator++(int) { const_pointer p = *this; ++hidden_ptr_; return p; } 204 const_pointer operator--(int) { const_pointer p = *this; --hidden_ptr_; return p; } 205 const T& operator*() const { return *hidden_ptr_; } 206 207 const T* hidden_ptr_; 208 }; 209 210 template<class T2> 211 struct rebind 212 { 213 typedef my_allocator<T2> other; 214 }; 215 216 size_type max_size() const 217 { return base_.max_size(); } 218 219 pointer allocate(size_type count, const void* hint = 0) { 220 return pointer(base_.allocate(count, hint)); 221 } 222 223 void deallocate(const pointer &ptr, size_type s) 224 { base_.deallocate(ptr.hidden_ptr_, s); } 225 226 template<class P> 227 void construct(const pointer &ptr, BOOST_FWD_REF(P) p) 228 { ::new(ptr.hidden_ptr_) value_type(::boost::forward<P>(p)); } 229 230 void destroy(const pointer &ptr) 231 { (*ptr.hidden_ptr_).~value_type(); } 232 233 }; 234 152 235 void allocator_test() { 153 236 154 237 CB_CONTAINER<MyInteger> cb1(10, 0); … … void allocator_test() { 159 242 alloc.max_size(); 160 243 161 244 generic_test(cb1); 245 246 247 CB_CONTAINER<MyInteger, my_allocator<MyInteger> > cb_a(10, 0); 248 generic_test(cb_a); 162 249 } 163 250 164 251 void begin_and_end_test() { -
include/boost/circular_buffer/base.hpp
-- 1.8.4.4 From 4bdfcaaa088a15fcc2294a524453cf9740e5070a Mon Sep 17 00:00:00 2001 From: Antony Polukhin <antoshkka@gmail.com> Date: Tue, 3 Dec 2013 15:44:43 +0400 Subject: [PATCH 2/2] Fixed setting memory to '0xcc' in debug mode for non-pointer allocator::pointer types --- include/boost/circular_buffer/base.hpp | 15 ++------------- include/boost/circular_buffer/debug.hpp | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/include/boost/circular_buffer/base.hpp b/include/boost/circular_buffer/base.hpp index a80a103..b3913d6 100644
a b 34 34 #include <utility> 35 35 #include <deque> 36 36 #include <stdexcept> 37 #if BOOST_CB_ENABLE_DEBUG38 #include <cstring>39 #endif40 37 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) 41 38 #include <stddef.h> 42 39 #endif 43 40 44 #if defined(BOOST_NO_STDC_NAMESPACE)45 namespace std {46 using ::memset;47 }48 #endif49 50 51 52 41 namespace boost { 53 42 54 43 /*! … … private: 2397 2386 throw_exception(std::length_error("circular_buffer")); 2398 2387 #if BOOST_CB_ENABLE_DEBUG 2399 2388 pointer p = (n == 0) ? 0 : m_alloc.allocate(n, 0); 2400 std::memset(boost::addressof(*p), cb_details::UNINITIALIZED, sizeof(value_type) * n);2389 cb_details::do_fill_uninitialized_memory(p, sizeof(value_type) * n); 2401 2390 return p; 2402 2391 #else 2403 2392 return (n == 0) ? 0 : m_alloc.allocate(n, 0); … … private: 2460 2449 m_alloc.destroy(p); 2461 2450 #if BOOST_CB_ENABLE_DEBUG 2462 2451 invalidate_iterators(iterator(this, p)); 2463 std::memset(boost::addressof(*p), cb_details::UNINITIALIZED, sizeof(value_type));2452 cb_details::do_fill_uninitialized_memory(p, sizeof(value_type)); 2464 2453 #endif 2465 2454 } 2466 2455 -
include/boost/circular_buffer/debug.hpp
diff --git a/include/boost/circular_buffer/debug.hpp b/include/boost/circular_buffer/debug.hpp index d3b6ef5..b6ab0fe 100644
a b 13 13 #pragma once 14 14 #endif 15 15 16 #if BOOST_CB_ENABLE_DEBUG 17 #include <cstring> 18 19 #if defined(BOOST_NO_STDC_NAMESPACE) 20 namespace std { 21 using ::memset; 22 } 23 #endif 24 25 #endif // BOOST_CB_ENABLE_DEBUG 16 26 namespace boost { 17 27 18 28 namespace cb_details { … … namespace cb_details { 22 32 // The value the uninitialized memory is filled with. 23 33 const int UNINITIALIZED = 0xcc; 24 34 35 template <class T> 36 inline void do_fill_uninitialized_memory(T* data, std::size_t size_in_bytes) BOOST_NOEXCEPT { 37 std::memset(static_cast<void*>(data), UNINITIALIZED, size_in_bytes); 38 } 39 40 template <class T> 41 inline void do_fill_uninitialized_memory(T& /*data*/, std::size_t /*size_in_bytes*/) BOOST_NOEXCEPT { 42 // Do nothing 43 } 44 45 25 46 class debug_iterator_registry; 26 47 27 48 /*!