mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-30 11:27:15 +02:00
Don't track construction when using boost::tuple
Because it doesn't quiet work on C++11 compilers onwards.
This commit is contained in:
@ -60,9 +60,11 @@ struct memory_tracker
|
||||
unsigned int count_allocators;
|
||||
unsigned int count_allocations;
|
||||
unsigned int count_constructions;
|
||||
bool tracking_constructions;
|
||||
|
||||
memory_tracker()
|
||||
: count_allocators(0), count_allocations(0), count_constructions(0)
|
||||
: count_allocators(0), count_allocations(0), count_constructions(0),
|
||||
tracking_constructions(true)
|
||||
{
|
||||
}
|
||||
|
||||
@ -133,15 +135,19 @@ struct memory_tracker
|
||||
|
||||
void track_construct(void* /*ptr*/, std::size_t /*size*/, int /*tag*/)
|
||||
{
|
||||
if (tracking_constructions) {
|
||||
++count_constructions;
|
||||
}
|
||||
}
|
||||
|
||||
void track_destroy(void* /*ptr*/, std::size_t /*size*/, int /*tag*/)
|
||||
{
|
||||
if (tracking_constructions) {
|
||||
BOOST_TEST(count_constructions > 0);
|
||||
if (count_constructions > 0)
|
||||
--count_constructions;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -155,6 +161,29 @@ namespace {
|
||||
test::detail::memory_tracker tracker;
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
struct disable_construction_tracking
|
||||
{
|
||||
bool old_value;
|
||||
|
||||
disable_construction_tracking()
|
||||
: old_value(detail::tracker.tracking_constructions)
|
||||
{
|
||||
test::detail::tracker.tracking_constructions = false;
|
||||
}
|
||||
|
||||
~disable_construction_tracking()
|
||||
{
|
||||
test::detail::tracker.tracking_constructions = old_value;
|
||||
}
|
||||
|
||||
private:
|
||||
disable_construction_tracking(disable_construction_tracking const&);
|
||||
disable_construction_tracking& operator=(
|
||||
disable_construction_tracking const&);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -392,10 +392,10 @@ template <class T> class allocator1
|
||||
}
|
||||
|
||||
#if BOOST_UNORDERED_CXX11_CONSTRUCTION
|
||||
template <typename... Args> void construct(T* p, Args&&... args)
|
||||
template <typename U, typename... Args> void construct(U* p, Args&&... args)
|
||||
{
|
||||
detail::tracker.track_construct((void*)p, sizeof(T), tag_);
|
||||
new (p) T(boost::forward<Args>(args)...);
|
||||
detail::tracker.track_construct((void*)p, sizeof(U), tag_);
|
||||
new (p) U(boost::forward<Args>(args)...);
|
||||
}
|
||||
#else
|
||||
void construct(T* p, T const& t)
|
||||
@ -405,10 +405,10 @@ template <class T> class allocator1
|
||||
}
|
||||
#endif
|
||||
|
||||
void destroy(T* p)
|
||||
template <typename U> void destroy(U* p)
|
||||
{
|
||||
detail::tracker.track_destroy((void*)p, sizeof(T), tag_);
|
||||
p->~T();
|
||||
detail::tracker.track_destroy((void*)p, sizeof(U), tag_);
|
||||
p->~U();
|
||||
|
||||
// Work around MSVC buggy unused parameter warning.
|
||||
ignore_variable(&p);
|
||||
|
@ -1120,6 +1120,10 @@ struct convertible_to_piecewise
|
||||
|
||||
UNORDERED_AUTO_TEST(map_emplace_test2)
|
||||
{
|
||||
// Emulating piecewise construction with boost::tuple bypasses the
|
||||
// allocator's construct method, but still uses test destroy method.
|
||||
test::detail::disable_construction_tracking _scoped;
|
||||
|
||||
{
|
||||
boost::unordered_map<overloaded_constructor, overloaded_constructor,
|
||||
boost::hash<overloaded_constructor>,
|
||||
@ -1169,8 +1173,8 @@ UNORDERED_AUTO_TEST(map_emplace_test2)
|
||||
x.find(overloaded_constructor(2, 3))->second ==
|
||||
overloaded_constructor(4, 5, 6));
|
||||
}
|
||||
{
|
||||
|
||||
{
|
||||
boost::unordered_multimap<overloaded_constructor,
|
||||
overloaded_constructor, boost::hash<overloaded_constructor>,
|
||||
std::equal_to<overloaded_constructor>,
|
||||
@ -1220,9 +1224,115 @@ UNORDERED_AUTO_TEST(set_emplace_test2)
|
||||
boost::make_tuple(2, 3));
|
||||
check =
|
||||
std::make_pair(overloaded_constructor(1), overloaded_constructor(2, 3));
|
||||
;
|
||||
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
|
||||
}
|
||||
|
||||
#if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
|
||||
|
||||
UNORDERED_AUTO_TEST(map_std_emplace_test2)
|
||||
{
|
||||
{
|
||||
boost::unordered_map<overloaded_constructor, overloaded_constructor,
|
||||
boost::hash<overloaded_constructor>,
|
||||
std::equal_to<overloaded_constructor>,
|
||||
test::allocator1<std::pair<overloaded_constructor const,
|
||||
overloaded_constructor> > >
|
||||
x;
|
||||
|
||||
x.emplace(
|
||||
std::piecewise_construct, std::make_tuple(), std::make_tuple());
|
||||
BOOST_TEST(x.find(overloaded_constructor()) != x.end() &&
|
||||
x.find(overloaded_constructor())->second ==
|
||||
overloaded_constructor());
|
||||
|
||||
x.emplace(
|
||||
convertible_to_piecewise(), std::make_tuple(1), std::make_tuple());
|
||||
BOOST_TEST(x.find(overloaded_constructor(1)) != x.end() &&
|
||||
x.find(overloaded_constructor(1))->second ==
|
||||
overloaded_constructor());
|
||||
|
||||
x.emplace(piecewise_rvalue(), std::make_tuple(2, 3),
|
||||
std::make_tuple(4, 5, 6));
|
||||
BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() &&
|
||||
x.find(overloaded_constructor(2, 3))->second ==
|
||||
overloaded_constructor(4, 5, 6));
|
||||
|
||||
derived_from_piecewise_construct_t d;
|
||||
x.emplace(d, std::make_tuple(9, 3, 1), std::make_tuple(10));
|
||||
BOOST_TEST(x.find(overloaded_constructor(9, 3, 1)) != x.end() &&
|
||||
x.find(overloaded_constructor(9, 3, 1))->second ==
|
||||
overloaded_constructor(10));
|
||||
|
||||
x.clear();
|
||||
|
||||
x.try_emplace(overloaded_constructor());
|
||||
BOOST_TEST(x.find(overloaded_constructor()) != x.end() &&
|
||||
x.find(overloaded_constructor())->second ==
|
||||
overloaded_constructor());
|
||||
|
||||
x.try_emplace(1);
|
||||
BOOST_TEST(x.find(overloaded_constructor(1)) != x.end() &&
|
||||
x.find(overloaded_constructor(1))->second ==
|
||||
overloaded_constructor());
|
||||
|
||||
x.try_emplace(overloaded_constructor(2, 3), 4, 5, 6);
|
||||
BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() &&
|
||||
x.find(overloaded_constructor(2, 3))->second ==
|
||||
overloaded_constructor(4, 5, 6));
|
||||
}
|
||||
{
|
||||
boost::unordered_multimap<overloaded_constructor,
|
||||
overloaded_constructor, boost::hash<overloaded_constructor>,
|
||||
std::equal_to<overloaded_constructor>,
|
||||
test::allocator1<std::pair<overloaded_constructor const,
|
||||
overloaded_constructor> > >
|
||||
x;
|
||||
|
||||
x.emplace(
|
||||
std::piecewise_construct, std::make_tuple(), std::make_tuple());
|
||||
BOOST_TEST(x.find(overloaded_constructor()) != x.end() &&
|
||||
x.find(overloaded_constructor())->second ==
|
||||
overloaded_constructor());
|
||||
|
||||
x.emplace(
|
||||
convertible_to_piecewise(), std::make_tuple(1), std::make_tuple());
|
||||
BOOST_TEST(x.find(overloaded_constructor(1)) != x.end() &&
|
||||
x.find(overloaded_constructor(1))->second ==
|
||||
overloaded_constructor());
|
||||
|
||||
x.emplace(piecewise_rvalue(), std::make_tuple(2, 3),
|
||||
std::make_tuple(4, 5, 6));
|
||||
BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() &&
|
||||
x.find(overloaded_constructor(2, 3))->second ==
|
||||
overloaded_constructor(4, 5, 6));
|
||||
|
||||
derived_from_piecewise_construct_t d;
|
||||
x.emplace(d, std::make_tuple(9, 3, 1), std::make_tuple(10));
|
||||
BOOST_TEST(x.find(overloaded_constructor(9, 3, 1)) != x.end() &&
|
||||
x.find(overloaded_constructor(9, 3, 1))->second ==
|
||||
overloaded_constructor(10));
|
||||
}
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(set_std_emplace_test2)
|
||||
{
|
||||
boost::unordered_set<
|
||||
std::pair<overloaded_constructor, overloaded_constructor> >
|
||||
x;
|
||||
std::pair<overloaded_constructor, overloaded_constructor> check;
|
||||
|
||||
x.emplace(std::piecewise_construct, std::make_tuple(), std::make_tuple());
|
||||
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
|
||||
|
||||
x.clear();
|
||||
x.emplace(
|
||||
std::piecewise_construct, std::make_tuple(1), std::make_tuple(2, 3));
|
||||
check =
|
||||
std::make_pair(overloaded_constructor(1), overloaded_constructor(2, 3));
|
||||
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
Reference in New Issue
Block a user