mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-31 11:57: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_allocators;
|
||||||
unsigned int count_allocations;
|
unsigned int count_allocations;
|
||||||
unsigned int count_constructions;
|
unsigned int count_constructions;
|
||||||
|
bool tracking_constructions;
|
||||||
|
|
||||||
memory_tracker()
|
memory_tracker()
|
||||||
: count_allocators(0), count_allocations(0), count_constructions(0)
|
: count_allocators(0), count_allocations(0), count_constructions(0),
|
||||||
|
tracking_constructions(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,14 +135,18 @@ struct memory_tracker
|
|||||||
|
|
||||||
void track_construct(void* /*ptr*/, std::size_t /*size*/, int /*tag*/)
|
void track_construct(void* /*ptr*/, std::size_t /*size*/, int /*tag*/)
|
||||||
{
|
{
|
||||||
++count_constructions;
|
if (tracking_constructions) {
|
||||||
|
++count_constructions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void track_destroy(void* /*ptr*/, std::size_t /*size*/, int /*tag*/)
|
void track_destroy(void* /*ptr*/, std::size_t /*size*/, int /*tag*/)
|
||||||
{
|
{
|
||||||
BOOST_TEST(count_constructions > 0);
|
if (tracking_constructions) {
|
||||||
if (count_constructions > 0)
|
BOOST_TEST(count_constructions > 0);
|
||||||
--count_constructions;
|
if (count_constructions > 0)
|
||||||
|
--count_constructions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -155,6 +161,29 @@ namespace {
|
|||||||
test::detail::memory_tracker tracker;
|
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
|
#endif
|
||||||
|
@ -392,10 +392,10 @@ template <class T> class allocator1
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if BOOST_UNORDERED_CXX11_CONSTRUCTION
|
#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_);
|
detail::tracker.track_construct((void*)p, sizeof(U), tag_);
|
||||||
new (p) T(boost::forward<Args>(args)...);
|
new (p) U(boost::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void construct(T* p, T const& t)
|
void construct(T* p, T const& t)
|
||||||
@ -405,10 +405,10 @@ template <class T> class allocator1
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void destroy(T* p)
|
template <typename U> void destroy(U* p)
|
||||||
{
|
{
|
||||||
detail::tracker.track_destroy((void*)p, sizeof(T), tag_);
|
detail::tracker.track_destroy((void*)p, sizeof(U), tag_);
|
||||||
p->~T();
|
p->~U();
|
||||||
|
|
||||||
// Work around MSVC buggy unused parameter warning.
|
// Work around MSVC buggy unused parameter warning.
|
||||||
ignore_variable(&p);
|
ignore_variable(&p);
|
||||||
|
@ -1120,6 +1120,10 @@ struct convertible_to_piecewise
|
|||||||
|
|
||||||
UNORDERED_AUTO_TEST(map_emplace_test2)
|
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::unordered_map<overloaded_constructor, overloaded_constructor,
|
||||||
boost::hash<overloaded_constructor>,
|
boost::hash<overloaded_constructor>,
|
||||||
@ -1169,8 +1173,8 @@ UNORDERED_AUTO_TEST(map_emplace_test2)
|
|||||||
x.find(overloaded_constructor(2, 3))->second ==
|
x.find(overloaded_constructor(2, 3))->second ==
|
||||||
overloaded_constructor(4, 5, 6));
|
overloaded_constructor(4, 5, 6));
|
||||||
}
|
}
|
||||||
{
|
|
||||||
|
|
||||||
|
{
|
||||||
boost::unordered_multimap<overloaded_constructor,
|
boost::unordered_multimap<overloaded_constructor,
|
||||||
overloaded_constructor, boost::hash<overloaded_constructor>,
|
overloaded_constructor, boost::hash<overloaded_constructor>,
|
||||||
std::equal_to<overloaded_constructor>,
|
std::equal_to<overloaded_constructor>,
|
||||||
@ -1220,9 +1224,115 @@ UNORDERED_AUTO_TEST(set_emplace_test2)
|
|||||||
boost::make_tuple(2, 3));
|
boost::make_tuple(2, 3));
|
||||||
check =
|
check =
|
||||||
std::make_pair(overloaded_constructor(1), overloaded_constructor(2, 3));
|
std::make_pair(overloaded_constructor(1), overloaded_constructor(2, 3));
|
||||||
;
|
|
||||||
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
|
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()
|
RUN_TESTS()
|
||||||
|
Reference in New Issue
Block a user