mirror of
https://github.com/intel/llvm.git
synced 2026-01-23 07:58:23 +08:00
[libc++] Add tests to make sure that stable algorithms work without memory available
Reviewed By: #libc, ldionne Spies: power-llvm-team, ldionne, libcxx-commits, arichardson, mstorsjo Differential Revision: https://reviews.llvm.org/D152939
This commit is contained in:
@@ -122,7 +122,10 @@ _LIBCPP_HIDE_FROM_ABI _ForwardIterator
|
||||
__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 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Pred
|
||||
}
|
||||
// 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<value_type*, ptrdiff_t> __p(0, 0);
|
||||
unique_ptr<value_type, __return_temporary_buffer> __h;
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "count_new.h"
|
||||
#include "test_iterators.h"
|
||||
#include "test_macros.h"
|
||||
|
||||
struct is_odd
|
||||
{
|
||||
@@ -36,7 +38,7 @@ template <class Iter>
|
||||
void
|
||||
test()
|
||||
{
|
||||
{ // check mixed
|
||||
{ // check mixed
|
||||
typedef std::pair<int,int> P;
|
||||
P array[] =
|
||||
{
|
||||
@@ -64,8 +66,8 @@ test()
|
||||
assert(array[7] == P(2, 2));
|
||||
assert(array[8] == P(4, 1));
|
||||
assert(array[9] == P(4, 2));
|
||||
}
|
||||
{
|
||||
}
|
||||
{
|
||||
typedef std::pair<int,int> P;
|
||||
P array[] =
|
||||
{
|
||||
@@ -104,8 +106,8 @@ test()
|
||||
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<int,int> P;
|
||||
P array[] =
|
||||
{
|
||||
@@ -133,8 +135,8 @@ test()
|
||||
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<int,int> P;
|
||||
P array[] =
|
||||
{
|
||||
@@ -162,8 +164,8 @@ test()
|
||||
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<int,int> P;
|
||||
P array[] =
|
||||
{
|
||||
@@ -191,8 +193,8 @@ test()
|
||||
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<int,int> P;
|
||||
P array[] =
|
||||
{
|
||||
@@ -220,8 +222,8 @@ test()
|
||||
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<int,int> P;
|
||||
P array[] =
|
||||
{
|
||||
@@ -249,8 +251,8 @@ test()
|
||||
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<int,int> P;
|
||||
P array[] =
|
||||
{
|
||||
@@ -278,7 +280,24 @@ test()
|
||||
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<int> 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<int*>(vec.data()), forward_iterator<int*>(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
|
||||
|
||||
@@ -14,12 +14,16 @@
|
||||
// void
|
||||
// inplace_merge(Iter first, Iter middle, Iter last);
|
||||
|
||||
#include <algorithm>
|
||||
#include <random>
|
||||
#include <cassert>
|
||||
// XFAIL: LIBCXX-AIX-FIXME
|
||||
|
||||
#include "test_macros.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
#include "count_new.h"
|
||||
#include "test_iterators.h"
|
||||
#include "test_macros.h"
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
struct S {
|
||||
@@ -107,7 +111,16 @@ int main(int, char**)
|
||||
test<bidirectional_iterator<S*> >();
|
||||
test<random_access_iterator<S*> >();
|
||||
test<S*>();
|
||||
#endif // TEST_STD_VER >= 11
|
||||
#endif
|
||||
|
||||
#if TEST_STD_VER >= 11 && !defined(TEST_HAS_NO_EXCEPTIONS)
|
||||
{
|
||||
std::vector<int> 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;
|
||||
}
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
// stable_sort(Iter first, Iter last);
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <iterator>
|
||||
#include <random>
|
||||
#include <cassert>
|
||||
|
||||
#include "count_new.h"
|
||||
#include "test_macros.h"
|
||||
|
||||
std::mt19937 randomness;
|
||||
@@ -155,5 +156,13 @@ int main(int, char**)
|
||||
test_larger_sorts(1000);
|
||||
test_larger_sorts(1009);
|
||||
|
||||
#if !defined(TEST_HAS_NO_EXCEPTIONS)
|
||||
{ // check that the algorithm works without memory
|
||||
std::vector<int> vec(150, 3);
|
||||
getGlobalMemCounter()->throw_after = 0;
|
||||
std::stable_sort(vec.begin(), vec.end());
|
||||
}
|
||||
#endif // !defined(TEST_HAS_NO_EXCEPTIONS)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -9,9 +9,10 @@
|
||||
#ifndef COUNT_NEW_H
|
||||
#define COUNT_NEW_H
|
||||
|
||||
# include <cstdlib>
|
||||
# include <cassert>
|
||||
# include <new>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
|
||||
#include "test_macros.h"
|
||||
@@ -78,7 +79,6 @@ public:
|
||||
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 @@ public:
|
||||
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 delete[](void* p) TEST_NOEXCEPT
|
||||
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<std::size_t>(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();
|
||||
|
||||
Reference in New Issue
Block a user