test_tuple_vector.cpp
Go to the documentation of this file.
1 // Copyright 2022-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 <array>
19 #include <cstddef>
20 #include <ostream>
21 #include <tuple>
22 #include <type_traits>
23 #include <utility>
24 
25 #include <range/v3/algorithm/equal.hpp>
26 #include <range/v3/iterator/access.hpp>
27 #include <range/v3/range/access.hpp>
28 #include <range/v3/range/concepts.hpp>
29 #include <range/v3/range/conversion.hpp>
30 #include <range/v3/range/traits.hpp>
31 #include <range/v3/utility/common_tuple.hpp>
32 #include <range/v3/view/all.hpp>
33 #include <range/v3/view/const.hpp>
34 #include <range/v3/view/filter.hpp>
35 
37 #include "beluga/primitives.hpp"
39 
40 namespace {
41 
42 struct State {
43  double x = 0.;
44  double y = 0.;
45 };
46 
47 inline void PrintTo(const State& state, std::ostream* os) {
48  *os << "A state (x: " << state.x << ", y: " << state.y << ")";
49 }
50 
51 inline auto StateEq(const State& expected) {
52  using namespace testing; // NOLINT
53  return AllOf(Field("x", &State::x, DoubleEq(expected.x)), Field("y", &State::y, DoubleEq(expected.y)));
54 }
55 
56 template <template <class...> class T>
57 struct TemplateWrapper {
58  template <class... Types>
59  using type = T<std::tuple<Types...>>;
60 };
61 
62 template <class T>
63 class ContainerTest : public testing::Test {
64  public:
65  template <class... Types>
66  using TemplateParam = typename T::template type<Types...>;
67 };
68 
69 using Implementations = testing::Types<TemplateWrapper<beluga::Vector>, TemplateWrapper<beluga::TupleVector>>;
70 TYPED_TEST_SUITE(ContainerTest, Implementations, );
71 
72 TYPED_TEST(ContainerTest, Size) {
73  auto container = typename TestFixture::template TemplateParam<State, beluga::Weight, beluga::Cluster>{100};
74  ASSERT_EQ(container.size(), 100);
75 }
76 
77 TYPED_TEST(ContainerTest, Resize) {
78  auto container = typename TestFixture::template TemplateParam<State, beluga::Weight, beluga::Cluster>{};
79  container.resize(3);
80  EXPECT_EQ(container.size(), 3);
81  int reps = 0;
82  for (auto&& [state, weight, cluster] : container) {
83  ASSERT_THAT(state, StateEq(State{}));
84  ASSERT_EQ(weight, double{});
85  ASSERT_EQ(cluster, beluga::Cluster{});
86  ++reps;
87  }
88  ASSERT_EQ(reps, 3);
89 }
90 
91 TYPED_TEST(ContainerTest, Clear) {
92  auto container = typename TestFixture::template TemplateParam<State, beluga::Weight, beluga::Cluster>{};
93  container.resize(15);
94  EXPECT_EQ(container.size(), 15);
95  container.clear();
96  EXPECT_EQ(container.size(), 0);
97 }
98 
99 TYPED_TEST(ContainerTest, PushBack) {
100  auto container = typename TestFixture::template TemplateParam<State, beluga::Weight, beluga::Cluster>{};
101  EXPECT_EQ(container.size(), 0);
102  container.push_back({{1, 2}, 3, 4});
103  EXPECT_EQ(container.size(), 1);
104  auto&& [state, weight, cluster] = ranges::views::all(container).front();
105  EXPECT_THAT(state, StateEq({1, 2}));
106  EXPECT_EQ(weight, 3);
107  EXPECT_EQ(cluster, 4);
108 }
109 
110 TYPED_TEST(ContainerTest, GetterSetter) {
111  auto container = typename TestFixture::template TemplateParam<State, beluga::Weight, beluga::Cluster>{};
112  auto&& view = container | ranges::views::all;
113  container.push_back({{1, 2}, 3, 4});
114  beluga::weight(view.front()) = 5;
115  ASSERT_EQ(beluga::weight(view.front()), 5);
116 }
117 
118 TYPED_TEST(ContainerTest, View) {
119  auto container = typename TestFixture::template TemplateParam<State, beluga::Weight, beluga::Cluster>{};
120  container.resize(3);
121  EXPECT_EQ(container.size(), 3);
122  constexpr double kTestWeight = 1.25;
123  for (auto&& weight : beluga::views::weights(container)) {
124  weight = kTestWeight;
125  }
126  for (auto&& weight : beluga::views::weights(container)) {
127  ASSERT_EQ(weight, kTestWeight);
128  }
129 }
130 
131 TYPED_TEST(ContainerTest, StructuredBinding) {
132  auto container = typename TestFixture::template TemplateParam<State, beluga::Weight, beluga::Cluster>{};
133  container.resize(3);
134  EXPECT_EQ(container.size(), 3);
135  constexpr std::size_t kTestCluster = 75;
136  for (auto&& [state, weight, cluster] : container) {
137  cluster = kTestCluster;
138  }
139  for (auto&& [state, weight, cluster] : container) {
140  ASSERT_EQ(cluster, kTestCluster);
141  }
142 }
143 
144 TYPED_TEST(ContainerTest, SingleElementTuple) {
145  auto container = typename TestFixture::template TemplateParam<int>{};
146  container.push_back({4});
147  container.push_back({4});
148  container.push_back({4});
149  EXPECT_EQ(container.size(), 3);
150  for (auto&& [value] : container) {
151  ASSERT_EQ(value, 4);
152  }
153 }
154 
155 TYPED_TEST(ContainerTest, DoubleElementTuple) {
156  auto container = typename TestFixture::template TemplateParam<int, float>{};
157  container.push_back({2, 0.5});
158  container.push_back({2, 0.5});
159  container.push_back({2, 0.5});
160  EXPECT_EQ(container.size(), 3);
161  for (auto&& [integer, real] : container) {
162  ASSERT_EQ(integer, 2);
163  ASSERT_EQ(real, 0.5);
164  }
165 }
166 
167 TEST(TupleVectorTest, ConceptChecks) {
168  auto container = beluga::TupleVector<std::tuple<float>>{std::make_tuple(1)};
169 
170  static_assert(ranges::sized_range<decltype(container)>);
171  static_assert(ranges::random_access_range<decltype(container)>);
172  static_assert(ranges::common_range<decltype(container)>);
173  static_assert(ranges::bidirectional_range<decltype(container)>);
174 
175  static_assert(!ranges::viewable_range<decltype(container)>);
176  static_assert(!ranges::contiguous_range<decltype(container)>);
177 }
178 
179 TEST(TupleVectorTest, TraitConsistency) {
181  using ConstContainer = decltype(std::declval<const Container&>());
182  using ConstView = decltype(std::declval<const Container&>() | ranges::views::const_);
183  using Iterator = decltype(ranges::begin(std::declval<Container&>()));
184 
185  // Expected types
186  static_assert(std::is_same_v<
187  ranges::range_value_t<Container>, //
188  std::tuple<float, int>>);
189  static_assert(std::is_same_v<
190  ranges::range_reference_t<Container>, //
191  ranges::common_tuple<float&, int&>>);
192  static_assert(std::is_same_v<
193  ranges::range_rvalue_reference_t<Container>, //
194  ranges::common_tuple<float&&, int&&>>);
195  static_assert(std::is_same_v<
196  ranges::range_value_t<ConstContainer>, //
197  std::tuple<float, int>>);
198  static_assert(std::is_same_v<
199  ranges::range_reference_t<ConstContainer>, //
200  ranges::common_tuple<const float&, const int&>>);
201  static_assert(std::is_same_v<
202  ranges::range_rvalue_reference_t<ConstContainer>, //
203  ranges::common_tuple<const float&&, const int&&>>);
204 
205  // Expected value type of a const view would be the same as the value type of the
206  // adapted container (std::tuple<float, int>)... This is not the case. :(
207  static_assert(std::is_same_v<
208  ranges::range_value_t<ConstView>, //
209  ranges::common_tuple<const float&, const int&>>);
210 
211  // Consistency
212  static_assert(std::is_same_v<
213  ranges::iter_value_t<Iterator>, //
214  typename Container::value_type>);
215  static_assert(std::is_same_v<
216  ranges::iter_reference_t<Iterator>, //
217  typename Container::reference_type>);
218 }
219 
220 TEST(TupleVectorTest, ConstCorrectness) {
221  auto container = beluga::TupleVector<std::tuple<float>>{std::make_tuple(1)};
222  static_assert(std::is_same_v<decltype(*ranges::begin(container)), ranges::common_tuple<float&>>);
223  static_assert(std::is_same_v<decltype(*ranges::begin(std::as_const(container))), ranges::common_tuple<const float&>>);
224 }
225 
226 TEST(TupleVectorTest, ConversionFromSizedRange) {
227  auto input = std::array{std::make_tuple(1, 1.0), std::make_tuple(2, 2.0), std::make_tuple(3, 3.0)};
228  auto output = input | ranges::to<beluga::TupleVector>;
229  ASSERT_TRUE(ranges::equal(input, output));
230 }
231 
232 TEST(TupleVectorTest, ConversionFromNonSizedRange) {
233  auto input = std::array{std::make_tuple(1, 1.0), std::make_tuple(2, 2.0), std::make_tuple(3, 3.0)};
234  auto output = input | ranges::views::filter([](auto) { return true; }) | ranges::to<beluga::TupleVector>;
235  ASSERT_TRUE(ranges::equal(input, output));
236 }
237 
238 TEST(TupleVectorTest, AssignFromSizedRange) {
239  auto input = std::array{std::make_tuple(1, 1.0), std::make_tuple(2, 2.0), std::make_tuple(3, 3.0)};
241  output.reserve(2);
242  output.assign_range(input);
243  ASSERT_TRUE(ranges::equal(input, output));
244 }
245 
246 TEST(TupleVectorTest, AssignFromNonSizedRange) {
247  auto input = std::array{std::make_tuple(1, 1.0), std::make_tuple(2, 2.0), std::make_tuple(3, 3.0)};
249  output.reserve(2);
250  output.assign_range(input | ranges::views::filter([](auto) { return true; }));
251  ASSERT_TRUE(ranges::equal(input, output));
252 }
253 
254 TEST(TupleVectorTest, AssignFromSizedRangeReserved) {
255  auto input = std::array{std::make_tuple(1, 1.0), std::make_tuple(2, 2.0), std::make_tuple(3, 3.0)};
257  output.reserve(4);
258  output.assign_range(input);
259  ASSERT_TRUE(ranges::equal(input, output));
260 }
261 
262 TEST(TupleVectorTest, AssignFromNonSizedRangeReserved) {
263  auto input = std::array{std::make_tuple(1, 1.0), std::make_tuple(2, 2.0), std::make_tuple(3, 3.0)};
265  output.reserve(4);
266  output.assign_range(input | ranges::views::filter([](auto) { return true; }));
267  ASSERT_TRUE(ranges::equal(input, output));
268 }
269 
270 } // namespace
testing
Definition: eigen_initializers.hpp:22
primitives.hpp
Implementation of library primitives to abstract member access.
beluga::TYPED_TEST_SUITE
TYPED_TEST_SUITE(SparseGridTests, SparseGridTestCases,)
beluga::state
constexpr state_detail::state_fn state
Customization point object for accessing the state of a particle.
Definition: primitives.hpp:163
tuple_vector.hpp
Implementation of a tuple of containers.
beluga::weight
constexpr weight_detail::weight_fn weight
Customization point object for accessing the weight of a particle.
Definition: primitives.hpp:264
particles.hpp
Implementation of views related to particle ranges.
beluga::TupleVector
Shorthand for a tuple of vectors with the default allocator.
Definition: tuple_vector.hpp:223
beluga::Numeric
Helper for creating strongly typed numeric types.
Definition: strongly_typed_numeric.hpp:38
beluga::TYPED_TEST
TYPED_TEST(SparseGridTests, CanBeConstructedEmpty)
Definition: test_sparse_value_grid.cpp:46
beluga::views::weights
constexpr auto weights
Definition: particles.hpp:34
beluga::TEST
TEST(Bresenham, MultiPassGuarantee)
Definition: test_bresenham.cpp:27


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