| // 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 |