From 56f10e6104f407352ff1ab5e2743100bb7ece872 Mon Sep 17 00:00:00 2001 From: Alexander van Gessel Date: Sat, 11 Nov 2017 00:14:51 +0100 Subject: [PATCH 1/2] Add emplace_{back,front} to circular_buffer --- include/boost/circular_buffer/base.hpp | 80 ++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/include/boost/circular_buffer/base.hpp b/include/boost/circular_buffer/base.hpp index 4babd9f..fa73e81 100644 --- a/include/boost/circular_buffer/base.hpp +++ b/include/boost/circular_buffer/base.hpp @@ -1449,6 +1449,42 @@ private: BOOST_CATCH_END } + template + void emplace_back_impl(BOOST_FWD_REF(Args) ...args) { + if (full()) { + if (empty()) + return; + replace(m_last, value_type(::boost::forward(args)...)); + increment(m_last); + m_first = m_last; + } else { + boost::container::allocator_traits::construct(m_alloc, cb_details::to_address(m_last), ::boost::forward(args)...); + increment(m_last); + ++m_size; + } + } + + template + void emplace_front_impl(BOOST_FWD_REF(Args) ...args) { + BOOST_TRY { + if (full()) { + if (empty()) + return; + decrement(m_first); + replace(m_first, value_type(::boost::forward(args)...)); + m_last = m_first; + } else { + decrement(m_first); + boost::container::allocator_traits::construct(m_alloc, cb_details::to_address(m_first), ::boost::forward(args)...); + ++m_size; + } + } BOOST_CATCH(...) { + increment(m_first); + BOOST_RETHROW + } + BOOST_CATCH_END + } + public: //! Insert a new element at the end of the circular_buffer. /*! @@ -1578,6 +1614,50 @@ public: push_front(boost::move(temp)); } + //! Construct a new element at the end of the circular_buffer. + /*! + \post if capacity() > 0 then back() == item
+ If the circular_buffer is full, the first element will be removed. If the capacity is + 0, nothing will be inserted. + \param item The element to be inserted. + \throws Whatever T::T(Args...) throws. + Whatever T::operator = (T&&) throws. + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Does not invalidate any iterators with the exception of iterators pointing to the overwritten element. + \par Complexity + Constant (in the size of the circular_buffer). + \sa \link push_back() push_back(const_reference)\endlink, + pop_back(), emplace_front() + */ + template + void emplace_back(BOOST_FWD_REF(Args) ...args) { + emplace_back_impl(::boost::forward(args)...); + } + + //! Construct a new element at the beginning of the circular_buffer. + /*! + \post if capacity() > 0 then back() == item
+ If the circular_buffer is full, the last element will be removed. If the capacity is + 0, nothing will be inserted. + \param item The element to be inserted. + \throws Whatever T::T(Args...) throws. + Whatever T::operator = (T&&) throws. + \par Exception Safety + Basic; no-throw if the operation in the Throws section does not throw anything. + \par Iterator Invalidation + Does not invalidate any iterators with the exception of iterators pointing to the overwritten element. + \par Complexity + Constant (in the size of the circular_buffer). + \sa \link push_front() push_front(const_reference)\endlink, + pop_front(), emplace_back() + */ + template + void emplace_front(BOOST_FWD_REF(Args) ...args) { + emplace_front_impl(::boost::forward(args)...); + } + //! Remove the last element from the circular_buffer. /*! \pre !empty() -- 2.11.0