blob: bb5432d89325e0f7f3a7f83bb96ab39468f80243 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fbl/algorithm.h>
#include <fbl/alloc_checker.h>
#include <fbl/array.h>
#include <zxtest/zxtest.h>
namespace {
class DestructorSignaler {
public:
DestructorSignaler() : array(nullptr), result(nullptr) {}
~DestructorSignaler() {
if (array && result)
*result = array->data();
}
fbl::Array<DestructorSignaler>* array;
DestructorSignaler** result;
};
TEST(ArrayTest, Destructor) {
DestructorSignaler bogus;
DestructorSignaler* result = &bogus;
fbl::AllocChecker ac;
DestructorSignaler* signalers = new (&ac) DestructorSignaler[2];
EXPECT_TRUE(ac.check());
{
fbl::Array<DestructorSignaler> array(signalers, 2);
array[0].array = &array;
array[0].result = &result;
}
EXPECT_FALSE(result == &bogus);
EXPECT_TRUE(result == nullptr);
}
TEST(ArrayTest, MoveToConstCtor) {
constexpr size_t kSize = 10;
fbl::Array<uint32_t> array(new uint32_t[kSize], kSize);
for (uint32_t i = 0; i < kSize; ++i) {
array[i] = i;
}
uint32_t* array_ptr = array.data();
fbl::Array<const uint32_t> const_array(std::move(array));
EXPECT_NULL(array.data());
EXPECT_EQ(array.size(), 0);
EXPECT_EQ(const_array.data(), array_ptr);
EXPECT_EQ(const_array.size(), kSize);
for (size_t i = 0; i < kSize; ++i) {
EXPECT_EQ(const_array[i], i);
}
}
TEST(ArrayTest, MoveToConstAssignment) {
constexpr size_t kSize = 10;
fbl::Array<uint32_t> array(new uint32_t[kSize], kSize);
for (uint32_t i = 0; i < kSize; ++i) {
array[i] = i;
}
uint32_t* array_ptr = array.data();
fbl::Array<const uint32_t> const_array;
const_array = std::move(array);
EXPECT_NULL(array.data());
EXPECT_EQ(array.size(), 0);
EXPECT_EQ(const_array.data(), array_ptr);
EXPECT_EQ(const_array.size(), kSize);
for (size_t i = 0; i < kSize; ++i) {
EXPECT_EQ(const_array[i], i);
}
}
TEST(ArrayTest, MakeArraySimple) {
constexpr size_t kSize = 10;
fbl::Array<uint32_t> array = fbl::MakeArray<uint32_t>(kSize);
// Ensure the correct size array was made.
EXPECT_EQ(array.size(), kSize);
// Ensure the underlying array was created and can be written to.
EXPECT_TRUE(array.data() != nullptr);
for (uint32_t i = 0; i < kSize; ++i) {
array[i] = i;
}
}
TEST(ArrayTest, MakeArrayAllocChecker) {
constexpr size_t kSize = 10;
fbl::AllocChecker ac;
fbl::Array<uint32_t> array = fbl::MakeArray<uint32_t>(&ac, kSize);
EXPECT_TRUE(ac.check());
EXPECT_EQ(array.size(), kSize);
EXPECT_TRUE(array.data() != nullptr);
}
// An object with an overloaded new operator that will always fail.
struct CannotAllocate {
static void* operator new[](std::size_t sz, fbl::AllocChecker* ac) noexcept {
ac->arm(sz, false);
return nullptr;
}
};
TEST(ArrayTest, MakeArrayFailingAllocChecker) {
// Attempt to create an array of CannotAllocate objects.
fbl::AllocChecker ac;
fbl::Array<CannotAllocate> array = fbl::MakeArray<CannotAllocate>(&ac, 10);
// Expect it to have failed.
EXPECT_FALSE(ac.check());
EXPECT_EQ(array.size(), 0);
EXPECT_EQ(array.data(), nullptr);
}
TEST(ArrayTest, MakeArrayEmpty) {
fbl::Array<uint32_t> array = fbl::MakeArray<uint32_t>(0);
EXPECT_EQ(array.size(), 0);
}
TEST(ArrayTest, MakeArrayDefaultConstructed) {
constexpr size_t kSize = 10;
struct MyInt {
int value = 42;
};
fbl::Array<MyInt> array = fbl::MakeArray<MyInt>(kSize);
EXPECT_EQ(array.size(), kSize);
for (size_t i = 0; i < kSize; i++) {
EXPECT_EQ(array[i].value, 42);
}
}
} // namespace