Compare commits

..

1 Commits

Author SHA1 Message Date
Marshall Clow
aca434d344 Release 1.55.0
[SVN r86621]
2013-11-11 19:45:21 +00:00
18 changed files with 262 additions and 335 deletions

View File

@@ -334,9 +334,9 @@ so for example: iterators `(begin() - 1)` and `(end() + 1)` are both invalid.
[h3 Debug Support]
In order to help a programmer to avoid and find common bugs,
the __cb can be enabled to provide a kind of debug support.
the __cb contains a kind of debug support.
When the debugging functionality is enabled, the __cb maintains a list of valid iterators.
The __cb maintains a list of valid iterators.
As soon as any element gets destroyed all iterators pointing to this element
are removed from this list and explicitly invalidated (an invalidation flag is set).
The debug support also consists of many assertions (`BOOST_ASSERT` macros)
@@ -349,13 +349,9 @@ Moreover, the uninitialized memory allocated by __cb is filled with the value `0
When debugging the code, this can help the programmer to recognize the initialized memory from the uninitialized.
For details refer the source code [@boost:boost/circular_buffer/debug.hpp circular_buffer/debug.hpp].
[caution Since the debugging code makes __cb and its iterators more interconnected, thread safety guarantees of __cb
are different when debug support is enabled. In addition to the container itself, all iterators tracked by the container
(including any copies thereof) must be protected from concurrent access. In particular, this includes copying, destroying or
obtaining iterators from the container, even if for read-only access.]
The debug support is disabled by default. To enable it, one has to define `BOOST_CB_ENABLE_DEBUG` macro with the value of 1
while compiling the code using __cb.
The debug support is enabled only in the debug mode (when the `NDEBUG` is not defined).
It can also be explicitly disabled (only for __cb)
by defining macro BOOST_CB_DISABLE_DEBUG.
[h3 Compatibility with Interprocess library]
@@ -364,7 +360,7 @@ The __cb is compatible with the [@boost:libs/interprocess/index.html Boost.Inte
library used for interprocess communication.
Considering that the circular_buffer's debug support relies on 'raw' pointers
(which is not permited by the Interprocess library)
the code has to compiled with debug support disabled (i.e. with `BOOST_CB_ENABLE_DEBUG` macro not defined or defined to 0).
the code has to compiled with `-DBOOST_CB_DISABLE_DEBUG` or `-DNDEBUG` (which disables the Debug Support).
Not doing that will cause the compilation to fail.
[endsect] [/section:implementation Implementation ]
@@ -536,10 +532,6 @@ Type: Patches
[section:release Release Notes]
[h4 Boost 1.56]
* C++11 allocator model support implemented by Glen Fernandes using Boost allocator_traits.
[h4 Boost 1.55]
* Documentation refactored by Paul A. Bristow using Quickbook, Doxygen and Autoindexing.

View File

@@ -11,7 +11,7 @@
path-constant nav_images : html/images/ ; # png and svg images for home, next, note, tip...
path-constant images_location : html/images ; # location of my SVG and PNG images referenced by Quickbook.
path-constant pdf_images_location : .. ; # location of SVG and PNG images referenced by pdf.
path-constant pdf_images_location : html ; # location of SVG and PNG images referenced by pdf.
path-constant here : . ; # location of /doc folder.
# echo "nav_images = " $(nav_images) ; # "nav_images = I:\boost-trunk\libs\circular_buffer\doc\html\images
@@ -181,15 +181,14 @@ boostbook standalone
# Set these one for PDF generation *only*:
# default png graphics are awful in PDF form,
# better use SVG instead:
<format>pdf:<xsl:param>admon.graphics.extension=".svg"
#<format>pdf:<xsl:param>admon.graphics.extension=".png" # Only png images are available.
# Don't need this, default path works OK:
#<format>pdf:<xsl:param>admon.graphics.path=$(nav_images)/ # next, prev, note, tip ... for pdf.
#<format>pdf:<xsl:param>admon.graphics.extension=".svg"
<format>pdf:<xsl:param>admon.graphics.extension=".png" # Only png images are available.
<format>pdf:<xsl:param>admon.graphics.path=$(nav_images)/ # next, prev, note, tip ... for pdf.
<format>pdf:<xsl:param>use.role.for.mediaobject=1
<format>pdf:<xsl:param>preferred.mediaobject.role=print
<format>pdf:<xsl:param>img.src.path=$(pdf_images_location)/ # graphics (diagrams) for pdf.
<format>pdf:<xsl:param>img.src.path=$(pdf_images_location)/ # graphics (diagrams) for pdf.
<format>pdf:<xsl:param>draft.mode="no"
<format>pdf:<xsl:param>boost.url.prefix=../../../..
<format>pdf:<xsl:param>boost.url.prefix=../../../..
<dependency>autodoc #
<dependency>png_install
@@ -206,14 +205,7 @@ install png_install : [ glob $(here)/*.png ] : <location>$(here)/../../../doc/ht
# because a modified pdf file is created, so this command
# will rename the file to the expected filename, here circular_buffer.pdf.
install pdfinstall : standalone : <install-type>PDF <location>. <name>circular_buffer.pdf ;
install pdf-install : standalone : <install-type>PDF <location>. <name>circular_buffer.pdf ;
###############################################################################
alias boostdoc
: standalone/<format>docbook
:
:
: ;
explicit boostdoc ;
alias boostrelease ;
explicit boostrelease ;

View File

@@ -7,6 +7,8 @@
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_CB_DISABLE_DEBUG
#include <boost/circular_buffer.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>

View File

@@ -5,13 +5,11 @@
// (See the accompanying file LICENSE_1_0.txt
// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
#undef BOOST_CB_ENABLE_DEBUG
//[circular_buffer_iter_example_1
/*`
*/
#define BOOST_CB_ENABLE_DEBUG 0 // The Debug Support has to be disabled, otherwise the code produces a runtime error.
#define BOOST_CB_DISABLE_DEBUG // The Debug Support has to be disabled, otherwise the code produces a runtime error.
#include <boost/circular_buffer.hpp>
#include <boost/assert.hpp>
@@ -36,5 +34,5 @@ int main(int /*argc*/, char* /*argv*/[])
return 0;
}
//] [/circular_buffer_iter_example_1]
//] [/circular_buffer_iter_example_1]

View File

@@ -11,17 +11,18 @@
#if !defined(BOOST_CIRCULAR_BUFFER_HPP)
#define BOOST_CIRCULAR_BUFFER_HPP
#if defined(_MSC_VER)
#if defined(_MSC_VER) && _MSC_VER >= 1200
#pragma once
#endif
#include <boost/circular_buffer_fwd.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/static_assert.hpp>
// BOOST_CB_ENABLE_DEBUG: Debug support control.
#if !defined(BOOST_CB_ENABLE_DEBUG)
#if defined(NDEBUG) || defined(BOOST_CB_DISABLE_DEBUG)
#define BOOST_CB_ENABLE_DEBUG 0
#else
#define BOOST_CB_ENABLE_DEBUG 1
#endif
// BOOST_CB_ASSERT: Runtime assertion.
@@ -32,20 +33,29 @@
#define BOOST_CB_ASSERT(Expr) ((void)0)
#endif
// BOOST_CB_STATIC_ASSERT: Compile time assertion.
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#define BOOST_CB_STATIC_ASSERT(Expr) ((void)0)
#else
#include <boost/static_assert.hpp>
#define BOOST_CB_STATIC_ASSERT(Expr) BOOST_STATIC_ASSERT(Expr)
#endif
// BOOST_CB_IS_CONVERTIBLE: Check if Iterator::value_type is convertible to Type.
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0550) || BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0550) || BOOST_WORKAROUND(__MWERKS__, <= 0x2407) || \
BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#define BOOST_CB_IS_CONVERTIBLE(Iterator, Type) ((void)0)
#else
#include <boost/detail/iterator.hpp>
#include <boost/type_traits/is_convertible.hpp>
#define BOOST_CB_IS_CONVERTIBLE(Iterator, Type) \
BOOST_STATIC_ASSERT((is_convertible<typename detail::iterator_traits<Iterator>::value_type, Type>::value))
BOOST_CB_STATIC_ASSERT((is_convertible<typename detail::iterator_traits<Iterator>::value_type, Type>::value))
#endif
// BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS:
// Check if the STL provides templated iterator constructors for its containers.
#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
#define BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS BOOST_STATIC_ASSERT(false);
#define BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS BOOST_CB_STATIC_ASSERT(false);
#else
#define BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS ((void)0);
#endif
@@ -57,6 +67,8 @@
#undef BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS
#undef BOOST_CB_IS_CONVERTIBLE
#undef BOOST_CB_STATIC_ASSERT
#undef BOOST_CB_ASSERT
#undef BOOST_CB_ENABLE_DEBUG
#endif // #if !defined(BOOST_CIRCULAR_BUFFER_HPP)

View File

@@ -3,7 +3,7 @@
// Copyright (c) 2003-2008 Jan Gaspar
// Copyright (c) 2013 Paul A. Bristow // Doxygen comments changed.
// Copyright (c) 2013 Antony Polukhin // Move semantics implementation.
// Copyright (c) 2014 Glen Fernandes // C++11 allocator model support.
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -12,7 +12,7 @@
#if !defined(BOOST_CIRCULAR_BUFFER_BASE_HPP)
#define BOOST_CIRCULAR_BUFFER_BASE_HPP
#if defined(_MSC_VER)
#if defined(_MSC_VER) && _MSC_VER >= 1200
#pragma once
#endif
@@ -20,7 +20,6 @@
#include <boost/call_traits.hpp>
#include <boost/concept_check.hpp>
#include <boost/limits.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/type_traits/is_stateless.hpp>
@@ -30,18 +29,26 @@
#include <boost/type_traits/is_nothrow_move_assignable.hpp>
#include <boost/type_traits/is_copy_constructible.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/move/adl_move_swap.hpp>
#include <boost/move/move.hpp>
#include <boost/utility/addressof.hpp>
#include <algorithm>
#include <utility>
#include <deque>
#include <stdexcept>
#if BOOST_CB_ENABLE_DEBUG
#include <cstring>
#endif
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
#include <stddef.h>
#endif
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std {
using ::memset;
}
#endif
namespace boost {
/*!
@@ -96,31 +103,31 @@ public:
typedef circular_buffer<T, Alloc> this_type;
//! The type of elements stored in the <code>circular_buffer</code>.
typedef typename boost::container::allocator_traits<Alloc>::value_type value_type;
typedef typename Alloc::value_type value_type;
//! A pointer to an element.
typedef typename boost::container::allocator_traits<Alloc>::pointer pointer;
typedef typename Alloc::pointer pointer;
//! A const pointer to the element.
typedef typename boost::container::allocator_traits<Alloc>::const_pointer const_pointer;
typedef typename Alloc::const_pointer const_pointer;
//! A reference to an element.
typedef typename boost::container::allocator_traits<Alloc>::reference reference;
typedef typename Alloc::reference reference;
//! A const reference to an element.
typedef typename boost::container::allocator_traits<Alloc>::const_reference const_reference;
typedef typename Alloc::const_reference const_reference;
//! The distance type.
/*!
(A signed integral type used to represent the distance between two iterators.)
*/
typedef typename boost::container::allocator_traits<Alloc>::difference_type difference_type;
typedef typename Alloc::difference_type difference_type;
//! The size type.
/*!
(An unsigned integral type that can represent any non-negative value of the container's distance type.)
*/
typedef typename boost::container::allocator_traits<Alloc>::size_type size_type;
typedef typename Alloc::size_type size_type;
//! The type of an allocator used in the <code>circular_buffer</code>.
typedef Alloc allocator_type;
@@ -128,10 +135,10 @@ public:
// Iterators
//! A const (random access) iterator used to iterate through the <code>circular_buffer</code>.
typedef cb_details::iterator< circular_buffer<T, Alloc>, cb_details::const_traits<boost::container::allocator_traits<Alloc> > > const_iterator;
typedef cb_details::iterator< circular_buffer<T, Alloc>, cb_details::const_traits<Alloc> > const_iterator;
//! A (random access) iterator used to iterate through the <code>circular_buffer</code>.
typedef cb_details::iterator< circular_buffer<T, Alloc>, cb_details::nonconst_traits<boost::container::allocator_traits<Alloc> > > iterator;
typedef cb_details::iterator< circular_buffer<T, Alloc>, cb_details::nonconst_traits<Alloc> > iterator;
//! A const iterator used to iterate backwards through a <code>circular_buffer</code>.
typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
@@ -176,6 +183,23 @@ public:
typedef BOOST_RV_REF(value_type) rvalue_type;
private:
// TODO: move to Boost.Move
/*! \cond */
template <class ValT>
static inline typename boost::conditional<
((boost::is_nothrow_move_constructible<ValT>::value && boost::is_nothrow_move_assignable<ValT>::value) || !boost::is_copy_constructible<ValT>::value)
#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
&& has_move_emulation_enabled<ValT>::value
#endif
,
rvalue_type,
param_value_type
>::type move_if_noexcept(ValT& value) BOOST_NOEXCEPT {
return boost::move(value);
}
/*! \endcond */
// Member variables
//! The internal buffer used for storing elements in the circular buffer.
@@ -666,11 +690,11 @@ public:
break;
}
if (is_uninitialized(dest)) {
boost::container::allocator_traits<Alloc>::construct(m_alloc, cb_details::to_address(dest), boost::move_if_noexcept(*src));
::new (dest) value_type(this_type::move_if_noexcept(*src));
++constructed;
} else {
value_type tmp = boost::move_if_noexcept(*src);
replace(src, boost::move_if_noexcept(*dest));
value_type tmp = this_type::move_if_noexcept(*src);
replace(src, this_type::move_if_noexcept(*dest));
replace(dest, boost::move(tmp));
}
}
@@ -745,12 +769,12 @@ public:
difference_type n = new_begin - begin();
if (m < n) {
for (; m > 0; --m) {
push_front(boost::move_if_noexcept(back()));
push_front(this_type::move_if_noexcept(back()));
pop_back();
}
} else {
for (; n > 0; --n) {
push_back(boost::move_if_noexcept(front()));
push_back(this_type::move_if_noexcept(front()));
pop_front();
}
}
@@ -787,7 +811,7 @@ public:
\sa <code>size()</code>, <code>capacity()</code>, <code>reserve()</code>
*/
size_type max_size() const BOOST_NOEXCEPT {
return (std::min<size_type>)(boost::container::allocator_traits<Alloc>::max_size(m_alloc), (std::numeric_limits<difference_type>::max)());
return (std::min<size_type>)(m_alloc.max_size(), (std::numeric_limits<difference_type>::max)());
}
//! Is the <code>circular_buffer</code> empty?
@@ -878,7 +902,7 @@ public:
iterator b = begin();
BOOST_TRY {
reset(buff,
cb_details::uninitialized_move_if_noexcept(b, b + (std::min)(new_capacity, size()), buff, m_alloc),
cb_details::uninitialized_move_if_noexcept<value_type>(b, b + (std::min)(new_capacity, size()), buff),
new_capacity);
} BOOST_CATCH(...) {
deallocate(buff, new_capacity);
@@ -953,8 +977,8 @@ public:
pointer buff = allocate(new_capacity);
iterator e = end();
BOOST_TRY {
reset(buff, cb_details::uninitialized_move_if_noexcept(e - (std::min)(new_capacity, size()),
e, buff, m_alloc), new_capacity);
reset(buff, cb_details::uninitialized_move_if_noexcept<value_type>(e - (std::min)(new_capacity, size()),
e, buff), new_capacity);
} BOOST_CATCH(...) {
deallocate(buff, new_capacity);
BOOST_RETHROW
@@ -1101,7 +1125,7 @@ public:
initialize_buffer(cb.capacity());
m_first = m_buff;
BOOST_TRY {
m_last = cb_details::uninitialized_copy(cb.begin(), cb.end(), m_buff, m_alloc);
m_last = cb_details::uninitialized_copy<value_type>(cb.begin(), cb.end(), m_buff);
} BOOST_CATCH(...) {
deallocate(m_buff, cb.capacity());
BOOST_RETHROW
@@ -1126,6 +1150,25 @@ public:
}
#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
/*! \cond */
template <class InputIterator>
circular_buffer(InputIterator first, InputIterator last)
: m_alloc(allocator_type()) {
initialize(first, last, is_integral<InputIterator>());
}
template <class InputIterator>
circular_buffer(capacity_type capacity, InputIterator first, InputIterator last)
: m_alloc(allocator_type()) {
initialize(capacity, first, last, is_integral<InputIterator>());
}
/*! \endcond */
#else
//! Create a full <code>circular_buffer</code> filled with a copy of the range.
/*!
\pre Valid range <code>[first, last)</code>.<br>
@@ -1178,6 +1221,8 @@ public:
initialize(buffer_capacity, first, last, is_integral<InputIterator>());
}
#endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
//! The destructor.
/*!
Destroys the <code>circular_buffer</code>.
@@ -1225,7 +1270,7 @@ public:
return *this;
pointer buff = allocate(cb.capacity());
BOOST_TRY {
reset(buff, cb_details::uninitialized_copy(cb.begin(), cb.end(), buff, m_alloc), cb.capacity());
reset(buff, cb_details::uninitialized_copy<value_type>(cb.begin(), cb.end(), buff), cb.capacity());
} BOOST_CATCH(...) {
deallocate(buff, cb.capacity());
BOOST_RETHROW
@@ -1400,11 +1445,11 @@ public:
*/
void swap(circular_buffer<T, Alloc>& cb) BOOST_NOEXCEPT {
swap_allocator(cb, is_stateless<allocator_type>());
adl_move_swap(m_buff, cb.m_buff);
adl_move_swap(m_end, cb.m_end);
adl_move_swap(m_first, cb.m_first);
adl_move_swap(m_last, cb.m_last);
adl_move_swap(m_size, cb.m_size);
std::swap(m_buff, cb.m_buff);
std::swap(m_end, cb.m_end);
std::swap(m_first, cb.m_first);
std::swap(m_last, cb.m_last);
std::swap(m_size, cb.m_size);
#if BOOST_CB_ENABLE_DEBUG
invalidate_all_iterators();
cb.invalidate_all_iterators();
@@ -1422,7 +1467,7 @@ private:
increment(m_last);
m_first = m_last;
} else {
boost::container::allocator_traits<Alloc>::construct(m_alloc, cb_details::to_address(m_last), static_cast<ValT>(item));
::new (m_last) value_type(static_cast<ValT>(item));
increment(m_last);
++m_size;
}
@@ -1439,7 +1484,7 @@ private:
m_last = m_first;
} else {
decrement(m_first);
boost::container::allocator_traits<Alloc>::construct(m_alloc, cb_details::to_address(m_first), static_cast<ValT>(item));
::new (m_first) value_type(static_cast<ValT>(item));
++m_size;
}
} BOOST_CATCH(...) {
@@ -1862,7 +1907,7 @@ private:
bool construct = !full();
BOOST_TRY {
while (src != pos.m_it) {
construct_or_replace(construct, dest, boost::move_if_noexcept(*src));
construct_or_replace(construct, dest, this_type::move_if_noexcept(*src));
increment(src);
increment(dest);
construct = false;
@@ -2109,7 +2154,7 @@ public:
pointer next = pos.m_it;
increment(next);
for (pointer p = pos.m_it; next != m_last; p = next, increment(next))
replace(p, boost::move_if_noexcept(*next));
replace(p, this_type::move_if_noexcept(*next));
decrement(m_last);
destroy_item(m_last);
--m_size;
@@ -2148,7 +2193,7 @@ public:
return first;
pointer p = first.m_it;
while (last.m_it != 0)
replace((first++).m_it, boost::move_if_noexcept(*last++));
replace((first++).m_it, this_type::move_if_noexcept(*last++));
do {
decrement(m_last);
destroy_item(m_last);
@@ -2186,7 +2231,7 @@ public:
pointer prev = pos.m_it;
pointer p = prev;
for (decrement(prev); p != m_first; p = prev, decrement(prev))
replace(p, boost::move_if_noexcept(*prev));
replace(p, this_type::move_if_noexcept(*prev));
destroy_item(m_first);
increment(m_first);
--m_size;
@@ -2231,7 +2276,7 @@ public:
while (first.m_it != m_first) {
decrement(first.m_it);
decrement(p);
replace(p, boost::move_if_noexcept(*first.m_it));
replace(p, this_type::move_if_noexcept(*first.m_it));
}
do {
destroy_item(m_first);
@@ -2372,11 +2417,11 @@ private:
if (n > max_size())
throw_exception(std::length_error("circular_buffer"));
#if BOOST_CB_ENABLE_DEBUG
pointer p = (n == 0) ? 0 : m_alloc.allocate(n);
cb_details::do_fill_uninitialized_memory(p, sizeof(value_type) * n);
pointer p = (n == 0) ? 0 : m_alloc.allocate(n, 0);
std::memset(p, cb_details::UNINITIALIZED, sizeof(value_type) * n);
return p;
#else
return (n == 0) ? 0 : m_alloc.allocate(n);
return (n == 0) ? 0 : m_alloc.allocate(n, 0);
#endif
}
@@ -2414,7 +2459,7 @@ private:
*/
void construct_or_replace(bool construct, pointer pos, param_value_type item) {
if (construct)
boost::container::allocator_traits<Alloc>::construct(m_alloc, cb_details::to_address(pos), item);
::new (pos) value_type(item);
else
replace(pos, item);
}
@@ -2426,17 +2471,17 @@ private:
*/
void construct_or_replace(bool construct, pointer pos, rvalue_type item) {
if (construct)
boost::container::allocator_traits<Alloc>::construct(m_alloc, cb_details::to_address(pos), boost::move(item));
::new (pos) value_type(boost::move(item));
else
replace(pos, boost::move(item));
}
//! Destroy an item.
void destroy_item(pointer p) {
boost::container::allocator_traits<Alloc>::destroy(m_alloc, cb_details::to_address(p));
m_alloc.destroy(p);
#if BOOST_CB_ENABLE_DEBUG
invalidate_iterators(iterator(this, p));
cb_details::do_fill_uninitialized_memory(p, sizeof(value_type));
std::memset(p, cb_details::UNINITIALIZED, sizeof(value_type));
#endif
}
@@ -2509,9 +2554,9 @@ private:
void initialize(Iterator first, Iterator last, const false_type&) {
BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
initialize(first, last, iterator_category<Iterator>::type());
initialize(first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
#else
initialize(first, last, BOOST_DEDUCED_TYPENAME iterator_category<Iterator>::type());
initialize(first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
#endif
}
@@ -2548,9 +2593,9 @@ private:
void initialize(capacity_type buffer_capacity, Iterator first, Iterator last, const false_type&) {
BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
initialize(buffer_capacity, first, last, iterator_category<Iterator>::type());
initialize(buffer_capacity, first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
#else
initialize(buffer_capacity, first, last, BOOST_DEDUCED_TYPENAME iterator_category<Iterator>::type());
initialize(buffer_capacity, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
#endif
}
@@ -2566,7 +2611,7 @@ private:
if (buffer_capacity == 0)
return;
while (first != last && !full()) {
boost::container::allocator_traits<Alloc>::construct(m_alloc, cb_details::to_address(m_last), *first++);
::new (m_last) value_type(*first++);
increment(m_last);
++m_size;
}
@@ -2602,7 +2647,7 @@ private:
m_size = distance;
}
BOOST_TRY {
m_last = cb_details::uninitialized_copy(first, last, m_buff, m_alloc);
m_last = cb_details::uninitialized_copy<value_type>(first, last, m_buff);
} BOOST_CATCH(...) {
deallocate(m_buff, buffer_capacity);
BOOST_RETHROW
@@ -2628,7 +2673,7 @@ private:
//! Specialized method for swapping the allocator.
void swap_allocator(circular_buffer<T, Alloc>& cb, const false_type&) {
adl_move_swap(m_alloc, cb.m_alloc);
std::swap(m_alloc, cb.m_alloc);
}
//! Specialized assign method.
@@ -2642,9 +2687,9 @@ private:
void assign(Iterator first, Iterator last, const false_type&) {
BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
assign(first, last, iterator_category<Iterator>::type());
assign(first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
#else
assign(first, last, BOOST_DEDUCED_TYPENAME iterator_category<Iterator>::type());
assign(first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
#endif
}
@@ -2656,8 +2701,8 @@ private:
std::deque<value_type, allocator_type> tmp(first, last, m_alloc);
size_type distance = tmp.size();
assign_n(distance, distance,
cb_details::make_assign_range
(boost::make_move_iterator(tmp.begin()), boost::make_move_iterator(tmp.end()), m_alloc));
cb_details::make_assign_range<value_type>
(boost::make_move_iterator(tmp.begin()), boost::make_move_iterator(tmp.end())));
}
//! Specialized assign method.
@@ -2665,7 +2710,7 @@ private:
void assign(ForwardIterator first, ForwardIterator last, const std::forward_iterator_tag&) {
BOOST_CB_ASSERT(std::distance(first, last) >= 0); // check for wrong range
size_type distance = std::distance(first, last);
assign_n(distance, distance, cb_details::make_assign_range(first, last, m_alloc));
assign_n(distance, distance, cb_details::make_assign_range<value_type>(first, last));
}
//! Specialized assign method.
@@ -2679,9 +2724,9 @@ private:
void assign(capacity_type new_capacity, Iterator first, Iterator last, const false_type&) {
BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
assign(new_capacity, first, last, iterator_category<Iterator>::type());
assign(new_capacity, first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
#else
assign(new_capacity, first, last, BOOST_DEDUCED_TYPENAME iterator_category<Iterator>::type());
assign(new_capacity, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
#endif
}
@@ -2692,7 +2737,12 @@ private:
clear();
insert(begin(), first, last);
} else {
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
circular_buffer<value_type, allocator_type> tmp(new_capacity, m_alloc);
tmp.insert(begin(), first, last);
#else
circular_buffer<value_type, allocator_type> tmp(new_capacity, first, last, m_alloc);
#endif
tmp.swap(*this);
}
}
@@ -2708,7 +2758,7 @@ private:
distance = new_capacity;
}
assign_n(new_capacity, distance,
cb_details::make_assign_range(first, last, m_alloc));
cb_details::make_assign_range<value_type>(first, last));
}
//! Helper assign method.
@@ -2755,7 +2805,7 @@ private:
BOOST_TRY {
while (src != p) {
decrement(src);
construct_or_replace(construct, dest, boost::move_if_noexcept(*src));
construct_or_replace(construct, dest, this_type::move_if_noexcept(*src));
decrement(dest);
construct = false;
}
@@ -2788,9 +2838,9 @@ private:
void insert(const iterator& pos, Iterator first, Iterator last, const false_type&) {
BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
insert(pos, first, last, iterator_category<Iterator>::type());
insert(pos, first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
#else
insert(pos, first, last, BOOST_DEDUCED_TYPENAME iterator_category<Iterator>::type());
insert(pos, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
#endif
}
@@ -2831,7 +2881,7 @@ private:
pointer p = m_last;
BOOST_TRY {
for (; ii < construct; ++ii, increment(p))
boost::container::allocator_traits<Alloc>::construct(m_alloc, cb_details::to_address(p), *wrapper());
::new (p) value_type(*wrapper());
for (;ii < n; ++ii, increment(p))
replace(p, *wrapper());
} BOOST_CATCH(...) {
@@ -2879,9 +2929,9 @@ private:
void rinsert(const iterator& pos, Iterator first, Iterator last, const false_type&) {
BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
rinsert(pos, first, last, iterator_category<Iterator>::type());
rinsert(pos, first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
#else
rinsert(pos, first, last, BOOST_DEDUCED_TYPENAME iterator_category<Iterator>::type());
rinsert(pos, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
#endif
}
@@ -2925,7 +2975,7 @@ private:
for (;ii > construct; --ii, increment(p))
replace(p, *wrapper());
for (; ii > 0; --ii, increment(p))
boost::container::allocator_traits<Alloc>::construct(m_alloc, cb_details::to_address(p), *wrapper());
::new (p) value_type(*wrapper());
} BOOST_CATCH(...) {
size_type constructed = ii < construct ? construct - ii : 0;
m_last = add(m_last, constructed);

View File

@@ -9,20 +9,10 @@
#if !defined(BOOST_CIRCULAR_BUFFER_DEBUG_HPP)
#define BOOST_CIRCULAR_BUFFER_DEBUG_HPP
#if defined(_MSC_VER)
#if defined(_MSC_VER) && _MSC_VER >= 1200
#pragma once
#endif
#if BOOST_CB_ENABLE_DEBUG
#include <cstring>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std {
using ::memset;
}
#endif
#endif // BOOST_CB_ENABLE_DEBUG
namespace boost {
namespace cb_details {
@@ -32,17 +22,6 @@ namespace cb_details {
// The value the uninitialized memory is filled with.
const int UNINITIALIZED = 0xcc;
template <class T>
inline void do_fill_uninitialized_memory(T* data, std::size_t size_in_bytes) BOOST_NOEXCEPT {
std::memset(static_cast<void*>(data), UNINITIALIZED, size_in_bytes);
}
template <class T>
inline void do_fill_uninitialized_memory(T& /*data*/, std::size_t /*size_in_bytes*/) BOOST_NOEXCEPT {
// Do nothing
}
class debug_iterator_registry;
/*!

View File

@@ -1,7 +1,6 @@
// Helper classes and functions for the circular buffer.
// Copyright (c) 2003-2008 Jan Gaspar
// Copyright (c) 2014 Glen Joseph Fernandes // C++11 allocator model support.
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -10,16 +9,14 @@
#if !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP)
#define BOOST_CIRCULAR_BUFFER_DETAILS_HPP
#if defined(_MSC_VER)
#if defined(_MSC_VER) && _MSC_VER >= 1200
#pragma once
#endif
#include <boost/iterator.hpp>
#include <boost/throw_exception.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/core/pointer_traits.hpp>
#include <boost/move/move.hpp>
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <iterator>
@@ -35,24 +32,17 @@ namespace boost {
namespace cb_details {
template<class Pointer>
inline typename boost::pointer_traits<Pointer>::element_type*
to_address(Pointer p) BOOST_NOEXCEPT
{
return boost::pointer_traits<Pointer>::to_address(p);
}
template <class Traits> struct nonconst_traits;
template<class ForwardIterator, class Diff, class T, class Alloc>
void uninitialized_fill_n_with_alloc(
ForwardIterator first, Diff n, const T& item, Alloc& alloc);
template<class InputIterator, class ForwardIterator, class Alloc>
ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a);
template<class ValueType, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest);
template<class InputIterator, class ForwardIterator, class Alloc>
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a);
template<class ValueType, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest);
/*!
\struct const_traits
@@ -120,7 +110,7 @@ private:
*/
template <class Value, class Alloc>
struct assign_n {
typedef typename boost::container::allocator_traits<Alloc>::size_type size_type;
typedef typename Alloc::size_type size_type;
size_type m_n;
Value m_item;
Alloc& m_alloc;
@@ -137,24 +127,23 @@ private:
\struct assign_range
\brief Helper functor for assigning range of items.
*/
template <class Iterator, class Alloc>
template <class ValueType, class Iterator>
struct assign_range {
Iterator m_first;
Iterator m_last;
Alloc& m_alloc;
assign_range(const Iterator& first, const Iterator& last, Alloc& alloc)
: m_first(first), m_last(last), m_alloc(alloc) {}
assign_range(const Iterator& first, const Iterator& last) BOOST_NOEXCEPT
: m_first(first), m_last(last) {}
template <class Pointer>
void operator () (Pointer p) const {
boost::cb_details::uninitialized_copy(m_first, m_last, p, m_alloc);
boost::cb_details::uninitialized_copy<ValueType>(m_first, m_last, p);
}
};
template <class Iterator, class Alloc>
inline assign_range<Iterator, Alloc> make_assign_range(const Iterator& first, const Iterator& last, Alloc& a) {
return assign_range<Iterator, Alloc>(first, last, a);
template <class ValueType, class Iterator>
inline assign_range<ValueType, Iterator> make_assign_range(const Iterator& first, const Iterator& last) {
return assign_range<ValueType, Iterator>(first, last);
}
/*!
@@ -203,7 +192,7 @@ public:
*/
template <class Buff, class Traits>
struct iterator :
public std::iterator<
public boost::iterator<
std::random_access_iterator_tag,
typename Traits::value_type,
typename Traits::difference_type,
@@ -216,7 +205,7 @@ struct iterator :
// Helper types
//! Base iterator.
typedef std::iterator<
typedef boost::iterator<
std::random_access_iterator_tag,
typename Traits::value_type,
typename Traits::difference_type,
@@ -434,47 +423,70 @@ operator + (typename Traits::difference_type n, const iterator<Buff, Traits>& it
return it + n;
}
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR)
//! Iterator category.
template <class Buff, class Traits>
inline std::random_access_iterator_tag iterator_category(const iterator<Buff, Traits>&) {
return std::random_access_iterator_tag();
}
//! The type of the elements stored in the circular buffer.
template <class Buff, class Traits>
inline typename Traits::value_type* value_type(const iterator<Buff, Traits>&) { return 0; }
//! Distance type.
template <class Buff, class Traits>
inline typename Traits::difference_type* distance_type(const iterator<Buff, Traits>&) { return 0; }
#endif // #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR)
/*!
\fn ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest)
\brief Equivalent of <code>std::uninitialized_copy</code> but with explicit specification of value type.
*/
template<class InputIterator, class ForwardIterator, class Alloc>
inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a) {
template<class ValueType, class InputIterator, class ForwardIterator>
inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest) {
typedef ValueType value_type;
// We do not use allocator.construct and allocator.destroy
// because C++03 requires to take parameter by const reference but
// Boost.move requires nonconst reference
ForwardIterator next = dest;
BOOST_TRY {
for (; first != last; ++first, ++dest)
boost::container::allocator_traits<Alloc>::construct(a, cb_details::to_address(dest), *first);
::new (dest) value_type(*first);
} BOOST_CATCH(...) {
for (; next != dest; ++next)
boost::container::allocator_traits<Alloc>::destroy(a, cb_details::to_address(next));
next->~value_type();
BOOST_RETHROW
}
BOOST_CATCH_END
return dest;
}
template<class InputIterator, class ForwardIterator, class Alloc>
ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a,
template<class ValueType, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest,
true_type) {
for (; first != last; ++first, ++dest)
boost::container::allocator_traits<Alloc>::construct(a, cb_details::to_address(dest), boost::move(*first));
::new (dest) ValueType(boost::move(*first));
return dest;
}
template<class InputIterator, class ForwardIterator, class Alloc>
ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a,
template<class ValueType, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest,
false_type) {
return uninitialized_copy(first, last, dest, a);
return uninitialized_copy<ValueType>(first, last, dest);
}
/*!
\fn ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest)
\brief Equivalent of <code>std::uninitialized_copy</code> but with explicit specification of value type and moves elements if they have noexcept move constructors.
*/
template<class InputIterator, class ForwardIterator, class Alloc>
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a) {
typedef typename boost::is_nothrow_move_constructible<typename boost::container::allocator_traits<Alloc>::value_type>::type tag_t;
return uninitialized_move_if_noexcept_impl(first, last, dest, a, tag_t());
template<class ValueType, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest) {
typedef typename boost::is_nothrow_move_constructible<ValueType>::type tag_t;
return uninitialized_move_if_noexcept_impl<ValueType>(first, last, dest, tag_t());
}
/*!
@@ -486,10 +498,10 @@ inline void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const
ForwardIterator next = first;
BOOST_TRY {
for (; n > 0; ++first, --n)
boost::container::allocator_traits<Alloc>::construct(alloc, cb_details::to_address(first), item);
alloc.construct(first, item);
} BOOST_CATCH(...) {
for (; next != first; ++next)
boost::container::allocator_traits<Alloc>::destroy(alloc, cb_details::to_address(next));
alloc.destroy(next);
BOOST_RETHROW
}
BOOST_CATCH_END

View File

@@ -11,7 +11,7 @@
#if !defined(BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP)
#define BOOST_CIRCULAR_BUFFER_SPACE_OPTIMIZED_HPP
#if defined(_MSC_VER)
#if defined(_MSC_VER) && _MSC_VER >= 1200
#pragma once
#endif
@@ -416,6 +416,31 @@ public:
: circular_buffer<T, Alloc>(init_capacity(capacity_ctrl, n), n, item, alloc)
, m_capacity_ctrl(capacity_ctrl) {}
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
/*! \cond */
circular_buffer_space_optimized(const circular_buffer_space_optimized<T, Alloc>& cb)
: circular_buffer<T, Alloc>(cb.begin(), cb.end())
, m_capacity_ctrl(cb.m_capacity_ctrl) {}
template <class InputIterator>
circular_buffer_space_optimized(InputIterator first, InputIterator last)
: circular_buffer<T, Alloc>(first, last)
, m_capacity_ctrl(circular_buffer<T, Alloc>::capacity()) {}
template <class InputIterator>
circular_buffer_space_optimized(capacity_type capacity_ctrl, InputIterator first, InputIterator last)
: circular_buffer<T, Alloc>(
init_capacity(capacity_ctrl, first, last, is_integral<InputIterator>()),
first, last)
, m_capacity_ctrl(capacity_ctrl) {
reduce_capacity(
is_same< BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<InputIterator>::type, std::input_iterator_tag >());
}
/*! \endcond */
#else
//! The copy constructor.
/*!
Creates a copy of the specified <code>circular_buffer_space_optimized</code>.
@@ -509,9 +534,11 @@ public:
first, last, alloc)
, m_capacity_ctrl(capacity_ctrl) {
reduce_capacity(
is_same< BOOST_DEDUCED_TYPENAME iterator_category<InputIterator>::type, std::input_iterator_tag >());
is_same< BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<InputIterator>::type, std::input_iterator_tag >());
}
#endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#if defined(BOOST_CB_NEVER_DEFINED)
// This section will never be compiled - the default destructor will be generated instead.
// Declared only for documentation purpose.
@@ -740,7 +767,7 @@ public:
\par Iterator Invalidation
Invalidates all iterators of both <code>circular_buffer_space_optimized</code> containers. (On the other
hand the iterators still point to the same elements but within another container. If you want to rely on
this feature you have to turn the __debug_support off,
this feature you have to turn the __debug_support off by defining macro BOOST_CB_DISABLE_DEBUG,
otherwise an assertion will report an error if such invalidated iterator is used.)
\par Complexity
Constant (in the size of the <code>circular_buffer_space_optimized</code>).
@@ -1605,10 +1632,10 @@ private:
const false_type&) {
BOOST_CB_IS_CONVERTIBLE(Iterator, value_type); // check for invalid iterator type
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
return init_capacity(capacity_ctrl, first, last, iterator_category<Iterator>::type());
return init_capacity(capacity_ctrl, first, last, BOOST_ITERATOR_CATEGORY<Iterator>::type());
#else
return init_capacity(
capacity_ctrl, first, last, BOOST_DEDUCED_TYPENAME iterator_category<Iterator>::type());
capacity_ctrl, first, last, BOOST_DEDUCED_TYPENAME BOOST_ITERATOR_CATEGORY<Iterator>::type());
#endif
}

View File

@@ -11,7 +11,7 @@
#if !defined(BOOST_CIRCULAR_BUFFER_FWD_HPP)
#define BOOST_CIRCULAR_BUFFER_FWD_HPP
#if defined(_MSC_VER)
#if defined(_MSC_VER) && _MSC_VER >= 1200
#pragma once
#endif

View File

@@ -1,14 +0,0 @@
{
"key": "circular_buffer",
"name": "Circular Buffer",
"authors": [
"Jan Gaspar"
],
"description": "A STL compliant container also known as ring or cyclic buffer.",
"category": [
"Containers"
],
"maintainers": [
"Jan Gaspar <jano_gaspar -at- yahoo.com>"
]
}

View File

@@ -6,7 +6,7 @@
# accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# Added warning suppression Paul A. Bristow 25 Nov 2008
# Added warning supression Paul A. Bristow 25 Nov 2008
# Bring in rules for testing.
import testing ;
@@ -22,11 +22,9 @@ project
;
test-suite "circular_buffer"
: [ run base_test.cpp : : : <threading>single : ]
[ run space_optimized_test.cpp : : : <threading>single : ]
[ run base_test.cpp : : : <threading>single <define>"BOOST_CB_ENABLE_DEBUG=1" : base_test_dbg ]
[ run space_optimized_test.cpp : : : <threading>single <define>"BOOST_CB_ENABLE_DEBUG=1" : space_optimized_test_dbg ]
[ run soft_iterator_invalidation.cpp : : : <threading>single : ]
[ run constant_erase_test.cpp : : : <threading>single : ]
: [ run base_test.cpp : <threading>single : ]
[ run space_optimized_test.cpp : <threading>single : ]
[ run soft_iterator_invalidation.cpp : <threading>single : ]
[ run constant_erase_test.cpp : <threading>single : ]
[ compile bounded_buffer_comparison.cpp : <threading>multi : ]
;

View File

@@ -193,7 +193,7 @@ void iterator_comparison_test() {
void iterator_invalidation_test() {
#if BOOST_CB_ENABLE_DEBUG
#if !defined(NDEBUG) && !defined(BOOST_CB_DISABLE_DEBUG)
circular_buffer<MyInteger>::iterator it1;
circular_buffer<MyInteger>::const_iterator it2;
@@ -563,7 +563,7 @@ void iterator_invalidation_test() {
BOOST_CHECK(it3.is_valid(&cb16));
BOOST_CHECK(!it4.is_valid(&cb16));
#endif // #if BOOST_CB_ENABLE_DEBUG
#endif // #if !defined(NDEBUG) && !defined(BOOST_CB_DISABLE_DEBUG)
}
// basic exception safety test (it is useful to use any memory-leak detection tool)

View File

@@ -7,6 +7,8 @@
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_CB_DISABLE_DEBUG
#include <boost/circular_buffer.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>

View File

@@ -2,7 +2,6 @@
// Copyright (c) 2003-2008 Jan Gaspar
// Copyright (c) 2013 Antony Polukhin
// Copyright (c) 2014 Glen Joseph Fernandes // C++11 allocator model support.
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -12,8 +11,7 @@
#include <boost/type_traits/is_nothrow_move_assignable.hpp>
#include <boost/type_traits/has_nothrow_constructor.hpp>
template <class Alloc>
void generic_test(CB_CONTAINER<MyInteger, Alloc>& cb) {
void generic_test(CB_CONTAINER<MyInteger>& cb) {
vector<int> v;
v.push_back(11);
@@ -151,98 +149,6 @@ void size_test() {
generic_test(cb2);
}
template<class T>
class my_allocator {
typedef std::allocator<T> base_t;
base_t base_;
public:
typedef T value_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef typename base_t::size_type size_type;
typedef typename base_t::difference_type difference_type;
private:
template<class U>
struct const_pointer_;
template<class U>
struct pointer_ {
pointer_(){}
pointer_(void* p) : hidden_ptr_((U*)p) {}
difference_type operator-(const const_pointer_<U>& rhs) const { return hidden_ptr_ - rhs.hidden_ptr_; }
difference_type operator-(pointer_ rhs) const { return hidden_ptr_ - rhs.hidden_ptr_; }
pointer_ operator-(size_type rhs) const { return hidden_ptr_ - rhs; }
bool operator == (pointer_ rhs) const { return hidden_ptr_ == rhs.hidden_ptr_; }
bool operator != (pointer_ rhs) const { return hidden_ptr_ != rhs.hidden_ptr_; }
bool operator < (pointer_ rhs) const { return hidden_ptr_ < rhs.hidden_ptr_; }
bool operator >= (pointer_ rhs) const { return hidden_ptr_ >= rhs.hidden_ptr_; }
pointer_& operator++() { ++hidden_ptr_; return *this; }
pointer_& operator--() { --hidden_ptr_; return *this; }
pointer_& operator+=(size_type s) { hidden_ptr_ += s; return *this; }
pointer_ operator+(size_type s) const { return hidden_ptr_ + s; }
pointer_ operator++(int) { pointer_ p = *this; ++hidden_ptr_; return p; }
pointer_ operator--(int) { pointer_ p = *this; --hidden_ptr_; return p; }
U& operator*() const { return *hidden_ptr_; }
U* operator->() const { return hidden_ptr_; }
U* hidden_ptr_;
};
template<class U>
struct const_pointer_ {
const_pointer_(){}
const_pointer_(pointer_<U> p) : hidden_ptr_(p.hidden_ptr_) {}
const_pointer_(const void* p) : hidden_ptr_((const U*)p) {}
difference_type operator-(pointer_<U> rhs) const { return hidden_ptr_ - rhs.hidden_ptr_; }
difference_type operator-(const_pointer_ rhs) const { return hidden_ptr_ - rhs.hidden_ptr_; }
const_pointer_ operator-(size_type rhs) const { return hidden_ptr_ - rhs; }
bool operator == (const_pointer_ rhs) const { return hidden_ptr_ == rhs.hidden_ptr_; }
bool operator != (const_pointer_ rhs) const { return hidden_ptr_ != rhs.hidden_ptr_; }
bool operator < (const_pointer_ rhs) const { return hidden_ptr_ < rhs.hidden_ptr_; }
bool operator >= (const_pointer_ rhs) const { return hidden_ptr_ >= rhs.hidden_ptr_; }
const_pointer_& operator++() { ++hidden_ptr_; return *this; }
const_pointer_& operator--() { --hidden_ptr_; return *this; }
const_pointer_& operator+=(size_type s) { hidden_ptr_ += s; return hidden_ptr_; }
const_pointer_ operator+(size_type s) const { return hidden_ptr_ + s; }
const_pointer_ operator++(int) { const_pointer_ p = *this; ++hidden_ptr_; return p; }
const_pointer_ operator--(int) { const_pointer_ p = *this; --hidden_ptr_; return p; }
const U& operator*() const { return *hidden_ptr_; }
const U* hidden_ptr_;
};
public:
typedef pointer_<T> pointer;
typedef const_pointer_<T> const_pointer;
template<class T2>
struct rebind
{
typedef my_allocator<T2> other;
};
size_type max_size() const
{ return base_.max_size(); }
pointer allocate(size_type count, const void* hint = 0) {
return pointer(base_.allocate(count, hint));
}
void deallocate(const pointer &ptr, size_type s)
{ base_.deallocate(ptr.hidden_ptr_, s); }
template<class P>
void construct(const pointer &ptr, BOOST_FWD_REF(P) p)
{ ::new(ptr.hidden_ptr_) value_type(::boost::forward<P>(p)); }
void destroy(const pointer &ptr)
{ (*ptr.hidden_ptr_).~value_type(); }
};
void allocator_test() {
CB_CONTAINER<MyInteger> cb1(10, 0);
@@ -253,40 +159,8 @@ void allocator_test() {
alloc.max_size();
generic_test(cb1);
CB_CONTAINER<MyInteger, my_allocator<MyInteger> > cb_a(10, 0);
generic_test(cb_a);
}
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
class cxx11_allocator {
public:
typedef T value_type;
cxx11_allocator() {
}
template<class U>
cxx11_allocator(const cxx11_allocator<U> &) {
}
T* allocate(std::size_t n) {
return static_cast<T*>(::operator new(n * sizeof(T)));
}
void deallocate(T * p, std::size_t n) {
::operator delete( p );
}
};
void cxx11_allocator_test() {
CB_CONTAINER<MyInteger, cxx11_allocator<MyInteger> > cb(10, 0);
generic_test(cb);
}
#endif
void begin_and_end_test() {
vector<int> v;
@@ -2114,6 +1988,7 @@ void move_container_on_cpp11() {
struct noncopyable_movable_except_t
: private boost::noncopyable // required, until there will be no support for is_copy_constructible added to Boost.Move
{
private:
BOOST_MOVABLE_BUT_NOT_COPYABLE(noncopyable_movable_except_t)
@@ -2152,6 +2027,7 @@ public:
};
struct noncopyable_movable_noexcept_t
: private boost::noncopyable // required, until there will be no support for is_copy_constructible added to Boost.Move
{
private:
BOOST_MOVABLE_BUT_NOT_COPYABLE(noncopyable_movable_noexcept_t)
@@ -2477,8 +2353,5 @@ void add_common_tests(test_suite* tests) {
tests->add(BOOST_TEST_CASE(&move_container_on_cpp11));
tests->add(BOOST_TEST_CASE(&move_container_values_noexcept));
tests->add(BOOST_TEST_CASE(&check_containers_exception_specifications));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
tests->add(BOOST_TEST_CASE(&cxx11_allocator_test));
#endif
}

View File

@@ -6,6 +6,8 @@
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_CB_DISABLE_DEBUG
#include "test.hpp"
int MyInteger::ms_exception_trigger = 0;

View File

@@ -9,6 +9,8 @@
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_CB_DISABLE_DEBUG
#include "test.hpp"
// test of the example (introduced in the documentation)

View File

@@ -125,7 +125,7 @@ void shrink_to_fit_test() {
void iterator_invalidation_test() {
#if BOOST_CB_ENABLE_DEBUG
#if !defined(NDEBUG) && !defined(BOOST_CB_DISABLE_DEBUG)
cb_space_optimized cb1(10, 1);
cb1.push_back(2);
@@ -177,7 +177,7 @@ void iterator_invalidation_test() {
BOOST_CHECK(!it2.is_valid(&cb1));
BOOST_CHECK(!it3.is_valid(&cb1));
#endif // #if BOOST_CB_ENABLE_DEBUG
#endif // #if !defined(NDEBUG) && !defined(BOOST_CB_DISABLE_DEBUG)
}
// test main