LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
CollectionView.h
Go to the documentation of this file.
1 
82 #ifndef LARDATA_UTILITIES_COLLECTIONVIEW_H
83 #define LARDATA_UTILITIES_COLLECTIONVIEW_H
84 
85 // C/C++ standard libraries
86 #include <cstddef> // std::size_t
87 #include <iterator> // std::iterator_traits, std::reverse_iterator
88 #include <stdexcept> // std::out_of_range
89 #include <string> // std::to_string()
90 #include <type_traits> // std::declval(), ...
91 
92 namespace lar {
93 
94  // forward declarations
95  template <typename Range>
97 
98  namespace details {
99 
100  //--------------------------------------------------------------------------
101  template <typename Range>
102  struct RangeTraits {
103  using range_t = Range;
105  static auto getCBegin(range_t const& range)
106  {
107  using std::cbegin;
108  return cbegin(range);
109  }
110  static auto getCEnd(range_t const& range)
111  {
112  using std::cend;
113  return cend(range);
114  }
115  using begin_iterator_t = std::decay_t<decltype(traits_t::getCBegin(std::declval<range_t>()))>;
116  using end_iterator_t = std::decay_t<decltype(traits_t::getCEnd(std::declval<range_t>()))>;
117  }; // RangeTraits<>
118 
119  //--------------------------------------------------------------------------
121  template <typename BeginIter, typename EndIter = BeginIter>
123  public:
124  using begin_iterator_t = BeginIter;
125  using end_iterator_t = EndIter;
126 
127  struct FromContainerTag {};
128  static constexpr FromContainerTag fromContainer{};
129 
131  CollectionExtremes(BeginIter b, EndIter e) : b(b), e(e) {}
132 
134  begin_iterator_t const& begin() const { return b; }
135 
137  end_iterator_t const& end() const { return e; }
138 
139  private:
142  }; // class CollectionExtremes<>
143 
144  //--------------------------------------------------------------------------
146  template <typename BeginIter, typename EndIter>
147  auto makeCollectionExtremes(BeginIter const& b, EndIter const& e)
148  {
150  }
151 
152  //--------------------------------------------------------------------------
154  template <typename Range>
155  auto makeCollectionExtremes(Range const& range)
156  {
157  using std::cbegin;
158  using std::cend;
159  return makeCollectionExtremes(cbegin(range), cend(range));
160  } // makeCollectionExtremes(range)
161 
162  //--------------------------------------------------------------------------
163  // forward declaration
164  template <typename Range>
166  //--------------------------------------------------------------------------
167 
168  } // namespace details
169 
170  //----------------------------------------------------------------------------
284  template <typename Range>
285  class CollectionView : private Range {
287  using range_t = Range;
289 
294 
296  using iter_traits_t = std::iterator_traits<begin_iter_t>;
297 
298  public:
300 
301  using value_type = typename iter_traits_t::value_type;
302  // reference not provided
303  using const_reference = typename iter_traits_t::reference;
304  // pointer not provided
305  using const_pointer = typename iter_traits_t::pointer;
306  // iterator not provided
308  // reverse_iterator not provided
309  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
310  using difference_type = typename iter_traits_t::difference_type;
311  using size_type = std::size_t;
312 
315 
317  bool empty() const noexcept { return cbegin() == cend(); }
318 
320  size_type size() const noexcept { return std::distance(cbegin(), cend()); }
321 
323  const_iterator cbegin() const noexcept
324  {
325  using std::cbegin;
326  return cbegin(asRange());
327  }
328 
330  end_iter_t cend() const noexcept
331  {
332  using std::cend;
333  return cend(asRange());
334  }
335 
337  const_iterator begin() const noexcept { return cbegin(); }
338 
340  end_iter_t end() const noexcept { return cend(); }
341 
343  auto front() const -> decltype(auto) { return *cbegin(); }
344 
346 
349 
351  const_reverse_iterator rbegin() const noexcept { return crbegin(); }
352 
354  const_reverse_iterator rend() const noexcept { return crend(); }
355 
358 
361 
363  auto back() const -> decltype(auto) { return *crbegin(); }
364 
366 
369 
371  auto operator[](size_type i) const -> decltype(auto) { return cbegin()[i]; }
372 
374  auto at(size_type i) const -> decltype(auto)
375  {
376  if (i >= size()) {
377  throw std::out_of_range("CollectionView index out of range: " + std::to_string(i) +
378  " >= " + std::to_string(size()));
379  }
380  return operator[](i);
381  }
382 
384 
387 
388  const_pointer data() const { return &front(); }
389 
391 
392  protected:
393  /*
399  CollectionViewWrapper() = default;
400  CollectionViewWrapper(this_t const&) = default;
401  CollectionViewWrapper(this_t&&) = default;
402  CollectionViewWrapper& operator=(this_t const&) = default;
403  CollectionViewWrapper& operator=(this_t&&) = default;
405  */
406 
408  explicit CollectionView(range_t&& range) : range_t(std::move(range)) {}
409 
410  // we license the creation of this class from ranges to a single function
411  // (and to derived classes)
412  friend this_t details::makeCollectionView<range_t>(range_t&&);
413 
414  private:
416  range_t const& asRange() const { return static_cast<range_t const&>(*this); }
417 
418  }; // class CollectionView<>
419 
420  //----------------------------------------------------------------------------
422  template <typename Range>
424  {
425  return reinterpret_cast<CollectionView<Range> const&>(c);
426  }
427 
428  //----------------------------------------------------------------------------
430  template <typename BeginIter, typename EndIter>
431  auto makeCollectionView(BeginIter const& b, EndIter const& e)
432  {
434  }
435 
437  template <typename BeginIter, typename EndIter = BeginIter>
438  using RangeAsCollection_t =
439  decltype(makeCollectionView(std::declval<BeginIter>(), std::declval<EndIter>()));
440 
441  //----------------------------------------------------------------------------
442  namespace details {
443  template <typename Range>
445  {
446  return CollectionView<Range>(std::move(range));
447  }
448  } // namespace details
449  //----------------------------------------------------------------------------
450 
451 } // namespace lar
452 
453 #endif // LARDATA_UTILITIES_COLLECTIONVIEW_H
Provides features of a collections, from begin and end iterators.
auto makeCollectionExtremes(BeginIter const &b, EndIter const &e)
Helper to create a CollectionExtremes object from two iterators.
decltype(auto) constexpr cend(T &&obj)
ADL-aware version of std::cend.
Definition: StdUtils.h:93
auto at(size_type i) const -> decltype(auto)
Returns the content of the i-th element.
end_iter_t cend() const noexcept
Returns an iterator past the end of the collection.
const_reverse_iterator crbegin() const noexcept
Returns a reverse iterator to the begin of the collection.
std::decay_t< decltype(traits_t::getCBegin(std::declval< range_t >()))> begin_iterator_t
range_t collection_type
Type of collection being wrapped.
const_iterator cbegin() const noexcept
Returns an iterator to the begin of the collection.
STL namespace.
const_iterator begin() const noexcept
Returns an iterator to the begin of the collection.
begin_iterator_t b
Stored copy of begin iterator.
typename iter_traits_t::difference_type difference_type
typename traits_t::end_iterator_t end_iter_t
Type of the end iterator.
CollectionExtremes(BeginIter b, EndIter e)
Constructor: copies the specified iterators.
end_iterator_t const & end() const
Returns the stored end iterator.
BoundaryListRangeBase< BoundaryIter > range_t
Type of the range being wrapped.
decltype(makeCollectionView(std::declval< BeginIter >(), std::declval< EndIter >())) RangeAsCollection_t
Type of collection view owning the two range boundary iterators.
CollectionView(range_t &&range)
Constructor: steals the data from the specified range.
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
CollectionView< Range > makeCollectionView(Range &&)
Class storing a begin and a end iterator.
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
auto front() const -> decltype(auto)
Returns the first element in the collection.
size_type size() const noexcept
Returns the size of the collection.
range_t const & asRange() const
Returns this very object, cast back to range_t.
std::reverse_iterator< const_iterator > const_reverse_iterator
typename traits_t::begin_iterator_t begin_iter_t
Type of the begin iterator.
LArSoft-specific namespace.
begin_iterator_t const & begin() const
Returns the stored begin iterator.
std::iterator_traits< begin_iter_t > iter_traits_t
Type of traits of iterator.
auto back() const -> decltype(auto)
Returns the last element in the collection.
const_reverse_iterator rbegin() const noexcept
Returns a reverse iterator to the begin of the collection.
static auto getCEnd(range_t const &range)
decltype(auto) constexpr cbegin(T &&obj)
ADL-aware version of std::cbegin.
Definition: StdUtils.h:85
auto operator[](size_type i) const -> decltype(auto)
Returns the content of the i-th element.
const_reverse_iterator crend() const noexcept
Returns a reverse iterator past the end of the collection.
Float_t e
Definition: plot.C:35
end_iter_t end() const noexcept
Returns an iterator past the end of the collection.
const_reverse_iterator rend() const noexcept
Returns a reverse iterator past the end of the collection.
end_iterator_t e
Stored copy of end iterator.
CollectionView< Range > const & wrapCollectionIntoView(Range const &c)
Returns the specified container, wrapped in the view.
std::decay_t< decltype(traits_t::getCEnd(std::declval< range_t >()))> end_iterator_t
const_pointer data() const
static auto getCBegin(range_t const &range)
bool empty() const noexcept
Returns whether the collection is empty.