LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
AssociatedData.h
Go to the documentation of this file.
1 
11 #ifndef LARDATA_RECOBASEPROXY_PROXYBASE_ASSOCIATEDDATA_H
12 #define LARDATA_RECOBASEPROXY_PROXYBASE_ASSOCIATEDDATA_H
13 
14 // LArSoft libraries
18 #include "lardata/Utilities/TupleLookupByTag.h" // util::add_tag_t, ...
19 #include "larcorealg/CoreUtils/MetaUtils.h" // util::is_not_same<>
20 
21 // framework libraries
24 
25 // C/C++ standard libraries
26 #include <vector>
27 // #include <tuple> // std::tuple_element_t<>, std::get()
28 #include <iterator> // std::distance(), std::forward_iterator_tag, ...
29 #include <algorithm> // std::min()
30 #include <memory> // std::addressof()
31 #include <utility> // std::forward(), std::declval(), ...
32 #include <type_traits> // std::is_same<>, std::enable_if_t<>, ...
33 #include <cstdlib> // std::size_t
34 #include <cassert>
35 
36 
37 namespace proxy {
38 
39 
40  //----------------------------------------------------------------------------
46  //----------------------------------------------------------------------------
47  namespace details {
48 
49  //--------------------------------------------------------------------------
50  //--- general infrastructure
51  //--------------------------------------------------------------------------
52 
98  template <
99  typename Iter,
100  typename DataIter,
101  typename ValueType = typename DataIter::value_type
102  >
103  class IteratorWrapperBase: private DataIter {
104  protected:
105  using data_iterator_t = DataIter;
106 
107  public:
108  using iterator = Iter;
109 
112  using typename data_iterator_t::difference_type;
113  using value_type = ValueType;
114  using pointer = std::add_pointer_t<value_type>;
115  using reference = std::add_lvalue_reference_t<value_type>;
116  using iterator_category = std::forward_iterator_tag;
118 
120  IteratorWrapperBase() = default;
121 
124 
127  { data_iterator_t::operator++(); return asIterator(); }
128 
130  bool operator!=(data_iterator_t const& other) const
131  { return other != asDataIterator(); }
132 
134  bool operator!=(iterator const& other) const
135  { return operator!=(other.asDataIterator()); }
136 
137  auto operator[](std::size_t index) const -> decltype(auto)
138  { return asIterator().transform(asDataIterator() + index); }
139 
141  auto operator*() const -> decltype(auto)
142  { return asIterator().transform(asDataIterator()); }
143 
145  auto operator->() const -> decltype(auto)
146  { return makeValuePointer(operator*()); }
147 
148 
149  protected:
151  static auto transform(data_iterator_t const&) -> decltype(auto)
152  { return data_iterator_t::operator*(); }
153 
155  { return static_cast<data_iterator_t const&>(*this); }
156 
157  private:
159  template <typename Value>
160  class ValuePtr {
161  Value value;
162  public:
163  ValuePtr(Value const& value): value(value) {}
165  auto operator->() const -> decltype(auto)
166  { return std::addressof(value); }
167  }; // class ValuePtr<>
168  template <typename Value>
169  static ValuePtr<Value> makeValuePointer(Value&& value)
170  { return { std::forward<Value>(value) }; }
171 
172  iterator const& asIterator() const
173  { return static_cast<iterator const&>(*this); }
174  iterator& asIterator() { return static_cast<iterator&>(*this); }
175 
176  }; // IteratorWrapperBase<>
177 
178 #if 0
179 
181  template <std::size_t N, typename TupleIter>
182  class tuple_element_iterator:
183  public IteratorWrapperBase<
184  tuple_element_iterator<N, TupleIter>,
185  TupleIter,
186  std::tuple_element_t<N, typename TupleIter::value_type>
187  >
188  {
189  using base_iterator_t = IteratorWrapperBase<
190  tuple_element_iterator<N, TupleIter>,
191  TupleIter,
192  std::tuple_element_t<N, typename TupleIter::value_type>
193  >;
194 
195  public:
196  using base_iterator_t::base_iterator_t;
197 
199  tuple_element_iterator(base_iterator_t const& from)
200  : base_iterator_t(from) {}
201 
202  static auto transform(TupleIter const& v) -> decltype(auto)
203  {return std::get<N>(*v); }
204 
205  }; // tuple_element_iterator
206 
207 #endif // 0
208  //--------------------------------------------------------------------------
209  //--- BEGIN iterators for art::Assns
210  //--------------------------------------------------------------------------
211 
212  //--------------------------------------------------------------------------
213 
215  template <typename ArtAssnsIterValue>
216  class AssnsNode: private ArtAssnsIterValue {
217 
218  using base_t = ArtAssnsIterValue;
220  using node_t = ArtAssnsIterValue;
221 
224 
225  public:
226 
228  using main_t = typename assns_node_traits_t::left_t;
229 
231  using value_t = typename assns_node_traits_t::right_t;
232 
234  using data_t = typename assns_node_traits_t::data_t;
235 
237  using mainptr_t = typename assns_node_traits_t::leftptr_t;
238 
240  using valueptr_t = typename assns_node_traits_t::rightptr_t;
241 
243  using dataptr_t = typename assns_node_traits_t::dataptr_t;
244 
247 
249  valueptr_t const& valuePtr() const { return base_t::second; }
250 
252  value_t const& value() const { return *valuePtr(); }
253 
255 
258 
260  mainptr_t const& mainPtr() const { return base_t::first; }
261 
263  main_t const& main() const { return *mainPtr(); }
264 
266 
268 
276  // the templates are needed to activate "SFINAE" on std::enable_if
278  template <typename Node = node_t>
279  static constexpr bool hasMetadata()
280  { return lar::util::assns_has_metadata_v<Node>; }
281 
283  template <typename Node = node_t>
284  std::enable_if_t<hasMetadata<Node>(), dataptr_t> dataPtr() const
285  { return base_t::data; }
286 
287  // this is even more complicate, since if `data_t` is void we can't write
288  // `data_t const&` as type of enable_if, because it does not depend on
289  // templates and therefore it may be unconditionally evaluated;
290  // and C++ does not like references to `void`...
292  template <typename Node = node_t>
293  std::enable_if_t<
294  hasMetadata<Node>(),
296  >
297  data() const { return *dataPtr(); }
298 
300 
301 
304 
306  operator valueptr_t const& () const& { return valuePtr(); }
307 
309  operator valueptr_t() const&& { return valuePtr(); }
310 
312  value_t const& operator*() const { return value(); }
313 
315  valueptr_t operator-> () const { return valuePtr(); }
316 
318  auto key() const -> decltype(auto) { return valuePtr().key(); }
319 
321  auto id() const -> decltype(auto) { return valuePtr().id(); }
323 
324 
326  static this_t const& makeFrom(node_t const& from)
327  { return static_cast<this_t const&>(from); }
328 
329  }; // class AssnsNode<>
330 
331 
332  template <typename ArtAssnsIterValue>
336  )
337  { return A.valuePtr() == B; }
338  template <typename ArtAssnsIterValue>
342  )
343  { return A == B.valuePtr(); }
344  template <typename ArtAssnsIterValue>
348  )
349  { return A.valuePtr() != B; }
350  template <typename ArtAssnsIterValue>
354  )
355  { return A != B.valuePtr(); }
356 
357 
359  template <typename ArtAssnsIterValue>
360  AssnsNode<ArtAssnsIterValue> const& makeAssnsNode(ArtAssnsIterValue const& from)
362 
363  } // namespace details
364 } // namespace proxy
365 
366 // we interrupt this namespace for an urgent specialization...
367 namespace lar {
368  namespace util {
369 
370  // specialization for the art node wrapper
371  template <typename ArtAssnsIterValue>
372  struct assns_metadata_type<proxy::details::AssnsNode<ArtAssnsIterValue>>
373  : assns_metadata_type<ArtAssnsIterValue>
374  {};
375 
376  } // namespace util
377 } // namespace lar
378 
379 // back to what we were doing:
380 namespace proxy {
381  namespace details{
382 
383  //--------------------------------------------------------------------------
385  template <typename ArtAssnsIter>
387  : public lar::util::assns_traits<typename ArtAssnsIter::value_type>
388  {
389  using art_node_t = typename ArtAssnsIter::value_type;
391  }; // struct AssnsIterTraits
392 
393 
396  template <typename ArtAssnsIter>
398  public IteratorWrapperBase<
399  assns_node_iterator<ArtAssnsIter>,
400  ArtAssnsIter,
401  typename AssnsIterTraits<ArtAssnsIter>::node_t
402  >
403  {
406  ArtAssnsIter,
408  >;
409 
410  using art_assns_iter_t = ArtAssnsIter;
412 
414  using AssnsNode_t = typename traits_t::node_t;
416 
417  public:
418  using base_iterator_t::base_iterator_t;
419 
422  : base_iterator_t(from) {}
423 
425  AssnsNode_t const& info() const { return base_iterator_t::operator*(); }
426 
428  AssnsNode_t const& operator() () const { return info(); }
429 
430  //--- BEGIN Access to the full association information -------------------
434 
435  using main_t = typename AssnsNode_t::main_t;
436  using value_t = typename AssnsNode_t::value_t;
437  using data_t = typename AssnsNode_t::data_t;
438  using mainptr_t = typename AssnsNode_t::mainptr_t;
439  using valueptr_t = typename AssnsNode_t::valueptr_t;
440  using dataptr_t = typename AssnsNode_t::dataptr_t;
441 
443  valueptr_t valuePtr() const { return info().valuePtr(); }
444 
446  value_t const& value() const { return info().value(); }
447 
449  mainptr_t mainPtr() const { return info().mainPtr(); }
450 
452  main_t const& main() const { return info().main(); }
453 
454  // see the comments on AssnsNode for the need of all these decorations
456  template <typename Node = AssnsNode_t>
457  static constexpr bool hasMetadata()
458  { return lar::util::assns_has_metadata_v<Node>; }
459 
461  template <typename ArtNode = ArtAssnsNode_t>
462  std::enable_if_t<hasMetadata<ArtNode>(), dataptr_t> dataPtr() const
463  { return info().dataPtr(); }
464 
466  template <typename ArtNode = ArtAssnsNode_t>
467  std::enable_if_t<
468  hasMetadata<ArtNode>(),
470  >
471  data() const
472  { return info().data(); }
473 
475  //--- END Access to the full association information ---------------------
476 
477  /*
478  * Associations with metadata have an iterator with value type
479  * art::AssnsNode, while the value for the ones without have just a
480  * std::pair.
481  * The std::pair returned by the one without metadata is a reference to an
482  * element of the original collection.
483  * Instead, the art::AssnsNode returned by the art::Assns iterator is a
484  * temporary put together copying information from the original pair
485  * collection and from the parallel metadata collection.
486  * Therefore, in the first case we can return references to the existing
487  * data, while in the latter we can't and we have to return the results by
488  * value.
489  * In this implementation we compromise and return always the data by
490  * value; the values are art pointers, or plain pointers, so the copy
491  * should not be extremely taxing. It is possible to change this, at the
492  * cost of additional complexity of the implementation.
493  */
494  static AssnsNode_t const& transform(art_assns_iter_t const& v)
495  { return makeAssnsNode(*v); }
496 
497  }; // class assns_node_iterator<>
498 
499  //--- END iterators for art::Assns -----------------------------------------
500 
501 
502  //--------------------------------------------------------------------------
503  //--- stuff for associated data (a form of auxiliary data)
504  //--------------------------------------------------------------------------
505 
508  template <typename BoundaryIter>
509  class BoundaryListRangeBase: private BoundaryIter {
510  using boundary_iterator_t = BoundaryIter;
511 
513  auto boundaryIter() const
514  { return static_cast<BoundaryIter const&>(*this); }
515 
516  public:
519  : boundary_iterator_t(it) {}
520 
522  auto begin() const -> decltype(auto)
523  { return *(boundaryIter()); }
524 
526  auto end() const -> decltype(auto)
527  { return *(std::next(boundaryIter())); }
528 
529  }; // BoundaryListRangeBase<>
530 
531 
533  template <typename BoundaryIter>
535  : public lar::CollectionView<BoundaryListRangeBase<BoundaryIter>>
536  {
537  // A CollectionView can't be constructed except from deriver classes;
538  // we define here such a class.
539 
542  public:
543  using boundary_iterator_t = BoundaryIter;
544 
547  : base_t(rangebase_t(iBegin))
548  {}
549 
550  }; // class BoundaryListRange<>
551 
552 
573  template <typename BoundaryIter>
575  (BoundaryIter const& iBegin)
576  { return { iBegin }; }
577 
578 
605  template <typename BoundaryIter>
607  : public IteratorWrapperBase
608  <BoundaryListRangeIterator<BoundaryIter>, BoundaryIter>
609  {
612 
613  public:
614  using boundary_iterator_t = BoundaryIter;
615 
617  using rangeview_t
618  = decltype(makeBoundaryListRange(std::declval<boundary_iterator_t>()));
619 
621  using pointer = std::add_pointer_t<std::decay_t<value_type>>;
622  using reference = std::add_lvalue_reference_t<std::decay_t<value_type>>;
623 
624 
625  using base_t::base_t; // import constructors (explicitly allowed)
626 
635  static auto transform(BoundaryIter const& iter)
636  { return makeBoundaryListRange(iter); }
637 
638  }; // class BoundaryListRangeIterator<>
639 
640 
668  template <typename Iter>
669  class BoundaryList {
671  public:
672  using data_iterator_t = Iter;
673  using boundaries_t = std::vector<data_iterator_t>;
674 
676  using range_iterator_t
678 
680  // BoundaryListRange<data_iterator_t> const&
682 
685 
686 
688  explicit BoundaryList(boundaries_t&& boundaries)
689  : boundaries(std::move(boundaries))
690  { assert(this->boundaries.size() >= 1); }
691 
693  std::size_t nRanges() const
694  { return boundaries.size() - 1; }
696  data_iterator_t const& rangeBegin(std::size_t i) const
697  { return boundaries[std::min(i, nRanges())]; }
699  data_iterator_t const& rangeEnd(std::size_t i) const
700  { return rangeBegin(i + 1); }
701 
703  std::size_t size() const { return nRanges(); }
706  { return { boundaries.begin() }; }
709  { return { std::prev(boundaries.end()) }; }
724  range_ref_t rangeRef(std::size_t i) const
725  { return { std::next(boundaries.begin(), i) }; }
739  range_t range(std::size_t i) const
740  { return lar::makeCollectionView(rangeBegin(i), rangeEnd(i)); }
741 
744  auto operator[](std::size_t i) const -> decltype(auto)
745  { return range(i); }
746 
747  private:
750 
751  }; // class BoundaryList
752 
753 
777  template <
778  typename Main, typename Aux, typename Metadata /* = void */,
779  typename Tag /* = Aux */
780  >
783 
784  public:
787 
788  private:
791  // = tuple_element_iterator<1U, lar::util::assns_iterator_t<assns_t>>;
792 
793  public:
794  using tag = Tag;
795 
797 
799  using auxiliary_data_t
801 
802  // constructor is not part of the interface
804  : fGroups(std::move(groups))
805  {}
806 
808  auto begin() const -> decltype(auto)
809  { return fGroups.begin(); }
810 
812  auto end() const -> decltype(auto)
813  { return fGroups.end(); }
814 
816  auto getRange(std::size_t i) const -> decltype(auto)
817  { return util::makeTagged<tag>(fGroups.range(i)); }
818 
820  auto operator[] (std::size_t index) const -> decltype(auto)
821  {
822  static_assert(
823  std::is_convertible<decltype(getRange(index)), auxiliary_data_t>(),
824  "Inconsistent data types."
825  );
826  return getRange(index);
827  }
828 
830  template <typename TestTag>
831  static constexpr bool hasTag() { return std::is_same<TestTag, tag>(); }
832 
833  private:
835 
836  }; // class AssociatedData<>
837 
838  //--------------------------------------------------------------------------
839 
840  } // namespace details
841 
842 
843  //----------------------------------------------------------------------------
845 
876  template <typename Tag, typename Assns>
877  auto makeAssociatedData(Assns const& assns, std::size_t minSize = 0);
878 
879  template <typename Assns>
880  auto makeAssociatedData(Assns const& assns, std::size_t minSize = 0)
881  { return makeAssociatedData<typename Assns::right_t>(assns, minSize); }
883 
884 
886 
901  template <typename Tag, typename MainColl, typename Assns>
902  auto makeAssociatedData(MainColl const& mainColl, Assns const& assns)
903  { return makeAssociatedData<Tag>(assns, mainColl.size()); }
904 
905  template <typename MainColl, typename Assns>
906  auto makeAssociatedData(MainColl const& mainColl, Assns const& assns)
907  { return makeAssociatedData<typename Assns::right_t>(mainColl, assns); }
909 
910 
911  //----------------------------------------------------------------------------
912 
913 
914 } // namespace proxy
915 
916 
917 //------------------------------------------------------------------------------
918 //--- template implementation
919 //------------------------------------------------------------------------------
920 namespace proxy {
921 
922  namespace details {
923 
924  //--------------------------------------------------------------------------
925  //--- associationRangeBoundaries() implementation
926  //--------------------------------------------------------------------------
927  template <std::size_t GroupKey, typename Iter>
929  (Iter begin, Iter end, std::size_t expectedSize /* = 0 */)
930  {
931  constexpr auto KeyIndex = GroupKey;
932 
933  auto extractKey
934  = [](auto const& assn){ return std::get<KeyIndex>(assn).key(); };
935 
936  typename BoundaryList<Iter>::boundaries_t boundaries;
937  boundaries.reserve(expectedSize + 1);
938  boundaries.push_back(begin);
939  std::size_t current = 0;
940  for (auto it = begin; it != end; ++it) {
941  auto const key = extractKey(*it);
942  if (key == current) continue;
943  if (key < current) {
944  auto index = std::distance(begin, it);
945  throw std::runtime_error("associationRanges() got input element #"
946  + std::to_string(index - 1) + " with key " + std::to_string(current)
947  + " and the next with key " + std::to_string(key) + "!"
948  );
949  }
950  boundaries.insert(boundaries.end(), key - current, it);
951  current = key;
952  } // for
953  boundaries.push_back(end);
954  return boundaries;
955  } // associationRangesImpl()
956 
957 
958  //--------------------------------------------------------------------------
959  template <std::size_t GroupKey, typename Iter>
960  auto associationRangeBoundaries(Iter begin, Iter end)
961  { return associationRangesImpl<GroupKey, Iter>(begin, end); }
962 
963 
964  //--------------------------------------------------------------------------
965  template <std::size_t GroupKey, typename Iter>
966  auto associationRangeBoundaries(Iter begin, Iter end, std::size_t n) {
967  auto boundaries = associationRangesImpl<GroupKey, Iter>(begin, end, n);
968  if (boundaries.size() <= n) {
969  boundaries.insert
970  (boundaries.end(), n + 1 - boundaries.size(), boundaries.back());
971  assert(boundaries.size() == (n + 1));
972  }
973  return boundaries;
974  } // associationRangeBoundaries(Iter, Iter, std::size_t)
975 
976 
977  //--------------------------------------------------------------------------
1000  template <std::size_t GroupKey, typename Iter>
1002  {
1003  return BoundaryList<Iter>
1004  (associationRangeBoundaries<GroupKey>(begin, end));
1005  }
1006 
1025  template <std::size_t GroupKey, typename Iter>
1026  BoundaryList<Iter> associationRanges(Iter begin, Iter end, std::size_t n)
1027  {
1028  return BoundaryList<Iter>
1029  (associationRangeBoundaries<GroupKey>(begin, end, n));
1030  }
1031 
1032 
1033  //--------------------------------------------------------------------------
1034 
1035  } // namespace details
1036 
1037 
1038  //----------------------------------------------------------------------------
1039  template <typename Tag, typename Assns>
1040  auto makeAssociatedData(Assns const& assns, std::size_t minSize /* = 0 */)
1041  {
1042  using Main_t = typename Assns::left_t;
1043  using Aux_t = typename Assns::right_t;
1044  using Metadata_t = lar::util::assns_metadata_t<Assns>;
1045  using AssociatedData_t
1047 
1048  // associationRangeBoundaries() produces iterators to association elements,
1049  // (i.e. tuples)
1050  using std::begin;
1051  using std::end;
1052  auto ranges = details::associationRangeBoundaries<0U>
1053  (begin(assns), end(assns), minSize);
1054  // we convert those iterators into iterators to the right associated item
1055  // (it takes a few steps)
1056  using group_ranges_t = typename AssociatedData_t::group_ranges_t;
1057  return AssociatedData_t(
1058  group_ranges_t
1059  (typename group_ranges_t::boundaries_t(ranges.begin(), ranges.end()))
1060  );
1061  } // makeAssociatedDataFrom(assns)
1062 
1063 
1064  //----------------------------------------------------------------------------
1065 
1066 } // namespace proxy
1067 //------------------------------------------------------------------------------
1068 
1069 #endif // LARDATA_RECOBASEPROXY_PROXYBASE_ASSOCIATEDDATA_H
boundaries_t boundaries
Begin iterator of each range, plus end iterator of whole sequence.
IteratorWrapperBase(data_iterator_t const &from)
Copy-from-base constructor.
BoundaryIter boundary_iterator_t
Type of boundary iterator.
auto end() const -> decltype(auto)
Returns the end iterator of the range (next to the begin iterator).
Provides features of a collections, from begin and end iterators.
Namespace for general, non-LArSoft-specific utilities.
Definition: PIDAAlg.h:17
decltype(makeBoundaryListRange(std::declval< boundary_iterator_t >())) rangeview_t
Type of range returned when dereferencing.
static AssnsNode_t const & transform(art_assns_iter_t const &v)
value_t const & value() const
Returns a reference to the associated value.
Builds and keeps track of internal boundaries in a sequence.
auto end() const -> decltype(auto)
Returns an iterator pointing past the last associated data range.
range_ref_t rangeRef(std::size_t i) const
Returns the specified range.
Basic C++ metaprogramming utilities.
typename AssnsNode_t::main_t main_t
Returns the art pointer to the associated value.
BoundaryList< Iter >::boundaries_t associationRangesImpl(Iter begin, Iter end, std::size_t expectedSize)
auto operator[](std::size_t index) const -> decltype(auto)
main_t const & main() const
Returns the main value, key of the association.
AssnsNode< ArtAssnsIterValue > const & makeAssnsNode(ArtAssnsIterValue const &from)
Reinterprets the specified association node as a AssnsNode.
bool operator==(AssnsNode< ArtAssnsIterValue > const &A, typename AssnsNode< ArtAssnsIterValue >::valueptr_t const &B)
data_iterator_t const & asDataIterator() const
Int_t B
Definition: plot.C:25
BoundaryListRange(boundary_iterator_t const &iBegin)
Constructor: from an iterator to the begin iterator.
BoundaryListRange< BoundaryIter > makeBoundaryListRange(BoundaryIter const &iBegin)
Reinterprets a iterator to boundaries list as a range collection.
decltype(makeCollectionView(std::declval< BeginIter >(), std::declval< EndIter >())) RangeAsCollection_t
Type of collection view owning the two range boundary iterators.
typename assns_node_traits_t::leftptr_t mainptr_t
Type of art pointer to the main (left) object in the association.
auto boundaryIter() const
Returns the iterator to the begin iterator.
typename assns_metadata_type< Assns >::type assns_metadata_t
Trait: type of metadata in Assns (association or its node).
Definition: AssnsTraits.h:62
STL namespace.
Trait: type is metadata in Assns (association or its node).
Definition: AssnsTraits.h:57
typename assns_node_traits_t::right_t value_t
Type of the associated (right) object.
iterator const & asIterator() const
typename range_iterator_t::value_type range_ref_t
Structure holding begin and end iterator for a single range.
Specializations of STL tuple utilities for art::AssnsNode.
std::add_lvalue_reference_t< std::decay_t< value_type >> reference
typename add_tag< T, Tag >::type add_tag_t
typename assns_node_traits_t::rightptr_t valueptr_t
Type of art pointer to the associated (right) object.
data_iterator_t const & rangeBegin(std::size_t i) const
Returns the begin iterator of the i-th range (end if overflow).
BoundaryListRangeBase(boundary_iterator_t const &it)
Constructor: copies the specified base iterator.
typename AssnsNode_t::value_t value_t
Returns the art pointer to the associated value.
auto getRange(std::size_t i) const -> decltype(auto)
Returns the range with the specified index (no check performed).
range_iterator_t begin() const
Returns the begin iterator of the first range.
static this_t const & makeFrom(node_t const &from)
Reinterprets the specified association node as a AssnsNode.
auto associationRangeBoundaries(Iter begin, Iter end)
typename AssnsNode_t::valueptr_t valueptr_t
Returns the art pointer to the associated value.
valueptr_t const & valuePtr() const
Returns the art pointer to the associated value.
Object to draft associated data interface.
A BoundaryListRangeBase with a full container interface.
std::size_t size() const
Returns the number of ranges contained in the list.
static constexpr bool hasMetadata()
Returns whether this node type supports metadata.
auto begin() const -> decltype(auto)
Returns the begin iterator of the range.
Value box for use with pointer dereference operator->().
Tag tag
Tag of this association proxy.
Traits for a association iterator.
std::enable_if_t< hasMetadata< ArtNode >), typename lar::util::assns_traits< ArtNode >::data_t const & > data() const
Returns a reference to the metadata on this association node.
std::size_t nRanges() const
Returns the number of ranges contained in the list.
ArtAssnsIterValue node_t
Type of the wrapped node.
auto operator*() const -> decltype(auto)
Dereference operator; need to be redefined by derived classes.
main_t const & main() const
Returns the main value, key of the association.
AssnsNode_t const & info() const
Returns the full information the iterator points to.
typename ArtAssnsIter::value_type art_node_t
std::add_pointer_t< std::decay_t< value_type >> pointer
typename AssnsNode_t::mainptr_t mainptr_t
Returns the art pointer to the associated value.
BoundaryList(boundaries_t &&boundaries)
Constructor: steals the specified boundary list.
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
std::enable_if_t< hasMetadata< Node >), typename lar::util::assns_traits< Node >::data_t const & > data() const
Returns a reference to the metadata on this association node.
Encloses LArSoft data product proxy objects and utilities.See this doxygen module for an introduction...
Simple iterator wrapper for manipulation of dereferenced result.
mainptr_t mainPtr() const
Returns the art pointer to the main value, key of the association.
assns_node_iterator(base_iterator_t const &from)
Constructor from a base iterator (explicitly allowed).
auto id() const -> decltype(auto)
Returns the product ID of the art pointer to the value.
util::add_tag_t< typename group_ranges_t::range_t, tag > auxiliary_data_t
Type of collection of auxiliary data associated with a main item.
Value value
Value to return the address of (may be reference).
Data types for the specified association type (or its node).
Definition: AssnsTraits.h:102
IteratorWrapperBase()=default
Default constructor: default-constructs the underlying iterator.
auto begin() const -> decltype(auto)
Returns an iterator pointing to the first associated data range.
static auto transform(data_iterator_t const &) -> decltype(auto)
Transforms and returns the value at the specified data iterator.
valueptr_t valuePtr() const
Returns the art pointer to the associated value.
typename assns_node_traits_t::left_t main_t
Type of the main (left) object in the association.
lar::RangeAsCollection_t< data_iterator_t > range_t
Range object directly containing the boundary iterators.
mainptr_t const & mainPtr() const
Returns the art pointer to the main value, key of the association.
iterator & operator++()
Prefix increment operator.
std::enable_if_t< hasMetadata< Node >), dataptr_t > dataPtr() const
Returns the pointer to the metadata on this association node.
Provides the features of a collections, from begin and end iterators.
static constexpr bool hasMetadata()
Returns whether this node type supports metadata.
auto makeCollectionView(BeginIter const &b, EndIter const &e)
Creates a CollectionView from the specified iterators.
typename AssnsNode_t::data_t data_t
Returns the art pointer to the associated value.
static ValuePtr< Value > makeValuePointer(Value &&value)
std::enable_if_t< hasMetadata< ArtNode >), dataptr_t > dataPtr() const
Returns the pointer to the metadata on this association node.
typename traits_t::node_t AssnsNode_t
Type of node for this association iterator.
bool operator!=(iterator const &other) const
Comparison with another iterator.
This type extends the interface of the art pointer to Assns right side.
value_t const & value() const
Returns the art pointer to the associated value.
auto operator->() const -> decltype(auto)
Dereference operator; need to be redefined by derived classes.
AssociatedData(group_ranges_t &&groups)
range_iterator_t end() const
Returns the end iterator of the last range.
typename assns_node_traits_t::data_t data_t
Type of the associated additional data (void if none).
typename assns_node_traits_t::dataptr_t dataptr_t
Type of the pointer to associated additional data.
std::string to_string(Flag_t< Storage > const flag)
Convert a flag into a stream (shows its index).
Definition: BitMask.h:187
LArSoft-specific namespace.
range_t range(std::size_t i) const
Returns the specified range in an object holding the iterators.
bool operator!=(data_iterator_t const &other) const
Comparison with a data iterator (makes unnecessary to wrap end iterators).
Int_t min
Definition: plot.C:26
Iterator exposing elements of a boundary list as ranges.
auto operator[](std::size_t i) const -> decltype(auto)
Utilities to address elements of a tuple-like class by tag.
auto makeAssociatedData(Assns const &assns, std::size_t minSize=0)
Processes and returns an associated data object.
typename traits_t::art_node_t ArtAssnsNode_t
Traits for art associations.
static constexpr bool hasTag()
Returns whether this data is labeled with the specified tag.
data_iterator_t const & rangeEnd(std::size_t i) const
Returns the end iterator of the i-th range (end if overflow).
Char_t n[5]
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
ArtAssnsIterValue base_t
Base class type.
value_t const & operator*() const
Returns a reference to the associated value (alias of value()).
auto operator->() const -> decltype(auto)
Access the contained value via its pointer.
QuadExpr operator*(double v, const QuadExpr &e)
Definition: QuadExpr.h:39
typename AssnsNode_t::dataptr_t dataptr_t
Returns the art pointer to the associated value.
static auto transform(BoundaryIter const &iter)
Returns the pointed range.
BoundaryList< Iter > associationRanges(Iter begin, Iter end)
Groups associations by the first key.
auto key() const -> decltype(auto)
Returns the key of the art pointer to the value.