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_class.h \
|
||||||
tommath_superclass.h \
|
tommath_superclass.h \
|
||||||
\
|
\
|
||||||
aux_/alert_manager_variadic_emplace.hpp \
|
|
||||||
aux_/array_view.hpp \
|
aux_/array_view.hpp \
|
||||||
aux_/allocating_handler.hpp \
|
aux_/allocating_handler.hpp \
|
||||||
aux_/bind_to_device.hpp \
|
aux_/bind_to_device.hpp \
|
||||||
|
|
|
@ -58,9 +58,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// used for emplace_alert() variadic template emulation for c++98
|
|
||||||
#define TORRENT_ALERT_MANAGER_MAX_ARITY 7
|
|
||||||
|
|
||||||
namespace libtorrent {
|
namespace libtorrent {
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||||
|
@ -74,8 +71,6 @@ namespace libtorrent {
|
||||||
, boost::uint32_t alert_mask = alert::error_notification);
|
, boost::uint32_t alert_mask = alert::error_notification);
|
||||||
~alert_manager();
|
~alert_manager();
|
||||||
|
|
||||||
#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
|
||||||
|
|
||||||
template <class T, typename... Args>
|
template <class T, typename... Args>
|
||||||
void emplace_alert(Args&&... args)
|
void emplace_alert(Args&&... args)
|
||||||
{
|
{
|
||||||
|
@ -95,20 +90,12 @@ namespace libtorrent {
|
||||||
* (1 + T::priority))
|
* (1 + T::priority))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
T alert(m_allocations[m_generation], std::forward<Args>(args)...);
|
T& alert = m_alerts[m_generation].emplace_back<T>(
|
||||||
m_alerts[m_generation].push_back(alert);
|
m_allocations[m_generation], std::forward<Args>(args)...);
|
||||||
|
|
||||||
maybe_notify(&alert, lock);
|
maybe_notify(&alert, lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// emulate variadic templates for c++98
|
|
||||||
|
|
||||||
#include "libtorrent/aux_/alert_manager_variadic_emplace.hpp"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool pending() const;
|
bool pending() const;
|
||||||
void get_all(std::vector<alert*>& alerts);
|
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)
|
, m_num_items(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// TODO: 2 add emplace_back() version
|
template <class U, typename... Args>
|
||||||
template <class U>
|
typename boost::enable_if<boost::is_base_of<T, U>, U&>::type
|
||||||
typename boost::enable_if<boost::is_base_of<T, U> >::type
|
emplace_back(Args&&... args)
|
||||||
push_back(U const& a)
|
|
||||||
{
|
{
|
||||||
// the size of the type rounded up to pointer alignment
|
// the size of the type rounded up to pointer alignment
|
||||||
const int object_size = (sizeof(U) + sizeof(*m_storage) - 1)
|
const int object_size = (sizeof(U) + sizeof(*m_storage) - 1)
|
||||||
|
@ -75,12 +74,13 @@ namespace libtorrent {
|
||||||
ptr += header_size;
|
ptr += header_size;
|
||||||
|
|
||||||
// construct in-place
|
// construct in-place
|
||||||
new (ptr) U(a);
|
new (ptr) U(std::forward<Args>(args)...);
|
||||||
|
|
||||||
// if we constructed the object without throwing any exception
|
// if we constructed the object without throwing any exception
|
||||||
// update counters to indicate the new item is in there
|
// update counters to indicate the new item is in there
|
||||||
++m_num_items;
|
++m_num_items;
|
||||||
m_size += header_size + object_size;
|
m_size += header_size + object_size;
|
||||||
|
return *reinterpret_cast<U*>(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_pointers(std::vector<T*>& out)
|
void get_pointers(std::vector<T*>& out)
|
||||||
|
|
|
@ -138,24 +138,24 @@ private:
|
||||||
F& operator=(F const& f);
|
F& operator=(F const& f);
|
||||||
};
|
};
|
||||||
|
|
||||||
// test push_back of heterogeneous types
|
// test emplace_back of heterogeneous types
|
||||||
// and retrieval of their pointers
|
// and retrieval of their pointers
|
||||||
TORRENT_TEST(push_back)
|
TORRENT_TEST(emplace_back)
|
||||||
{
|
{
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
|
|
||||||
heterogeneous_queue<A> q;
|
heterogeneous_queue<A> q;
|
||||||
q.push_back(B(0, 1));
|
q.emplace_back<B>(0, 1);
|
||||||
TEST_EQUAL(q.size(), 1);
|
TEST_EQUAL(q.size(), 1);
|
||||||
q.push_back(B(2, 3));
|
q.emplace_back<B>(2, 3);
|
||||||
TEST_EQUAL(q.size(), 2);
|
TEST_EQUAL(q.size(), 2);
|
||||||
q.push_back(B(4, 5));
|
q.emplace_back<B>(4, 5);
|
||||||
TEST_EQUAL(q.size(), 3);
|
TEST_EQUAL(q.size(), 3);
|
||||||
q.push_back(C(6, 7));
|
q.emplace_back<C>(6, 7);
|
||||||
TEST_EQUAL(q.size(), 4);
|
TEST_EQUAL(q.size(), 4);
|
||||||
q.push_back(C(8, 9));
|
q.emplace_back<C>(8, 9);
|
||||||
TEST_EQUAL(q.size(), 5);
|
TEST_EQUAL(q.size(), 5);
|
||||||
q.push_back(C(10, 11));
|
q.emplace_back<C>(10, 11);
|
||||||
TEST_EQUAL(q.size(), 6);
|
TEST_EQUAL(q.size(), 6);
|
||||||
|
|
||||||
std::vector<A*> ptrs;
|
std::vector<A*> ptrs;
|
||||||
|
@ -196,13 +196,13 @@ TORRENT_TEST(swap)
|
||||||
heterogeneous_queue<A> q1;
|
heterogeneous_queue<A> q1;
|
||||||
heterogeneous_queue<A> q2;
|
heterogeneous_queue<A> q2;
|
||||||
|
|
||||||
q1.push_back(B(0, 1));
|
q1.emplace_back<B>(0, 1);
|
||||||
q1.push_back(B(2, 3));
|
q1.emplace_back<B>(2, 3);
|
||||||
q1.push_back(B(4, 5));
|
q1.emplace_back<B>(4, 5);
|
||||||
TEST_EQUAL(q1.size(), 3);
|
TEST_EQUAL(q1.size(), 3);
|
||||||
|
|
||||||
q2.push_back(C(6, 7));
|
q2.emplace_back<C>(6, 7);
|
||||||
q2.push_back(C(8, 9));
|
q2.emplace_back<C>(8, 9);
|
||||||
TEST_EQUAL(q2.size(), 2);
|
TEST_EQUAL(q2.size(), 2);
|
||||||
|
|
||||||
std::vector<A*> ptrs;
|
std::vector<A*> ptrs;
|
||||||
|
@ -245,13 +245,13 @@ TORRENT_TEST(destruction)
|
||||||
heterogeneous_queue<D> q;
|
heterogeneous_queue<D> q;
|
||||||
TEST_EQUAL(D::instances, 0);
|
TEST_EQUAL(D::instances, 0);
|
||||||
|
|
||||||
q.push_back(D());
|
q.emplace_back<D>();
|
||||||
TEST_EQUAL(D::instances, 1);
|
TEST_EQUAL(D::instances, 1);
|
||||||
q.push_back(D());
|
q.emplace_back<D>();
|
||||||
TEST_EQUAL(D::instances, 2);
|
TEST_EQUAL(D::instances, 2);
|
||||||
q.push_back(D());
|
q.emplace_back<D>();
|
||||||
TEST_EQUAL(D::instances, 3);
|
TEST_EQUAL(D::instances, 3);
|
||||||
q.push_back(D());
|
q.emplace_back<D>();
|
||||||
TEST_EQUAL(D::instances, 4);
|
TEST_EQUAL(D::instances, 4);
|
||||||
|
|
||||||
q.clear();
|
q.clear();
|
||||||
|
@ -269,7 +269,7 @@ TORRENT_TEST(copy_move)
|
||||||
// make sure the queue has to grow at some point, to exercise its
|
// make sure the queue has to grow at some point, to exercise its
|
||||||
// copy/move of elements
|
// copy/move of elements
|
||||||
for (int i = 0; i < 1000; ++i)
|
for (int i = 0; i < 1000; ++i)
|
||||||
q.push_back(F(i));
|
q.emplace_back<F>(i);
|
||||||
|
|
||||||
std::vector<F*> ptrs;
|
std::vector<F*> ptrs;
|
||||||
q.get_pointers(ptrs);
|
q.get_pointers(ptrs);
|
||||||
|
@ -293,7 +293,7 @@ TORRENT_TEST(nontrivial)
|
||||||
heterogeneous_queue<E> q;
|
heterogeneous_queue<E> q;
|
||||||
for (int i = 0; i < 10000; ++i)
|
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