Index: test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp.pass.cpp =================================================================== --- test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp.pass.cpp +++ test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp.pass.cpp @@ -14,11 +14,9 @@ #include #include -#include "../../../stack_allocator.h" - int main() { - std::priority_queue > > q((std::less())); + std::priority_queue > q((std::less())); assert(q.size() == 0); q.push(1); q.push(2); Index: test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_default.pass.cpp =================================================================== --- test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_default.pass.cpp +++ test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_default.pass.cpp @@ -14,11 +14,9 @@ #include #include -#include "../../../stack_allocator.h" - int main() { - std::priority_queue > > q; + std::priority_queue > q; assert(q.size() == 0); q.push(1); q.push(2); Index: test/std/containers/container.adaptors/queue/queue.cons/ctor_default.pass.cpp =================================================================== --- test/std/containers/container.adaptors/queue/queue.cons/ctor_default.pass.cpp +++ test/std/containers/container.adaptors/queue/queue.cons/ctor_default.pass.cpp @@ -14,11 +14,10 @@ #include #include -#include "../../../stack_allocator.h" int main() { - std::queue > > q; + std::queue > q; assert(q.size() == 0); q.push(1); q.push(2); Index: test/std/containers/container.adaptors/stack/stack.cons/ctor_default.pass.cpp =================================================================== --- test/std/containers/container.adaptors/stack/stack.cons/ctor_default.pass.cpp +++ test/std/containers/container.adaptors/stack/stack.cons/ctor_default.pass.cpp @@ -15,11 +15,9 @@ #include #include -#include "../../../stack_allocator.h" - int main() { - std::stack > > q; + std::stack > q; assert(q.size() == 0); q.push(1); q.push(2); Index: test/std/containers/sequences/deque/deque.cons/alloc.pass.cpp =================================================================== --- test/std/containers/sequences/deque/deque.cons/alloc.pass.cpp +++ test/std/containers/sequences/deque/deque.cons/alloc.pass.cpp @@ -14,6 +14,7 @@ #include #include +#include "stack_allocator.h" #include "test_allocator.h" #include "../../../NotConstructible.h" #include "min_allocator.h" @@ -31,6 +32,12 @@ { test(std::allocator()); test(test_allocator(3)); + { + typedef StackAllocTraits Traits; + typedef Traits::AllocT AllocT; + Traits T; + test(T.alloc); + } #if TEST_STD_VER >= 11 test(min_allocator()); test(min_allocator{}); Index: test/std/containers/sequences/deque/deque.cons/default.pass.cpp =================================================================== --- test/std/containers/sequences/deque/deque.cons/default.pass.cpp +++ test/std/containers/sequences/deque/deque.cons/default.pass.cpp @@ -14,7 +14,6 @@ #include #include -#include "../../../stack_allocator.h" #include "../../../NotConstructible.h" #include "min_allocator.h" @@ -33,7 +32,6 @@ int main() { test >(); - test >(); #if TEST_STD_VER >= 11 test >(); test >(); Index: test/std/containers/sequences/deque/deque.cons/iter_iter.pass.cpp =================================================================== --- test/std/containers/sequences/deque/deque.cons/iter_iter.pass.cpp +++ test/std/containers/sequences/deque/deque.cons/iter_iter.pass.cpp @@ -14,7 +14,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "test_iterators.h" #include "min_allocator.h" @@ -33,14 +33,14 @@ assert(*i == *f); } -template +template void -test(InputIterator f, InputIterator l) +test(InputIterator f, InputIterator l, Alloc const& A) { typedef typename std::iterator_traits::value_type T; - typedef std::deque C; + typedef std::deque C; typedef typename C::const_iterator const_iterator; - C d(f, l); + C d(f, l, A); assert(d.size() == std::distance(f, l)); assert(distance(d.begin(), d.end()) == d.size()); for (const_iterator i = d.begin(), e = d.end(); i != e; ++i, ++f) @@ -55,8 +55,15 @@ test(forward_iterator(ab), forward_iterator(an)); test(bidirectional_iterator(ab), bidirectional_iterator(an)); test(random_access_iterator(ab), random_access_iterator(an)); - test >(ab, an); + { + typedef StackAllocTraits Traits; + Traits T; + test(ab, an, T.alloc); + } #if TEST_STD_VER >= 11 - test >(ab, an); + { + min_allocator A; + test(ab, an, A); + } #endif } Index: test/std/containers/sequences/deque/deque.cons/size.pass.cpp =================================================================== --- test/std/containers/sequences/deque/deque.cons/size.pass.cpp +++ test/std/containers/sequences/deque/deque.cons/size.pass.cpp @@ -14,7 +14,8 @@ #include #include -#include "../../../stack_allocator.h" +#include "test_macros.h" +#include "stack_allocator.h" #include "DefaultOnly.h" #include "min_allocator.h" @@ -22,7 +23,7 @@ void test2(unsigned n) { -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER >= 14 typedef std::deque C; typedef typename C::const_iterator const_iterator; assert(DefaultOnly::count == 0); @@ -31,10 +32,8 @@ assert(DefaultOnly::count == n); assert(d.size() == n); assert(distance(d.begin(), d.end()) == d.size()); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES for (const_iterator i = d.begin(), e = d.end(); i != e; ++i) assert(*i == T()); -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } assert(DefaultOnly::count == 0); #endif @@ -52,10 +51,10 @@ assert(DefaultOnly::count == n); assert(d.size() == n); assert(distance(d.begin(), d.end()) == d.size()); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#if TEST_STD_VER >= 11 for (const_iterator i = d.begin(), e = d.end(); i != e; ++i) assert(*i == T()); -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif } assert(DefaultOnly::count == 0); } @@ -64,7 +63,7 @@ void test3(unsigned n, Allocator const &alloc = Allocator()) { -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER >= 14 typedef std::deque C; typedef typename C::const_iterator const_iterator; { @@ -98,16 +97,21 @@ test >(4096); test >(4097); - test1 >(4095); #if TEST_STD_VER >= 11 test >(4095); #endif -#if _LIBCPP_STD_VER > 11 +#if TEST_STD_VER >= 14 test3> (1023); test3>(1); test3> (3); + { + // FIXME: The deque only uses 4096 elements but it needs extra room. + typedef StackAllocTraits Traits; + Traits T; + test3(4095, T.alloc); + } #endif } Index: test/std/containers/sequences/deque/deque.cons/size_value.pass.cpp =================================================================== --- test/std/containers/sequences/deque/deque.cons/size_value.pass.cpp +++ test/std/containers/sequences/deque/deque.cons/size_value.pass.cpp @@ -14,7 +14,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "min_allocator.h" template @@ -44,7 +44,7 @@ test >(4095, 78); test >(4096, 1165); test >(4097, 157); - test >(4095, 90); + #if TEST_STD_VER >= 11 test >(4095, 90); #endif Index: test/std/containers/sequences/deque/deque.cons/size_value_alloc.pass.cpp =================================================================== --- test/std/containers/sequences/deque/deque.cons/size_value_alloc.pass.cpp +++ test/std/containers/sequences/deque/deque.cons/size_value_alloc.pass.cpp @@ -14,6 +14,7 @@ #include #include +#include "stack_allocator.h" #include "min_allocator.h" template @@ -47,6 +48,23 @@ test(4096, 1165, a); test(4097, 157, a); } + { + typedef StackAllocTraits Traits; + Traits T; + Traits::AllocT& a = T.alloc; + test(0, 5, a); a.reset(); + test(1, 10, a); a.reset(); + test(10, 11, a); a.reset(); + test(1023, -11, a); a.reset(); + test(1024, 25, a); a.reset(); + test(1025, 0, a); a.reset(); + test(2047, 110, a); a.reset(); + test(2048, -500, a); a.reset(); + test(2049, 654, a); a.reset(); + test(4095, 78, a); a.reset(); + test(4096, 1165, a); a.reset(); + test(4097, 157, a); a.reset(); + } #if TEST_STD_VER >= 11 { min_allocator a; Index: test/std/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp =================================================================== --- test/std/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp +++ test/std/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp @@ -20,7 +20,7 @@ #include "test_macros.h" #include "test_iterators.h" #include "MoveOnly.h" -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "min_allocator.h" template @@ -233,12 +233,12 @@ } } -template +template void -test_move() +test_move(Alloc const& A = Alloc()) { #if TEST_STD_VER >= 11 - C c; + C c(A); typedef typename C::const_iterator CI; { MoveOnly mo(0); @@ -270,7 +270,12 @@ testN >(rng[i], rng[j], rng[k]); testNI >(1500, 2000, 1000); #if TEST_STD_VER >= 11 - test_move > >(); + { + typedef StackAllocTraits Traits; + typedef std::deque C; + Traits T; + test_move(T.alloc); + } #endif } #if TEST_STD_VER >= 11 Index: test/std/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp =================================================================== --- test/std/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp +++ test/std/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp @@ -13,7 +13,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "min_allocator.h" int main() @@ -29,7 +29,11 @@ assert(std::distance(l.begin(), l.end()) == 0); } { - std::list > l; + typedef StackAllocTraits Traits; + typedef Traits::AllocT AllocT; + Traits T; + std::list l(T.alloc); + assert(l.get_allocator() == T.alloc); assert(l.size() == 0); assert(std::distance(l.begin(), l.end()) == 0); } Index: test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp =================================================================== --- test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp +++ test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp @@ -15,7 +15,7 @@ #include #include #include "test_iterators.h" -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "min_allocator.h" int main() @@ -42,9 +42,14 @@ assert(*i == j); } { + int a[] = {0, 1, 2, 3}; - std::list > l(input_iterator(a), - input_iterator(a + sizeof(a)/sizeof(a[0]))); + typedef StackAllocTraits Traits; + typedef Traits::AllocT AllocT; + Traits T; + std::list l(input_iterator(a), + input_iterator(a + sizeof(a)/sizeof(a[0])), + T.alloc); assert(l.size() == sizeof(a)/sizeof(a[0])); assert(std::distance(l.begin(), l.end()) == sizeof(a)/sizeof(a[0])); int j = 0; Index: test/std/containers/sequences/list/list.cons/size_type.pass.cpp =================================================================== --- test/std/containers/sequences/list/list.cons/size_type.pass.cpp +++ test/std/containers/sequences/list/list.cons/size_type.pass.cpp @@ -14,7 +14,7 @@ #include #include #include "DefaultOnly.h" -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "min_allocator.h" template @@ -47,8 +47,14 @@ ++i; assert(*i == 0); } +#if TEST_STD_VER >= 14 { - std::list > l(3); + // FIXME The list rebinds the allocator internally and it needs + // space for more than 3 elements. + typedef StackAllocTraits Traits; + typedef Traits::AllocT AllocT; + Traits T; + std::list l(3, T.alloc); assert(l.size() == 3); assert(std::distance(l.begin(), l.end()) == 3); std::list::const_iterator i = l.begin(); @@ -58,7 +64,6 @@ ++i; assert(*i == 0); } -#if _LIBCPP_STD_VER > 11 { typedef std::list > C; C l(3, min_allocator ()); @@ -73,14 +78,12 @@ test3> (3); } #endif -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#if TEST_STD_VER >= 11 { std::list l(3); assert(l.size() == 3); assert(std::distance(l.begin(), l.end()) == 3); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if TEST_STD_VER >= 11 { std::list> l(3); assert(l.size() == 3); @@ -92,12 +95,10 @@ ++i; assert(*i == 0); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { std::list> l(3); assert(l.size() == 3); assert(std::distance(l.begin(), l.end()) == 3); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES #endif } Index: test/std/containers/sequences/list/list.cons/size_value_alloc.pass.cpp =================================================================== --- test/std/containers/sequences/list/list.cons/size_value_alloc.pass.cpp +++ test/std/containers/sequences/list/list.cons/size_value_alloc.pass.cpp @@ -14,7 +14,7 @@ #include #include #include "DefaultOnly.h" -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "min_allocator.h" int main() @@ -42,7 +42,13 @@ assert(*i == 2); } { - std::list > l(3, 2); + // FIXME The list rebinds the allocator internally and it needs + // space for more than 3 elements. + typedef StackAllocTraits Traits; + typedef Traits::AllocT AllocT; + Traits T; + std::list l(3, 2, T.alloc); + assert(l.get_allocator() == T.alloc); assert(l.size() == 3); assert(std::distance(l.begin(), l.end()) == 3); std::list::const_iterator i = l.begin(); Index: test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp =================================================================== --- test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp +++ test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp @@ -13,7 +13,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -37,7 +37,9 @@ assert(is_contiguous_container_asan_correct(v)); } { - std::vector > v(100); + typedef StackAllocTraits Traits; + Traits T; + std::vector v(100, 0, T.alloc); assert(v.capacity() == 100); v.reserve(50); assert(v.size() == 100); Index: test/std/containers/sequences/vector/vector.capacity/resize_size.pass.cpp =================================================================== --- test/std/containers/sequences/vector/vector.capacity/resize_size.pass.cpp +++ test/std/containers/sequences/vector/vector.capacity/resize_size.pass.cpp @@ -13,14 +13,14 @@ #include #include -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "MoveOnly.h" #include "min_allocator.h" #include "asan_testing.h" int main() { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#if TEST_STD_VER >= 11 { std::vector v(100); v.resize(50); @@ -33,7 +33,10 @@ assert(is_contiguous_container_asan_correct(v)); } { - std::vector > v(100); + typedef StackAllocTraits Traits; + Traits T; + std::vector v(T.alloc); + v.resize(100); v.resize(50); assert(v.size() == 50); assert(v.capacity() == 100); @@ -43,7 +46,7 @@ assert(v.capacity() >= 200); assert(is_contiguous_container_asan_correct(v)); } -#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif { std::vector v(100); v.resize(50); @@ -56,7 +59,10 @@ assert(is_contiguous_container_asan_correct(v)); } { - std::vector > v(100); + typedef StackAllocTraits Traits; + Traits T; + std::vector v(T.alloc); + v.resize(100); v.resize(50); assert(v.size() == 50); assert(v.capacity() == 100); @@ -66,7 +72,6 @@ assert(v.capacity() >= 200); assert(is_contiguous_container_asan_correct(v)); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES #if TEST_STD_VER >= 11 { std::vector> v(100); Index: test/std/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp =================================================================== --- test/std/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp +++ test/std/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp @@ -13,7 +13,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -35,7 +35,9 @@ assert(v[i] == 1); } { - std::vector > v(100); + typedef StackAllocTraits Traits; + Traits T; + std::vector v(100, 0, T.alloc); v.resize(50, 1); assert(v.size() == 50); assert(v.capacity() == 100); Index: test/std/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp =================================================================== --- test/std/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp +++ test/std/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp @@ -13,9 +13,10 @@ #include #include -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "min_allocator.h" #include "asan_testing.h" +#include int main() { @@ -29,7 +30,9 @@ assert(is_contiguous_container_asan_correct(v)); } { - std::vector > v(100); + typedef StackAllocTraits Traits; + Traits T; + std::vector v(100, 0, T.alloc); v.push_back(1); assert(is_contiguous_container_asan_correct(v)); v.shrink_to_fit(); @@ -37,9 +40,11 @@ assert(v.size() == 101); assert(is_contiguous_container_asan_correct(v)); } -#ifndef _LIBCPP_NO_EXCEPTIONS +#ifndef TEST_HAS_NO_EXCEPTIONS { - std::vector > v(100); + typedef StackAllocTraits Traits; + Traits T; + std::vector v(100, 0, T.alloc); v.push_back(1); assert(is_contiguous_container_asan_correct(v)); v.shrink_to_fit(); Index: test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp =================================================================== --- test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp +++ test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp @@ -18,7 +18,7 @@ #include "test_macros.h" #include "test_allocator.h" #include "../../../NotConstructible.h" -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -49,10 +49,11 @@ void test1(const typename C::allocator_type& a) { + typedef typename C::allocator_type AllocT; #if TEST_STD_VER > 14 - static_assert((noexcept(C{typename C::allocator_type{}})), "" ); + static_assert(noexcept(C(a)), "" ); #elif TEST_STD_VER >= 11 - static_assert((noexcept(C(typename C::allocator_type())) == std::is_nothrow_copy_constructible::value), "" ); + static_assert(noexcept(C(a)) == std::is_nothrow_copy_constructible::value, ""); #endif C c(a); LIBCPP_ASSERT(c.__invariants()); @@ -71,8 +72,11 @@ (test_allocator(5)); } { - std::vector > v; - assert(v.empty()); + + typedef StackAllocTraits TraitsT; + typedef TraitsT::AllocT AllocT; + TraitsT T; + test1 >(T.alloc); } #if TEST_STD_VER >= 11 { Index: test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp =================================================================== --- test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp +++ test/std/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp @@ -16,7 +16,6 @@ #include "test_macros.h" #include "test_iterators.h" -#include "../../../stack_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -32,6 +31,7 @@ assert(*i == *first); } + int main() { int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0}; @@ -42,11 +42,6 @@ test >(random_access_iterator(a), random_access_iterator(an)); test >(a, an); - test > >(input_iterator(a), input_iterator(an)); - test > >(forward_iterator(a), forward_iterator(an)); - test > >(bidirectional_iterator(a), bidirectional_iterator(an)); - test > >(random_access_iterator(a), random_access_iterator(an)); - test > >(a, an); #if TEST_STD_VER >= 11 test> >(input_iterator(a), input_iterator(an)); test> >(forward_iterator(a), forward_iterator(an)); Index: test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp =================================================================== --- test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp +++ test/std/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp @@ -17,7 +17,7 @@ #include "test_macros.h" #include "test_iterators.h" -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -47,6 +47,7 @@ #endif + int main() { { @@ -59,6 +60,21 @@ test >(random_access_iterator(a), random_access_iterator(an), alloc); test >(a, an, alloc); } + { + int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0}; + int* an = a + sizeof(a)/sizeof(a[0]); + typedef StackAllocTraits Traits; + typedef Traits::AllocT AllocT; + Traits T; + AllocT& A = T.alloc; + test >(forward_iterator(a), forward_iterator(an), A); + A.reset(); + test >(bidirectional_iterator(a), bidirectional_iterator(an), A); + A.reset(); + test >(random_access_iterator(a), random_access_iterator(an), A); + A.reset(); + test >(a, an, A); + } #if TEST_STD_VER >= 11 { int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0}; Index: test/std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp =================================================================== --- test/std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp +++ test/std/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp @@ -15,7 +15,6 @@ #include #include "test_macros.h" -#include "../../../stack_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -34,7 +33,6 @@ int main() { test >(50, 3); - test > >(50, 5); #if TEST_STD_VER >= 11 test> >(50, 3); #endif Index: test/std/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp =================================================================== --- test/std/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp +++ test/std/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp @@ -15,6 +15,7 @@ #include #include "test_macros.h" +#include "stack_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -35,6 +36,12 @@ int main() { test >(50, 3, std::allocator()); + { + typedef StackAllocTraits Traits; + typedef Traits::AllocT AllocT; + Traits T; + test >(50, 5, T.alloc); + } #if TEST_STD_VER >= 11 test> >(50, 3, min_allocator()); #endif Index: test/std/containers/sequences/vector/vector.modifiers/emplace.pass.cpp =================================================================== --- test/std/containers/sequences/vector/vector.modifiers/emplace.pass.cpp +++ test/std/containers/sequences/vector/vector.modifiers/emplace.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // // template iterator emplace(const_iterator pos, Args&&... args); @@ -17,11 +19,10 @@ #include #include -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "min_allocator.h" #include "asan_testing.h" -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES class A { @@ -55,11 +56,8 @@ double getd() const {return d_;} }; -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - int main() { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { std::vector c; std::vector::iterator i = c.emplace(c.cbegin(), 2, 3.5); @@ -88,8 +86,10 @@ assert(is_contiguous_container_asan_correct(c)); } { - std::vector > c; - std::vector >::iterator i = c.emplace(c.cbegin(), 2, 3.5); + typedef StackAllocTraits Traits; + Traits T; + std::vector c(T.alloc); + std::vector::iterator i = c.emplace(c.cbegin(), 2, 3.5); assert(i == c.begin()); assert(c.size() == 1); assert(c.front().geti() == 2); @@ -122,7 +122,6 @@ assert(false); } #endif -#if TEST_STD_VER >= 11 { std::vector> c; std::vector>::iterator i = c.emplace(c.cbegin(), 2, 3.5); @@ -155,6 +154,5 @@ assert(false); } #endif -#endif -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + } Index: test/std/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp =================================================================== --- test/std/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp +++ test/std/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp @@ -15,7 +15,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "min_allocator.h" #include "test_allocator.h" #include "asan_testing.h" @@ -72,7 +72,9 @@ assert(is_contiguous_container_asan_correct(c)); } { - std::vector > c; + typedef StackAllocTraits Traits; + Traits T; + std::vector c(T.alloc); A& r1 = c.emplace_back(2, 3.5); assert(c.size() == 1); assert(&r1 == &c.back()); Index: test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp =================================================================== --- test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp +++ test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp @@ -18,7 +18,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "test_iterators.h" #include "min_allocator.h" #include "asan_testing.h" @@ -96,7 +96,10 @@ assert(v[j] == 0); } { - std::vector > v(100); + typedef StackAllocTraits Traits; + typedef Traits::AllocT AllocT; + Traits T; + std::vector v(100, 0, T.alloc); int a[] = {1, 2, 3, 4, 5}; const int N = sizeof(a)/sizeof(a[0]); std::vector::iterator i = v.insert(v.cbegin() + 10, input_iterator(a), @@ -113,7 +116,10 @@ assert(v[j] == 0); } { - std::vector > v(100); + typedef StackAllocTraits Traits; + typedef Traits::AllocT AllocT; + Traits T; + std::vector v(100, 0, T.alloc); int a[] = {1, 2, 3, 4, 5}; const int N = sizeof(a)/sizeof(a[0]); std::vector::iterator i = v.insert(v.cbegin() + 10, forward_iterator(a), Index: test/std/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp =================================================================== --- test/std/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp +++ test/std/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // // iterator insert(const_iterator position, value_type&& x); @@ -17,14 +19,13 @@ #include #include -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "MoveOnly.h" #include "min_allocator.h" #include "asan_testing.h" int main() { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { std::vector v(100); std::vector::iterator i = v.insert(v.cbegin() + 10, MoveOnly(3)); @@ -39,8 +40,12 @@ assert(v[j] == MoveOnly()); } { - std::vector > v(100); - std::vector >::iterator i = v.insert(v.cbegin() + 10, MoveOnly(3)); + typedef StackAllocTraits Traits; + typedef Traits::AllocT AllocT; + Traits T; + std::vector v(T.alloc); + v.resize(100); + std::vector::iterator i = v.insert(v.cbegin() + 10, MoveOnly(3)); assert(v.size() == 101); assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); @@ -59,7 +64,6 @@ assert(false); } #endif -#if TEST_STD_VER >= 11 { std::vector> v(100); std::vector>::iterator i = v.insert(v.cbegin() + 10, MoveOnly(3)); @@ -81,6 +85,4 @@ assert(false); } #endif -#endif -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } Index: test/std/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp =================================================================== --- test/std/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp +++ test/std/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp @@ -17,7 +17,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -70,8 +70,11 @@ assert(v[j] == 0); } { - std::vector > v(100); - std::vector >::iterator i = v.insert(v.cbegin() + 10, 5, 1); + typedef StackAllocTraits Traits; + typedef Traits::AllocT AllocT; + Traits T; + std::vector v(100, 0, T.alloc); + std::vector::iterator i = v.insert(v.cbegin() + 10, 5, 1); assert(v.size() == 105); assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); Index: test/std/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp =================================================================== --- test/std/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp +++ test/std/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp @@ -17,7 +17,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -68,8 +68,11 @@ assert(v[j] == 0); } { - std::vector > v(100); - std::vector >::iterator i = v.insert(v.cbegin() + 10, 1); + typedef StackAllocTraits Traits; + typedef Traits::AllocT AllocT; + Traits T; + std::vector v(100, 0, T.alloc); + std::vector::iterator i = v.insert(v.cbegin() + 10, 1); assert(v.size() == 101); assert(is_contiguous_container_asan_correct(v)); assert(i == v.begin() + 10); Index: test/std/containers/sequences/vector/vector.modifiers/pop_back.pass.cpp =================================================================== --- test/std/containers/sequences/vector/vector.modifiers/pop_back.pass.cpp +++ test/std/containers/sequences/vector/vector.modifiers/pop_back.pass.cpp @@ -17,7 +17,6 @@ #include #include -#include "../../../stack_allocator.h" #include "min_allocator.h" #if _LIBCPP_DEBUG >= 1 Index: test/std/containers/sequences/vector/vector.modifiers/push_back.pass.cpp =================================================================== --- test/std/containers/sequences/vector/vector.modifiers/push_back.pass.cpp +++ test/std/containers/sequences/vector/vector.modifiers/push_back.pass.cpp @@ -13,7 +13,7 @@ #include #include -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "min_allocator.h" #include "asan_testing.h" @@ -48,7 +48,9 @@ assert(c[j] == j); } { - std::vector > c; + typedef StackAllocTraits Traits; + Traits T; + std::vector c(T.alloc); c.push_back(0); assert(c.size() == 1); assert(is_contiguous_container_asan_correct(c)); Index: test/std/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp =================================================================== --- test/std/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp +++ test/std/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // // void push_back(value_type&& x); @@ -14,13 +16,12 @@ #include #include #include "MoveOnly.h" -#include "../../../stack_allocator.h" +#include "stack_allocator.h" #include "min_allocator.h" #include "asan_testing.h" int main() { -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES { std::vector c; c.push_back(MoveOnly(0)); @@ -50,7 +51,9 @@ assert(c[j] == MoveOnly(j)); } { - std::vector > c; + typedef StackAllocTraits Traits; + Traits T; + std::vector c(T.alloc); c.push_back(MoveOnly(0)); assert(c.size() == 1); assert(is_contiguous_container_asan_correct(c)); @@ -77,7 +80,6 @@ for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); } -#if TEST_STD_VER >= 11 { std::vector> c; c.push_back(MoveOnly(0)); @@ -106,6 +108,4 @@ for (int j = 0; j < c.size(); ++j) assert(c[j] == MoveOnly(j)); } -#endif -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } Index: test/std/containers/stack_allocator.h =================================================================== --- test/std/containers/stack_allocator.h +++ /dev/null @@ -1,66 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef STACK_ALLOCATOR_H -#define STACK_ALLOCATOR_H - -#include -#include - -template -class stack_allocator -{ - char buf_[sizeof(T)*N]; - char* ptr_; -public: - typedef T value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - template struct rebind {typedef stack_allocator other;}; - - stack_allocator() : ptr_(buf_) {} - -private: - stack_allocator(const stack_allocator&);// = delete; - stack_allocator& operator=(const stack_allocator&);// = delete; - -public: - pointer allocate(size_type n, const void* = 0) - { - if (n > N - (ptr_ - buf_) / sizeof(value_type)) { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw std::bad_alloc(); -#else - std::terminate(); -#endif - } - pointer r = (T*)ptr_; - ptr_ += n * sizeof(T); - return r; - } - void deallocate(pointer p, size_type n) - { - if ((char*)(p + n) == ptr_) - ptr_ = (char*)p; - } - - size_type max_size() const {return N;} -}; - -template -inline -void -swap(stack_allocator& x, stack_allocator& y) {} - -#endif // STACK_ALLOCATOR_H Index: test/support/stack_allocator.h =================================================================== --- /dev/null +++ test/support/stack_allocator.h @@ -0,0 +1,186 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef STACK_ALLOCATOR_H +#define STACK_ALLOCATOR_H + +#include +#include +#include +#include +#include + +#include "test_macros.h" +template class stack_allocator; + +const std::size_t MaxAlign = TEST_ALIGNOF(std::max_align_t); + +template +struct AlignedAllocSize : std::integral_constant { +}; + +inline std::size_t alignedAllocSize(std::size_t S, std::size_t A = MaxAlign) { + return (S + A - 1) & ~(A - 1); +} + +struct stack_buffer_base { + const std::size_t size; + char* const buff; + char* const buff_end; + void* ptr; + void* last_alloc; + std::size_t remaining_size; + + stack_buffer_base(char* buff_imp, std::size_t buff_size) + : size(buff_size), buff(buff_imp), buff_end(buff + size), ptr(buff), + last_alloc(nullptr), remaining_size(buff_size) + { + assert((buff_size % MaxAlign) == 0); + } + + void reset() { + ptr = buff; + last_alloc = nullptr; + remaining_size = size; + } + + template + void* allocate(std::size_t S) { + const std::size_t AllocSize = alignedAllocSize(sizeof(T)) * S; + if (std::align(MaxAlign, AllocSize, ptr, remaining_size)) { + void* ret = ptr; + ptr = static_cast(ptr) + AllocSize; + remaining_size -= AllocSize; + last_alloc = ret; + return ret; + } + return nullptr; + } + + void deallocate(void* P, std::size_t S = 1) { + if (P == last_alloc) { + ptr = last_alloc; + last_alloc = nullptr; + remaining_size = buff_end - static_cast(ptr); + } + } + + template + std::size_t max_size() const { + return size / alignedAllocSize(sizeof(T)); + } + +private: + stack_buffer_base(stack_buffer_base const&); + stack_buffer_base& operator=(stack_buffer_base const&); +}; + +template +struct stack_buffer : stack_buffer_base { + static const std::size_t alloc_size = AlignedAllocSize::value; + static const std::size_t NumBytes = alloc_size * N; + +public: + typedef stack_allocator allocator_type; + + stack_buffer() : stack_buffer_base(buff_imp, NumBytes) {} + + allocator_type makeAlloc() { + allocator_type alloc(this); + return alloc; + } +private: + TEST_ALIGNAS(MaxAlign) char buff_imp[NumBytes]; + + stack_buffer(stack_buffer const&); + stack_buffer& operator=(stack_buffer const&); +}; + +template +class stack_allocator +{ + static_assert(AlignedAllocSize::value <= NumBytesP, ""); + static const std::size_t NumBytes = NumBytesP; + template friend struct stack_allocator; + stack_buffer_base* handle; + + stack_allocator& operator=(const stack_allocator&); + +public: + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + template struct rebind { + typedef stack_allocator other; + }; + + template + explicit stack_allocator(stack_buffer& buff) : handle(&buff) { + static_assert((stack_buffer::NumBytes == NumBytes), ""); + } + + stack_allocator(const stack_allocator& OA) : handle(OA.handle) {} + + template + explicit stack_allocator(stack_allocator const& OAlloc) + : handle(OAlloc.handle) + { + } + + stack_buffer_base* getBase() const { return handle; } + void reset() { getBase()->reset(); } +public: + pointer allocate(size_type n) + { + void* ptr = handle->allocate(n); + if (!ptr) { +#ifndef _LIBCPP_NO_EXCEPTIONS + throw std::bad_alloc(); +#else + std::terminate(); +#endif + } + return static_cast(ptr); + } + + void deallocate(pointer p, size_type n) + { + handle->deallocate(p, n); + } + + size_type max_size() const {return NumBytes / alignedAllocSize(sizeof(T));} +}; + +template +inline bool operator==(stack_allocator const& LHS, stack_allocator const& RHS) { + return LHS.getBase() == RHS.getBase(); +} + +template +inline bool operator!=(stack_allocator const& LHS, stack_allocator const& RHS) { + return LHS.getBase() != RHS.getBase(); +} + + +template +struct StackAllocTraits { + typedef stack_buffer BuffT; + typedef typename BuffT::allocator_type AllocT; + + StackAllocTraits() : buff(), alloc(buff) {} + BuffT buff; + AllocT alloc; +}; + +#endif // STACK_ALLOCATOR_H Index: test/support/test.support/test_stack_allocator.pass.cpp =================================================================== --- /dev/null +++ test/support/test.support/test_stack_allocator.pass.cpp @@ -0,0 +1,87 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// "support/stack_allocator.h" + +#include "stack_allocator.h" + +#include "test_macros.h" + +template +struct TEST_ALIGNAS(A) AlignedType { + char buff[S]; +}; + +static const size_t MA = TEST_ALIGNOF(std::max_align_t); + +typedef AlignedType<1, 1> S1; +typedef AlignedType<2, 2> S2; +typedef AlignedType<17, 1> S17; +typedef AlignedType SPtr; +typedef AlignedType SMA; +typedef AlignedType SMA2; + +template +void test_basic() { + typedef stack_buffer BuffT; + typedef typename BuffT::allocator_type AllocT; + typedef std::allocator_traits ATraits; + BuffT SB; + AllocT SA(SB); + uintptr_t lastVal = 0; + for (size_t i=0; i < SA.max_size(); ++i) { + T* ptr = ATraits::allocate(SA, 1); + assert(ptr); + const uintptr_t PVal = reinterpret_cast(ptr); + assert(PVal % TEST_ALIGNOF(std::max_align_t) == 0); + assert(PVal >= (lastVal + sizeof(T))); + lastVal = PVal; + } +#ifndef TEST_HAS_NO_EXCEPTIONS + try { + ATraits::allocate(SA, 1); + assert(false); + } catch (std::bad_alloc const&) {} +#endif +} + +template +void test_rebind() { + typedef stack_buffer BuffT; + typedef typename BuffT::allocator_type AllocT; + typedef std::allocator_traits ATraits; + BuffT SB, SB2; + AllocT SA(SB); + AllocT SA2(SB2); + typedef typename AllocT::template rebind::other OAllocT; + static_assert(std::is_same< + typename ATraits::template rebind_alloc, OAllocT>::value, ""); + { + OAllocT SO(SA); + assert(SO == SA); + assert(SO != SA2); + OAllocT SO2(SA2); + assert(SO2 == SA2); + assert(SO2 != SA); + } + { + typedef typename OAllocT::template rebind::other BackAllocT; + static_assert((std::is_same::value), ""); + } +}; + +int main() { + test_basic(); + test_basic(); + test_basic(); + test_basic(); + test_basic(); + test_basic(); + test_rebind(); +} Index: test/support/test_macros.h =================================================================== --- test/support/test_macros.h +++ test/support/test_macros.h @@ -120,6 +120,25 @@ #define TEST_NORETURN [[noreturn]] #endif +#if TEST_STD_VER < 11 +#ifdef __clang__ +#define TEST_ALIGNOF(X) __alignof(X) +#define TEST_ALIGNAS(X) __attribute__((__aligned__(X))) +#elif defined(__GNUC__) +#define TEST_ALIGNOF(X) __alignof(X) +#define TEST_ALIGNAS(X) __attribute__((__aligned__(X))) +#elif defined(_MSC_VER) +#define TEST_ALIGNOF(X) __alignof__(X) +#define TEST_ALIGNAS(X) __declspec(align(X)) +#else +#error Unsupported compiler +#endif +#else // TEST_STD_VER >= 11 +#define TEST_ALIGNOF(X) alignof(X) +#define TEST_ALIGNAS(X) alignas(X) +#endif + + /* Macros for testing libc++ specific behavior and extensions */ #if defined(_LIBCPP_VERSION) #define LIBCPP_ASSERT(...) assert(__VA_ARGS__)