[libcxx-commits] [libcxx] 9a140a1 - [libc++] Make test_allocator constexpr-friendly for constexpr string/vector
Mark de Wever via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Nov 7 07:15:55 PST 2021
Author: Nikolas Klauser
Date: 2021-11-07T16:15:28+01:00
New Revision: 9a140a1586cc4d13ecc97a28065f9ed2f93c99de
URL: https://github.com/llvm/llvm-project/commit/9a140a1586cc4d13ecc97a28065f9ed2f93c99de
DIFF: https://github.com/llvm/llvm-project/commit/9a140a1586cc4d13ecc97a28065f9ed2f93c99de.diff
LOG: [libc++] Make test_allocator constexpr-friendly for constexpr string/vector
Make test_allocator etc. constexpr-friendly so they can be used to test constexpr string and possibly constexpr vector
Reviewed By: Quuxplusone, #libc, ldionne
Differential Revision: https://reviews.llvm.org/D110994
Added:
Modified:
libcxx/test/std/containers/associative/map/map.cons/assign_initializer_list.pass.cpp
libcxx/test/std/containers/associative/set/set.cons/assign_initializer_list.pass.cpp
libcxx/test/std/containers/container.requirements/container.requirements.general/allocator_move.pass.cpp
libcxx/test/std/containers/sequences/deque/deque.modifiers/push_back_exception_safety.pass.cpp
libcxx/test/std/containers/sequences/deque/deque.modifiers/push_front_exception_safety.pass.cpp
libcxx/test/std/containers/sequences/vector.bool/move.pass.cpp
libcxx/test/std/containers/sequences/vector/vector.cons/move.pass.cpp
libcxx/test/std/re/re.results/re.results.const/move.pass.cpp
libcxx/test/std/strings/basic.string/string.capacity/capacity.pass.cpp
libcxx/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp
libcxx/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp
libcxx/test/std/thread/futures/futures.promise/move_assign.pass.cpp
libcxx/test/std/thread/futures/futures.promise/move_ctor.pass.cpp
libcxx/test/std/thread/futures/futures.promise/swap.pass.cpp
libcxx/test/std/thread/futures/futures.shared_future/dtor.pass.cpp
libcxx/test/std/thread/futures/futures.task/futures.task.members/ctor_func_alloc.pass.cpp
libcxx/test/std/thread/futures/futures.unique_future/dtor.pass.cpp
libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp
libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp
libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator_throw.pass.cpp
libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp
libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator_throw.pass.cpp
libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.mod/reset_pointer_deleter_allocator.pass.cpp
libcxx/test/support/test_allocator.h
Removed:
################################################################################
diff --git a/libcxx/test/std/containers/associative/map/map.cons/assign_initializer_list.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/assign_initializer_list.pass.cpp
index 824b362dca17e..a22d41e9760b9 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/assign_initializer_list.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/assign_initializer_list.pass.cpp
@@ -74,17 +74,18 @@ void test_basic() {
void duplicate_keys_test() {
+ test_allocator_statistics alloc_stats;
typedef std::map<int, int, std::less<int>, test_allocator<std::pair<const int, int> > > Map;
{
- LIBCPP_ASSERT(test_alloc_base::alloc_count == 0);
- Map s = {{1, 0}, {2, 0}, {3, 0}};
- LIBCPP_ASSERT(test_alloc_base::alloc_count == 3);
+ LIBCPP_ASSERT(alloc_stats.alloc_count == 0);
+ Map s({{1, 0}, {2, 0}, {3, 0}}, std::less<int>(), test_allocator<std::pair<const int, int> >(&alloc_stats));
+ LIBCPP_ASSERT(alloc_stats.alloc_count == 3);
s = {{4, 0}, {4, 0}, {4, 0}, {4, 0}};
- LIBCPP_ASSERT(test_alloc_base::alloc_count == 1);
+ LIBCPP_ASSERT(alloc_stats.alloc_count == 1);
assert(s.size() == 1);
assert(s.begin()->first == 4);
}
- LIBCPP_ASSERT(test_alloc_base::alloc_count == 0);
+ LIBCPP_ASSERT(alloc_stats.alloc_count == 0);
}
int main(int, char**)
diff --git a/libcxx/test/std/containers/associative/set/set.cons/assign_initializer_list.pass.cpp b/libcxx/test/std/containers/associative/set/set.cons/assign_initializer_list.pass.cpp
index b04d7f576bac0..b096995513a94 100644
--- a/libcxx/test/std/containers/associative/set/set.cons/assign_initializer_list.pass.cpp
+++ b/libcxx/test/std/containers/associative/set/set.cons/assign_initializer_list.pass.cpp
@@ -55,17 +55,18 @@ void basic_test() {
}
void duplicate_keys_test() {
+ test_allocator_statistics alloc_stats;
typedef std::set<int, std::less<int>, test_allocator<int> > Set;
{
- LIBCPP_ASSERT(test_alloc_base::alloc_count == 0);
- Set s = {1, 2, 3};
- LIBCPP_ASSERT(test_alloc_base::alloc_count == 3);
+ LIBCPP_ASSERT(alloc_stats.alloc_count == 0);
+ Set s({1, 2, 3}, std::less<int>(), test_allocator<int>(&alloc_stats));
+ LIBCPP_ASSERT(alloc_stats.alloc_count == 3);
s = {4, 4, 4, 4, 4};
- LIBCPP_ASSERT(test_alloc_base::alloc_count == 1);
+ LIBCPP_ASSERT(alloc_stats.alloc_count == 1);
assert(s.size() == 1);
assert(*s.begin() == 4);
}
- LIBCPP_ASSERT(test_alloc_base::alloc_count == 0);
+ LIBCPP_ASSERT(alloc_stats.alloc_count == 0);
}
int main(int, char**) {
diff --git a/libcxx/test/std/containers/container.requirements/container.requirements.general/allocator_move.pass.cpp b/libcxx/test/std/containers/container.requirements/container.requirements.general/allocator_move.pass.cpp
index 0cc573e8592d9..cc8949e751dd0 100644
--- a/libcxx/test/std/containers/container.requirements/container.requirements.general/allocator_move.pass.cpp
+++ b/libcxx/test/std/containers/container.requirements/container.requirements.general/allocator_move.pass.cpp
@@ -27,27 +27,28 @@
template <class C>
void test(int expected_num_allocs = 1) {
+ test_allocator_statistics alloc_stats;
{
- test_alloc_base::clear();
+ alloc_stats.clear();
using AllocT = typename C::allocator_type;
- C v(AllocT(42, 101));
+ C v(AllocT(42, 101, &alloc_stats));
- assert(test_alloc_base::count == expected_num_allocs);
+ assert(alloc_stats.count == expected_num_allocs);
- const int num_stored_allocs = test_alloc_base::count;
+ const int num_stored_allocs = alloc_stats.count;
{
const AllocT& a = v.get_allocator();
- assert(test_alloc_base::count == 1 + num_stored_allocs);
+ assert(alloc_stats.count == 1 + num_stored_allocs);
assert(a.get_data() == 42);
assert(a.get_id() == 101);
}
- assert(test_alloc_base::count == num_stored_allocs);
- test_alloc_base::clear_ctor_counters();
+ assert(alloc_stats.count == num_stored_allocs);
+ alloc_stats.clear_ctor_counters();
C v2 = std::move(v);
- assert(test_alloc_base::count == num_stored_allocs * 2);
- assert(test_alloc_base::copied == 0);
- assert(test_alloc_base::moved == num_stored_allocs);
+ assert(alloc_stats.count == num_stored_allocs * 2);
+ assert(alloc_stats.copied == 0);
+ assert(alloc_stats.moved == num_stored_allocs);
{
const AllocT& a = v.get_allocator();
assert(a.get_id() == test_alloc_base::moved_value);
diff --git a/libcxx/test/std/containers/sequences/deque/deque.modifiers/push_back_exception_safety.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.modifiers/push_back_exception_safety.pass.cpp
index b24fd0753770b..137129368b4ad 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.modifiers/push_back_exception_safety.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.modifiers/push_back_exception_safety.pass.cpp
@@ -86,11 +86,12 @@ int main(int, char**)
}
{
+ test_allocator_statistics alloc_stats;
typedef std::deque<CMyClass, test_allocator<CMyClass> > C;
- C vec;
- C vec2(vec);
+ C vec((test_allocator<CMyClass>(&alloc_stats)));
+ C vec2(vec, test_allocator<CMyClass>(&alloc_stats));
- C::allocator_type::throw_after = 1;
+ alloc_stats.throw_after = 1;
try {
vec.push_back(instance);
assert(false);
diff --git a/libcxx/test/std/containers/sequences/deque/deque.modifiers/push_front_exception_safety.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.modifiers/push_front_exception_safety.pass.cpp
index 990f41f487266..79f9a14f23091 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.modifiers/push_front_exception_safety.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.modifiers/push_front_exception_safety.pass.cpp
@@ -86,11 +86,12 @@ int main(int, char**)
}
{
+ test_allocator_statistics alloc_stats;
typedef std::deque<CMyClass, test_allocator<CMyClass> > C;
- C vec;
- C vec2(vec);
+ C vec((test_allocator<CMyClass>(&alloc_stats)));
+ C vec2(vec, test_allocator<CMyClass>(&alloc_stats));
- C::allocator_type::throw_after = 1;
+ alloc_stats.throw_after = 1;
try {
vec.push_front(instance);
assert(false);
diff --git a/libcxx/test/std/containers/sequences/vector.bool/move.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/move.pass.cpp
index 8da56e6aa2efa..a554ec8ab0162 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/move.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/move.pass.cpp
@@ -20,9 +20,10 @@
int main(int, char**)
{
+ test_allocator_statistics alloc_stats;
{
- std::vector<bool, test_allocator<bool> > l(test_allocator<bool>(5));
- std::vector<bool, test_allocator<bool> > lo(test_allocator<bool>(5));
+ std::vector<bool, test_allocator<bool> > l(test_allocator<bool>(5, &alloc_stats));
+ std::vector<bool, test_allocator<bool> > lo(test_allocator<bool>(5, &alloc_stats));
for (int i = 1; i <= 3; ++i)
{
l.push_back(true);
@@ -60,24 +61,24 @@ int main(int, char**)
assert(l2.get_allocator() == lo.get_allocator());
}
{
- test_alloc_base::clear();
+ alloc_stats.clear();
using Vect = std::vector<bool, test_allocator<bool> >;
using AllocT = Vect::allocator_type;
- Vect v(test_allocator<bool>(42, 101));
- assert(test_alloc_base::count == 1);
+ Vect v(test_allocator<bool>(42, 101, &alloc_stats));
+ assert(alloc_stats.count == 1);
{
const AllocT& a = v.get_allocator();
- assert(test_alloc_base::count == 2);
+ assert(alloc_stats.count == 2);
assert(a.get_data() == 42);
assert(a.get_id() == 101);
}
- assert(test_alloc_base::count == 1);
- test_alloc_base::clear_ctor_counters();
+ assert(alloc_stats.count == 1);
+ alloc_stats.clear_ctor_counters();
Vect v2 = std::move(v);
- assert(test_alloc_base::count == 2);
- assert(test_alloc_base::copied == 0);
- assert(test_alloc_base::moved == 1);
+ assert(alloc_stats.count == 2);
+ assert(alloc_stats.copied == 0);
+ assert(alloc_stats.moved == 1);
{
const AllocT& a = v.get_allocator();
assert(a.get_id() == test_alloc_base::moved_value);
diff --git a/libcxx/test/std/containers/sequences/vector/vector.cons/move.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.cons/move.pass.cpp
index 1c2126477ba05..8c797d1a7cbe0 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.cons/move.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.cons/move.pass.cpp
@@ -23,9 +23,10 @@
int main(int, char**)
{
+ test_allocator_statistics alloc_stats;
{
- std::vector<MoveOnly, test_allocator<MoveOnly> > l(test_allocator<MoveOnly>(5));
- std::vector<MoveOnly, test_allocator<MoveOnly> > lo(test_allocator<MoveOnly>(5));
+ std::vector<MoveOnly, test_allocator<MoveOnly> > l(test_allocator<MoveOnly>(5, &alloc_stats));
+ std::vector<MoveOnly, test_allocator<MoveOnly> > lo(test_allocator<MoveOnly>(5, &alloc_stats));
assert(is_contiguous_container_asan_correct(l));
assert(is_contiguous_container_asan_correct(lo));
for (int i = 1; i <= 3; ++i)
@@ -100,24 +101,24 @@ int main(int, char**)
assert(is_contiguous_container_asan_correct(c2));
}
{
- test_alloc_base::clear();
+ alloc_stats.clear();
using Vect = std::vector<int, test_allocator<int> >;
- Vect v(test_allocator<int>(42, 101));
- assert(test_alloc_base::count == 1);
- assert(test_alloc_base::copied == 1);
- assert(test_alloc_base::moved == 0);
+ Vect v(test_allocator<int>(42, 101, &alloc_stats));
+ assert(alloc_stats.count == 1);
+ assert(alloc_stats.copied == 1);
+ assert(alloc_stats.moved == 0);
{
const test_allocator<int>& a = v.get_allocator();
assert(a.get_data() == 42);
assert(a.get_id() == 101);
}
- assert(test_alloc_base::count == 1);
- test_alloc_base::clear_ctor_counters();
+ assert(alloc_stats.count == 1);
+ alloc_stats.clear_ctor_counters();
Vect v2 = std::move(v);
- assert(test_alloc_base::count == 2);
- assert(test_alloc_base::copied == 0);
- assert(test_alloc_base::moved == 1);
+ assert(alloc_stats.count == 2);
+ assert(alloc_stats.copied == 0);
+ assert(alloc_stats.moved == 1);
{
const test_allocator<int>& a = v.get_allocator();
assert(a.get_id() == test_alloc_base::moved_value);
diff --git a/libcxx/test/std/re/re.results/re.results.const/move.pass.cpp b/libcxx/test/std/re/re.results/re.results.const/move.pass.cpp
index 82f2b3e655310..0806edef1429b 100644
--- a/libcxx/test/std/re/re.results/re.results.const/move.pass.cpp
+++ b/libcxx/test/std/re/re.results/re.results.const/move.pass.cpp
@@ -37,16 +37,17 @@ test(const Allocator& a)
int main(int, char**)
{
+ test_allocator_statistics alloc_stats;
test<char> (std::allocator<std::sub_match<const char *> >());
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
test<wchar_t>(std::allocator<std::sub_match<const wchar_t *> >());
#endif
- test<char> (test_allocator<std::sub_match<const char*> >(3));
- assert(test_alloc_base::moved == 1);
+ test<char> (test_allocator<std::sub_match<const char*> >(3, &alloc_stats));
+ assert(alloc_stats.moved == 1);
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
- test<wchar_t>(test_allocator<std::sub_match<const wchar_t*> >(3));
- assert(test_alloc_base::moved == 2);
+ test<wchar_t>(test_allocator<std::sub_match<const wchar_t*> >(3, &alloc_stats));
+ assert(alloc_stats.moved == 2);
#endif
return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/capacity.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/capacity.pass.cpp
index 02187c5193af9..c401384a23dc6 100644
--- a/libcxx/test/std/strings/basic.string/string.capacity/capacity.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/capacity.pass.cpp
@@ -18,11 +18,13 @@
#include "test_macros.h"
+test_allocator_statistics alloc_stats;
+
template <class S>
void
test(S s)
{
- S::allocator_type::throw_after = 0;
+ alloc_stats.throw_after = 0;
#ifndef TEST_HAS_NO_EXCEPTIONS
try
#endif
@@ -37,14 +39,14 @@ test(S s)
assert(false);
}
#endif
- S::allocator_type::throw_after = INT_MAX;
+ alloc_stats.throw_after = INT_MAX;
}
int main(int, char**)
{
{
typedef std::basic_string<char, std::char_traits<char>, test_allocator<char> > S;
- S s;
+ S s((test_allocator<char>(&alloc_stats)));
test(s);
s.assign(10, 'a');
s.erase(5);
diff --git a/libcxx/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp
index 00af31d0c18c0..d38e7c4116841 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp
@@ -19,7 +19,6 @@
#include "test_allocator.h"
#include "min_allocator.h"
-
template <class S>
void
test(S s0, const typename S::allocator_type& a)
@@ -33,9 +32,9 @@ test(S s0, const typename S::allocator_type& a)
assert(s2.get_allocator() == a);
}
-
int main(int, char**)
{
+ test_allocator_statistics alloc_stats;
{
typedef test_allocator<char> A;
typedef std::basic_string<char, std::char_traits<char>, A> S;
@@ -44,12 +43,12 @@ int main(int, char**)
#elif TEST_STD_VER >= 11
static_assert((noexcept(S()) == std::is_nothrow_move_constructible<A>::value), "" );
#endif
- test(S(), A(3));
- test(S("1"), A(5));
- test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A(7));
+ test(S(), A(3, &alloc_stats));
+ test(S("1"), A(5, &alloc_stats));
+ test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A(7, &alloc_stats));
}
- int alloc_count = test_alloc_base::alloc_count;
+ int alloc_count = alloc_stats.alloc_count;
{
typedef test_allocator<char> A;
typedef std::basic_string<char, std::char_traits<char>, A> S;
@@ -58,10 +57,10 @@ int main(int, char**)
#elif TEST_STD_VER >= 11
static_assert((noexcept(S()) == std::is_nothrow_move_constructible<A>::value), "" );
#endif
- S s1 ( "Twas brillig, and the slivy toves did gyre and gymbal in the wabe" );
- S s2 (std::move(s1), A(1));
+ S s1 ( "Twas brillig, and the slivy toves did gyre and gymbal in the wabe", A(&alloc_stats));
+ S s2 (std::move(s1), A(1, &alloc_stats));
}
- assert ( test_alloc_base::alloc_count == alloc_count );
+ assert ( alloc_stats.alloc_count == alloc_count );
{
typedef min_allocator<char> A;
typedef std::basic_string<char, std::char_traits<char>, A> S;
diff --git a/libcxx/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp b/libcxx/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp
index 150a277fe0aea..cbb2c2e7e25fe 100644
--- a/libcxx/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp
+++ b/libcxx/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp
@@ -25,31 +25,32 @@
int main(int, char**)
{
- assert(test_alloc_base::alloc_count == 0);
+ test_allocator_statistics alloc_stats;
+ assert(alloc_stats.alloc_count == 0);
{
- std::promise<int> p(std::allocator_arg, test_allocator<int>(42));
- assert(test_alloc_base::alloc_count == 1);
+ std::promise<int> p(std::allocator_arg, test_allocator<int>(42, &alloc_stats));
+ assert(alloc_stats.alloc_count == 1);
std::future<int> f = p.get_future();
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
{
- std::promise<int&> p(std::allocator_arg, test_allocator<int>(42));
- assert(test_alloc_base::alloc_count == 1);
+ std::promise<int&> p(std::allocator_arg, test_allocator<int>(42, &alloc_stats));
+ assert(alloc_stats.alloc_count == 1);
std::future<int&> f = p.get_future();
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
{
- std::promise<void> p(std::allocator_arg, test_allocator<void>(42));
- assert(test_alloc_base::alloc_count == 1);
+ std::promise<void> p(std::allocator_arg, test_allocator<void>(42, &alloc_stats));
+ assert(alloc_stats.alloc_count == 1);
std::future<void> f = p.get_future();
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
// Test with a minimal allocator
{
std::promise<int> p(std::allocator_arg, bare_allocator<void>());
diff --git a/libcxx/test/std/thread/futures/futures.promise/move_assign.pass.cpp b/libcxx/test/std/thread/futures/futures.promise/move_assign.pass.cpp
index f3978e79f47e1..ac504efbd6027 100644
--- a/libcxx/test/std/thread/futures/futures.promise/move_assign.pass.cpp
+++ b/libcxx/test/std/thread/futures/futures.promise/move_assign.pass.cpp
@@ -23,15 +23,16 @@
int main(int, char**)
{
- assert(test_alloc_base::alloc_count == 0);
+ test_allocator_statistics alloc_stats;
+ assert(alloc_stats.alloc_count == 0);
{
- std::promise<int> p0(std::allocator_arg, test_allocator<int>());
- std::promise<int> p(std::allocator_arg, test_allocator<int>());
- assert(test_alloc_base::alloc_count == 2);
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>(&alloc_stats));
+ std::promise<int> p(std::allocator_arg, test_allocator<int>(&alloc_stats));
+ assert(alloc_stats.alloc_count == 2);
p = std::move(p0);
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
std::future<int> f = p.get_future();
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
#ifndef TEST_HAS_NO_EXCEPTIONS
try
@@ -44,17 +45,17 @@ int main(int, char**)
assert(e.code() == make_error_code(std::future_errc::no_state));
}
#endif
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
{
- std::promise<int&> p0(std::allocator_arg, test_allocator<int>());
- std::promise<int&> p(std::allocator_arg, test_allocator<int>());
- assert(test_alloc_base::alloc_count == 2);
+ std::promise<int&> p0(std::allocator_arg, test_allocator<int>(&alloc_stats));
+ std::promise<int&> p(std::allocator_arg, test_allocator<int>(&alloc_stats));
+ assert(alloc_stats.alloc_count == 2);
p = std::move(p0);
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
std::future<int&> f = p.get_future();
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
#ifndef TEST_HAS_NO_EXCEPTIONS
try
@@ -67,17 +68,17 @@ int main(int, char**)
assert(e.code() == make_error_code(std::future_errc::no_state));
}
#endif
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
{
- std::promise<void> p0(std::allocator_arg, test_allocator<void>());
- std::promise<void> p(std::allocator_arg, test_allocator<void>());
- assert(test_alloc_base::alloc_count == 2);
+ std::promise<void> p0(std::allocator_arg, test_allocator<void>(&alloc_stats));
+ std::promise<void> p(std::allocator_arg, test_allocator<void>(&alloc_stats));
+ assert(alloc_stats.alloc_count == 2);
p = std::move(p0);
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
std::future<void> f = p.get_future();
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
#ifndef TEST_HAS_NO_EXCEPTIONS
try
@@ -90,9 +91,9 @@ int main(int, char**)
assert(e.code() == make_error_code(std::future_errc::no_state));
}
#endif
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
return 0;
}
diff --git a/libcxx/test/std/thread/futures/futures.promise/move_ctor.pass.cpp b/libcxx/test/std/thread/futures/futures.promise/move_ctor.pass.cpp
index 1fdd61cc3bbee..9775e6655835c 100644
--- a/libcxx/test/std/thread/futures/futures.promise/move_ctor.pass.cpp
+++ b/libcxx/test/std/thread/futures/futures.promise/move_ctor.pass.cpp
@@ -23,13 +23,14 @@
int main(int, char**)
{
- assert(test_alloc_base::alloc_count == 0);
+ test_allocator_statistics alloc_stats;
+ assert(alloc_stats.alloc_count == 0);
{
- std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>(&alloc_stats));
std::promise<int> p(std::move(p0));
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
std::future<int> f = p.get_future();
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
#ifndef TEST_HAS_NO_EXCEPTIONS
try
@@ -41,16 +42,16 @@ int main(int, char**)
{
assert(e.code() == make_error_code(std::future_errc::no_state));
}
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
#endif
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
{
- std::promise<int&> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int&> p0(std::allocator_arg, test_allocator<int>(&alloc_stats));
std::promise<int&> p(std::move(p0));
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
std::future<int&> f = p.get_future();
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
#ifndef TEST_HAS_NO_EXCEPTIONS
try
@@ -62,16 +63,16 @@ int main(int, char**)
{
assert(e.code() == make_error_code(std::future_errc::no_state));
}
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
#endif
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
{
- std::promise<void> p0(std::allocator_arg, test_allocator<void>());
+ std::promise<void> p0(std::allocator_arg, test_allocator<void>(&alloc_stats));
std::promise<void> p(std::move(p0));
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
std::future<void> f = p.get_future();
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
#ifndef TEST_HAS_NO_EXCEPTIONS
try
@@ -83,10 +84,10 @@ int main(int, char**)
{
assert(e.code() == make_error_code(std::future_errc::no_state));
}
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
#endif
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
return 0;
}
diff --git a/libcxx/test/std/thread/futures/futures.promise/swap.pass.cpp b/libcxx/test/std/thread/futures/futures.promise/swap.pass.cpp
index bdb4595d62ab4..fbf77b121d474 100644
--- a/libcxx/test/std/thread/futures/futures.promise/swap.pass.cpp
+++ b/libcxx/test/std/thread/futures/futures.promise/swap.pass.cpp
@@ -25,63 +25,64 @@
int main(int, char**)
{
- assert(test_alloc_base::alloc_count == 0);
+ test_allocator_statistics alloc_stats;
+ assert(alloc_stats.alloc_count == 0);
{
- std::promise<int> p0(std::allocator_arg, test_allocator<int>());
- std::promise<int> p(std::allocator_arg, test_allocator<int>());
- assert(test_alloc_base::alloc_count == 2);
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>(&alloc_stats));
+ std::promise<int> p(std::allocator_arg, test_allocator<int>(&alloc_stats));
+ assert(alloc_stats.alloc_count == 2);
p.swap(p0);
- assert(test_alloc_base::alloc_count == 2);
+ assert(alloc_stats.alloc_count == 2);
std::future<int> f = p.get_future();
- assert(test_alloc_base::alloc_count == 2);
+ assert(alloc_stats.alloc_count == 2);
assert(f.valid());
f = p0.get_future();
assert(f.valid());
- assert(test_alloc_base::alloc_count == 2);
+ assert(alloc_stats.alloc_count == 2);
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
{
- std::promise<int> p0(std::allocator_arg, test_allocator<int>());
- std::promise<int> p(std::allocator_arg, test_allocator<int>());
- assert(test_alloc_base::alloc_count == 2);
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>(&alloc_stats));
+ std::promise<int> p(std::allocator_arg, test_allocator<int>(&alloc_stats));
+ assert(alloc_stats.alloc_count == 2);
swap(p, p0);
- assert(test_alloc_base::alloc_count == 2);
+ assert(alloc_stats.alloc_count == 2);
std::future<int> f = p.get_future();
- assert(test_alloc_base::alloc_count == 2);
+ assert(alloc_stats.alloc_count == 2);
assert(f.valid());
f = p0.get_future();
assert(f.valid());
- assert(test_alloc_base::alloc_count == 2);
+ assert(alloc_stats.alloc_count == 2);
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
{
- std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>(&alloc_stats));
std::promise<int> p;
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
p.swap(p0);
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
std::future<int> f = p.get_future();
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
f = p0.get_future();
assert(f.valid());
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
{
- std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>(&alloc_stats));
std::promise<int> p;
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
swap(p, p0);
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
std::future<int> f = p.get_future();
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
f = p0.get_future();
assert(f.valid());
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
return 0;
}
diff --git a/libcxx/test/std/thread/futures/futures.shared_future/dtor.pass.cpp b/libcxx/test/std/thread/futures/futures.shared_future/dtor.pass.cpp
index 3d72b983d6b05..027073fde8cc3 100644
--- a/libcxx/test/std/thread/futures/futures.shared_future/dtor.pass.cpp
+++ b/libcxx/test/std/thread/futures/futures.shared_future/dtor.pass.cpp
@@ -24,49 +24,50 @@
int main(int, char**)
{
- assert(test_alloc_base::alloc_count == 0);
+ test_allocator_statistics alloc_stats;
+ assert(alloc_stats.alloc_count == 0);
{
typedef int T;
std::shared_future<T> f;
{
- std::promise<T> p(std::allocator_arg, test_allocator<T>());
- assert(test_alloc_base::alloc_count == 1);
+ std::promise<T> p(std::allocator_arg, test_allocator<T>(&alloc_stats));
+ assert(alloc_stats.alloc_count == 1);
f = p.get_future();
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
}
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
{
typedef int& T;
std::shared_future<T> f;
{
- std::promise<T> p(std::allocator_arg, test_allocator<int>());
- assert(test_alloc_base::alloc_count == 1);
+ std::promise<T> p(std::allocator_arg, test_allocator<int>(&alloc_stats));
+ assert(alloc_stats.alloc_count == 1);
f = p.get_future();
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
}
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
{
typedef void T;
std::shared_future<T> f;
{
- std::promise<T> p(std::allocator_arg, test_allocator<T>());
- assert(test_alloc_base::alloc_count == 1);
+ std::promise<T> p(std::allocator_arg, test_allocator<T>(&alloc_stats));
+ assert(alloc_stats.alloc_count == 1);
f = p.get_future();
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
}
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
return 0;
}
diff --git a/libcxx/test/std/thread/futures/futures.task/futures.task.members/ctor_func_alloc.pass.cpp b/libcxx/test/std/thread/futures/futures.task/futures.task.members/ctor_func_alloc.pass.cpp
index 2255a4549534a..788afbdffdfe3 100644
--- a/libcxx/test/std/thread/futures/futures.task/futures.task.members/ctor_func_alloc.pass.cpp
+++ b/libcxx/test/std/thread/futures/futures.task/futures.task.members/ctor_func_alloc.pass.cpp
@@ -47,10 +47,11 @@ int func(int i) { return i; }
int main(int, char**)
{
+ test_allocator_statistics alloc_stats;
{
std::packaged_task<double(int, char)> p(std::allocator_arg,
- test_allocator<A>(), A(5));
- assert(test_alloc_base::alloc_count > 0);
+ test_allocator<A>(&alloc_stats), A(5));
+ assert(alloc_stats.alloc_count > 0);
assert(p.valid());
std::future<double> f = p.get_future();
p(3, 'a');
@@ -58,14 +59,14 @@ int main(int, char**)
assert(A::n_copies == 0);
assert(A::n_moves > 0);
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
A::n_copies = 0;
A::n_moves = 0;
{
A a(5);
std::packaged_task<double(int, char)> p(std::allocator_arg,
- test_allocator<A>(), a);
- assert(test_alloc_base::alloc_count > 0);
+ test_allocator<A>(&alloc_stats), a);
+ assert(alloc_stats.alloc_count > 0);
assert(p.valid());
std::future<double> f = p.get_future();
p(3, 'a');
@@ -73,31 +74,31 @@ int main(int, char**)
assert(A::n_copies > 0);
assert(A::n_moves >= 0);
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
A::n_copies = 0;
A::n_moves = 0;
{
A a(5);
- std::packaged_task<int(int)> p(std::allocator_arg, test_allocator<A>(), &func);
- assert(test_alloc_base::alloc_count > 0);
+ std::packaged_task<int(int)> p(std::allocator_arg, test_allocator<A>(&alloc_stats), &func);
+ assert(alloc_stats.alloc_count > 0);
assert(p.valid());
std::future<int> f = p.get_future();
p(4);
assert(f.get() == 4);
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
A::n_copies = 0;
A::n_moves = 0;
{
A a(5);
- std::packaged_task<int(int)> p(std::allocator_arg, test_allocator<A>(), func);
- assert(test_alloc_base::alloc_count > 0);
+ std::packaged_task<int(int)> p(std::allocator_arg, test_allocator<A>(&alloc_stats), func);
+ assert(alloc_stats.alloc_count > 0);
assert(p.valid());
std::future<int> f = p.get_future();
p(4);
assert(f.get() == 4);
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
A::n_copies = 0;
A::n_moves = 0;
{
diff --git a/libcxx/test/std/thread/futures/futures.unique_future/dtor.pass.cpp b/libcxx/test/std/thread/futures/futures.unique_future/dtor.pass.cpp
index 05bfe2bea7f4f..643fb6a4259a6 100644
--- a/libcxx/test/std/thread/futures/futures.unique_future/dtor.pass.cpp
+++ b/libcxx/test/std/thread/futures/futures.unique_future/dtor.pass.cpp
@@ -24,49 +24,50 @@
int main(int, char**)
{
- assert(test_alloc_base::alloc_count == 0);
+ test_allocator_statistics alloc_stats;
+ assert(alloc_stats.alloc_count == 0);
{
typedef int T;
std::future<T> f;
{
- std::promise<T> p(std::allocator_arg, test_allocator<T>());
- assert(test_alloc_base::alloc_count == 1);
+ std::promise<T> p(std::allocator_arg, test_allocator<T>(&alloc_stats));
+ assert(alloc_stats.alloc_count == 1);
f = p.get_future();
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
}
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
{
typedef int& T;
std::future<T> f;
{
- std::promise<T> p(std::allocator_arg, test_allocator<int>());
- assert(test_alloc_base::alloc_count == 1);
+ std::promise<T> p(std::allocator_arg, test_allocator<int>(&alloc_stats));
+ assert(alloc_stats.alloc_count == 1);
f = p.get_future();
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
}
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
{
typedef void T;
std::future<T> f;
{
- std::promise<T> p(std::allocator_arg, test_allocator<T>());
- assert(test_alloc_base::alloc_count == 1);
+ std::promise<T> p(std::allocator_arg, test_allocator<T>(&alloc_stats));
+ assert(alloc_stats.alloc_count == 1);
f = p.get_future();
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
}
- assert(test_alloc_base::alloc_count == 1);
+ assert(alloc_stats.alloc_count == 1);
assert(f.valid());
}
- assert(test_alloc_base::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
return 0;
}
diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp
index b5821d861e866..e364e9eebc046 100644
--- a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp
@@ -25,7 +25,6 @@
#include "count_new.h"
#include "../function_types.h"
-
#if TEST_STD_VER >= 11
struct RValueCallable {
template <class ...Args>
@@ -37,6 +36,8 @@ struct LValueCallable {
};
#endif
+test_allocator_statistics alloc_stats;
+
class DummyClass {};
template <class FuncType, class AllocType>
@@ -69,7 +70,7 @@ void test_FreeFunction(AllocType& alloc)
std::function<FuncType> f2(std::allocator_arg, alloc, target);
// The allocator may not fit in the small object buffer, if we allocated
// check it was done via the allocator.
- assert(globalMemCounter.checkOutstandingNewEq(test_alloc_base::alloc_count));
+ assert(globalMemCounter.checkOutstandingNewEq(alloc_stats.alloc_count));
assert(f2.template target<FuncType*>());
assert(*f2.template target<FuncType*>() == target);
assert(f2.template target<FuncType>() == 0);
@@ -86,7 +87,7 @@ void test_MemFunClass(AllocType& alloc)
TargetType target = &MemFunClass::foo;
assert(globalMemCounter.checkOutstandingNewEq(0));
std::function<FuncType> f2(std::allocator_arg, alloc, target);
- assert(globalMemCounter.checkOutstandingNewEq(test_alloc_base::alloc_count));
+ assert(globalMemCounter.checkOutstandingNewEq(alloc_stats.alloc_count));
assert(f2.template target<TargetType>());
assert(*f2.template target<TargetType>() == target);
assert(f2.template target<FuncType*>() == 0);
@@ -111,15 +112,14 @@ void test_for_alloc(Alloc& alloc) {
test_MemFunClass<int(MemFunClass::*)(int, int) const, int(MemFunClass&, int, int)>(alloc);
}
-int main(int, char**)
-{
+int main(int, char**) {
globalMemCounter.reset();
{
bare_allocator<DummyClass> bare_alloc;
test_for_alloc(bare_alloc);
}
{
- non_default_test_allocator<DummyClass> non_default_alloc(42);
+ non_default_test_allocator<DummyClass> non_default_alloc(42, &alloc_stats);
test_for_alloc(non_default_alloc);
}
#if TEST_STD_VER >= 11
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp
index fb5e4f4d8f2e6..4d59d7f5667f8 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp
@@ -30,8 +30,9 @@ int A::count = 0;
int main(int, char**)
{
+ test_allocator_statistics alloc_stats;
{
- std::shared_ptr<A> p(nullptr, test_deleter<A>(3), test_allocator<A>(5));
+ std::shared_ptr<A> p(nullptr, test_deleter<A>(3), test_allocator<A>(5, &alloc_stats));
assert(A::count == 0);
assert(p.use_count() == 1);
assert(p.get() == 0);
@@ -42,14 +43,14 @@ int main(int, char**)
assert(d);
assert(d->state() == 3);
#endif
- assert(test_allocator<A>::count == 1);
- assert(test_allocator<A>::alloc_count == 1);
+ assert(alloc_stats.count == 1);
+ assert(alloc_stats.alloc_count == 1);
}
assert(A::count == 0);
assert(test_deleter<A>::count == 0);
assert(test_deleter<A>::dealloc_count == 1);
- assert(test_allocator<A>::count == 0);
- assert(test_allocator<A>::alloc_count == 0);
+ assert(alloc_stats.count == 0);
+ assert(alloc_stats.alloc_count == 0);
test_deleter<A>::dealloc_count = 0;
// Test an allocator with a minimal interface
{
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator_throw.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator_throw.pass.cpp
index ce9c3e5875eb7..5864433105581 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator_throw.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator_throw.pass.cpp
@@ -30,10 +30,11 @@ int A::count = 0;
int main(int, char**)
{
+ test_allocator_statistics alloc_stats;
try
{
- test_allocator<A>::throw_after = 0;
- std::shared_ptr<A> p(nullptr, test_deleter<A>(3), test_allocator<A>(5));
+ alloc_stats.throw_after = 0;
+ std::shared_ptr<A> p(nullptr, test_deleter<A>(3), test_allocator<A>(5, &alloc_stats));
assert(false);
}
catch (std::bad_alloc&)
@@ -41,8 +42,8 @@ int main(int, char**)
assert(A::count == 0);
assert(test_deleter<A>::count == 0);
assert(test_deleter<A>::dealloc_count == 1);
- assert(test_allocator<A>::count == 0);
- assert(test_allocator<A>::alloc_count == 0);
+ assert(alloc_stats.count == 0);
+ assert(alloc_stats.alloc_count == 0);
}
return 0;
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp
index d42ce342b790b..3b86b07d79234 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp
@@ -62,9 +62,10 @@ class MoveDeleter
int main(int, char**)
{
+ test_allocator_statistics alloc_stats;
{
A* ptr = new A;
- std::shared_ptr<A> p(ptr, test_deleter<A>(3), test_allocator<A>(5));
+ std::shared_ptr<A> p(ptr, test_deleter<A>(3), test_allocator<A>(5, &alloc_stats));
assert(A::count == 1);
assert(p.use_count() == 1);
assert(p.get() == ptr);
@@ -75,14 +76,14 @@ int main(int, char**)
assert(d);
assert(d->state() == 3);
#endif
- assert(test_allocator<A>::count == 1);
- assert(test_allocator<A>::alloc_count == 1);
+ assert(alloc_stats.count == 1);
+ assert(alloc_stats.alloc_count == 1);
}
assert(A::count == 0);
assert(test_deleter<A>::count == 0);
assert(test_deleter<A>::dealloc_count == 1);
- assert(test_allocator<A>::count == 0);
- assert(test_allocator<A>::alloc_count == 0);
+ assert(alloc_stats.count == 0);
+ assert(alloc_stats.alloc_count == 0);
test_deleter<A>::dealloc_count = 0;
// Test an allocator with a minimal interface
{
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator_throw.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator_throw.pass.cpp
index 240fd358e063f..6baf2debaa999 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator_throw.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator_throw.pass.cpp
@@ -30,20 +30,21 @@ int A::count = 0;
int main(int, char**)
{
+ test_allocator_statistics alloc_stats;
A* ptr = new A;
try
{
- test_allocator<A>::throw_after = 0;
- std::shared_ptr<A> p(ptr, test_deleter<A>(3), test_allocator<A>(5));
+ alloc_stats.throw_after = 0;
+ std::shared_ptr<A> p(ptr, test_deleter<A>(3), test_allocator<A>(5, &alloc_stats));
assert(false);
}
catch (std::bad_alloc&)
{
- assert(A::count == 0);
- assert(test_deleter<A>::count == 0);
+ assert(alloc_stats.count == 0);
+ assert(alloc_stats.count == 0);
assert(test_deleter<A>::dealloc_count == 1);
- assert(test_allocator<A>::count == 0);
- assert(test_allocator<A>::alloc_count == 0);
+ assert(alloc_stats.count == 0);
+ assert(alloc_stats.alloc_count == 0);
}
return 0;
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
index b892fb4fd9b15..472cb3d0a7d7c 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
@@ -141,17 +141,18 @@ int main(int, char**)
test<bare_allocator<void> >();
test<test_allocator<void> >();
+ test_allocator_statistics alloc_stats;
{
int i = 67;
char c = 'e';
- std::shared_ptr<A> p = std::allocate_shared<A>(test_allocator<A>(54), i, c);
- assert(test_allocator<A>::alloc_count == 1);
+ std::shared_ptr<A> p = std::allocate_shared<A>(test_allocator<A>(54, &alloc_stats), i, c);
+ assert(alloc_stats.alloc_count == 1);
assert(A::count == 1);
assert(p->get_int() == 67);
assert(p->get_char() == 'e');
}
assert(A::count == 0);
- assert(test_allocator<A>::alloc_count == 0);
+ assert(alloc_stats.alloc_count == 0);
{
int i = 67;
char c = 'e';
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.mod/reset_pointer_deleter_allocator.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.mod/reset_pointer_deleter_allocator.pass.cpp
index 17afcca06e013..a6ea07ea37cee 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.mod/reset_pointer_deleter_allocator.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.mod/reset_pointer_deleter_allocator.pass.cpp
@@ -43,10 +43,11 @@ int A::count = 0;
int main(int, char**)
{
+ test_allocator_statistics alloc_stats;
{
std::shared_ptr<B> p(new B);
A* ptr = new A;
- p.reset(ptr, test_deleter<A>(3), test_allocator<A>(4));
+ p.reset(ptr, test_deleter<A>(3), test_allocator<A>(4, &alloc_stats));
assert(A::count == 1);
assert(B::count == 1);
assert(p.use_count() == 1);
@@ -58,18 +59,18 @@ int main(int, char**)
assert(d);
assert(d->state() == 3);
#endif
- assert(test_allocator<A>::count == 1);
- assert(test_allocator<A>::alloc_count == 1);
+ assert(alloc_stats.count == 1);
+ assert(alloc_stats.alloc_count == 1);
}
assert(A::count == 0);
assert(test_deleter<A>::count == 0);
assert(test_deleter<A>::dealloc_count == 1);
- assert(test_allocator<A>::count == 0);
- assert(test_allocator<A>::alloc_count == 0);
+ assert(alloc_stats.count == 0);
+ assert(alloc_stats.alloc_count == 0);
{
std::shared_ptr<B> p;
A* ptr = new A;
- p.reset(ptr, test_deleter<A>(3), test_allocator<A>(4));
+ p.reset(ptr, test_deleter<A>(3), test_allocator<A>(4, &alloc_stats));
assert(A::count == 1);
assert(B::count == 1);
assert(p.use_count() == 1);
@@ -81,14 +82,14 @@ int main(int, char**)
assert(d);
assert(d->state() == 3);
#endif
- assert(test_allocator<A>::count == 1);
- assert(test_allocator<A>::alloc_count == 1);
+ assert(alloc_stats.count == 1);
+ assert(alloc_stats.alloc_count == 1);
}
assert(A::count == 0);
assert(test_deleter<A>::count == 0);
assert(test_deleter<A>::dealloc_count == 2);
- assert(test_allocator<A>::count == 0);
- assert(test_allocator<A>::alloc_count == 0);
+ assert(alloc_stats.count == 0);
+ assert(alloc_stats.alloc_count == 0);
#if TEST_STD_VER > 14
{
diff --git a/libcxx/test/support/test_allocator.h b/libcxx/test/support/test_allocator.h
index e0e402a87971c..b5320067ca04b 100644
--- a/libcxx/test/support/test_allocator.h
+++ b/libcxx/test/support/test_allocator.h
@@ -26,23 +26,16 @@ inline typename std::allocator_traits<Alloc>::size_type alloc_max_size(Alloc con
return AT::max_size(a);
}
-class test_alloc_base {
-protected:
- static int time_to_throw;
-
-public:
- static int throw_after;
- static int count;
- static int alloc_count;
- static int copied;
- static int moved;
- static int converted;
-
- const static int destructed_value = -1;
- const static int default_value = 0;
- const static int moved_value = INT_MAX;
-
- static void clear() {
+struct test_allocator_statistics {
+ int time_to_throw = 0;
+ int throw_after = INT_MAX;
+ int count = 0;
+ int alloc_count = 0;
+ int copied = 0;
+ int moved = 0;
+ int converted = 0;
+
+ TEST_CONSTEXPR_CXX14 void clear() {
assert(count == 0 && "clearing leaking allocator data?");
count = 0;
time_to_throw = 0;
@@ -51,25 +44,24 @@ class test_alloc_base {
clear_ctor_counters();
}
- static void clear_ctor_counters() {
+ TEST_CONSTEXPR_CXX14 void clear_ctor_counters() {
copied = 0;
moved = 0;
converted = 0;
}
};
-int test_alloc_base::count = 0;
-int test_alloc_base::time_to_throw = 0;
-int test_alloc_base::alloc_count = 0;
-int test_alloc_base::throw_after = INT_MAX;
-int test_alloc_base::copied = 0;
-int test_alloc_base::moved = 0;
-int test_alloc_base::converted = 0;
+struct test_alloc_base {
+ TEST_CONSTEXPR static const int destructed_value = -1;
+ TEST_CONSTEXPR static const int moved_value = INT_MAX;
+};
template <class T>
-class test_allocator : public test_alloc_base {
- int data_; // participates in equality
- int id_; // unique identifier, doesn't participate in equality
+class test_allocator {
+ int data_ = 0; // participates in equality
+ int id_ = 0; // unique identifier, doesn't participate in equality
+ test_allocator_statistics* stats_ = nullptr;
+
template <class U>
friend class test_allocator;
@@ -87,74 +79,113 @@ class test_allocator : public test_alloc_base {
typedef test_allocator<U> other;
};
- test_allocator() TEST_NOEXCEPT : data_(0), id_(0) { ++count; }
- explicit test_allocator(int i, int id = 0) TEST_NOEXCEPT : data_(i), id_(id) { ++count; }
- test_allocator(const test_allocator& a) TEST_NOEXCEPT : data_(a.data_), id_(a.id_) {
- ++count;
- ++copied;
- assert(a.data_ != destructed_value && a.id_ != destructed_value && "copying from destroyed allocator");
+ TEST_CONSTEXPR test_allocator() TEST_NOEXCEPT = default;
+
+ TEST_CONSTEXPR_CXX14 explicit test_allocator(test_allocator_statistics* stats) TEST_NOEXCEPT : stats_(stats) {
+ if (stats_ != nullptr)
+ ++stats_->count;
+ }
+
+ TEST_CONSTEXPR explicit test_allocator(int data) TEST_NOEXCEPT : data_(data) {}
+
+ TEST_CONSTEXPR_CXX14 explicit test_allocator(int data, test_allocator_statistics* stats) TEST_NOEXCEPT
+ : data_(data), stats_(stats) {
+ if (stats != nullptr)
+ ++stats_->count;
+ }
+
+ TEST_CONSTEXPR explicit test_allocator(int data, int id) TEST_NOEXCEPT : data_(data), id_(id) {}
+
+ TEST_CONSTEXPR_CXX14 explicit test_allocator(int data, int id, test_allocator_statistics* stats) TEST_NOEXCEPT
+ : data_(data), id_(id), stats_(stats) {
+ if (stats_ != nullptr)
+ ++stats_->count;
}
+
+ TEST_CONSTEXPR_CXX14 test_allocator(const test_allocator& a) TEST_NOEXCEPT
+ : data_(a.data_), id_(a.id_), stats_(a.stats_) {
+ assert(a.data_ != test_alloc_base::destructed_value && a.id_ != test_alloc_base::destructed_value &&
+ "copying from destroyed allocator");
+ if (stats_ != nullptr) {
+ ++stats_->count;
+ ++stats_->copied;
+ }
+ }
+
#if TEST_STD_VER >= 11
- test_allocator(test_allocator&& a) TEST_NOEXCEPT : data_(a.data_), id_(a.id_) {
- ++count;
- ++moved;
- assert(a.data_ != destructed_value && a.id_ != destructed_value && "moving from destroyed allocator");
- a.data_ = moved_value;
- a.id_ = moved_value;
+ TEST_CONSTEXPR_CXX14 test_allocator(test_allocator&& a) TEST_NOEXCEPT : data_(a.data_), id_(a.id_), stats_(a.stats_) {
+ if (stats_ != nullptr) {
+ ++stats_->count;
+ ++stats_->moved;
+ }
+ assert(a.data_ != test_alloc_base::destructed_value && a.id_ != test_alloc_base::destructed_value &&
+ "moving from destroyed allocator");
+ a.data_ = test_alloc_base::moved_value;
+ a.id_ = test_alloc_base::moved_value;
}
#endif
+
template <class U>
- test_allocator(const test_allocator<U>& a) TEST_NOEXCEPT : data_(a.data_), id_(a.id_) {
- ++count;
- ++converted;
+ TEST_CONSTEXPR_CXX14 test_allocator(const test_allocator<U>& a) TEST_NOEXCEPT
+ : data_(a.data_), id_(a.id_), stats_(a.stats_) {
+ if (stats_ != nullptr) {
+ ++stats_->count;
+ ++stats_->converted;
+ }
}
- ~test_allocator() TEST_NOEXCEPT {
- assert(data_ >= 0);
- assert(id_ >= 0);
- --count;
- data_ = destructed_value;
- id_ = destructed_value;
+
+ TEST_CONSTEXPR_CXX20 ~test_allocator() TEST_NOEXCEPT {
+ assert(data_ != test_alloc_base::destructed_value);
+ assert(id_ != test_alloc_base::destructed_value);
+ if (stats_ != nullptr)
+ --stats_->count;
+ data_ = test_alloc_base::destructed_value;
+ id_ = test_alloc_base::destructed_value;
}
- pointer address(reference x) const { return &x; }
- const_pointer address(const_reference x) const { return &x; }
- pointer allocate(size_type n, const void* = 0) {
- assert(data_ >= 0);
- if (time_to_throw >= throw_after) {
-#ifndef TEST_HAS_NO_EXCEPTIONS
- throw std::bad_alloc();
-#else
- std::terminate();
-#endif
+
+ TEST_CONSTEXPR pointer address(reference x) const { return &x; }
+ TEST_CONSTEXPR const_pointer address(const_reference x) const { return &x; }
+
+ TEST_CONSTEXPR_CXX14 pointer allocate(size_type n, const void* = 0) {
+ assert(data_ != test_alloc_base::destructed_value);
+ if (stats_ != nullptr) {
+ if (stats_->time_to_throw >= stats_->throw_after)
+ TEST_THROW(std::bad_alloc());
+ ++stats_->time_to_throw;
+ ++stats_->alloc_count;
}
- ++time_to_throw;
- ++alloc_count;
- return (pointer)::operator new(n * sizeof(T));
+ return std::allocator<value_type>().allocate(n);
}
- void deallocate(pointer p, size_type) {
- assert(data_ >= 0);
- --alloc_count;
- ::operator delete((void*)p);
+
+ TEST_CONSTEXPR_CXX14 void deallocate(pointer p, size_type s) {
+ assert(data_ != test_alloc_base::destructed_value);
+ if (stats_ != nullptr)
+ --stats_->alloc_count;
+ std::allocator<value_type>().deallocate(p, s);
}
- size_type max_size() const TEST_NOEXCEPT { return UINT_MAX / sizeof(T); }
+
+ TEST_CONSTEXPR size_type max_size() const TEST_NOEXCEPT { return UINT_MAX / sizeof(T); }
+
#if TEST_STD_VER < 11
void construct(pointer p, const T& val) { ::new (static_cast<void*>(p)) T(val); }
#else
template <class U>
- void construct(pointer p, U&& val) {
+ TEST_CONSTEXPR_CXX14 void construct(pointer p, U&& val) {
::new (static_cast<void*>(p)) T(std::forward<U>(val));
}
#endif
- void destroy(pointer p) { p->~T(); }
- friend bool operator==(const test_allocator& x, const test_allocator& y) { return x.data_ == y.data_; }
- friend bool operator!=(const test_allocator& x, const test_allocator& y) { return !(x == y); }
+ TEST_CONSTEXPR_CXX14 void destroy(pointer p) { p->~T(); }
+ TEST_CONSTEXPR friend bool operator==(const test_allocator& x, const test_allocator& y) { return x.data_ == y.data_; }
+ TEST_CONSTEXPR friend bool operator!=(const test_allocator& x, const test_allocator& y) { return !(x == y); }
- int get_data() const { return data_; }
- int get_id() const { return id_; }
+ TEST_CONSTEXPR int get_data() const { return data_; }
+ TEST_CONSTEXPR int get_id() const { return id_; }
};
template <class T>
-class non_default_test_allocator : public test_alloc_base {
- int data_;
+class non_default_test_allocator {
+ int data_ = 0;
+ test_allocator_statistics* stats_ = nullptr;
template <class U>
friend class non_default_test_allocator;
@@ -173,59 +204,71 @@ class non_default_test_allocator : public test_alloc_base {
typedef non_default_test_allocator<U> other;
};
- // non_default_test_allocator() TEST_NOEXCEPT : data_(0) {++count;}
- explicit non_default_test_allocator(int i) TEST_NOEXCEPT : data_(i) { ++count; }
- non_default_test_allocator(const non_default_test_allocator& a) TEST_NOEXCEPT : data_(a.data_) { ++count; }
+ TEST_CONSTEXPR_CXX14
+ explicit non_default_test_allocator(int i, test_allocator_statistics* stats = nullptr) TEST_NOEXCEPT
+ : data_(i), stats_(stats) {
+ if (stats_ != nullptr) {
+ ++stats_->count;
+ }
+ }
+
+ TEST_CONSTEXPR_CXX14
+ non_default_test_allocator(const non_default_test_allocator& a) TEST_NOEXCEPT : data_(a.data_), stats_(a.stats_) {
+ if (stats_ != nullptr)
+ ++stats_->count;
+ }
+
template <class U>
- non_default_test_allocator(const non_default_test_allocator<U>& a) TEST_NOEXCEPT : data_(a.data_) {
- ++count;
+ TEST_CONSTEXPR_CXX14 non_default_test_allocator(const non_default_test_allocator<U>& a) TEST_NOEXCEPT
+ : data_(a.data_), stats_(a.stats_) {
+ if (stats_ != nullptr)
+ ++stats_->count;
}
- ~non_default_test_allocator() TEST_NOEXCEPT {
- assert(data_ >= 0);
- --count;
- data_ = -1;
+
+ TEST_CONSTEXPR_CXX20 ~non_default_test_allocator() TEST_NOEXCEPT {
+ assert(data_ != test_alloc_base::destructed_value);
+ if (stats_ != nullptr)
+ --stats_->count;
+ data_ = test_alloc_base::destructed_value;
}
- pointer address(reference x) const { return &x; }
- const_pointer address(const_reference x) const { return &x; }
- pointer allocate(size_type n, const void* = 0) {
- assert(data_ >= 0);
- if (time_to_throw >= throw_after) {
-#ifndef TEST_HAS_NO_EXCEPTIONS
- throw std::bad_alloc();
-#else
- std::terminate();
-#endif
+
+ TEST_CONSTEXPR pointer address(reference x) const { return &x; }
+ TEST_CONSTEXPR const_pointer address(const_reference x) const { return &x; }
+
+ TEST_CONSTEXPR_CXX20 pointer allocate(size_type n, const void* = nullptr) {
+ assert(data_ != test_alloc_base::destructed_value);
+ if (stats_ != nullptr) {
+ if (stats_->time_to_throw >= stats_->throw_after)
+ TEST_THROW(std::bad_alloc());
+ ++stats_->time_to_throw;
+ ++stats_->alloc_count;
}
- ++time_to_throw;
- ++alloc_count;
- return (pointer)::operator new(n * sizeof(T));
- }
- void deallocate(pointer p, size_type) {
- assert(data_ >= 0);
- --alloc_count;
- ::operator delete((void*)p);
+ return std::allocator<value_type>().allocate(n);
}
- size_type max_size() const TEST_NOEXCEPT { return UINT_MAX / sizeof(T); }
-#if TEST_STD_VER < 11
- void construct(pointer p, const T& val) { ::new (static_cast<void*>(p)) T(val); }
-#else
- template <class U>
- void construct(pointer p, U&& val) {
- ::new (static_cast<void*>(p)) T(std::forward<U>(val));
+
+ TEST_CONSTEXPR_CXX20 void deallocate(pointer p, size_type n) {
+ assert(data_ != test_alloc_base::destructed_value);
+ if (stats_ != nullptr)
+ --stats_->alloc_count;
+ std::allocator<value_type>().deallocate(p, n);
}
-#endif
- void destroy(pointer p) { p->~T(); }
- friend bool operator==(const non_default_test_allocator& x, const non_default_test_allocator& y) {
+ TEST_CONSTEXPR size_type max_size() const TEST_NOEXCEPT { return UINT_MAX / sizeof(T); }
+
+ TEST_CONSTEXPR friend bool operator==(const non_default_test_allocator& x, const non_default_test_allocator& y) {
return x.data_ == y.data_;
}
- friend bool operator!=(const non_default_test_allocator& x, const non_default_test_allocator& y) { return !(x == y); }
+
+ TEST_CONSTEXPR friend bool operator!=(const non_default_test_allocator& x, const non_default_test_allocator& y) {
+ return !(x == y);
+ }
};
template <>
-class test_allocator<void> : public test_alloc_base {
- int data_;
- int id_;
+class test_allocator<void> {
+ int data_ = 0;
+ int id_ = 0;
+ test_allocator_statistics* stats_ = nullptr;
template <class U>
friend class test_allocator;
@@ -242,26 +285,46 @@ class test_allocator<void> : public test_alloc_base {
typedef test_allocator<U> other;
};
- test_allocator() TEST_NOEXCEPT : data_(0), id_(0) {}
- explicit test_allocator(int i, int id = 0) TEST_NOEXCEPT : data_(i), id_(id) {}
- test_allocator(const test_allocator& a) TEST_NOEXCEPT : data_(a.data_), id_(a.id_) {}
+ TEST_CONSTEXPR test_allocator() TEST_NOEXCEPT = default;
+
+ TEST_CONSTEXPR_CXX14 explicit test_allocator(test_allocator_statistics* stats) TEST_NOEXCEPT : stats_(stats) {}
+
+ TEST_CONSTEXPR explicit test_allocator(int data) TEST_NOEXCEPT : data_(data) {}
+
+ TEST_CONSTEXPR explicit test_allocator(int data, test_allocator_statistics* stats) TEST_NOEXCEPT
+ : data_(data), stats_(stats)
+ {}
+
+ TEST_CONSTEXPR explicit test_allocator(int data, int id) : data_(data), id_(id) {}
+
+ TEST_CONSTEXPR_CXX14 explicit test_allocator(int data, int id, test_allocator_statistics* stats) TEST_NOEXCEPT
+ : data_(data), id_(id), stats_(stats)
+ {}
+
+ TEST_CONSTEXPR_CXX14 explicit test_allocator(const test_allocator& a) TEST_NOEXCEPT
+ : data_(a.data_), id_(a.id_), stats_(a.stats_)
+ {}
+
template <class U>
- test_allocator(const test_allocator<U>& a) TEST_NOEXCEPT : data_(a.data_), id_(a.id_) {}
- ~test_allocator() TEST_NOEXCEPT {
- data_ = -1;
- id_ = -1;
+ TEST_CONSTEXPR_CXX14 test_allocator(const test_allocator<U>& a) TEST_NOEXCEPT
+ : data_(a.data_), id_(a.id_), stats_(a.stats_)
+ {}
+
+ TEST_CONSTEXPR_CXX20 ~test_allocator() TEST_NOEXCEPT {
+ data_ = test_alloc_base::destructed_value;
+ id_ = test_alloc_base::destructed_value;
}
- int get_id() const { return id_; }
- int get_data() const { return data_; }
+ TEST_CONSTEXPR int get_id() const { return id_; }
+ TEST_CONSTEXPR int get_data() const { return data_; }
- friend bool operator==(const test_allocator& x, const test_allocator& y) { return x.data_ == y.data_; }
- friend bool operator!=(const test_allocator& x, const test_allocator& y) { return !(x == y); }
+ TEST_CONSTEXPR friend bool operator==(const test_allocator& x, const test_allocator& y) { return x.data_ == y.data_; }
+ TEST_CONSTEXPR friend bool operator!=(const test_allocator& x, const test_allocator& y) { return !(x == y); }
};
template <class T>
class other_allocator {
- int data_;
+ int data_ = -1;
template <class U>
friend class other_allocator;
@@ -269,17 +332,22 @@ class other_allocator {
public:
typedef T value_type;
- other_allocator() : data_(-1) {}
- explicit other_allocator(int i) : data_(i) {}
+ TEST_CONSTEXPR_CXX14 other_allocator() {}
+ TEST_CONSTEXPR_CXX14 explicit other_allocator(int i) : data_(i) {}
+
template <class U>
- other_allocator(const other_allocator<U>& a) : data_(a.data_) {}
- T* allocate(std::size_t n) { return (T*)::operator new(n * sizeof(T)); }
- void deallocate(T* p, std::size_t) { ::operator delete((void*)p); }
+ TEST_CONSTEXPR_CXX14 other_allocator(const other_allocator<U>& a) : data_(a.data_) {}
- other_allocator select_on_container_copy_construction() const { return other_allocator(-2); }
+ TEST_CONSTEXPR_CXX20 T* allocate(std::size_t n) { return std::allocator<value_type>().allocate(n); }
+ TEST_CONSTEXPR_CXX20 void deallocate(T* p, std::size_t s) { std::allocator<value_type>().deallocate(p, s); }
- friend bool operator==(const other_allocator& x, const other_allocator& y) { return x.data_ == y.data_; }
- friend bool operator!=(const other_allocator& x, const other_allocator& y) { return !(x == y); }
+ TEST_CONSTEXPR_CXX14 other_allocator select_on_container_copy_construction() const { return other_allocator(-2); }
+
+ TEST_CONSTEXPR_CXX14 friend bool operator==(const other_allocator& x, const other_allocator& y) {
+ return x.data_ == y.data_;
+ }
+
+ TEST_CONSTEXPR_CXX14 friend bool operator!=(const other_allocator& x, const other_allocator& y) { return !(x == y); }
typedef std::true_type propagate_on_container_copy_assignment;
typedef std::true_type propagate_on_container_move_assignment;
@@ -301,15 +369,15 @@ struct Tag_X {
// All constructors must be passed the Tag type.
// DefaultInsertable into vector<X, TaggingAllocator<X>>,
- Tag_X(Ctor_Tag) {}
+ constexpr Tag_X(Ctor_Tag) {}
// CopyInsertable into vector<X, TaggingAllocator<X>>,
- Tag_X(Ctor_Tag, const Tag_X&) {}
+ constexpr Tag_X(Ctor_Tag, const Tag_X&) {}
// MoveInsertable into vector<X, TaggingAllocator<X>>, and
- Tag_X(Ctor_Tag, Tag_X&&) {}
+ constexpr Tag_X(Ctor_Tag, Tag_X&&) {}
// EmplaceConstructible into vector<X, TaggingAllocator<X>> from args.
template <typename... Args>
- Tag_X(Ctor_Tag, Args&&...) {}
+ constexpr Tag_X(Ctor_Tag, Args&&...) {}
// not DefaultConstructible, CopyConstructible or MoveConstructible.
Tag_X() = delete;
@@ -317,15 +385,13 @@ struct Tag_X {
Tag_X(Tag_X&&) = delete;
// CopyAssignable.
- Tag_X& operator=(const Tag_X&) { return *this; }
+ TEST_CONSTEXPR_CXX14 Tag_X& operator=(const Tag_X&) { return *this; };
// MoveAssignable.
- Tag_X& operator=(Tag_X&&) { return *this; }
+ TEST_CONSTEXPR_CXX14 Tag_X& operator=(Tag_X&&) { return *this; };
private:
- // Not Destructible.
- ~Tag_X() {}
-
+ ~Tag_X() = default;
// Erasable from vector<X, TaggingAllocator<X>>.
friend class TaggingAllocator<Tag_X>;
};
@@ -337,71 +403,109 @@ class TaggingAllocator {
TaggingAllocator() = default;
template <typename U>
- TaggingAllocator(const TaggingAllocator<U>&) {}
-
- T* allocate(std::size_t n) { return std::allocator<T>{}.allocate(n); }
-
- void deallocate(T* p, std::size_t n) { std::allocator<T>{}.deallocate(p, n); }
+ constexpr TaggingAllocator(const TaggingAllocator<U>&){};
template <typename... Args>
void construct(Tag_X* p, Args&&... args) {
::new ((void*)p) Tag_X(Ctor_Tag{}, std::forward<Args>(args)...);
}
- template <typename U, typename... Args>
- void construct(U* p, Args&&... args) {
- ::new ((void*)p) U(std::forward<Args>(args)...);
- }
-
- template <typename U, typename... Args>
+ template <typename U>
void destroy(U* p) {
p->~U();
}
-};
-
-template <typename T, typename U>
-bool operator==(const TaggingAllocator<T>&, const TaggingAllocator<U>&) {
- return true;
-}
-template <typename T, typename U>
-bool operator!=(const TaggingAllocator<T>&, const TaggingAllocator<U>&) {
- return false;
-}
+ TEST_CONSTEXPR_CXX20 T* allocate(std::size_t n) { return std::allocator<T>{}.allocate(n); }
+ TEST_CONSTEXPR_CXX20 void deallocate(T* p, std::size_t n) { std::allocator<T>{}.deallocate(p, n); }
+};
#endif
template <std::size_t MaxAllocs>
struct limited_alloc_handle {
- std::size_t outstanding_;
- void* last_alloc_;
-
- limited_alloc_handle() : outstanding_(0), last_alloc_(nullptr) {}
+ std::size_t outstanding_ = 0;
+ void* last_alloc_ = nullptr;
template <class T>
- T* allocate(std::size_t N) {
+ TEST_CONSTEXPR_CXX20 T* allocate(std::size_t N) {
if (N + outstanding_ > MaxAllocs)
TEST_THROW(std::bad_alloc());
- last_alloc_ = ::operator new(N * sizeof(T));
+ last_alloc_ = std::allocator<T>().allocate(N);
outstanding_ += N;
return static_cast<T*>(last_alloc_);
}
- void deallocate(void* ptr, std::size_t N) {
+ template <class T>
+ TEST_CONSTEXPR_CXX20 void deallocate(T* ptr, std::size_t N) {
if (ptr == last_alloc_) {
last_alloc_ = nullptr;
assert(outstanding_ >= N);
outstanding_ -= N;
}
- ::operator delete(ptr);
+ std::allocator<T>().deallocate(ptr, N);
}
};
+namespace detail {
+template <class T>
+class thread_unsafe_shared_ptr {
+public:
+ thread_unsafe_shared_ptr() = default;
+
+ TEST_CONSTEXPR_CXX14 thread_unsafe_shared_ptr(const thread_unsafe_shared_ptr& other) : block(other.block) {
+ ++block->ref_count;
+ }
+
+ TEST_CONSTEXPR_CXX20 ~thread_unsafe_shared_ptr() {
+ --block->ref_count;
+ if (block->ref_count != 0)
+ return;
+ typedef std::allocator_traits<std::allocator<control_block> > allocator_traits;
+ std::allocator<control_block> alloc;
+ allocator_traits::destroy(alloc, block);
+ allocator_traits::deallocate(alloc, block, 1);
+ }
+
+ TEST_CONSTEXPR const T& operator*() const { return block->content; }
+ TEST_CONSTEXPR const T* operator->() const { return &block->content; }
+ TEST_CONSTEXPR_CXX14 T& operator*() { return block->content; }
+ TEST_CONSTEXPR_CXX14 T* operator->() { return &block->content; }
+ TEST_CONSTEXPR_CXX14 T* get() { return &block->content; }
+ TEST_CONSTEXPR const T* get() const { return &block->content; }
+
+private:
+ struct control_block {
+ template <class... Args>
+ TEST_CONSTEXPR control_block(Args... args) : content(std::forward<Args>(args)...) {}
+ size_t ref_count = 1;
+ T content;
+ };
+
+ control_block* block = nullptr;
+
+ template <class U, class... Args>
+ friend TEST_CONSTEXPR_CXX20 thread_unsafe_shared_ptr<U> make_thread_unsafe_shared(Args...);
+};
+
+template <class T, class... Args>
+TEST_CONSTEXPR_CXX20 thread_unsafe_shared_ptr<T> make_thread_unsafe_shared(Args... args) {
+ typedef typename thread_unsafe_shared_ptr<T>::control_block control_block_type;
+ typedef std::allocator_traits<std::allocator<control_block_type> > allocator_traits;
+
+ thread_unsafe_shared_ptr<T> ptr;
+ std::allocator<control_block_type> alloc;
+ ptr.block = allocator_traits::allocate(alloc, 1);
+ allocator_traits::construct(alloc, ptr.block, std::forward<Args>(args)...);
+
+ return ptr;
+}
+} // namespace detail
+
template <class T, std::size_t N>
class limited_allocator {
template <class U, std::size_t UN>
friend class limited_allocator;
typedef limited_alloc_handle<N> BuffT;
- std::shared_ptr<BuffT> handle_;
+ detail::thread_unsafe_shared_ptr<BuffT> handle_;
public:
typedef T value_type;
@@ -417,29 +521,28 @@ class limited_allocator {
typedef limited_allocator<U, N> other;
};
- limited_allocator() : handle_(new BuffT) {}
+ TEST_CONSTEXPR_CXX20 limited_allocator() : handle_(detail::make_thread_unsafe_shared<BuffT>()) {}
- limited_allocator(limited_allocator const& other) : handle_(other.handle_) {}
+ limited_allocator(limited_allocator const&) = default;
template <class U>
- explicit limited_allocator(limited_allocator<U, N> const& other) : handle_(other.handle_) {}
+ TEST_CONSTEXPR explicit limited_allocator(limited_allocator<U, N> const& other) : handle_(other.handle_) {}
limited_allocator& operator=(const limited_allocator&) = delete;
- pointer allocate(size_type n) { return handle_->template allocate<T>(n); }
- void deallocate(pointer p, size_type n) { handle_->deallocate(p, n); }
- size_type max_size() const { return N; }
-
- BuffT* getHandle() const { return handle_.get(); }
+ TEST_CONSTEXPR_CXX20 pointer allocate(size_type n) { return handle_->template allocate<T>(n); }
+ TEST_CONSTEXPR_CXX20 void deallocate(pointer p, size_type n) { handle_->template deallocate<T>(p, n); }
+ TEST_CONSTEXPR size_type max_size() const { return N; }
+ TEST_CONSTEXPR BuffT* getHandle() const { return handle_.get(); }
};
template <class T, class U, std::size_t N>
-inline bool operator==(limited_allocator<T, N> const& LHS, limited_allocator<U, N> const& RHS) {
+TEST_CONSTEXPR inline bool operator==(limited_allocator<T, N> const& LHS, limited_allocator<U, N> const& RHS) {
return LHS.getHandle() == RHS.getHandle();
}
template <class T, class U, std::size_t N>
-inline bool operator!=(limited_allocator<T, N> const& LHS, limited_allocator<U, N> const& RHS) {
+TEST_CONSTEXPR inline bool operator!=(limited_allocator<T, N> const& LHS, limited_allocator<U, N> const& RHS) {
return !(LHS == RHS);
}
More information about the libcxx-commits
mailing list