15 #include <gmock/gmock.h>
16 #include <gtest/gtest.h>
21 #include <range/v3/algorithm/count.hpp>
22 #include <range/v3/range/access.hpp>
23 #include <range/v3/range/concepts.hpp>
24 #include <range/v3/range/conversion.hpp>
25 #include <range/v3/range/primitives.hpp>
26 #include <range/v3/view/generate.hpp>
27 #include <range/v3/view/iota.hpp>
28 #include <range/v3/view/take.hpp>
29 #include <range/v3/view/take_exactly.hpp>
35 TEST(RandomIntersperseView, ConceptChecksFromContiguousRange) {
36 auto input = std::array{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
39 static_assert(ranges::common_range<decltype(input)>);
40 static_assert(!ranges::common_range<decltype(output)>);
42 static_assert(!ranges::viewable_range<decltype(input)>);
43 static_assert(ranges::viewable_range<decltype(output)>);
45 static_assert(ranges::forward_range<decltype(input)>);
46 static_assert(ranges::forward_range<decltype(output)>);
48 static_assert(ranges::sized_range<decltype(input)>);
49 static_assert(!ranges::sized_range<decltype(output)>);
51 static_assert(ranges::bidirectional_range<decltype(input)>);
52 static_assert(!ranges::bidirectional_range<decltype(output)>);
54 static_assert(ranges::random_access_range<decltype(input)>);
55 static_assert(!ranges::random_access_range<decltype(output)>);
57 static_assert(ranges::contiguous_range<decltype(input)>);
58 static_assert(!ranges::contiguous_range<decltype(output)>);
61 TEST(RandomIntersperseView, ConceptChecksFromInfiniteRange) {
62 auto input = ranges::views::generate([]() {
return 1; });
65 static_assert(!ranges::common_range<decltype(input)>);
66 static_assert(!ranges::common_range<decltype(output)>);
68 static_assert(ranges::viewable_range<decltype(input)>);
69 static_assert(ranges::viewable_range<decltype(output)>);
71 static_assert(!ranges::forward_range<decltype(input)>);
72 static_assert(!ranges::forward_range<decltype(output)>);
74 static_assert(!ranges::sized_range<decltype(input)>);
75 static_assert(!ranges::sized_range<decltype(output)>);
77 static_assert(!ranges::bidirectional_range<decltype(input)>);
78 static_assert(!ranges::bidirectional_range<decltype(output)>);
80 static_assert(!ranges::random_access_range<decltype(input)>);
81 static_assert(!ranges::random_access_range<decltype(output)>);
83 static_assert(!ranges::contiguous_range<decltype(input)>);
84 static_assert(!ranges::contiguous_range<decltype(output)>);
87 TEST(RandomIntersperseView, GuaranteedIntersperseFirstElement) {
88 const double probability = 1.0;
89 auto input = std::array{10, 20, 30};
91 auto it = ranges::begin(output);
95 TEST(RandomIntersperseView, GuaranteedIntersperseDoubleDereference) {
96 const double probability = 1.0;
97 auto input = std::array{10, 20, 30};
99 auto it = ranges::begin(output);
107 TEST(RandomIntersperseView, GuaranteedIntersperseWithNullaryFunction) {
108 const double probability = 1.0;
109 auto input = std::array{10, 20, 30};
110 auto output = input |
112 ranges::views::take_exactly(5) |
113 ranges::to<std::vector>;
114 ASSERT_EQ(ranges::size(output), 5);
115 ASSERT_THAT(output, testing::ElementsAre(10, 4, 4, 4, 4));
118 TEST(RandomIntersperseView, GuaranteedIntersperseWithUnaryFunction) {
119 const double probability = 1.0;
120 auto input = std::array{10, 20, 30};
121 auto output = input |
123 ranges::views::take_exactly(2) |
124 ranges::to<std::vector>;
125 ASSERT_EQ(ranges::size(output), 2);
126 ASSERT_THAT(output, testing::ElementsAre(10, 42));
129 TEST(RandomIntersperseView, ZeroProbabilityIntersperseTakeFive) {
130 const double probability = 0.0;
131 auto input = std::array{10, 20, 30};
132 auto output = input |
134 ranges::views::take(5) |
135 ranges::to<std::vector>;
136 ASSERT_EQ(ranges::size(output), 3);
137 ASSERT_THAT(output, testing::ElementsAre(10, 20, 30));
140 TEST(RandomIntersperseView, ZeroProbabilityMultipass) {
141 const double probability = 0.0;
142 auto input = std::array{10, 20, 30};
143 auto output = input |
145 ranges::views::take(3);
146 ASSERT_THAT(output | ranges::to<std::vector>, testing::ElementsAre(10, 20, 30));
147 ASSERT_THAT(output | ranges::to<std::vector>, testing::ElementsAre(10, 20, 30));
150 class RandomIntersperseViewWithParam :
public ::testing::TestWithParam<double> {};
152 TEST_P(RandomIntersperseViewWithParam, TestPercentage) {
153 const double probability = GetParam();
154 const int size = 100
'000;
155 auto output = ranges::views::iota(1, size + 1) | beluga::views::random_intersperse([]() { return 0; }, probability);
156 const double count = static_cast<double>(ranges::count(output, 0));
157 const double actual_probability = count / (size + count);
158 ASSERT_NEAR(probability, actual_probability, 0.01);
161 INSTANTIATE_TEST_SUITE_P(
162 RandomIntersperseViewParams,
163 RandomIntersperseViewWithParam,
164 testing::Values(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9));