LArSoft  v07_13_02
Liquid Argon Software toolkit - http://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 
86 // C/C++ standard libraries
87 #include <stdexcept> // std::out_of_range
88 #include <iterator> // std::iterator_traits, std::reverse_iterator
89 #include <string> // std::to_string()
90 #include <type_traits> // std::declval(), ...
91 #include <cstddef> // std::size_t
92 
93 
94 namespace lar {
95 
96  // forward declarations
97  template <typename Range>
99 
100 
101  namespace details {
102 
103  //--------------------------------------------------------------------------
104  template <typename Range>
105  struct RangeTraits {
106  using range_t = Range;
108  static auto getCBegin(range_t const& range)
109  { using std::cbegin; return cbegin(range); }
110  static auto getCEnd(range_t const& range)
111  { using std::cend; return cend(range); }
112  using begin_iterator_t
113  = std::decay_t<decltype(traits_t::getCBegin(std::declval<range_t>()))>;
114  using end_iterator_t
115  = std::decay_t<decltype(traits_t::getCEnd(std::declval<range_t>()))>;
116  }; // RangeTraits<>
117 
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 
140  private:
143  }; // class CollectionExtremes<>
144 
145 
146  //--------------------------------------------------------------------------
148  template <typename BeginIter, typename EndIter>
149  auto makeCollectionExtremes(BeginIter const& b, EndIter const& e)
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 
171  //----------------------------------------------------------------------------
285  template <typename Range>
286  class CollectionView: private Range {
288  using range_t = Range;
290 
295 
297  using iter_traits_t = std::iterator_traits<begin_iter_t>;
298 
299  public:
301 
302  using value_type = typename iter_traits_t::value_type;
303  // reference not provided
304  using const_reference = typename iter_traits_t::reference;
305  // pointer not provided
306  using const_pointer = typename iter_traits_t::pointer;
307  // iterator not provided
309  // reverse_iterator not provided
310  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
311  using difference_type = typename iter_traits_t::difference_type;
312  using size_type = std::size_t;
313 
316 
318  bool empty() const noexcept { return cbegin() == cend(); }
319 
321  size_type size() const noexcept { return std::distance(cbegin(), cend()); }
322 
324  const_iterator cbegin() const noexcept
325  { using std::cbegin; return cbegin(asRange()); }
326 
328  end_iter_t cend() const noexcept
329  { using std::cend; return cend(asRange()); }
330 
332  const_iterator begin() const noexcept { return cbegin(); }
333 
335  end_iter_t end() const noexcept { return cend(); }
336 
338  auto front() const -> decltype(auto) { return *cbegin(); }
339 
341 
344 
346  const_reverse_iterator rbegin() const noexcept { return crbegin(); }
347 
349  const_reverse_iterator rend() const noexcept { return crend(); }
350 
353  { return const_reverse_iterator(cend()); }
354 
356  const_reverse_iterator crend() const noexcept
357  { return const_reverse_iterator(cbegin()); }
358 
360  auto back() const -> decltype(auto) { return *crbegin(); }
361 
363 
366 
368  auto operator[] (size_type i) const -> decltype(auto)
369  { return cbegin()[i]; }
370 
372  auto at(size_type i) const -> decltype(auto)
373  {
374  if (i >= size()) {
375  throw std::out_of_range(
376  "CollectionView index out of range: "
377  + std::to_string(i) + " >= " + std::to_string(size())
378  );
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
417  { return static_cast<range_t const&>(*this); }
418 
419  }; // class CollectionView<>
420 
421 
422  //----------------------------------------------------------------------------
424  template <typename Range>
426  { return reinterpret_cast<CollectionView<Range> const&>(c); }
427 
428 
429  //----------------------------------------------------------------------------
431  template <typename BeginIter, typename EndIter>
432  auto makeCollectionView(BeginIter const& b, EndIter const& e)
433  {
435  }
436 
438  template <typename BeginIter, typename EndIter = BeginIter>
439  using RangeAsCollection_t = decltype
440  (makeCollectionView(std::declval<BeginIter>(), std::declval<EndIter>()));
441 
442 
443  //----------------------------------------------------------------------------
444  namespace details {
445  template <typename Range>
447  { return CollectionView<Range>(std::move(range)); }
448  } // namespace details
449  //----------------------------------------------------------------------------
450 
451 } // namespace lar
452 
453 
454 #endif // LARDATA_UTILITIES_COLLECTIONVIEW_H
455 
auto at(size_type i) const -> decltype(auto)
Returns the content of the i-th element.
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.
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.
decltype(makeCollectionView(std::declval< BeginIter >(), std::declval< EndIter >())) RangeAsCollection_t
Type of collection view owning the two range boundary iterators.
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.
CollectionView(range_t &&range)
Constructor: steals the data from the specified range.
CollectionView< Range > makeCollectionView(Range &&)
Class storing a begin and a end iterator.
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
std::string to_string(Flag_t< Storage > const flag)
Convert a flag into a stream (shows its index).
Definition: BitMask.h:187
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)
const_reverse_iterator crend() const noexcept
Returns a reverse iterator past the end of the collection.
Float_t e
Definition: plot.C:34
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.