All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
IntegerRanges_test.cc
Go to the documentation of this file.
1 /**
2  * @file IntegerRanges_test.cc
3  * @brief Unit test for `IntegerRanges` class.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date May 18, 2021
6  * @see icarusalg/Utilities/IntegerRanges.h
7  */
8 
9 
10 // Boost libraries
11 #define BOOST_TEST_MODULE IntegerRanges
12 #include <boost/test/unit_test.hpp>
13 
14 // ICARUS libraries
16 
17 // LArSoft libraries
19 
20 // C/C++ standard libraries
21 #include <iostream>
22 #include <utility> // std::pair<>
23 #include <array>
24 #include <type_traits> // std::is_same_v, std::remove_reference_t
25 
26 
27 // -----------------------------------------------------------------------------
28 template <typename Cont>
29 std::size_t count(Cont const& cont)
30  { return std::distance(begin(cont), end(cont)); }
31 
32 
33 // -----------------------------------------------------------------------------
35 
36  icarus::IntegerRanges<int> const ranges;
37 
38  BOOST_CHECK(ranges.empty());
39  BOOST_CHECK_EQUAL(ranges.size(), 0U);
40  BOOST_CHECK_EQUAL(ranges.nRanges(), 0U);
41  BOOST_CHECK_EQUAL(count(ranges.ranges()), 0U);
42 
43 } // TestConstDefaultConstructed()
44 
45 
46 // -----------------------------------------------------------------------------
48 
50 
51  BOOST_CHECK(ranges.empty());
52  BOOST_CHECK_EQUAL(ranges.size(), 0U);
53  BOOST_CHECK_EQUAL(ranges.nRanges(), 0U);
54  BOOST_CHECK_EQUAL(count(ranges.ranges()), 0U);
55 
56  ranges.clear();
57  BOOST_CHECK(ranges.empty());
58  BOOST_CHECK_EQUAL(ranges.size(), 0U);
59  BOOST_CHECK_EQUAL(ranges.nRanges(), 0U);
60  BOOST_CHECK_EQUAL(count(ranges.ranges()), 0U);
61 
62 } // TestDefaultConstructed()
63 
64 
65 // -----------------------------------------------------------------------------
67 
68 
69  std::array const test { 1, 2, 3, 4, 6, 7, 8, 10, 11 };
70  std::array<std::pair<int, int>, 3U> const groups = {
71  std::pair{ 1, 5 },
72  std::pair{ 6, 9 },
73  std::pair{ 10, 12 }
74  };
75 
76 
77  icarus::IntegerRanges ranges { 1, 2, 3, 4, 6, 7, 8, 10, 11 };
78  std::cout << "Testing: " << ranges << std::endl;
79 
80  BOOST_CHECK_EQUAL(ranges.empty(), test.empty());
81  BOOST_CHECK_EQUAL(ranges.size(), test.size());
82  BOOST_CHECK_EQUAL(ranges.nRanges(), groups.size());
83 
84  auto const& rangeContent = ranges.ranges();
85  for (auto const& [ i, r, e ]: util::enumerate(rangeContent, groups)) {
86  BOOST_TEST_MESSAGE("[" << i << "]");
87  BOOST_CHECK_EQUAL(r.lower, e.first);
88  BOOST_CHECK_EQUAL(r.upper, e.second);
89  } // for
90 
91 } // TestInitializerList()
92 
93 
94 // -----------------------------------------------------------------------------
96 
97 
98  std::array const test { 1, 2, 3, 4, 6, 7, 8, 10, 11 };
99  std::array<std::pair<int, int>, 3U> const groups = {
100  std::pair{ 1, 5 },
101  std::pair{ 6, 9 },
102  std::pair{ 10, 12 }
103  };
104 
105 
106  auto const ranges = icarus::makeIntegerRanges(test);
107  static_assert(std::is_same_v<
108  std::remove_reference_t<decltype(ranges)>,
110  >);
111  std::cout << "Testing: " << ranges << std::endl;
112 
113  BOOST_CHECK_EQUAL(ranges.empty(), test.empty());
114  BOOST_CHECK_EQUAL(ranges.size(), test.size());
115  BOOST_CHECK_EQUAL(ranges.nRanges(), groups.size());
116 
117  auto const& rangeContent = ranges.ranges();
118  for (auto const& [ i, r, e ]: util::enumerate(rangeContent, groups)) {
119  BOOST_TEST_MESSAGE("[" << i << "]");
120  BOOST_CHECK_EQUAL(r.lower, e.first);
121  BOOST_CHECK_EQUAL(r.upper, e.second);
122  } // for
123 
124 } // TestCollection()
125 
126 
127 // -----------------------------------------------------------------------------
128 void TestSparse() {
129 
130 
131  std::array const test { 1, 2, 3, 4, 6, 7, 8, 10, 11 };
132  std::array<std::pair<int, int>, 3U> const groups = {
133  std::pair{ 1, 5 },
134  std::pair{ 6, 9 },
135  std::pair{ 10, 12 }
136  };
137 
138 
139  icarus::IntegerRanges ranges { test.begin(), test.end() };
140  std::cout << "Testing: " << ranges << std::endl;
141 
142  BOOST_CHECK_EQUAL(ranges.empty(), test.empty());
143  BOOST_CHECK_EQUAL(ranges.size(), test.size());
144  BOOST_CHECK_EQUAL(ranges.nRanges(), groups.size());
145 
146  auto const& rangeContent = ranges.ranges();
147  for (auto const& [ i, r, e ]: util::enumerate(rangeContent, groups)) {
148  BOOST_TEST_MESSAGE("[" << i << "]");
149  BOOST_CHECK_EQUAL(r.lower, e.first);
150  BOOST_CHECK_EQUAL(r.upper, e.second);
151  } // for
152 
153 } // TestSparse()
154 
155 
156 // -----------------------------------------------------------------------------
157 void TestSingles() {
158 
159 
160  std::array const test { 1, 3, 6, 7, 8, 11 };
161  std::array<std::pair<int, int>, 4U> const groups = {
162  std::pair{ 1, 2 },
163  std::pair{ 3, 4 },
164  std::pair{ 6, 9 },
165  std::pair{ 11, 12 }
166  };
167 
168 
169  icarus::IntegerRanges ranges { test.begin(), test.end() };
170  std::cout << "Testing: " << ranges << std::endl;
171 
172  BOOST_CHECK_EQUAL(ranges.empty(), test.empty());
173  BOOST_CHECK_EQUAL(ranges.size(), test.size());
174  BOOST_CHECK_EQUAL(ranges.nRanges(), groups.size());
175 
176  auto const& rangeContent = ranges.ranges();
177  for (auto const& [ i, r, e ]: util::enumerate(rangeContent, groups)) {
178  BOOST_TEST_MESSAGE("[" << i << "]");
179  BOOST_CHECK_EQUAL(r.lower, e.first);
180  BOOST_CHECK_EQUAL(r.upper, e.second);
181  } // for
182 
183 } // TestSingles()
184 
185 
186 // -----------------------------------------------------------------------------
188 
189  std::array const test { 1, 1, 3, 6, 6, 6, 7, 8, 11, 11 };
190  std::array<std::pair<int, int>, 4U> const groups = {
191  std::pair{ 1, 2 },
192  std::pair{ 3, 4 },
193  std::pair{ 6, 9 },
194  std::pair{ 11, 12 }
195  };
196 
197 
198  icarus::IntegerRanges ranges { test.begin(), test.end() };
199  std::cout << "Testing: " << ranges << std::endl;
200 
201  BOOST_CHECK_EQUAL(ranges.empty(), test.empty());
202  BOOST_CHECK_EQUAL(ranges.size(), test.size() - 4U); // account for duplicates
203  BOOST_CHECK_EQUAL(ranges.nRanges(), groups.size());
204 
205  auto const& rangeContent = ranges.ranges();
206  for (auto const& [ i, r, e ]: util::enumerate(rangeContent, groups)) {
207  BOOST_TEST_MESSAGE("[" << i << "]");
208  BOOST_CHECK_EQUAL(r.lower, e.first);
209  BOOST_CHECK_EQUAL(r.upper, e.second);
210  } // for
211 
212 } // TestDuplicates()
213 
214 
215 // -----------------------------------------------------------------------------
216 void TestUnsorted() {
217 
218  std::array const test { 1, 3, 7, 8, 8, 6, 11 };
219 
220  BOOST_CHECK_THROW(
221  (icarus::IntegerRanges<int, true>{ test.begin(), test.end() }),
222  std::runtime_error
223  );
224 
225  // technically, the following is also allowed to throw (not guaranteed to)
226  BOOST_CHECK_NO_THROW(
227  (icarus::IntegerRanges<int, false>{ test.begin(), test.end() })
228  );
229 
230 } // TestDuplicates()
231 
232 
233 //------------------------------------------------------------------------------
235 
236  /*
237  * The promise:
238  *
239  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
240  * std::array data { 1, 2, 4, 5, 6, 8, 10 };
241  *
242  * IntegerRanges ranges { data };
243  * std::cout << "Ranges: " << ranges << std::endl;
244  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
245  * will print something like `Ranges: 1 2 4--6 8 10`.
246  */
247 
248  std::array data { 1, 2, 4, 5, 5, 6, 8, 10 };
249 
251  std::cout << "Ranges: " << ranges << std::endl;
252 
253  // ----------------------------------------------------------------------------
254  std::stringstream sstr;
255  sstr << "Ranges: " << ranges;
256  BOOST_CHECK_EQUAL(sstr.str(), "Ranges: 1 2 4--6 8 10");
257 
258 } // TestIntegerRangesDocumentation()
259 
260 
261 //------------------------------------------------------------------------------
262 //--- The tests
263 //---
264 BOOST_AUTO_TEST_CASE( BasicTestCase ) {
265 
269  TestCollection();
270  TestSparse();
271  TestSingles();
272  TestDuplicates();
273  TestUnsorted();
274 
275 } // BOOST_AUTO_TEST_CASE( BasicTestCase )
276 
277 
278 BOOST_AUTO_TEST_CASE( DocumentationTestCase ) {
279 
281 
282 } // BOOST_AUTO_TEST_CASE( DocumentationTestCase )
283 
284 
285 //------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(AllTests)
void TestDefaultConstructed()
std::size_t nRanges() const noexcept
Returns the number of non-contiguous ranges in the set.
Class compacting a list of integers.
void TestIntegerRangesDocumentation()
Definition of util::enumerate().
void TestCollection()
void TestSingles()
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
Definition: enumerate.h:69
void TestSparse()
IntegerRanges< typename Coll::value_type, CheckGrowing > makeIntegerRanges(Coll const &coll)
void clear() noexcept
Removes all the entries and makes the set as default-constructed.
void TestInitializerList()
then echo ***************************************echo array
Definition: find_fhicl.sh:28
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
void TestDuplicates()
std::size_t size() const noexcept
Returns the number of elements in the ranges (gaps excluded).
auto begin(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:573
void TestConstDefaultConstructed()
bool empty() const noexcept
Returns whether there is any element in the range set.
void TestUnsorted()
A sequence of contiguous ranges of integral numbers.
Definition: IntegerRanges.h:41
do i e
BEGIN_PROLOG hitmakerfive clustermakerfour pfparticlemakerthree showermakertwo END_PROLOG hitmakerfive clustermakerfour pfparticlemakerthree sequence::inline_paths sequence::inline_paths sequence::inline_paths showermakers test
std::size_t count(Cont const &cont)
decltype(auto) ranges() const noexcept
Returns an iterable object with all sorted ranges as elements.
esac echo uname r
BEGIN_PROLOG could also be cout