diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h --- a/libcxx/include/__algorithm/stable_partition.h +++ b/libcxx/include/__algorithm/stable_partition.h @@ -122,7 +122,10 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag) { - const unsigned __alloc_limit = 3; // might want to make this a function of trivial assignment + typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + + const difference_type __alloc_limit = 3; // might want to make this a function of trivial assignment // Either prove all true and return __first or point to first false while (true) { @@ -134,8 +137,6 @@ } // We now have a reduced range [__first, __last) // *__first is known to be false - typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; - typedef typename iterator_traits<_ForwardIterator>::value_type value_type; difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last); pair __p(0, 0); unique_ptr __h; diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/stable_partition.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/stable_partition.pass.cpp --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/stable_partition.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/stable_partition.pass.cpp @@ -17,9 +17,11 @@ #include #include #include +#include -#include "test_macros.h" +#include "count_new.h" #include "test_iterators.h" +#include "test_macros.h" struct is_odd { @@ -36,7 +38,7 @@ void test() { - { // check mixed + { // check mixed typedef std::pair P; P array[] = { @@ -64,8 +66,8 @@ assert(array[7] == P(2, 2)); assert(array[8] == P(4, 1)); assert(array[9] == P(4, 2)); - } - { + } + { typedef std::pair P; P array[] = { @@ -104,8 +106,8 @@ r = std::stable_partition(Iter(array+4), Iter(array+5), odd_first()); assert(base(r) == array+4); assert(array[4] == P(0, 1)); - } - { // check all false + } + { // check all false typedef std::pair P; P array[] = { @@ -133,8 +135,8 @@ assert(array[7] == P(6, 2)); assert(array[8] == P(8, 1)); assert(array[9] == P(8, 2)); - } - { // check all true + } + { // check all true typedef std::pair P; P array[] = { @@ -162,8 +164,8 @@ assert(array[7] == P(7, 2)); assert(array[8] == P(9, 1)); assert(array[9] == P(9, 2)); - } - { // check all false but first true + } + { // check all false but first true typedef std::pair P; P array[] = { @@ -191,8 +193,8 @@ assert(array[7] == P(6, 2)); assert(array[8] == P(8, 1)); assert(array[9] == P(8, 2)); - } - { // check all false but last true + } + { // check all false but last true typedef std::pair P; P array[] = { @@ -220,8 +222,8 @@ assert(array[7] == P(6, 1)); assert(array[8] == P(6, 2)); assert(array[9] == P(8, 1)); - } - { // check all true but first false + } + { // check all true but first false typedef std::pair P; P array[] = { @@ -249,8 +251,8 @@ assert(array[7] == P(9, 1)); assert(array[8] == P(9, 2)); assert(array[9] == P(0, 1)); - } - { // check all true but last false + } + { // check all true but last false typedef std::pair P; P array[] = { @@ -278,7 +280,24 @@ assert(array[7] == P(7, 2)); assert(array[8] == P(9, 1)); assert(array[9] == P(0, 2)); - } + } +#if TEST_STD_VER >= 11 && !defined(TEST_HAS_NO_EXCEPTIONS) + { // check that the algorithm still works when no memory is available + std::vector vec(150, 3); + vec[5] = 6; + getGlobalMemCounter()->throw_after = 0; + std::stable_partition(vec.begin(), vec.end(), [](int i) { return i < 5; }); + assert(std::is_partitioned(vec.begin(), vec.end(), [](int i) { return i < 5; })); + vec[5] = 6; + getGlobalMemCounter()->throw_after = 0; + std::stable_partition( + forward_iterator(vec.data()), forward_iterator(vec.data() + vec.size()), [](int i) { + return i < 5; + }); + assert(std::is_partitioned(vec.begin(), vec.end(), [](int i) { return i < 5; })); + getGlobalMemCounter()->reset(); + } +#endif // TEST_STD_VER >= 11 && !defined(TEST_HAS_NO_EXCEPTIONS) } #if TEST_STD_VER >= 11 diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp --- a/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp +++ b/libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp @@ -14,12 +14,16 @@ // void // inplace_merge(Iter first, Iter middle, Iter last); +// XFAIL: LIBCXX-AIX-FIXME + #include -#include #include +#include +#include -#include "test_macros.h" +#include "count_new.h" #include "test_iterators.h" +#include "test_macros.h" #if TEST_STD_VER >= 11 struct S { @@ -107,7 +111,16 @@ test >(); test >(); test(); -#endif // TEST_STD_VER >= 11 +#endif + +#if TEST_STD_VER >= 11 && !defined(TEST_HAS_NO_EXCEPTIONS) + { + std::vector vec(150, 3); + getGlobalMemCounter()->throw_after = 0; + std::inplace_merge(vec.begin(), vec.begin() + 100, vec.end()); + assert(std::all_of(vec.begin(), vec.end(), [](int i) { return i == 3; })); + } +#endif // TEST_STD_VER >= 11 && !defined(TEST_HAS_NO_EXCEPTIONS) return 0; } diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp --- a/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp +++ b/libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp @@ -15,10 +15,11 @@ // stable_sort(Iter first, Iter last); #include +#include #include #include -#include +#include "count_new.h" #include "test_macros.h" std::mt19937 randomness; @@ -155,5 +156,13 @@ test_larger_sorts(1000); test_larger_sorts(1009); +#if !defined(TEST_HAS_NO_EXCEPTIONS) + { // check that the algorithm works without memory + std::vector vec(150, 3); + getGlobalMemCounter()->throw_after = 0; + std::stable_sort(vec.begin(), vec.end()); + } +#endif // !defined(TEST_HAS_NO_EXCEPTIONS) + return 0; } diff --git a/libcxx/test/support/count_new.h b/libcxx/test/support/count_new.h --- a/libcxx/test/support/count_new.h +++ b/libcxx/test/support/count_new.h @@ -9,9 +9,10 @@ #ifndef COUNT_NEW_H #define COUNT_NEW_H -# include -# include -# include +#include +#include +#include +#include #include #include "test_macros.h" @@ -78,7 +79,6 @@ void newCalled(std::size_t s) { assert(disable_allocations == false); - assert(s); if (throw_after == 0) { throw_after = never_throw_value; detail::throw_bad_alloc_helper(); @@ -112,7 +112,6 @@ void newArrayCalled(std::size_t s) { assert(disable_allocations == false); - assert(s); if (throw_after == 0) { throw_after = never_throw_value; detail::throw_bad_alloc_helper(); @@ -410,11 +409,11 @@ void* operator new(std::size_t s, std::align_val_t av) TEST_THROW_SPEC(std::bad_alloc) { const std::size_t a = static_cast(av); getGlobalMemCounter()->alignedNewCalled(s, a); - void *ret; + void *ret = nullptr; #ifdef USE_ALIGNED_ALLOC ret = _aligned_malloc(s, a); #else - posix_memalign(&ret, a, s); + assert(posix_memalign(&ret, std::max(a, sizeof(void*)), s) != EINVAL); #endif if (ret == nullptr) detail::throw_bad_alloc_helper();