test_circular_array.cpp
Go to the documentation of this file.
1 // Copyright 2024 Ekumen, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <gmock/gmock.h>
16 #include <gtest/gtest.h>
17 
18 #include <algorithm>
19 #include <array>
20 #include <iterator>
21 #include <stdexcept>
22 
23 #include <range/v3/range/concepts.hpp>
24 #include <range/v3/range/conversion.hpp>
25 #include <range/v3/view/stride.hpp>
26 #include <range/v3/view/transform.hpp>
27 
30 
31 namespace {
32 
33 TEST(CircularArrayTest, Empty) {
34  const auto array = beluga::CircularArray<int, 2>{};
35  EXPECT_EQ(array.size(), 0);
36  EXPECT_EQ(array.effective_size(), 0);
37  EXPECT_EQ(array.max_size(), 2);
38  EXPECT_TRUE(array.empty());
39  EXPECT_FALSE(array.full());
40 }
41 
42 TEST(CircularArrayTest, PartiallyFilled) {
43  const auto array = beluga::CircularArray<int, 2>{{1}};
44  EXPECT_EQ(array.size(), 1);
45  EXPECT_EQ(array.effective_size(), 1);
46  EXPECT_EQ(array.max_size(), 2);
47  EXPECT_FALSE(array.empty());
48  EXPECT_FALSE(array.full());
49 }
50 
51 TEST(CircularArrayTest, Full) {
52  const auto array = beluga::CircularArray<int, 2>{{1, 2}};
53  EXPECT_EQ(array.size(), 2);
54  EXPECT_EQ(array.effective_size(), 2);
55  EXPECT_EQ(array.max_size(), 2);
56  EXPECT_FALSE(array.empty());
57  EXPECT_TRUE(array.full());
58 }
59 
60 TEST(CircularArrayTest, FromRange) {
61  auto input = std::array{1, 2, 3};
62  auto array = beluga::CircularArray<int, 5>{input.begin(), input.end()};
63  EXPECT_THAT(array, ::testing::ElementsAre(1, 2, 3));
64  EXPECT_THROW((beluga::CircularArray<int, 2>(input.begin(), input.end())), std::length_error);
65 }
66 
67 TEST(CircularArrayTest, FromRangeUsingReverseLayout) {
68  auto input = std::array{1, 2, 3};
70  auto array = beluga::CircularArray<int, 5, kFlags>{input.begin(), input.end()};
71  EXPECT_THAT(array, ::testing::ElementsAre(1, 2, 3));
72  EXPECT_THROW((beluga::CircularArray<int, 2, kFlags>(input.begin(), input.end())), std::length_error);
73 }
74 
75 TEST(CircularArrayTest, Read) {
76  const auto array = beluga::CircularArray<int, 5>{{1, 2, 3}};
77  EXPECT_EQ(array.front(), 1);
78  EXPECT_EQ(array.back(), 3);
79  EXPECT_EQ(array[0], 1);
80  EXPECT_EQ(array.at(0), 1);
81  EXPECT_EQ(array[1], 2);
82  EXPECT_EQ(array.at(1), 2);
83  EXPECT_EQ(array[2], 3);
84  EXPECT_EQ(array.at(2), 3);
85  EXPECT_THROW({ (void)array.at(3); }, std::out_of_range);
86  EXPECT_THAT(array, ::testing::ElementsAre(1, 2, 3));
87 }
88 
89 TEST(CircularArrayTest, ReverseLayoutRead) {
91  const auto array = beluga::CircularArray<int, 5, kFlags>{{1, 2, 3}};
92  EXPECT_EQ(array.front(), 1);
93  EXPECT_EQ(array.back(), 3);
94  EXPECT_EQ(array[0], 1);
95  EXPECT_EQ(array.at(0), 1);
96  EXPECT_EQ(array[1], 2);
97  EXPECT_EQ(array.at(1), 2);
98  EXPECT_EQ(array[2], 3);
99  EXPECT_EQ(array.at(2), 3);
100  EXPECT_THROW({ (void)array.at(3); }, std::out_of_range);
101  EXPECT_THAT(array, ::testing::ElementsAre(1, 2, 3));
102 }
103 
104 TEST(CircularArrayTest, ExtrapolateOnRead) {
106  const auto array = beluga::CircularArray<int, 5, kFlags>{{1, 2, 3}};
107  EXPECT_EQ(array.size(), 3);
108  EXPECT_EQ(array.effective_size(), 5);
109  EXPECT_EQ(array.max_size(), 5);
110  EXPECT_THAT(array, ::testing::ElementsAre(1, 2, 3, 3, 3));
111 }
112 
113 TEST(CircularArrayTest, Write) {
114  auto array = beluga::CircularArray<int, 2>{};
115  EXPECT_TRUE(array.empty());
116  array.push_back(1);
117  array << 2;
118  EXPECT_TRUE(array.full());
119  EXPECT_THROW({ array.push_back(3); }, std::length_error);
120  EXPECT_THAT(array, ::testing::ElementsAre(1, 2));
121  array.pop_front();
122  EXPECT_THAT(array, ::testing::ElementsAre(2));
123  array.pop_front();
124  EXPECT_TRUE(array.empty());
125 }
126 
127 TEST(CircularArrayTest, ReverseLayoutWrite) {
130  EXPECT_TRUE(array.empty());
131  array.push_front(1);
132  array << 2;
133  EXPECT_TRUE(array.full());
134  EXPECT_THROW({ array.push_front(3); }, std::length_error);
135  EXPECT_THAT(array, ::testing::ElementsAre(2, 1));
136  array.pop_back();
137  EXPECT_THAT(array, ::testing::ElementsAre(2));
138  array.pop_back();
139  EXPECT_TRUE(array.empty());
140 }
141 
142 TEST(CircularArrayTest, FrontInsertWrite) {
144  auto output_array = beluga::CircularArray<int, 6, kFlags>{};
145  const auto input_array = beluga::CircularArray<int, 3, kFlags>{{1, 3, 2}};
146  std::copy(input_array.begin(), input_array.end(), std::front_inserter(output_array));
147  std::copy(input_array.rbegin(), input_array.rend(), std::front_inserter(output_array));
148  EXPECT_THAT(output_array, ::testing::ElementsAre(1, 3, 2, 2, 3, 1));
149 }
150 
151 TEST(CircularArrayTest, BackInsertWrite) {
152  auto output_array = beluga::CircularArray<int, 6>{};
153  const auto input_array = beluga::CircularArray<int, 3>{{1, 3, 2}};
154  std::copy(input_array.begin(), input_array.end(), std::back_inserter(output_array));
155  std::copy(input_array.rbegin(), input_array.rend(), std::back_inserter(output_array));
156  EXPECT_THAT(output_array, ::testing::ElementsAre(1, 3, 2, 2, 3, 1));
157 }
158 
159 TEST(CircularArrayTest, NoWriteWhenFull) {
160  auto array = beluga::CircularArray<int, 2>{{1, 2}};
161  EXPECT_THROW({ array.push_back(3); }, std::length_error);
162 }
163 
164 TEST(CircularArrayTest, RolloverOnWrite) {
166  auto array = beluga::CircularArray<int, 2, kFlags>{{1, 2}};
167  array.push_back(3);
168  EXPECT_THAT(array, ::testing::ElementsAre(2, 3));
169 }
170 
171 TEST(CircularArrayTest, Fill) {
172  auto array = beluga::CircularArray<int, 3>{{1}};
173  EXPECT_THAT(array, ::testing::ElementsAre(1));
174  array.fill(0);
175  EXPECT_THAT(array, ::testing::ElementsAre(1, 0, 0));
176 }
177 
178 TEST(CircularArrayTest, Swap) {
179  using std::swap;
180  constexpr auto kFlags =
182  auto lhs = beluga::CircularArray<int, 3, kFlags>{{-1, -2, -3}};
183  lhs.push_front(0); // then becomes 0, -1, -2
184  auto rhs = beluga::CircularArray<int, 3>{{1, 2, 3}};
185  swap(lhs, rhs);
186  EXPECT_THAT(lhs, ::testing::ElementsAre(3, 2, 1));
187  EXPECT_THAT(rhs, ::testing::ElementsAre(-2, -1, 0));
188 }
189 
190 TEST(CircularArrayTest, RangeLike) {
191  static_assert(ranges::random_access_range<beluga::CircularArray<int, 5>>);
192  const auto input_array = beluga::CircularArray<int, 5>{{1, 2, 3, 4, 5}};
193  const auto output_array = input_array | ranges::views::stride(2) |
194  ranges::views::transform([](int x) { return x * x; }) |
195  ranges::to<beluga::CircularArray<int, 3>>;
196  EXPECT_THAT(output_array, ::testing::ElementsAre(1, 9, 25));
197 }
198 
199 TEST(CircularArrayTest, TupleLike) {
201  const auto array = beluga::CircularArray<int, 3>{{1, 2, 3}};
202  const auto& [a, b, c] = array;
203  EXPECT_EQ(a, 1);
204  EXPECT_EQ(b, 2);
205  EXPECT_EQ(c, 3);
206 }
207 
208 } // namespace
beluga::swap
constexpr void swap(CircularArray< T, N, F > &a, CircularArray< T, N, G > &b)
Swaps arrays a and b.
Definition: circular_array.hpp:523
beluga::CircularArray::push_front
std::enable_if_t< Enabled > push_front(value_type value)
Pushes a value at the front of the array.
Definition: circular_array.hpp:232
beluga::CircularArrayFeatureFlags::kRolloverOnWrite
@ kRolloverOnWrite
circular_array.hpp
Implementation of a generic circular array container.
beluga::is_tuple_like_v
constexpr bool is_tuple_like_v
Convenience template variable for is_tuple_like.
Definition: tuple_traits.hpp:53
beluga::CircularArray
An implementation of generic, non-threadsafe circular array.
Definition: circular_array.hpp:76
beluga::CircularArrayFeatureFlags::kLayoutReversal
@ kLayoutReversal
tuple_traits.hpp
Implementation of traits for tuple-like types.
beluga::CircularArrayFeatureFlags::kExtrapolateOnRead
@ kExtrapolateOnRead
beluga::CircularArray::begin
constexpr iterator begin() noexcept
Returns an iterator pointing to the front of the array.
Definition: circular_array.hpp:174
beluga::CircularArray::push_back
std::enable_if_t< Enabled > push_back(value_type value)
Pushes a value to the back of the array.
Definition: circular_array.hpp:209
beluga::TEST
TEST(Bresenham, MultiPassGuarantee)
Definition: test_bresenham.cpp:27


beluga
Author(s):
autogenerated on Tue Jul 16 2024 02:59:53