Skip to content

Commit 7e233f7

Browse files
committed
Merge branch 'develop'
2 parents f5303c7 + 689e79a commit 7e233f7

File tree

4 files changed

+120
-100
lines changed

4 files changed

+120
-100
lines changed

doc/circular_buffer.qbk

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,10 @@ Type: Patches
532532

533533
[section:release Release Notes]
534534

535+
[h4 Boost 1.56]
536+
537+
* C++11 allocator model support implemented by Glen Fernandes using Boost allocator_traits.
538+
535539
[h4 Boost 1.55]
536540

537541
* Documentation refactored by Paul A. Bristow using Quickbook, Doxygen and Autoindexing.

include/boost/circular_buffer/base.hpp

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// Copyright (c) 2003-2008 Jan Gaspar
44
// Copyright (c) 2013 Paul A. Bristow // Doxygen comments changed.
55
// Copyright (c) 2013 Antony Polukhin // Move semantics implementation.
6-
6+
// Copyright (c) 2014 Glen Fernandes // C++11 allocator model support.
77

88
// Use, modification, and distribution is subject to the Boost Software
99
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -20,6 +20,7 @@
2020
#include <boost/call_traits.hpp>
2121
#include <boost/concept_check.hpp>
2222
#include <boost/limits.hpp>
23+
#include <boost/container/allocator_traits.hpp>
2324
#include <boost/iterator/reverse_iterator.hpp>
2425
#include <boost/iterator/iterator_traits.hpp>
2526
#include <boost/type_traits/is_stateless.hpp>
@@ -30,10 +31,12 @@
3031
#include <boost/type_traits/is_copy_constructible.hpp>
3132
#include <boost/type_traits/conditional.hpp>
3233
#include <boost/move/move.hpp>
34+
#include <boost/utility/addressof.hpp>
3335
#include <algorithm>
3436
#include <utility>
3537
#include <deque>
3638
#include <stdexcept>
39+
3740
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
3841
#include <stddef.h>
3942
#endif
@@ -92,42 +95,42 @@ class circular_buffer
9295
typedef circular_buffer<T, Alloc> this_type;
9396

9497
//! The type of elements stored in the <code>circular_buffer</code>.
95-
typedef typename Alloc::value_type value_type;
98+
typedef typename boost::container::allocator_traits<Alloc>::value_type value_type;
9699

97100
//! A pointer to an element.
98-
typedef typename Alloc::pointer pointer;
101+
typedef typename boost::container::allocator_traits<Alloc>::pointer pointer;
99102

100103
//! A const pointer to the element.
101-
typedef typename Alloc::const_pointer const_pointer;
104+
typedef typename boost::container::allocator_traits<Alloc>::const_pointer const_pointer;
102105

103106
//! A reference to an element.
104-
typedef typename Alloc::reference reference;
107+
typedef typename boost::container::allocator_traits<Alloc>::reference reference;
105108

106109
//! A const reference to an element.
107-
typedef typename Alloc::const_reference const_reference;
110+
typedef typename boost::container::allocator_traits<Alloc>::const_reference const_reference;
108111

109112
//! The distance type.
110113
/*!
111114
(A signed integral type used to represent the distance between two iterators.)
112115
*/
113-
typedef typename Alloc::difference_type difference_type;
116+
typedef typename boost::container::allocator_traits<Alloc>::difference_type difference_type;
114117

115118
//! The size type.
116119
/*!
117120
(An unsigned integral type that can represent any non-negative value of the container's distance type.)
118121
*/
119-
typedef typename Alloc::size_type size_type;
122+
typedef typename boost::container::allocator_traits<Alloc>::size_type size_type;
120123

121124
//! The type of an allocator used in the <code>circular_buffer</code>.
122125
typedef Alloc allocator_type;
123126

124127
// Iterators
125128

126129
//! A const (random access) iterator used to iterate through the <code>circular_buffer</code>.
127-
typedef cb_details::iterator< circular_buffer<T, Alloc>, cb_details::const_traits<Alloc> > const_iterator;
130+
typedef cb_details::iterator< circular_buffer<T, Alloc>, cb_details::const_traits<boost::container::allocator_traits<Alloc> > > const_iterator;
128131

129132
//! A (random access) iterator used to iterate through the <code>circular_buffer</code>.
130-
typedef cb_details::iterator< circular_buffer<T, Alloc>, cb_details::nonconst_traits<Alloc> > iterator;
133+
typedef cb_details::iterator< circular_buffer<T, Alloc>, cb_details::nonconst_traits<boost::container::allocator_traits<Alloc> > > iterator;
131134

132135
//! A const iterator used to iterate backwards through a <code>circular_buffer</code>.
133136
typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
@@ -679,7 +682,7 @@ class circular_buffer
679682
break;
680683
}
681684
if (is_uninitialized(dest)) {
682-
cb_details::do_construct<value_type>(dest, this_type::move_if_noexcept(*src), m_alloc);
685+
boost::container::allocator_traits<Alloc>::construct(m_alloc, boost::addressof(*dest), this_type::move_if_noexcept(*src));
683686
++constructed;
684687
} else {
685688
value_type tmp = this_type::move_if_noexcept(*src);
@@ -800,7 +803,7 @@ class circular_buffer
800803
\sa <code>size()</code>, <code>capacity()</code>, <code>reserve()</code>
801804
*/
802805
size_type max_size() const BOOST_NOEXCEPT {
803-
return (std::min<size_type>)(m_alloc.max_size(), (std::numeric_limits<difference_type>::max)());
806+
return (std::min<size_type>)(boost::container::allocator_traits<Alloc>::max_size(m_alloc), (std::numeric_limits<difference_type>::max)());
804807
}
805808

806809
//! Is the <code>circular_buffer</code> empty?
@@ -1435,7 +1438,7 @@ class circular_buffer
14351438
increment(m_last);
14361439
m_first = m_last;
14371440
} else {
1438-
cb_details::do_construct<value_type>(m_last, static_cast<ValT>(item), m_alloc);
1441+
boost::container::allocator_traits<Alloc>::construct(m_alloc, boost::addressof(*m_last), static_cast<ValT>(item));
14391442
increment(m_last);
14401443
++m_size;
14411444
}
@@ -1452,7 +1455,7 @@ class circular_buffer
14521455
m_last = m_first;
14531456
} else {
14541457
decrement(m_first);
1455-
cb_details::do_construct<value_type>(m_first, static_cast<ValT>(item), m_alloc);
1458+
boost::container::allocator_traits<Alloc>::construct(m_alloc, boost::addressof(*m_first), static_cast<ValT>(item));
14561459
++m_size;
14571460
}
14581461
} BOOST_CATCH(...) {
@@ -2385,11 +2388,11 @@ class circular_buffer
23852388
if (n > max_size())
23862389
throw_exception(std::length_error("circular_buffer"));
23872390
#if BOOST_CB_ENABLE_DEBUG
2388-
pointer p = (n == 0) ? 0 : m_alloc.allocate(n, 0);
2391+
pointer p = (n == 0) ? 0 : m_alloc.allocate(n);
23892392
cb_details::do_fill_uninitialized_memory(p, sizeof(value_type) * n);
23902393
return p;
23912394
#else
2392-
return (n == 0) ? 0 : m_alloc.allocate(n, 0);
2395+
return (n == 0) ? 0 : m_alloc.allocate(n);
23932396
#endif
23942397
}
23952398

@@ -2427,7 +2430,7 @@ class circular_buffer
24272430
*/
24282431
void construct_or_replace(bool construct, pointer pos, param_value_type item) {
24292432
if (construct)
2430-
cb_details::do_construct<value_type>(pos, item, m_alloc);
2433+
boost::container::allocator_traits<Alloc>::construct(m_alloc, boost::addressof(*pos), item);
24312434
else
24322435
replace(pos, item);
24332436
}
@@ -2439,14 +2442,14 @@ class circular_buffer
24392442
*/
24402443
void construct_or_replace(bool construct, pointer pos, rvalue_type item) {
24412444
if (construct)
2442-
cb_details::do_construct<value_type>(pos, boost::move(item), m_alloc);
2445+
boost::container::allocator_traits<Alloc>::construct(m_alloc, boost::addressof(*pos), boost::move(item));
24432446
else
24442447
replace(pos, boost::move(item));
24452448
}
24462449

24472450
//! Destroy an item.
24482451
void destroy_item(pointer p) {
2449-
m_alloc.destroy(p);
2452+
boost::container::allocator_traits<Alloc>::destroy(m_alloc, boost::addressof(*p));
24502453
#if BOOST_CB_ENABLE_DEBUG
24512454
invalidate_iterators(iterator(this, p));
24522455
cb_details::do_fill_uninitialized_memory(p, sizeof(value_type));
@@ -2579,7 +2582,7 @@ class circular_buffer
25792582
if (buffer_capacity == 0)
25802583
return;
25812584
while (first != last && !full()) {
2582-
cb_details::do_construct<value_type>(m_last, *first++, m_alloc);
2585+
boost::container::allocator_traits<Alloc>::construct(m_alloc, boost::addressof(*m_last), *first++);
25832586
increment(m_last);
25842587
++m_size;
25852588
}
@@ -2844,7 +2847,7 @@ class circular_buffer
28442847
pointer p = m_last;
28452848
BOOST_TRY {
28462849
for (; ii < construct; ++ii, increment(p))
2847-
cb_details::do_construct<value_type>(p, *wrapper(), m_alloc);
2850+
boost::container::allocator_traits<Alloc>::construct(m_alloc, boost::addressof(*p), *wrapper());
28482851
for (;ii < n; ++ii, increment(p))
28492852
replace(p, *wrapper());
28502853
} BOOST_CATCH(...) {
@@ -2938,7 +2941,7 @@ class circular_buffer
29382941
for (;ii > construct; --ii, increment(p))
29392942
replace(p, *wrapper());
29402943
for (; ii > 0; --ii, increment(p))
2941-
cb_details::do_construct<value_type>(p, *wrapper(), m_alloc);
2944+
boost::container::allocator_traits<Alloc>::construct(m_alloc, boost::addressof(*p), *wrapper());
29422945
} BOOST_CATCH(...) {
29432946
size_type constructed = ii < construct ? construct - ii : 0;
29442947
m_last = add(m_last, constructed);

include/boost/circular_buffer/details.hpp

Lines changed: 10 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Helper classes and functions for the circular buffer.
22

33
// Copyright (c) 2003-2008 Jan Gaspar
4+
// Copyright (c) 2014 Glen Fernandes // C++11 allocator model support.
45

56
// Use, modification, and distribution is subject to the Boost Software
67
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -15,8 +16,10 @@
1516

1617
#include <boost/iterator.hpp>
1718
#include <boost/throw_exception.hpp>
19+
#include <boost/container/allocator_traits.hpp>
1820
#include <boost/move/move.hpp>
1921
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
22+
#include <boost/utility/addressof.hpp>
2023
#include <boost/detail/no_exceptions_support.hpp>
2124
#include <iterator>
2225

@@ -44,37 +47,6 @@ ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, Forw
4447
template<class InputIterator, class ForwardIterator, class Alloc>
4548
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a);
4649

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-
}
67-
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-
}
77-
7850
/*!
7951
\struct const_traits
8052
\brief Defines the data types for a const iterator.
@@ -141,7 +113,7 @@ struct item_wrapper {
141113
*/
142114
template <class Value, class Alloc>
143115
struct assign_n {
144-
typedef typename Alloc::size_type size_type;
116+
typedef typename boost::container::allocator_traits<Alloc>::size_type size_type;
145117
size_type m_n;
146118
Value m_item;
147119
Alloc& m_alloc;
@@ -464,10 +436,10 @@ inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator las
464436
ForwardIterator next = dest;
465437
BOOST_TRY {
466438
for (; first != last; ++first, ++dest)
467-
do_construct<typename Alloc::value_type>(dest, *first, a);
439+
boost::container::allocator_traits<Alloc>::construct(a, boost::addressof(*dest), *first);
468440
} BOOST_CATCH(...) {
469441
for (; next != dest; ++next)
470-
a.destroy(next);
442+
boost::container::allocator_traits<Alloc>::destroy(a, boost::addressof(*next));
471443
BOOST_RETHROW
472444
}
473445
BOOST_CATCH_END
@@ -478,7 +450,7 @@ template<class InputIterator, class ForwardIterator, class Alloc>
478450
ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a,
479451
true_type) {
480452
for (; first != last; ++first, ++dest)
481-
do_construct<typename Alloc::value_type>(dest, boost::move(*first), a);
453+
boost::container::allocator_traits<Alloc>::construct(a, boost::addressof(*dest), boost::move(*first));
482454
return dest;
483455
}
484456

@@ -494,7 +466,7 @@ ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIt
494466
*/
495467
template<class InputIterator, class ForwardIterator, class Alloc>
496468
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;
469+
typedef typename boost::is_nothrow_move_constructible<typename boost::container::allocator_traits<Alloc>::value_type>::type tag_t;
498470
return uninitialized_move_if_noexcept_impl(first, last, dest, a, tag_t());
499471
}
500472

@@ -507,10 +479,10 @@ inline void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const
507479
ForwardIterator next = first;
508480
BOOST_TRY {
509481
for (; n > 0; ++first, --n)
510-
do_construct<typename Alloc::value_type>(first, item, alloc);
482+
boost::container::allocator_traits<Alloc>::construct(alloc, boost::addressof(*first), item);
511483
} BOOST_CATCH(...) {
512484
for (; next != first; ++next)
513-
alloc.destroy(next);
485+
boost::container::allocator_traits<Alloc>::destroy(alloc, boost::addressof(*next));
514486
BOOST_RETHROW
515487
}
516488
BOOST_CATCH_END

0 commit comments

Comments
 (0)