LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
filterRangeFor.h
Go to the documentation of this file.
1 
10 #ifndef LARDATA_UTILITIES_FILTERRANGEFOR_H
11 #define LARDATA_UTILITIES_FILTERRANGEFOR_H
12 
13 // Boost libraries
14 #include <boost/iterator/filter_iterator.hpp>
15 
16 namespace util {
17 
57  template <typename Range, typename Pred>
58  auto filterRangeFor(Range&& range, Pred&& pred) -> decltype(auto);
59 
60 } // namespace util
61 
62 //------------------------------------------------------------------------------
63 //--- implementation
64 //------------------------------------------------------------------------------
65 namespace util {
66 
67  namespace details {
68 
69  //--------------------------------------------------------------------------
70  template <typename Range, typename Pred>
72 
74  static auto getBegin(Range&& range) -> decltype(auto)
75  {
76  using std::begin;
77  return begin(range);
78  }
79 
81  static auto getEnd(Range&& range) -> decltype(auto)
82  {
83  using std::end;
84  return end(range);
85  }
86 
88  static auto makeBeginIterator(Range&& range, Pred&& pred)
89  {
90  auto begin = getBegin(std::forward<Range>(range));
91  auto end = getEnd(std::forward<Range>(range));
92  return boost::make_filter_iterator(std::forward<Pred>(pred), begin, end);
93  }
94 
96  static auto makeEndIterator(Range&& range, Pred&& pred)
97  {
98  auto end = getEnd(std::forward<Range>(range));
99  return boost::make_filter_iterator(std::forward<Pred>(pred), end, end);
100  }
101 
102  using begin_iterator_t =
103  decltype(makeBeginIterator(std::declval<Range&&>(), std::declval<Pred&&>()));
104  using end_iterator_t =
105  decltype(makeEndIterator(std::declval<Range&&>(), std::declval<Pred&&>()));
106 
109 
110  public:
112  FilterRangeForStruct(Range&& range, Pred&& pred)
113  : fBegin(makeBeginIterator(std::forward<Range>(range), std::forward<Pred>(pred)))
114  , fEnd(makeEndIterator(std::forward<Range>(range), std::forward<Pred>(pred)))
115  {}
116 
117  auto begin() const { return fBegin; }
118  auto end() const { return fEnd; }
119 
120  }; // class FilterRangeForStruct<>
121 
122  //--------------------------------------------------------------------------
123 
124  } // namespace details
125 
126  //----------------------------------------------------------------------------
127  template <typename Range, typename Pred>
128  auto filterRangeFor(Range&& range, Pred&& pred) -> decltype(auto)
129  {
130  return details::FilterRangeForStruct<Range, Pred>(std::forward<Range>(range),
131  std::forward<Pred>(pred));
132  }
133 
134  //----------------------------------------------------------------------------
135 
136 } // namespace util
137 
138 //------------------------------------------------------------------------------
139 
140 #endif // LARDATA_UTILITIES_FILTERRANGEFOR_H
Namespace for general, non-LArSoft-specific utilities.
Definition: PIDAAlg.h:26
static auto makeEndIterator(Range &&range, Pred &&pred)
Create a Boost filter iterator pointing to the end of data.
decltype(makeBeginIterator(std::declval< Range && >(), std::declval< Pred && >())) begin_iterator_t
STL namespace.
auto filterRangeFor(Range &&range, Pred &&pred) -> decltype(auto)
Provides iteration only through elements passing a condition.
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
static auto makeBeginIterator(Range &&range, Pred &&pred)
Create a Boost filter iterator pointing to the beginning of data.
static auto getEnd(Range &&range) -> decltype(auto)
Extract the end iterator from a range.
FilterRangeForStruct(Range &&range, Pred &&pred)
Extracts the iterators from the specified range.
decltype(makeEndIterator(std::declval< Range && >(), std::declval< Pred && >())) end_iterator_t
represents a "Range" w/ notion of ordering. A range is defined by a pair of "start" and "end" values...
Definition: Range.h:35
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
static auto getBegin(Range &&range) -> decltype(auto)
Extract the begin iterator from a range.