filterRangeFor.h
Go to the documentation of this file.
1 /**
2  * @file lardata/Utilities/filterRangeFor.h
3  * @brief Utilities to manipulate range for loops.
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date May 1, 2018
6  *
7  * This is a header-only library.
8  */
9 
10 #ifndef LARDATA_UTILITIES_FILTERRANGEFOR_H
11 #define LARDATA_UTILITIES_FILTERRANGEFOR_H
12 
13 
14 // Boost libraries
15 #include <boost/iterator/filter_iterator.hpp>
16 
17 
18 namespace util {
19 
20  /**
21  * @brief Provides iteration only through elements passing a condition.
22  * @tparam Range the data to be iterated
23  * @tparam Pred the type of the predicate to be fulfilled
24  * @param range the data to be iterated through
25  * @param pred the predicate to be tested
26  * @return an object suitable to be used in a range-for loop
27  *
28  * This adapter makes the range for loop iterate only through the elements of
29  * `range` which fulfil the predicate `pred`.
30  *
31  * This example will print: "0 3 6 9 ":
32  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
33  *
34  * std::vector<int> data = { 0, 1, 2, 3, 4, 5, 6 ,7, 8, 9 };
35  * for (int v: util::filterRangeFor(data, [](int v){ return v % 3 == 0; })) {
36  *
37  * std::cout << v << " ";
38  *
39  * } // for
40  * std::cout << std::endl;
41  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42  *
43  * Note that `pred` may be copied (`range` will not be).
44  *
45  *
46  * Requirements
47  * -------------
48  *
49  * * `Range` is an object which can itself go through a range-for:
50  *
51  * for (auto&& v: range);
52  *
53  * is valid
54  * * `Pred` is a copiable unary function type, whose single argument can be
55  * converted from the value type of `Range`, and whose return value can be
56  * converted into a `bool` vaule
57  *
58  */
59  template <typename Range, typename Pred>
60  auto filterRangeFor(Range&& range, Pred&& pred) -> decltype(auto);
61 
62 } // namespace util
63 
64 
65 //------------------------------------------------------------------------------
66 //--- implementation
67 //------------------------------------------------------------------------------
68 namespace util {
69 
70  namespace details {
71 
72  //--------------------------------------------------------------------------
73  template <typename Range, typename Pred>
75 
76  /// Extract the begin iterator from a range.
77  static auto getBegin(Range&& range) -> decltype(auto)
78  { using std::begin; return begin(range); }
79 
80  /// Extract the end iterator from a range.
81  static auto getEnd(Range&& range) -> decltype(auto)
82  { using std::end; return end(range); }
83 
84  /// Create a Boost filter iterator pointing to the beginning of data.
85  static auto makeBeginIterator(Range&& range, Pred&& pred)
86  {
87  auto begin = getBegin(std::forward<Range>(range));
88  auto end = getEnd(std::forward<Range>(range));
89  return
90  boost::make_filter_iterator(std::forward<Pred>(pred), begin, end);
91  }
92 
93  /// Create a Boost filter iterator pointing to the end of data.
94  static auto makeEndIterator(Range&& range, Pred&& pred)
95  {
96  auto end = getEnd(std::forward<Range>(range));
97  return
98  boost::make_filter_iterator(std::forward<Pred>(pred), end, end);
99  }
100 
101 
102  using begin_iterator_t = decltype
103  (makeBeginIterator(std::declval<Range&&>(), std::declval<Pred&&>()));
104  using end_iterator_t = decltype
105  (makeEndIterator(std::declval<Range&&>(), std::declval<Pred&&>()));
106 
109 
110  public:
111 
112  /// Extracts the iterators from the specified range.
113  FilterRangeForStruct(Range&& range, Pred&& pred)
114  : fBegin(
116  (std::forward<Range>(range), std::forward<Pred>(pred))
117  )
118  , fEnd(
120  (std::forward<Range>(range), std::forward<Pred>(pred))
121  )
122  {}
123 
124  auto begin() const { return fBegin; }
125  auto end() const { return fEnd; }
126 
127  }; // class FilterRangeForStruct<>
128 
129  //--------------------------------------------------------------------------
130 
131 
132  } // namespace details
133 
134 
135  //----------------------------------------------------------------------------
136  template <typename Range, typename Pred>
137  auto filterRangeFor(Range&& range, Pred&& pred) -> decltype(auto)
138  {
140  (std::forward<Range>(range), std::forward<Pred>(pred));
141  }
142 
143 
144  //----------------------------------------------------------------------------
145 
146 } // namespace util
147 
148 
149 //------------------------------------------------------------------------------
150 
151 #endif // LARDATA_UTILITIES_FILTERRANGEFOR_H
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
Namespace for general, non-LArSoft-specific utilities.
static auto makeEndIterator(Range &&range, Pred &&pred)
Create a Boost filter iterator pointing to the end of data.
STL namespace.
auto filterRangeFor(Range &&range, Pred &&pred) -> decltype(auto)
Provides iteration only through elements passing a condition.
static auto makeBeginIterator(Range &&range, Pred &&pred)
Create a Boost filter iterator pointing to the beginning of data.
static auto getBegin(Range &&range) -> decltype(auto)
Extract the begin iterator from a range.
FilterRangeForStruct(Range &&range, Pred &&pred)
Extracts the iterators from the specified range.
static auto getEnd(Range &&range) -> decltype(auto)
Extract the end iterator from a range.
represents a "Range" w/ notion of ordering. A range is defined by a pair of "start" and "end" values...
Definition: Range.h:34
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72