forked from premiere/premiere-libtorrent
remove variadic template emulation for c++98, and introduce emplace_back to heterogeneous_queue as well, to avoid all moves of alert objects (#658)
This commit is contained in:
parent
10ec0234a7
commit
c3e1e405b2
|
@ -159,7 +159,6 @@ nobase_include_HEADERS = \
|
|||
tommath_class.h \
|
||||
tommath_superclass.h \
|
||||
\
|
||||
aux_/alert_manager_variadic_emplace.hpp \
|
||||
aux_/array_view.hpp \
|
||||
aux_/allocating_handler.hpp \
|
||||
aux_/bind_to_device.hpp \
|
||||
|
|
|
@ -58,9 +58,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
// used for emplace_alert() variadic template emulation for c++98
|
||||
#define TORRENT_ALERT_MANAGER_MAX_ARITY 7
|
||||
|
||||
namespace libtorrent {
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
|
@ -74,8 +71,6 @@ namespace libtorrent {
|
|||
, boost::uint32_t alert_mask = alert::error_notification);
|
||||
~alert_manager();
|
||||
|
||||
#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
|
||||
template <class T, typename... Args>
|
||||
void emplace_alert(Args&&... args)
|
||||
{
|
||||
|
@ -95,20 +90,12 @@ namespace libtorrent {
|
|||
* (1 + T::priority))
|
||||
return;
|
||||
|
||||
T alert(m_allocations[m_generation], std::forward<Args>(args)...);
|
||||
m_alerts[m_generation].push_back(alert);
|
||||
T& alert = m_alerts[m_generation].emplace_back<T>(
|
||||
m_allocations[m_generation], std::forward<Args>(args)...);
|
||||
|
||||
maybe_notify(&alert, lock);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// emulate variadic templates for c++98
|
||||
|
||||
#include "libtorrent/aux_/alert_manager_variadic_emplace.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
bool pending() const;
|
||||
void get_all(std::vector<alert*>& alerts);
|
||||
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
|
||||
#if !defined BOOST_PP_IS_ITERATING || !BOOST_PP_IS_ITERATING
|
||||
// set-up iteration
|
||||
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/punctuation/comma_if.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3, (0, TORRENT_ALERT_MANAGER_MAX_ARITY, \
|
||||
"libtorrent/aux_/alert_manager_variadic_emplace.hpp"))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
|
||||
// loop body
|
||||
|
||||
#define I BOOST_PP_ITERATION()
|
||||
|
||||
template <class T
|
||||
BOOST_PP_COMMA_IF(I)
|
||||
BOOST_PP_ENUM_PARAMS(I, typename A)>
|
||||
void emplace_alert(BOOST_PP_ENUM_BINARY_PARAMS(I, A, const& a) )
|
||||
{
|
||||
mutex::scoped_lock lock(m_mutex);
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
if (m_dispatch)
|
||||
{
|
||||
m_dispatch(std::auto_ptr<alert>(new T(m_allocations[m_generation]
|
||||
BOOST_PP_COMMA_IF(I)
|
||||
BOOST_PP_ENUM_PARAMS(I, a))));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// don't add more than this number of alerts, unless it's a
|
||||
// high priority alert, in which case we try harder to deliver it
|
||||
// for high priority alerts, double the upper limit
|
||||
if (m_alerts[m_generation].size() >= m_queue_size_limit
|
||||
* (1 + T::priority))
|
||||
return;
|
||||
|
||||
T alert(m_allocations[m_generation]
|
||||
BOOST_PP_COMMA_IF(I)
|
||||
BOOST_PP_ENUM_PARAMS(I, a));
|
||||
m_alerts[m_generation].push_back(alert);
|
||||
|
||||
maybe_notify(&alert, lock);
|
||||
}
|
||||
|
||||
#undef I
|
||||
|
||||
#endif
|
||||
|
|
@ -53,10 +53,9 @@ namespace libtorrent {
|
|||
, m_num_items(0)
|
||||
{}
|
||||
|
||||
// TODO: 2 add emplace_back() version
|
||||
template <class U>
|
||||
typename boost::enable_if<boost::is_base_of<T, U> >::type
|
||||
push_back(U const& a)
|
||||
template <class U, typename... Args>
|
||||
typename boost::enable_if<boost::is_base_of<T, U>, U&>::type
|
||||
emplace_back(Args&&... args)
|
||||
{
|
||||
// the size of the type rounded up to pointer alignment
|
||||
const int object_size = (sizeof(U) + sizeof(*m_storage) - 1)
|
||||
|
@ -75,12 +74,13 @@ namespace libtorrent {
|
|||
ptr += header_size;
|
||||
|
||||
// construct in-place
|
||||
new (ptr) U(a);
|
||||
new (ptr) U(std::forward<Args>(args)...);
|
||||
|
||||
// if we constructed the object without throwing any exception
|
||||
// update counters to indicate the new item is in there
|
||||
++m_num_items;
|
||||
m_size += header_size + object_size;
|
||||
return *reinterpret_cast<U*>(ptr);
|
||||
}
|
||||
|
||||
void get_pointers(std::vector<T*>& out)
|
||||
|
|
|
@ -138,24 +138,24 @@ private:
|
|||
F& operator=(F const& f);
|
||||
};
|
||||
|
||||
// test push_back of heterogeneous types
|
||||
// test emplace_back of heterogeneous types
|
||||
// and retrieval of their pointers
|
||||
TORRENT_TEST(push_back)
|
||||
TORRENT_TEST(emplace_back)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
heterogeneous_queue<A> q;
|
||||
q.push_back(B(0, 1));
|
||||
q.emplace_back<B>(0, 1);
|
||||
TEST_EQUAL(q.size(), 1);
|
||||
q.push_back(B(2, 3));
|
||||
q.emplace_back<B>(2, 3);
|
||||
TEST_EQUAL(q.size(), 2);
|
||||
q.push_back(B(4, 5));
|
||||
q.emplace_back<B>(4, 5);
|
||||
TEST_EQUAL(q.size(), 3);
|
||||
q.push_back(C(6, 7));
|
||||
q.emplace_back<C>(6, 7);
|
||||
TEST_EQUAL(q.size(), 4);
|
||||
q.push_back(C(8, 9));
|
||||
q.emplace_back<C>(8, 9);
|
||||
TEST_EQUAL(q.size(), 5);
|
||||
q.push_back(C(10, 11));
|
||||
q.emplace_back<C>(10, 11);
|
||||
TEST_EQUAL(q.size(), 6);
|
||||
|
||||
std::vector<A*> ptrs;
|
||||
|
@ -196,13 +196,13 @@ TORRENT_TEST(swap)
|
|||
heterogeneous_queue<A> q1;
|
||||
heterogeneous_queue<A> q2;
|
||||
|
||||
q1.push_back(B(0, 1));
|
||||
q1.push_back(B(2, 3));
|
||||
q1.push_back(B(4, 5));
|
||||
q1.emplace_back<B>(0, 1);
|
||||
q1.emplace_back<B>(2, 3);
|
||||
q1.emplace_back<B>(4, 5);
|
||||
TEST_EQUAL(q1.size(), 3);
|
||||
|
||||
q2.push_back(C(6, 7));
|
||||
q2.push_back(C(8, 9));
|
||||
q2.emplace_back<C>(6, 7);
|
||||
q2.emplace_back<C>(8, 9);
|
||||
TEST_EQUAL(q2.size(), 2);
|
||||
|
||||
std::vector<A*> ptrs;
|
||||
|
@ -245,13 +245,13 @@ TORRENT_TEST(destruction)
|
|||
heterogeneous_queue<D> q;
|
||||
TEST_EQUAL(D::instances, 0);
|
||||
|
||||
q.push_back(D());
|
||||
q.emplace_back<D>();
|
||||
TEST_EQUAL(D::instances, 1);
|
||||
q.push_back(D());
|
||||
q.emplace_back<D>();
|
||||
TEST_EQUAL(D::instances, 2);
|
||||
q.push_back(D());
|
||||
q.emplace_back<D>();
|
||||
TEST_EQUAL(D::instances, 3);
|
||||
q.push_back(D());
|
||||
q.emplace_back<D>();
|
||||
TEST_EQUAL(D::instances, 4);
|
||||
|
||||
q.clear();
|
||||
|
@ -269,7 +269,7 @@ TORRENT_TEST(copy_move)
|
|||
// make sure the queue has to grow at some point, to exercise its
|
||||
// copy/move of elements
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
q.push_back(F(i));
|
||||
q.emplace_back<F>(i);
|
||||
|
||||
std::vector<F*> ptrs;
|
||||
q.get_pointers(ptrs);
|
||||
|
@ -293,7 +293,7 @@ TORRENT_TEST(nontrivial)
|
|||
heterogeneous_queue<E> q;
|
||||
for (int i = 0; i < 10000; ++i)
|
||||
{
|
||||
q.push_back(E("testing to allocate non-trivial objects"));
|
||||
q.emplace_back<E>("testing to allocate non-trivial objects");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue