blob: cfffa7a4e1a56336409865d71f9e8d0e444d2207 [file] [log] [blame] [edit]
// Copyright (c) 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "source/util/span.h"
#include "gmock/gmock.h"
namespace spvtools {
namespace utils {
namespace {
using SpanTest = ::testing::Test;
TEST(SpanTest, Initialize_Default) {
const Span<int> s;
EXPECT_EQ(s.begin(), nullptr);
EXPECT_EQ(s.end(), nullptr);
EXPECT_EQ(s.cbegin(), nullptr);
EXPECT_EQ(s.cend(), nullptr);
EXPECT_EQ(s.size(), std::size_t(0));
EXPECT_EQ(s.size_bytes(), std::size_t(0));
EXPECT_TRUE(s.empty());
EXPECT_EQ(s.data(), nullptr);
}
TEST(SpanTest, Initialize_EmptySpan) {
int ints[3];
int* first = ints + 1;
const Span<int> s(first, 0);
EXPECT_EQ(s.begin(), first);
EXPECT_EQ(s.end(), first);
EXPECT_EQ(s.begin(), s.end());
EXPECT_EQ(s.cbegin(), first);
EXPECT_EQ(s.cend(), first);
EXPECT_EQ(s.cbegin(), s.cend());
EXPECT_EQ(s.size(), std::size_t(0));
EXPECT_EQ(s.size_bytes(), std::size_t(0));
EXPECT_TRUE(s.empty());
EXPECT_EQ(s.data(), first);
}
TEST(SpanTest, Initialize_NonemptySpan) {
int ints[10] = {0, 10, 20, 30, 40, 50, 60};
int* first = ints + 2;
const Span<int> s(first, 3);
EXPECT_EQ(s.begin(), first);
EXPECT_EQ(s.end(), first + 3);
EXPECT_NE(s.begin(), s.end());
EXPECT_EQ(s.cbegin(), first);
EXPECT_EQ(s.cend(), first + 3);
EXPECT_NE(s.cbegin(), s.cend());
EXPECT_EQ(s.size(), std::size_t(3));
EXPECT_EQ(s.size_bytes(), 3 * sizeof(int));
EXPECT_FALSE(s.empty());
EXPECT_EQ(&(s.front()), first);
EXPECT_EQ(s.front(), 20);
EXPECT_EQ(&(s.back()), first + 2);
EXPECT_EQ(s.back(), 40);
EXPECT_EQ(s.data(), first);
EXPECT_EQ(&s[0], first);
EXPECT_EQ(s[0], 20);
EXPECT_EQ(&s[1], first + 1);
EXPECT_EQ(s[1], 30);
EXPECT_EQ(&s[2], first + 2);
EXPECT_EQ(s[2], 40);
EXPECT_EQ(&s[3], first + 3);
EXPECT_EQ(&s[3], s.end());
}
TEST(SpanTest, Initialize_NonemptySpan_Iterator_PostIncrement) {
int ints[10] = {0, 10, 20, 30, 40, 50, 60};
int* first = ints + 2;
const Span<int> s(first, 3);
auto iter = s.begin();
EXPECT_NE(iter, s.end());
EXPECT_EQ(*iter++, 20);
EXPECT_NE(iter, s.end());
EXPECT_EQ(*iter++, 30);
EXPECT_NE(iter, s.end());
EXPECT_EQ(*iter++, 40);
EXPECT_EQ(iter, s.end());
}
TEST(SpanTest, Initialize_NonemptySpan_Iterator_PreIncrement) {
int ints[10] = {0, 10, 20, 30, 40, 50, 60};
int* first = ints + 2;
const Span<int> s(first, 3);
auto iter = s.begin();
EXPECT_EQ(*++iter, 30);
EXPECT_NE(iter, s.end());
EXPECT_EQ(*++iter, 40);
EXPECT_EQ(++iter, s.end());
}
TEST(SpanTest, Initialize_NonemptySpan_Iterator_PostDecrement) {
int ints[10] = {0, 10, 20, 30, 40, 50, 60};
int* first = ints + 2;
const Span<int> s(first, 3);
auto iter = s.end();
EXPECT_EQ(iter--, s.end());
EXPECT_EQ(*iter--, 40);
EXPECT_NE(iter, s.begin());
EXPECT_EQ(*iter--, 30);
EXPECT_EQ(iter, s.begin());
EXPECT_EQ(*iter--, 20);
EXPECT_NE(iter, s.begin());
}
TEST(SpanTest, Initialize_NonemptySpan_Iterator_PreDecrement) {
int ints[10] = {0, 10, 20, 30, 40, 50, 60};
int* first = ints + 2;
const Span<int> s(first, 3);
auto iter = s.end();
EXPECT_EQ(*--iter, 40);
EXPECT_NE(iter, s.begin());
EXPECT_EQ(*--iter, 30);
EXPECT_NE(iter, s.begin());
EXPECT_EQ(*--iter, 20);
EXPECT_EQ(iter, s.begin());
}
TEST(SpanTest, Subspan_FromNil) {
const Span<int> snil(nullptr, 0);
const auto s0 = snil.subspan(0);
const auto s2 = snil.subspan(2);
EXPECT_EQ(s0.begin(), nullptr);
EXPECT_EQ(s0.end(), nullptr);
EXPECT_EQ(s0.size(), 0u);
EXPECT_TRUE(s0.empty());
EXPECT_EQ(s2.begin(), nullptr);
EXPECT_EQ(s2.end(), nullptr);
EXPECT_EQ(s2.size(), 0u);
EXPECT_TRUE(s2.empty());
}
TEST(SpanTest, Subspan_FromEmpty) {
int ints[10] = {0, 10, 20, 30, 40, 50, 60};
int* first = ints + 2;
const Span<int> s(first, 0);
const auto s0 = s.subspan(0);
const auto s2 = s.subspan(2);
EXPECT_EQ(s0.begin(), nullptr);
EXPECT_EQ(s0.end(), nullptr);
EXPECT_EQ(s0.size(), 0u);
EXPECT_TRUE(s0.empty());
EXPECT_EQ(s2.begin(), nullptr);
EXPECT_EQ(s2.end(), nullptr);
EXPECT_EQ(s2.size(), 0u);
EXPECT_TRUE(s2.empty());
}
TEST(SpanTest, Subspan_FromNonEmpty) {
int ints[10] = {0, 10, 20, 30, 40, 50, 60};
int* first = ints + 2;
const Span<int> s(first, 3);
const auto s0 = s.subspan(0);
const auto s2 = s.subspan(2);
const auto s3 = s.subspan(3);
const auto s4 = s.subspan(4);
EXPECT_EQ(s0.begin(), s.begin());
EXPECT_EQ(s0.end(), s.end());
EXPECT_EQ(s0.size(), 3u);
EXPECT_EQ(s2.begin(), s.begin() + 2);
EXPECT_EQ(s2.end(), s.end());
EXPECT_EQ(s2.size(), 1u);
EXPECT_EQ(s3.begin(), nullptr);
EXPECT_EQ(s3.end(), nullptr);
EXPECT_EQ(s3.size(), 0u);
EXPECT_EQ(s4.begin(), nullptr);
EXPECT_EQ(s4.end(), nullptr);
EXPECT_EQ(s4.size(), 0u);
}
} // namespace
} // namespace utils
} // namespace spvtools