15 #include <gmock/gmock.h>
16 #include <gtest/gtest.h>
22 #include <type_traits>
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>
47 inline void PrintTo(
const State&
state, std::ostream* os) {
48 *os <<
"A state (x: " <<
state.x <<
", y: " <<
state.y <<
")";
51 inline auto StateEq(
const State& expected) {
53 return AllOf(Field(
"x", &State::x, DoubleEq(expected.x)), Field(
"y", &State::y, DoubleEq(expected.y)));
56 template <
template <
class...>
class T>
57 struct TemplateWrapper {
58 template <
class... Types>
59 using type = T<std::tuple<Types...>>;
63 class ContainerTest :
public testing::Test {
65 template <
class... Types>
66 using TemplateParam =
typename T::template type<Types...>;
69 using Implementations = testing::Types<TemplateWrapper<beluga::Vector>, TemplateWrapper<beluga::TupleVector>>;
73 auto container =
typename TestFixture::template TemplateParam<State, beluga::Weight, beluga::Cluster>{100};
74 ASSERT_EQ(container.size(), 100);
78 auto container =
typename TestFixture::template TemplateParam<State, beluga::Weight, beluga::Cluster>{};
80 EXPECT_EQ(container.size(), 3);
83 ASSERT_THAT(
state, StateEq(State{}));
84 ASSERT_EQ(
weight,
double{});
92 auto container =
typename TestFixture::template TemplateParam<State, beluga::Weight, beluga::Cluster>{};
94 EXPECT_EQ(container.size(), 15);
96 EXPECT_EQ(container.size(), 0);
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}));
107 EXPECT_EQ(cluster, 4);
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});
119 auto container =
typename TestFixture::template TemplateParam<State, beluga::Weight, beluga::Cluster>{};
121 EXPECT_EQ(container.size(), 3);
122 constexpr
double kTestWeight = 1.25;
127 ASSERT_EQ(
weight, kTestWeight);
131 TYPED_TEST(ContainerTest, StructuredBinding) {
132 auto container =
typename TestFixture::template TemplateParam<State, beluga::Weight, beluga::Cluster>{};
134 EXPECT_EQ(container.size(), 3);
135 constexpr std::size_t kTestCluster = 75;
136 for (
auto&& [
state,
weight, cluster] : container) {
137 cluster = kTestCluster;
139 for (
auto&& [
state,
weight, cluster] : container) {
140 ASSERT_EQ(cluster, kTestCluster);
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) {
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);
167 TEST(TupleVectorTest, ConceptChecks) {
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)>);
175 static_assert(!ranges::viewable_range<decltype(container)>);
176 static_assert(!ranges::contiguous_range<decltype(container)>);
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&>()));
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&&>>);
207 static_assert(std::is_same_v<
208 ranges::range_value_t<ConstView>,
209 ranges::common_tuple<const float&, const int&>>);
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>);
220 TEST(TupleVectorTest, ConstCorrectness) {
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&>>);
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));
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));
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)};
242 output.assign_range(input);
243 ASSERT_TRUE(ranges::equal(input, output));
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)};
250 output.assign_range(input | ranges::views::filter([](
auto) {
return true; }));
251 ASSERT_TRUE(ranges::equal(input, output));
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)};
258 output.assign_range(input);
259 ASSERT_TRUE(ranges::equal(input, output));
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)};
266 output.assign_range(input | ranges::views::filter([](
auto) {
return true; }));
267 ASSERT_TRUE(ranges::equal(input, output));