summaryrefslogtreecommitdiff
path: root/boost/circular_buffer/details.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/circular_buffer/details.hpp')
-rw-r--r--boost/circular_buffer/details.hpp113
1 files changed, 71 insertions, 42 deletions
diff --git a/boost/circular_buffer/details.hpp b/boost/circular_buffer/details.hpp
index da25ff07ed..44ca9c9689 100644
--- a/boost/circular_buffer/details.hpp
+++ b/boost/circular_buffer/details.hpp
@@ -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
@@ -9,15 +10,27 @@
#if !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP)
#define BOOST_CIRCULAR_BUFFER_DETAILS_HPP
-#if defined(_MSC_VER) && _MSC_VER >= 1200
+#if defined(_MSC_VER)
#pragma once
#endif
#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>
+// Silence MS /W4 warnings like C4913:
+// "user defined binary operator ',' exists but no overload could convert all operands, default built-in binary operator ',' used"
+// This might happen when previously including some boost headers that overload the coma operator.
+#if defined(_MSC_VER)
+# pragma warning(push)
+# pragma warning(disable:4913)
+#endif
+
namespace boost {
namespace cb_details {
@@ -29,8 +42,10 @@ 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_with_alloc(
- InputIterator first, InputIterator last, ForwardIterator dest, Alloc& alloc);
+ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a);
+
+template<class InputIterator, class ForwardIterator, class Alloc>
+ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a);
/*!
\struct const_traits
@@ -98,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;
@@ -117,19 +132,24 @@ private:
*/
template <class Iterator, class Alloc>
struct assign_range {
- const Iterator& m_first;
- const Iterator& m_last;
- Alloc& m_alloc;
+ 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) {}
+ : m_first(first), m_last(last), m_alloc(alloc) {}
+
template <class Pointer>
void operator () (Pointer p) const {
- uninitialized_copy_with_alloc(m_first, m_last, p, m_alloc);
+ boost::cb_details::uninitialized_copy(m_first, m_last, p, m_alloc);
}
-private:
- assign_range<Iterator, Alloc>& operator = (const assign_range<Iterator, Alloc>&); // do not generate
};
+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);
+}
+
/*!
\class capacity_control
\brief Capacity controller of the space optimized circular buffer.
@@ -137,18 +157,19 @@ private:
template <class Size>
class capacity_control {
- //! The capacity of the space optimized circular buffer.
+ //! The capacity of the space-optimized circular buffer.
Size m_capacity;
- //! The lowest guaranteed capacity of the adapted circular buffer.
+ //! The lowest guaranteed or minimum capacity of the adapted space-optimized circular buffer.
Size m_min_capacity;
public:
//! Constructor.
capacity_control(Size buffer_capacity, Size min_buffer_capacity = 0)
- : m_capacity(buffer_capacity), m_min_capacity(min_buffer_capacity) {
- BOOST_CB_ASSERT(buffer_capacity >= min_buffer_capacity); // check for capacity lower than min_capacity
+ : m_capacity(buffer_capacity), m_min_capacity(min_buffer_capacity)
+ { // Check for capacity lower than min_capacity.
+ BOOST_CB_ASSERT(buffer_capacity >= min_buffer_capacity);
}
// Default copy constructor.
@@ -406,45 +427,49 @@ 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_with_alloc(InputIterator first, InputIterator last, ForwardIterator dest,
- Alloc& alloc)
- \brief Equivalent of <code>std::uninitialized_copy</code> with allocator.
+ \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_with_alloc(InputIterator first, InputIterator last, ForwardIterator dest,
- Alloc& alloc) {
+inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a) {
ForwardIterator next = dest;
BOOST_TRY {
for (; first != last; ++first, ++dest)
- alloc.construct(dest, *first);
+ boost::container::allocator_traits<Alloc>::construct(a, boost::addressof(*dest), *first);
} BOOST_CATCH(...) {
for (; next != dest; ++next)
- alloc.destroy(next);
+ boost::container::allocator_traits<Alloc>::destroy(a, boost::addressof(*next));
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,
+ true_type) {
+ for (; first != last; ++first, ++dest)
+ boost::container::allocator_traits<Alloc>::construct(a, boost::addressof(*dest), 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,
+ false_type) {
+ return uninitialized_copy(first, last, dest, a);
+}
+
+/*!
+ \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());
+}
+
/*!
\fn void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const T& item, Alloc& alloc)
\brief Equivalent of <code>std::uninitialized_fill_n</code> with allocator.
@@ -454,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)
- alloc.construct(first, item);
+ 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
@@ -467,4 +492,8 @@ inline void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const
} // namespace boost
+#if defined(_MSC_VER)
+# pragma warning(pop)
+#endif
+
#endif // #if !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP)