enumerate.h
Go to the documentation of this file.
1 /**
2  * @file larcorealg/CoreUtils/enumerate.h
3  * @brief Definition of `util::enumerate()`.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date April 14, 2019
6  *
7  * This is a header-only library.
8  */
9 
10 #ifndef LARCOREALG_COREUTILS_ENUMERATE_H
11 #define LARCOREALG_COREUTILS_ENUMERATE_H
12 
13 
14 // LArSoft libraries
17 
18 // C/C++ libraries
19 #include <utility> // std::forward()
20 #include <cstddef> // std::size_t
21 
22 
23 
24 namespace util {
25 
26 
27  // -- BEGIN -- Enumerated iterations -----------------------------------------
28  /// @name Enumerated iterations
29  /// @{
30 
31  /**
32  * @brief Range-for loop helper tracking the number of iteration.
33  * @tparam Lead index of the parameter driving the start and end of the loop
34  * @tparam Iterables type of objects to be iterated together
35  * @param iterables all iterable objects to be iterated together
36  * @return an object suitable for range-for loop
37  *
38  * In the range-for loop, at each iteration this object yields a `tuple` of
39  * values, each of the type returned by dereferencing `begin(iterable)`.
40  * For example:
41  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
42  * constexpr std::size_t N = 4;
43  * std::array<int, N> twice;
44  * std::vector<double> thrice(N + 1);
45  *
46  * for (auto&& [i, a, b]: util::enumerate(twice, thrice)) {
47  *
48  * a = 2 * i;
49  * b = 3.0 * i;
50  *
51  * } // for
52  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
53  * In this example, `N` iterations will be run because that is the size of
54  * the first iterable given to `enumerate`. If a different leading iterable
55  * is needed, that has to be specified as an argument. The following loop
56  * is completely equivalent to the former one:
57  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
58  * for (auto&& [i, b, a]: util::enumerate<1U>(thrice, twice)) {
59  *
60  * a = 2 * i;
61  * b = 3.0 * i;
62  *
63  * } // for
64  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
65  * (the index is zero-based, so `1U` refers to the second argument).
66  *
67  */
68  template <std::size_t Lead, typename... Iterables>
69  auto enumerate(Iterables&&... iterables)
70  {
71  return zip<Lead + 1>
72  (infinite_counter(), std::forward<Iterables>(iterables)...);
73  }
74 
75  /// This version of `enumerate` implicitly uses the first iterable as lead.
76  template <typename... Iterables>
77  auto enumerate(Iterables&&... iterables)
78  { return enumerate<0U>(std::forward<Iterables>(iterables)...); }
79 
80 
81  /// @}
82  // --- END -- Enumerated iterations ------------------------------------------
83 
84 } // namespace util
85 
86 
87 #endif // LARCOREALG_COREUTILS_ENUMERATE_H
Definition of util::zip().
Namespace for general, non-LArSoft-specific utilities.
auto infinite_counter(T begin=T{})
Version of util::counter() starting at begin and never ending.
Definition: counter.h:291
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
Definition: enumerate.h:69
Test of util::counter and support utilities.