blob: 546ef377a5e57478816643a2593eea7fee878337 [file] [log] [blame]
// Copyright 2024 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "core/fxcrt/fixed_size_data_vector.h"
#include <limits>
#include <numeric>
#include <utility>
#include "core/fxcrt/span.h"
#include "core/fxcrt/span_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
TEST(FixedSizedDataVector, NoData) {
FixedSizeDataVector<int> vec;
EXPECT_EQ(0u, vec.size());
EXPECT_TRUE(vec.empty());
EXPECT_TRUE(vec.span().empty());
}
TEST(FixedSizeDataVector, UninitData) {
auto vec = FixedSizeDataVector<int>::Uninit(4);
EXPECT_FALSE(vec.empty());
ASSERT_EQ(4u, vec.size());
ASSERT_EQ(4u, vec.span().size());
constexpr int kData[] = {1, 2, 3, 4};
fxcrt::spancpy(vec.span(), pdfium::make_span(kData));
EXPECT_THAT(vec.span(), testing::ElementsAre(1, 2, 3, 4));
}
TEST(FixedSizeDataVector, ZeroedData) {
auto vec = FixedSizeDataVector<int>::Zeroed(4);
EXPECT_FALSE(vec.empty());
EXPECT_EQ(4u, vec.size());
EXPECT_EQ(4u, vec.span().size());
EXPECT_THAT(vec.span(), testing::ElementsAre(0, 0, 0, 0));
constexpr int kData[] = {1, 2, 3, 4};
fxcrt::spancpy(vec.span(), pdfium::make_span(kData));
EXPECT_THAT(vec.span(), testing::ElementsAre(1, 2, 3, 4));
}
TEST(FixedSizeDataVector, TryZeroedData) {
auto vec = FixedSizeDataVector<int>::TryZeroed(4);
EXPECT_FALSE(vec.empty());
ASSERT_EQ(4u, vec.size());
ASSERT_EQ(4u, vec.span().size());
EXPECT_THAT(vec.span(), testing::ElementsAre(0, 0, 0, 0));
constexpr int kData[] = {1, 2, 3, 4};
fxcrt::spancpy(vec.span(), pdfium::make_span(kData));
EXPECT_THAT(vec.span(), testing::ElementsAre(1, 2, 3, 4));
}
TEST(FixedSizeDataVector, TryAllocFailure) {
constexpr size_t kCloseToMaxByteAlloc =
std::numeric_limits<size_t>::max() - 100;
auto vec = FixedSizeDataVector<int>::TryZeroed(kCloseToMaxByteAlloc);
EXPECT_TRUE(vec.empty());
EXPECT_EQ(0u, vec.size());
EXPECT_EQ(0u, vec.span().size());
}
TEST(FixedSizeDataVector, MoveConstruct) {
constexpr int kData[] = {1, 2, 3, 4};
auto vec = FixedSizeDataVector<int>::Uninit(4);
ASSERT_EQ(4u, vec.span().size());
fxcrt::spancpy(vec.span(), pdfium::make_span(kData));
const int* const original_data_ptr = vec.span().data();
FixedSizeDataVector<int> vec2(std::move(vec));
EXPECT_FALSE(vec2.empty());
EXPECT_EQ(4u, vec2.size());
EXPECT_EQ(4u, vec2.span().size());
EXPECT_THAT(vec2.span(), testing::ElementsAre(1, 2, 3, 4));
EXPECT_EQ(vec2.span().data(), original_data_ptr);
EXPECT_EQ(0u, vec.size());
EXPECT_TRUE(vec.empty());
EXPECT_TRUE(vec.span().empty());
vec = std::move(vec2);
EXPECT_FALSE(vec.empty());
EXPECT_EQ(4u, vec.size());
EXPECT_EQ(4u, vec.span().size());
EXPECT_THAT(vec.span(), testing::ElementsAre(1, 2, 3, 4));
EXPECT_EQ(vec.span().data(), original_data_ptr);
EXPECT_EQ(0u, vec2.size());
EXPECT_TRUE(vec2.empty());
EXPECT_TRUE(vec2.span().empty());
}
TEST(FixedSizeDataVector, MoveAssign) {
auto vec = FixedSizeDataVector<int>();
auto vec2 = FixedSizeDataVector<int>::Zeroed(4);
constexpr int kData[] = {1, 2, 3, 4};
ASSERT_EQ(4u, vec2.span().size());
fxcrt::spancpy(vec2.span(), pdfium::make_span(kData));
vec = std::move(vec2);
EXPECT_TRUE(vec2.empty());
EXPECT_EQ(4u, vec.span().size());
EXPECT_THAT(vec.span(), testing::ElementsAre(1, 2, 3, 4));
}
TEST(FixedSizeDataVector, Subspan) {
auto vec = FixedSizeDataVector<uint32_t>::Uninit(4);
std::iota(vec.span().begin(), vec.span().end(), 0u);
pdfium::span<uint32_t> empty = vec.subspan(2, 0);
EXPECT_TRUE(empty.empty());
pdfium::span<uint32_t> first = vec.subspan(0, 1);
ASSERT_EQ(first.size(), 1u);
EXPECT_EQ(first[0], 0u);
pdfium::span<uint32_t> mids = vec.subspan(1, 2);
ASSERT_EQ(mids.size(), 2u);
EXPECT_EQ(mids[0], 1u);
EXPECT_EQ(mids[1], 2u);
pdfium::span<uint32_t> rest = vec.subspan(3);
ASSERT_EQ(rest.size(), 1u);
EXPECT_EQ(rest[0], 3u);
}
TEST(FixedSizeDataVector, First) {
auto vec = FixedSizeDataVector<uint32_t>::Uninit(4);
std::iota(vec.span().begin(), vec.span().end(), 0u);
pdfium::span<uint32_t> empty = vec.first(0);
EXPECT_TRUE(empty.empty());
pdfium::span<uint32_t> some = vec.first(2);
ASSERT_EQ(some.size(), 2u);
EXPECT_EQ(some[0], 0u);
EXPECT_EQ(some[1], 1u);
}
TEST(FixedSizeDataVector, Last) {
auto vec = FixedSizeDataVector<uint32_t>::Uninit(4);
std::iota(vec.span().begin(), vec.span().end(), 0u);
pdfium::span<uint32_t> empty = vec.first(0);
EXPECT_TRUE(empty.empty());
pdfium::span<uint32_t> some = vec.first(2);
ASSERT_EQ(some.size(), 2u);
EXPECT_EQ(some[0], 0u);
EXPECT_EQ(some[1], 1u);
}