diff options
Diffstat (limited to 'boost/circular_buffer/details.hpp')
-rw-r--r-- | boost/circular_buffer/details.hpp | 113 |
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) |