test_random_intersperse.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 <array>
19 #include <vector>
20 
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>
30 
32 
33 namespace {
34 
35 TEST(RandomIntersperseView, ConceptChecksFromContiguousRange) {
36  auto input = std::array{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
37  auto output = beluga::views::random_intersperse(input, []() { return 0; });
38 
39  static_assert(ranges::common_range<decltype(input)>);
40  static_assert(!ranges::common_range<decltype(output)>);
41 
42  static_assert(!ranges::viewable_range<decltype(input)>);
43  static_assert(ranges::viewable_range<decltype(output)>);
44 
45  static_assert(ranges::forward_range<decltype(input)>);
46  static_assert(ranges::forward_range<decltype(output)>);
47 
48  static_assert(ranges::sized_range<decltype(input)>);
49  static_assert(!ranges::sized_range<decltype(output)>);
50 
51  static_assert(ranges::bidirectional_range<decltype(input)>);
52  static_assert(!ranges::bidirectional_range<decltype(output)>);
53 
54  static_assert(ranges::random_access_range<decltype(input)>);
55  static_assert(!ranges::random_access_range<decltype(output)>);
56 
57  static_assert(ranges::contiguous_range<decltype(input)>);
58  static_assert(!ranges::contiguous_range<decltype(output)>);
59 }
60 
61 TEST(RandomIntersperseView, ConceptChecksFromInfiniteRange) {
62  auto input = ranges::views::generate([]() { return 1; });
63  auto output = beluga::views::random_intersperse(input, []() { return 0; });
64 
65  static_assert(!ranges::common_range<decltype(input)>);
66  static_assert(!ranges::common_range<decltype(output)>);
67 
68  static_assert(ranges::viewable_range<decltype(input)>);
69  static_assert(ranges::viewable_range<decltype(output)>);
70 
71  static_assert(!ranges::forward_range<decltype(input)>);
72  static_assert(!ranges::forward_range<decltype(output)>);
73 
74  static_assert(!ranges::sized_range<decltype(input)>);
75  static_assert(!ranges::sized_range<decltype(output)>);
76 
77  static_assert(!ranges::bidirectional_range<decltype(input)>);
78  static_assert(!ranges::bidirectional_range<decltype(output)>);
79 
80  static_assert(!ranges::random_access_range<decltype(input)>);
81  static_assert(!ranges::random_access_range<decltype(output)>);
82 
83  static_assert(!ranges::contiguous_range<decltype(input)>);
84  static_assert(!ranges::contiguous_range<decltype(output)>);
85 }
86 
87 TEST(RandomIntersperseView, GuaranteedIntersperseFirstElement) {
88  const double probability = 1.0;
89  auto input = std::array{10, 20, 30};
90  auto output = input | beluga::views::random_intersperse([i = 0]() mutable { return i++; }, probability);
91  auto it = ranges::begin(output);
92  ASSERT_EQ(*it, 10); // The first element is always from the input range
93 }
94 
95 TEST(RandomIntersperseView, GuaranteedIntersperseDoubleDereference) {
96  const double probability = 1.0;
97  auto input = std::array{10, 20, 30};
98  auto output = input | beluga::views::random_intersperse([i = 0]() mutable { return i++; }, probability);
99  auto it = ranges::begin(output);
100  ++it;
101  ASSERT_EQ(*it, 0);
102  ASSERT_EQ(*it, 0);
103  ++it;
104  ASSERT_EQ(*it, 1);
105 }
106 
107 TEST(RandomIntersperseView, GuaranteedIntersperseWithNullaryFunction) {
108  const double probability = 1.0;
109  auto input = std::array{10, 20, 30};
110  auto output = input | //
111  beluga::views::random_intersperse([]() { return 4; }, probability) | //
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));
116 }
117 
118 TEST(RandomIntersperseView, GuaranteedIntersperseWithUnaryFunction) {
119  const double probability = 1.0;
120  auto input = std::array{10, 20, 30};
121  auto output = input | //
122  beluga::views::random_intersperse([](auto&) { return 42; }, probability) | //
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));
127 }
128 
129 TEST(RandomIntersperseView, ZeroProbabilityIntersperseTakeFive) {
130  const double probability = 0.0;
131  auto input = std::array{10, 20, 30};
132  auto output = input | //
133  beluga::views::random_intersperse([]() { return 4; }, probability) | //
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));
138 }
139 
140 TEST(RandomIntersperseView, ZeroProbabilityMultipass) {
141  const double probability = 0.0;
142  auto input = std::array{10, 20, 30};
143  auto output = input | //
144  beluga::views::random_intersperse([]() { return 4; }, probability) | //
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));
148 }
149 
150 class RandomIntersperseViewWithParam : public ::testing::TestWithParam<double> {};
151 
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);
159 }
160 
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));
165 
166 } // namespace
random_intersperse.hpp
Implementation of a random_intersperse range adaptor object.
beluga::views::random_intersperse
constexpr detail::random_intersperse_fn random_intersperse
Definition: random_intersperse.hpp:190
beluga::TEST
TEST(Bresenham, MultiPassGuarantee)
Definition: test_bresenham.cpp:27


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