Compare commits

..

24 Commits

Author SHA1 Message Date
Antony Polukhin
5136d09e0a Merge branch 'master' into develop 2014-10-14 13:54:40 +04:00
Antony Polukhin
8a35c1deb0 Merge pull request #4 from danieljames/metadata
Create metadata file.
2014-08-18 19:55:51 +04:00
Daniel James
a54ccf9962 Add metadata file. 2014-08-18 14:57:42 +01:00
Antony Polukhin
d48b479c6a Use move_if_noexcept from Boost.Move 2014-08-18 12:08:23 +04:00
Glen Fernandes
8ba2c24454 Merge pull request #2 from jzmaddock/patch-1
Update jamfile.v2
2014-08-14 12:28:36 -07:00
Glen Fernandes
05a6e6e0d5 Merge pull request #3 from jzmaddock/patch-2
Update jamfile.v2
2014-08-14 12:26:40 -07:00
jzmaddock
483a1bdc2d Update jamfile.v2
Fix image location for PDF builds.
Use SVG for admon graphics (default path works OK for these).
Change name of pdf install target as current Boost.Build chokes over targets with hyphens in them.
2014-08-14 17:33:00 +01:00
jzmaddock
cfdf5c063b Update jamfile.v2
Fix image location for PDF builds.
Use SVG for admon graphics (default path works OK for these).
Change name of pdf install target as current Boost.Build chokes over targets with hyphens in them.
2014-08-14 17:31:43 +01:00
Antony Polukhin
f02cbb939c Finished sync of develop and master branches 2014-08-12 20:50:49 +04:00
Antony Polukhin
d18e2283a4 Merge branch 'master' into develop 2014-08-12 20:47:16 +04:00
Glen Fernandes
7e233f7b41 Merge branch 'develop' 2014-05-04 07:42:32 -07:00
Glen Fernandes
689e79abd9 Correct unit test custom pointer dereference operator 2014-05-02 22:06:39 -07:00
Glen Fernandes
002f351a9f Merge pull request #1 from glenfe/develop
Add C++11 allocator model support
2014-05-02 13:20:22 -07:00
Glen Fernandes
18306aee33 Eliminate need for do_construct helper 2014-05-02 10:26:11 -07:00
Glen Fernandes
c4b62627e7 Add C++11 allocator model support 2014-05-01 23:50:44 -07:00
Antony Polukhin
f5303c70d8 Merge branch 'develop' 2014-01-19 12:02:44 +04:00
Antony Polukhin
b896ace67c Create first merge point for Git 2014-01-01 15:35:13 +04:00
Antony Polukhin
62233c53bb Removed some whitespaces 2013-12-09 11:13:34 +04:00
Antony Polukhin
fc1d341a26 Fixed setting memory to '0xcc' in debug mode for non-pointer allocator::pointer types 2013-12-09 11:13:34 +04:00
Antony Polukhin
ece1277965 Fixed issues with allocators that do not return pointers, added tes case for such situations (refs #9334) 2013-12-09 11:13:34 +04:00
Antony Polukhin
33cfe492d9 Merge circular_buffer from trunk:
* dropped support of antique compilers (thanks to Stephen Kelly for doing it all around the boost!)

[SVN r86677]
2013-11-13 13:30:10 +00:00
Daniel James
90711fb1fe Merge circular buffer documentation fixes.
[SVN r86209]
2013-10-08 21:01:18 +00:00
Antony Polukhin
6eb5fd4a3d Big merge of Boost.CircularBuffer :
* Full merge of QuickBoock documentation from Paul A. Bristow
* Merged rvalue references support with tests and documentation (fixed #7888)

[SVN r85510]
2013-08-29 08:39:09 +00:00
Marshall Clow
6998f28fda Apply patch to release branch; Fixes #8032
[SVN r84450]
2013-05-23 18:45:31 +00:00
6 changed files with 150 additions and 134 deletions

View File

@@ -532,6 +532,10 @@ 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 : html ; # location of SVG and PNG images referenced by pdf.
path-constant pdf_images_location : .. ; # 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,14 +181,15 @@ 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.
<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.
# 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>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
@@ -205,7 +206,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 pdf-install : standalone : <install-type>PDF <location>. <name>circular_buffer.pdf ;
install pdfinstall : standalone : <install-type>PDF <location>. <name>circular_buffer.pdf ;

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
@@ -20,6 +20,7 @@
#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,10 +31,12 @@
#include <boost/type_traits/is_copy_constructible.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/move/move.hpp>
#include <boost/utility/addressof.hpp>
#include <algorithm>
#include <utility>
#include <deque>
#include <stdexcept>
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
#include <stddef.h>
#endif
@@ -92,31 +95,31 @@ public:
typedef circular_buffer<T, Alloc> this_type;
//! The type of elements stored in the <code>circular_buffer</code>.
typedef typename Alloc::value_type value_type;
typedef typename boost::container::allocator_traits<Alloc>::value_type value_type;
//! A pointer to an element.
typedef typename Alloc::pointer pointer;
typedef typename boost::container::allocator_traits<Alloc>::pointer pointer;
//! A const pointer to the element.
typedef typename Alloc::const_pointer const_pointer;
typedef typename boost::container::allocator_traits<Alloc>::const_pointer const_pointer;
//! A reference to an element.
typedef typename Alloc::reference reference;
typedef typename boost::container::allocator_traits<Alloc>::reference reference;
//! A const reference to an element.
typedef typename Alloc::const_reference const_reference;
typedef typename boost::container::allocator_traits<Alloc>::const_reference const_reference;
//! The distance type.
/*!
(A signed integral type used to represent the distance between two iterators.)
*/
typedef typename Alloc::difference_type difference_type;
typedef typename boost::container::allocator_traits<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 Alloc::size_type size_type;
typedef typename boost::container::allocator_traits<Alloc>::size_type size_type;
//! The type of an allocator used in the <code>circular_buffer</code>.
typedef Alloc allocator_type;
@@ -124,10 +127,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<Alloc> > const_iterator;
typedef cb_details::iterator< circular_buffer<T, Alloc>, cb_details::const_traits<boost::container::allocator_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<Alloc> > iterator;
typedef cb_details::iterator< circular_buffer<T, Alloc>, cb_details::nonconst_traits<boost::container::allocator_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;
@@ -172,23 +175,6 @@ 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.
@@ -679,11 +665,11 @@ public:
break;
}
if (is_uninitialized(dest)) {
cb_details::do_construct<value_type>(dest, this_type::move_if_noexcept(*src), m_alloc);
boost::container::allocator_traits<Alloc>::construct(m_alloc, boost::addressof(*dest), boost::move_if_noexcept(*src));
++constructed;
} else {
value_type tmp = this_type::move_if_noexcept(*src);
replace(src, this_type::move_if_noexcept(*dest));
value_type tmp = boost::move_if_noexcept(*src);
replace(src, boost::move_if_noexcept(*dest));
replace(dest, boost::move(tmp));
}
}
@@ -758,12 +744,12 @@ public:
difference_type n = new_begin - begin();
if (m < n) {
for (; m > 0; --m) {
push_front(this_type::move_if_noexcept(back()));
push_front(boost::move_if_noexcept(back()));
pop_back();
}
} else {
for (; n > 0; --n) {
push_back(this_type::move_if_noexcept(front()));
push_back(boost::move_if_noexcept(front()));
pop_front();
}
}
@@ -800,7 +786,7 @@ public:
\sa <code>size()</code>, <code>capacity()</code>, <code>reserve()</code>
*/
size_type max_size() const BOOST_NOEXCEPT {
return (std::min<size_type>)(m_alloc.max_size(), (std::numeric_limits<difference_type>::max)());
return (std::min<size_type>)(boost::container::allocator_traits<Alloc>::max_size(m_alloc), (std::numeric_limits<difference_type>::max)());
}
//! Is the <code>circular_buffer</code> empty?
@@ -1435,7 +1421,7 @@ private:
increment(m_last);
m_first = m_last;
} else {
cb_details::do_construct<value_type>(m_last, static_cast<ValT>(item), m_alloc);
boost::container::allocator_traits<Alloc>::construct(m_alloc, boost::addressof(*m_last), static_cast<ValT>(item));
increment(m_last);
++m_size;
}
@@ -1452,7 +1438,7 @@ private:
m_last = m_first;
} else {
decrement(m_first);
cb_details::do_construct<value_type>(m_first, static_cast<ValT>(item), m_alloc);
boost::container::allocator_traits<Alloc>::construct(m_alloc, boost::addressof(*m_first), static_cast<ValT>(item));
++m_size;
}
} BOOST_CATCH(...) {
@@ -1875,7 +1861,7 @@ private:
bool construct = !full();
BOOST_TRY {
while (src != pos.m_it) {
construct_or_replace(construct, dest, this_type::move_if_noexcept(*src));
construct_or_replace(construct, dest, boost::move_if_noexcept(*src));
increment(src);
increment(dest);
construct = false;
@@ -2122,7 +2108,7 @@ public:
pointer next = pos.m_it;
increment(next);
for (pointer p = pos.m_it; next != m_last; p = next, increment(next))
replace(p, this_type::move_if_noexcept(*next));
replace(p, boost::move_if_noexcept(*next));
decrement(m_last);
destroy_item(m_last);
--m_size;
@@ -2161,7 +2147,7 @@ public:
return first;
pointer p = first.m_it;
while (last.m_it != 0)
replace((first++).m_it, this_type::move_if_noexcept(*last++));
replace((first++).m_it, boost::move_if_noexcept(*last++));
do {
decrement(m_last);
destroy_item(m_last);
@@ -2199,7 +2185,7 @@ public:
pointer prev = pos.m_it;
pointer p = prev;
for (decrement(prev); p != m_first; p = prev, decrement(prev))
replace(p, this_type::move_if_noexcept(*prev));
replace(p, boost::move_if_noexcept(*prev));
destroy_item(m_first);
increment(m_first);
--m_size;
@@ -2244,7 +2230,7 @@ public:
while (first.m_it != m_first) {
decrement(first.m_it);
decrement(p);
replace(p, this_type::move_if_noexcept(*first.m_it));
replace(p, boost::move_if_noexcept(*first.m_it));
}
do {
destroy_item(m_first);
@@ -2385,11 +2371,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, 0);
pointer p = (n == 0) ? 0 : m_alloc.allocate(n);
cb_details::do_fill_uninitialized_memory(p, sizeof(value_type) * n);
return p;
#else
return (n == 0) ? 0 : m_alloc.allocate(n, 0);
return (n == 0) ? 0 : m_alloc.allocate(n);
#endif
}
@@ -2427,7 +2413,7 @@ private:
*/
void construct_or_replace(bool construct, pointer pos, param_value_type item) {
if (construct)
cb_details::do_construct<value_type>(pos, item, m_alloc);
boost::container::allocator_traits<Alloc>::construct(m_alloc, boost::addressof(*pos), item);
else
replace(pos, item);
}
@@ -2439,14 +2425,14 @@ private:
*/
void construct_or_replace(bool construct, pointer pos, rvalue_type item) {
if (construct)
cb_details::do_construct<value_type>(pos, boost::move(item), m_alloc);
boost::container::allocator_traits<Alloc>::construct(m_alloc, boost::addressof(*pos), boost::move(item));
else
replace(pos, boost::move(item));
}
//! Destroy an item.
void destroy_item(pointer p) {
m_alloc.destroy(p);
boost::container::allocator_traits<Alloc>::destroy(m_alloc, boost::addressof(*p));
#if BOOST_CB_ENABLE_DEBUG
invalidate_iterators(iterator(this, p));
cb_details::do_fill_uninitialized_memory(p, sizeof(value_type));
@@ -2579,7 +2565,7 @@ private:
if (buffer_capacity == 0)
return;
while (first != last && !full()) {
cb_details::do_construct<value_type>(m_last, *first++, m_alloc);
boost::container::allocator_traits<Alloc>::construct(m_alloc, boost::addressof(*m_last), *first++);
increment(m_last);
++m_size;
}
@@ -2768,7 +2754,7 @@ private:
BOOST_TRY {
while (src != p) {
decrement(src);
construct_or_replace(construct, dest, this_type::move_if_noexcept(*src));
construct_or_replace(construct, dest, boost::move_if_noexcept(*src));
decrement(dest);
construct = false;
}
@@ -2844,7 +2830,7 @@ private:
pointer p = m_last;
BOOST_TRY {
for (; ii < construct; ++ii, increment(p))
cb_details::do_construct<value_type>(p, *wrapper(), m_alloc);
boost::container::allocator_traits<Alloc>::construct(m_alloc, boost::addressof(*p), *wrapper());
for (;ii < n; ++ii, increment(p))
replace(p, *wrapper());
} BOOST_CATCH(...) {
@@ -2938,7 +2924,7 @@ private:
for (;ii > construct; --ii, increment(p))
replace(p, *wrapper());
for (; ii > 0; --ii, increment(p))
cb_details::do_construct<value_type>(p, *wrapper(), m_alloc);
boost::container::allocator_traits<Alloc>::construct(m_alloc, boost::addressof(*p), *wrapper());
} BOOST_CATCH(...) {
size_type constructed = ii < construct ? construct - ii : 0;
m_last = add(m_last, constructed);

View File

@@ -1,6 +1,7 @@
// Helper classes and functions for the circular buffer.
// Copyright (c) 2003-2008 Jan Gaspar
// 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
@@ -15,8 +16,10 @@
#include <boost/iterator.hpp>
#include <boost/throw_exception.hpp>
#include <boost/container/allocator_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>
@@ -44,37 +47,6 @@ ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, Forw
template<class InputIterator, class ForwardIterator, class Alloc>
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a);
//! Those `do_construct` methods are required because in C++03 default allocators
//! have `construct` method that accepts second parameter in as a const reference;
//! while move-only types emulated by Boost.Move require constructor that accepts
//! a non-const reference.
//!
//! So when we need to call `construct` and pointer to value_type is provided, we
//! assume that it is safe to call placement new instead of Alloc::construct.
//! Otherwise we are asume that user has made his own allocator or uses allocator
//! from other libraries. In that case it's users ability to provide Alloc::construct
//! with non-const reference parameter or just do not use move-only types.
template <class ValueType, class Alloc>
inline void do_construct(ValueType* p, BOOST_RV_REF(ValueType) item, Alloc&) {
::new (p) ValueType(boost::move(item));
}
template <class ValueType, class Alloc>
inline void do_construct(ValueType* p, const ValueType& item, Alloc&) {
::new (p) ValueType(item);
}
template <class ValueType, class Alloc, class PointerT>
inline void do_construct(PointerT& p, BOOST_RV_REF(ValueType) item, Alloc& a) {
a.construct(p, boost::move(item));
}
template <class ValueType, class Alloc, class PointerT>
inline void do_construct(PointerT& p, const ValueType& item, Alloc& a) {
a.construct(p, item);
}
/*!
\struct const_traits
\brief Defines the data types for a const iterator.
@@ -141,7 +113,7 @@ private:
*/
template <class Value, class Alloc>
struct assign_n {
typedef typename Alloc::size_type size_type;
typedef typename boost::container::allocator_traits<Alloc>::size_type size_type;
size_type m_n;
Value m_item;
Alloc& m_alloc;
@@ -464,10 +436,10 @@ inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator las
ForwardIterator next = dest;
BOOST_TRY {
for (; first != last; ++first, ++dest)
do_construct<typename Alloc::value_type>(dest, *first, a);
boost::container::allocator_traits<Alloc>::construct(a, boost::addressof(*dest), *first);
} BOOST_CATCH(...) {
for (; next != dest; ++next)
a.destroy(next);
boost::container::allocator_traits<Alloc>::destroy(a, boost::addressof(*next));
BOOST_RETHROW
}
BOOST_CATCH_END
@@ -478,7 +450,7 @@ template<class InputIterator, class ForwardIterator, class Alloc>
ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a,
true_type) {
for (; first != last; ++first, ++dest)
do_construct<typename Alloc::value_type>(dest, boost::move(*first), a);
boost::container::allocator_traits<Alloc>::construct(a, boost::addressof(*dest), boost::move(*first));
return dest;
}
@@ -494,7 +466,7 @@ ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIt
*/
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 Alloc::value_type>::type tag_t;
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());
}
@@ -507,10 +479,10 @@ inline void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const
ForwardIterator next = first;
BOOST_TRY {
for (; n > 0; ++first, --n)
do_construct<typename Alloc::value_type>(first, item, alloc);
boost::container::allocator_traits<Alloc>::construct(alloc, boost::addressof(*first), item);
} BOOST_CATCH(...) {
for (; next != first; ++next)
alloc.destroy(next);
boost::container::allocator_traits<Alloc>::destroy(alloc, boost::addressof(*next));
BOOST_RETHROW
}
BOOST_CATCH_END

14
meta/libraries.json Normal file
View File

@@ -0,0 +1,14 @@
{
"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

@@ -2,6 +2,7 @@
// Copyright (c) 2003-2008 Jan Gaspar
// Copyright (c) 2013 Antony Polukhin
// 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
@@ -163,50 +164,59 @@ public:
typedef typename base_t::size_type size_type;
typedef typename base_t::difference_type difference_type;
struct const_pointer;
struct pointer {
pointer(){}
pointer(void* p) : hidden_ptr_((T*)p) {}
difference_type operator-(const const_pointer& 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; }
T& operator*() const { return *hidden_ptr_; }
private:
template<class U>
struct const_pointer_;
T* hidden_ptr_;
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* hidden_ptr_;
};
struct const_pointer {
const_pointer(){}
const_pointer(pointer p) : hidden_ptr_(p.hidden_ptr_) {}
const_pointer(const void* p) : hidden_ptr_((const T*)p) {}
difference_type operator-(pointer 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 T& operator*() const { return *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 T* hidden_ptr_;
const U* hidden_ptr_;
};
public:
typedef pointer_<T> pointer;
typedef const_pointer_<T> const_pointer;
template<class T2>
struct rebind
{
@@ -248,6 +258,34 @@ void allocator_test() {
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;
@@ -2075,7 +2113,6 @@ 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)
@@ -2114,7 +2151,6 @@ 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)
@@ -2440,5 +2476,8 @@ 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
}