LArSoft  v09_90_00
Liquid Argon Software toolkit - https://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
15 #include "larcorealg/CoreUtils/MetaUtils.h" // util::is_not_same<>
19 #include "lardata/Utilities/TupleLookupByTag.h" // util::add_tag_t, ...
20 
21 // framework libraries
24 
25 // C/C++ standard libraries
26 #include <vector>
27 // #include <tuple> // std::tuple_element_t<>, std::get()
28 #include <algorithm> // std::min()
29 #include <cassert>
30 #include <cstdlib> // std::size_t
31 #include <iterator> // std::distance(), std::forward_iterator_tag, ...
32 #include <memory> // std::addressof()
33 #include <type_traits> // std::is_same<>, std::enable_if_t<>, ...
34 #include <utility> // std::forward(), std::declval(), ...
35 
36 namespace proxy {
37 
38  //----------------------------------------------------------------------------
44  //----------------------------------------------------------------------------
45  namespace details {
46 
47  //--------------------------------------------------------------------------
48  //--- general infrastructure
49  //--------------------------------------------------------------------------
50 
96  template <typename Iter, typename DataIter, typename ValueType = typename DataIter::value_type>
97  class IteratorWrapperBase : private DataIter {
98  protected:
99  using data_iterator_t = DataIter;
100 
101  public:
102  using iterator = Iter;
103 
106  using typename data_iterator_t::difference_type;
107  using value_type = ValueType;
108  using pointer = std::add_pointer_t<value_type>;
109  using reference = std::add_lvalue_reference_t<value_type>;
110  using iterator_category = std::forward_iterator_tag;
112 
114  IteratorWrapperBase() = default;
115 
118 
121  {
122  data_iterator_t::operator++();
123  return asIterator();
124  }
125 
127  bool operator!=(data_iterator_t const& other) const { return other != asDataIterator(); }
128 
130  bool operator!=(iterator const& other) const { return operator!=(other.asDataIterator()); }
131 
132  auto operator[](std::size_t index) const -> decltype(auto)
133  {
134  return asIterator().transform(asDataIterator() + index);
135  }
136 
138  auto operator*() const -> decltype(auto) { return asIterator().transform(asDataIterator()); }
139 
141  auto operator->() const -> decltype(auto) { return makeValuePointer(operator*()); }
142 
143  protected:
145  static auto transform(data_iterator_t const&) -> decltype(auto)
146  {
148  }
149 
151  {
152  return static_cast<data_iterator_t const&>(*this);
153  }
154 
155  private:
157  template <typename Value>
158  class ValuePtr {
159  Value value;
160  public:
161  ValuePtr(Value const& value) : value(value) {}
163  auto operator->() const -> decltype(auto) { return std::addressof(value); }
164  }; // class ValuePtr<>
165  template <typename Value>
166  static ValuePtr<Value> makeValuePointer(Value&& value)
167  {
168  return {std::forward<Value>(value)};
169  }
170 
171  iterator const& asIterator() const { return static_cast<iterator const&>(*this); }
172  iterator& asIterator() { return static_cast<iterator&>(*this); }
173 
174  }; // IteratorWrapperBase<>
175 
176 #if 0
177 
179  template <std::size_t N, typename TupleIter>
180  class tuple_element_iterator:
181  public IteratorWrapperBase<
182  tuple_element_iterator<N, TupleIter>,
183  TupleIter,
184  std::tuple_element_t<N, typename TupleIter::value_type>
185  >
186  {
187  using base_iterator_t = IteratorWrapperBase<
188  tuple_element_iterator<N, TupleIter>,
189  TupleIter,
190  std::tuple_element_t<N, typename TupleIter::value_type>
191  >;
192 
193  public:
194  using base_iterator_t::base_iterator_t;
195 
197  tuple_element_iterator(base_iterator_t const& from)
198  : base_iterator_t(from) {}
199 
200  static auto transform(TupleIter const& v) -> decltype(auto)
201  {return std::get<N>(*v); }
202 
203  }; // tuple_element_iterator
204 
205 #endif // 0
206  //--------------------------------------------------------------------------
207  //--- BEGIN iterators for art::Assns
208  //--------------------------------------------------------------------------
209 
210  //--------------------------------------------------------------------------
211 
213  template <typename ArtAssnsIterValue>
214  class AssnsNode : private ArtAssnsIterValue {
215 
216  using base_t = ArtAssnsIterValue;
218  using node_t = ArtAssnsIterValue;
219 
222 
223  public:
225  using main_t = typename assns_node_traits_t::left_t;
226 
228  using value_t = typename assns_node_traits_t::right_t;
229 
231  using data_t = typename assns_node_traits_t::data_t;
232 
234  using mainptr_t = typename assns_node_traits_t::leftptr_t;
235 
237  using valueptr_t = typename assns_node_traits_t::rightptr_t;
238 
240  using dataptr_t = typename assns_node_traits_t::dataptr_t;
241 
244 
246  valueptr_t const& valuePtr() const { return base_t::second; }
247 
249  value_t const& value() const { return *valuePtr(); }
250 
252 
255 
257  mainptr_t const& mainPtr() const { return base_t::first; }
258 
260  main_t const& main() const { return *mainPtr(); }
261 
263 
265 
273  // the templates are needed to activate "SFINAE" on std::enable_if
275  template <typename Node = node_t>
276  static constexpr bool hasMetadata()
277  {
278  return lar::util::assns_has_metadata_v<Node>;
279  }
280 
282  template <typename Node = node_t>
283  std::enable_if_t<hasMetadata<Node>(), dataptr_t> dataPtr() const
284  {
285  return base_t::data;
286  }
287 
288  // this is even more complicate, since if `data_t` is void we can't write
289  // `data_t const&` as type of enable_if, because it does not depend on
290  // templates and therefore it may be unconditionally evaluated;
291  // and C++ does not like references to `void`...
293  template <typename Node = node_t>
294  std::enable_if_t<hasMetadata<Node>(), typename lar::util::assns_traits<Node>::data_t const&>
295  data() const
296  {
297  return *dataPtr();
298  }
299 
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 
325  static this_t const& makeFrom(node_t const& from) { return static_cast<this_t const&>(from); }
326 
327  }; // class AssnsNode<>
328 
329  template <typename ArtAssnsIterValue>
332  {
333  return A.valuePtr() == B;
334  }
335  template <typename ArtAssnsIterValue>
338  {
339  return A == B.valuePtr();
340  }
341  template <typename ArtAssnsIterValue>
344  {
345  return A.valuePtr() != B;
346  }
347  template <typename ArtAssnsIterValue>
350  {
351  return A != B.valuePtr();
352  }
353 
355  template <typename ArtAssnsIterValue>
356  AssnsNode<ArtAssnsIterValue> const& makeAssnsNode(ArtAssnsIterValue const& from)
357  {
359  }
360 
361  } // namespace details
362 } // namespace proxy
363 
364 // we interrupt this namespace for an urgent specialization...
365 namespace lar {
366  namespace util {
367 
368  // specialization for the art node wrapper
369  template <typename ArtAssnsIterValue>
370  struct assns_metadata_type<proxy::details::AssnsNode<ArtAssnsIterValue>>
371  : assns_metadata_type<ArtAssnsIterValue> {};
372 
373  } // namespace util
374 } // namespace lar
375 
376 // back to what we were doing:
377 namespace proxy {
378  namespace details {
379 
380  //--------------------------------------------------------------------------
382  template <typename ArtAssnsIter>
383  struct AssnsIterTraits : public lar::util::assns_traits<typename ArtAssnsIter::value_type> {
384  using art_node_t = typename ArtAssnsIter::value_type;
386  }; // struct AssnsIterTraits
387 
390  template <typename ArtAssnsIter>
392  : public IteratorWrapperBase<assns_node_iterator<ArtAssnsIter>,
393  ArtAssnsIter,
394  typename AssnsIterTraits<ArtAssnsIter>::node_t> {
396  ArtAssnsIter,
398 
399  using art_assns_iter_t = ArtAssnsIter;
401 
403  using AssnsNode_t = typename traits_t::node_t;
405 
406  public:
407  using base_iterator_t::base_iterator_t;
408 
411 
413  AssnsNode_t const& info() const { return base_iterator_t::operator*(); }
414 
416  AssnsNode_t const& operator()() const { return info(); }
417 
418  //--- BEGIN Access to the full association information -------------------
422 
423  using main_t = typename AssnsNode_t::main_t;
424  using value_t = typename AssnsNode_t::value_t;
425  using data_t = typename AssnsNode_t::data_t;
426  using mainptr_t = typename AssnsNode_t::mainptr_t;
427  using valueptr_t = typename AssnsNode_t::valueptr_t;
428  using dataptr_t = typename AssnsNode_t::dataptr_t;
429 
431  valueptr_t valuePtr() const { return info().valuePtr(); }
432 
434  value_t const& value() const { return info().value(); }
435 
437  mainptr_t mainPtr() const { return info().mainPtr(); }
438 
440  main_t const& main() const { return info().main(); }
441 
442  // see the comments on AssnsNode for the need of all these decorations
444  template <typename Node = AssnsNode_t>
445  static constexpr bool hasMetadata()
446  {
447  return lar::util::assns_has_metadata_v<Node>;
448  }
449 
451  template <typename ArtNode = ArtAssnsNode_t>
452  std::enable_if_t<hasMetadata<ArtNode>(), dataptr_t> dataPtr() const
453  {
454  return info().dataPtr();
455  }
456 
458  template <typename ArtNode = ArtAssnsNode_t>
459  std::enable_if_t<hasMetadata<ArtNode>(),
461  data() const
462  {
463  return info().data();
464  }
465 
467  //--- END Access to the full association information ---------------------
468 
469  /*
470  * Associations with metadata have an iterator with value type
471  * art::AssnsNode, while the value for the ones without have just a
472  * std::pair.
473  * The std::pair returned by the one without metadata is a reference to an
474  * element of the original collection.
475  * Instead, the art::AssnsNode returned by the art::Assns iterator is a
476  * temporary put together copying information from the original pair
477  * collection and from the parallel metadata collection.
478  * Therefore, in the first case we can return references to the existing
479  * data, while in the latter we can't and we have to return the results by
480  * value.
481  * In this implementation we compromise and return always the data by
482  * value; the values are art pointers, or plain pointers, so the copy
483  * should not be extremely taxing. It is possible to change this, at the
484  * cost of additional complexity of the implementation.
485  */
486  static AssnsNode_t const& transform(art_assns_iter_t const& v) { return makeAssnsNode(*v); }
487 
488  }; // class assns_node_iterator<>
489 
490  //--- END iterators for art::Assns -----------------------------------------
491 
492  //--------------------------------------------------------------------------
493  //--- stuff for associated data (a form of auxiliary data)
494  //--------------------------------------------------------------------------
495 
498  template <typename BoundaryIter>
499  class BoundaryListRangeBase : private BoundaryIter {
500  using boundary_iterator_t = BoundaryIter;
501 
503  auto boundaryIter() const { return static_cast<BoundaryIter const&>(*this); }
504 
505  public:
508 
510  auto begin() const -> decltype(auto) { return *(boundaryIter()); }
511 
513  auto end() const -> decltype(auto) { return *(std::next(boundaryIter())); }
514 
515  }; // BoundaryListRangeBase<>
516 
518  template <typename BoundaryIter>
519  class BoundaryListRange : public lar::CollectionView<BoundaryListRangeBase<BoundaryIter>> {
520  // A CollectionView can't be constructed except from deriver classes;
521  // we define here such a class.
522 
525 
526  public:
527  using boundary_iterator_t = BoundaryIter;
528 
531 
532  }; // class BoundaryListRange<>
533 
554  template <typename BoundaryIter>
556  {
557  return {iBegin};
558  }
559 
586  template <typename BoundaryIter>
588  : public IteratorWrapperBase<BoundaryListRangeIterator<BoundaryIter>, BoundaryIter> {
590 
591  public:
592  using boundary_iterator_t = BoundaryIter;
593 
595  using rangeview_t = decltype(makeBoundaryListRange(std::declval<boundary_iterator_t>()));
596 
598  using pointer = std::add_pointer_t<std::decay_t<value_type>>;
599  using reference = std::add_lvalue_reference_t<std::decay_t<value_type>>;
600 
601  using base_t::base_t; // import constructors (explicitly allowed)
602 
611  static auto transform(BoundaryIter const& iter) { return makeBoundaryListRange(iter); }
612 
613  }; // class BoundaryListRangeIterator<>
614 
642  template <typename Iter>
643  class BoundaryList {
645 
646  public:
647  using data_iterator_t = Iter;
648  using boundaries_t = std::vector<data_iterator_t>;
649 
652 
654  // BoundaryListRange<data_iterator_t> const&
656 
659 
661  explicit BoundaryList(boundaries_t&& boundaries) : boundaries(std::move(boundaries))
662  {
663  assert(this->boundaries.size() >= 1);
664  }
665 
667  std::size_t nRanges() const { return boundaries.size() - 1; }
669  data_iterator_t const& rangeBegin(std::size_t i) const
670  {
671  return boundaries[std::min(i, nRanges())];
672  }
674  data_iterator_t const& rangeEnd(std::size_t i) const { return rangeBegin(i + 1); }
675 
677  std::size_t size() const { return nRanges(); }
679  range_iterator_t begin() const { return {boundaries.begin()}; }
681  range_iterator_t end() const { return {std::prev(boundaries.end())}; }
696  range_ref_t rangeRef(std::size_t i) const { return {std::next(boundaries.begin(), i)}; }
710  range_t range(std::size_t i) const
711  {
712  return lar::makeCollectionView(rangeBegin(i), rangeEnd(i));
713  }
714 
717  auto operator[](std::size_t i) const -> decltype(auto) { return range(i); }
718 
719  private:
722 
723  }; // class BoundaryList
724 
748  template <typename Main, typename Aux, typename Metadata /* = void */, typename Tag /* = Aux */
749  >
752 
753  public:
756 
757  private:
759  // = tuple_element_iterator<1U, lar::util::assns_iterator_t<assns_t>>;
760 
761  public:
762  using tag = Tag;
763 
765 
768 
769  // constructor is not part of the interface
770  AssociatedData(group_ranges_t&& groups) : fGroups(std::move(groups)) {}
771 
773  auto begin() const -> decltype(auto) { return fGroups.begin(); }
774 
776  auto end() const -> decltype(auto) { return fGroups.end(); }
777 
779  auto getRange(std::size_t i) const -> decltype(auto)
780  {
781  return util::makeTagged<tag>(fGroups.range(i));
782  }
783 
785  auto operator[](std::size_t index) const -> decltype(auto)
786  {
787  static_assert(std::is_convertible<decltype(getRange(index)), auxiliary_data_t>(),
788  "Inconsistent data types.");
789  return getRange(index);
790  }
791 
793  template <typename TestTag>
794  static constexpr bool hasTag()
795  {
796  return std::is_same<TestTag, tag>();
797  }
798 
799  private:
801 
802  }; // class AssociatedData<>
803 
804  //--------------------------------------------------------------------------
805 
806  } // namespace details
807 
808  //----------------------------------------------------------------------------
810 
841  template <typename Tag, typename Assns>
842  auto makeAssociatedData(Assns const& assns, std::size_t minSize = 0);
843 
844  template <typename Assns>
845  auto makeAssociatedData(Assns const& assns, std::size_t minSize = 0)
846  {
847  return makeAssociatedData<typename Assns::right_t>(assns, minSize);
848  }
850 
852 
867  template <typename Tag, typename MainColl, typename Assns>
868  auto makeAssociatedData(MainColl const& mainColl, Assns const& assns)
869  {
870  return makeAssociatedData<Tag>(assns, mainColl.size());
871  }
872 
873  template <typename MainColl, typename Assns>
874  auto makeAssociatedData(MainColl const& mainColl, Assns const& assns)
875  {
876  return makeAssociatedData<typename Assns::right_t>(mainColl, assns);
877  }
879 
880  //----------------------------------------------------------------------------
881 
882 } // namespace proxy
883 
884 //------------------------------------------------------------------------------
885 //--- template implementation
886 //------------------------------------------------------------------------------
887 namespace proxy {
888 
889  namespace details {
890 
891  //--------------------------------------------------------------------------
892  //--- associationRangeBoundaries() implementation
893  //--------------------------------------------------------------------------
894  template <std::size_t GroupKey, typename Iter>
896  associationRangesImpl(Iter begin, Iter end, std::size_t expectedSize /* = 0 */)
897  {
898  constexpr auto KeyIndex = GroupKey;
899 
900  auto extractKey = [](auto const& assn) { return std::get<KeyIndex>(assn).key(); };
901 
902  typename BoundaryList<Iter>::boundaries_t boundaries;
903  boundaries.reserve(expectedSize + 1);
904  boundaries.push_back(begin);
905  std::size_t current = 0;
906  for (auto it = begin; it != end; ++it) {
907  auto const key = extractKey(*it);
908  if (key == current) continue;
909  if (key < current) {
910  auto index = std::distance(begin, it);
911  throw std::runtime_error(
912  "associationRanges() got input element #" + std::to_string(index - 1) + " with key " +
913  std::to_string(current) + " and the next with key " + std::to_string(key) + "!");
914  }
915  boundaries.insert(boundaries.end(), key - current, it);
916  current = key;
917  } // for
918  boundaries.push_back(end);
919  return boundaries;
920  } // associationRangesImpl()
921 
922  //--------------------------------------------------------------------------
923  template <std::size_t GroupKey, typename Iter>
925  {
926  return associationRangesImpl<GroupKey, Iter>(begin, end);
927  }
928 
929  //--------------------------------------------------------------------------
930  template <std::size_t GroupKey, typename Iter>
931  auto associationRangeBoundaries(Iter begin, Iter end, std::size_t n)
932  {
933  auto boundaries = associationRangesImpl<GroupKey, Iter>(begin, end, n);
934  if (boundaries.size() <= n) {
935  boundaries.insert(boundaries.end(), n + 1 - boundaries.size(), boundaries.back());
936  assert(boundaries.size() == (n + 1));
937  }
938  return boundaries;
939  } // associationRangeBoundaries(Iter, Iter, std::size_t)
940 
941  //--------------------------------------------------------------------------
964  template <std::size_t GroupKey, typename Iter>
966  {
967  return BoundaryList<Iter>(associationRangeBoundaries<GroupKey>(begin, end));
968  }
969 
988  template <std::size_t GroupKey, typename Iter>
989  BoundaryList<Iter> associationRanges(Iter begin, Iter end, std::size_t n)
990  {
991  return BoundaryList<Iter>(associationRangeBoundaries<GroupKey>(begin, end, n));
992  }
993 
994  //--------------------------------------------------------------------------
995 
996  } // namespace details
997 
998  //----------------------------------------------------------------------------
999  template <typename Tag, typename Assns>
1000  auto makeAssociatedData(Assns const& assns, std::size_t minSize /* = 0 */)
1001  {
1002  using Main_t = typename Assns::left_t;
1003  using Aux_t = typename Assns::right_t;
1004  using Metadata_t = lar::util::assns_metadata_t<Assns>;
1006 
1007  // associationRangeBoundaries() produces iterators to association elements,
1008  // (i.e. tuples)
1009  using std::begin;
1010  using std::end;
1011  auto ranges = details::associationRangeBoundaries<0U>(begin(assns), end(assns), minSize);
1012  // we convert those iterators into iterators to the right associated item
1013  // (it takes a few steps)
1014  using group_ranges_t = typename AssociatedData_t::group_ranges_t;
1015  return AssociatedData_t(
1016  group_ranges_t(typename group_ranges_t::boundaries_t(ranges.begin(), ranges.end())));
1017  } // makeAssociatedDataFrom(assns)
1018 
1019  //----------------------------------------------------------------------------
1020 
1021 } // namespace proxy
1022 //------------------------------------------------------------------------------
1023 
1024 #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.
Provides features of a collections, from begin and end iterators.
Namespace for general, non-LArSoft-specific utilities.
Definition: PIDAAlg.h:26
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.
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*() 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< 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
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.
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.
auto begin() const -> decltype(auto)
Returns an iterator pointing to the first associated data range.
auto getRange(std::size_t i) const -> decltype(auto)
Returns the range with the specified index (no check performed).
typename assns_metadata_type< Assns >::type assns_metadata_t
Trait: type of metadata in Assns (association or its node).
Definition: AssnsTraits.h:59
STL namespace.
Trait: type is metadata in Assns (association or its node).
Definition: AssnsTraits.h:54
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.
valueptr_t operator->() const
Returns the associated value (alias of valuePtr()).
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
struct node_s node_t
Definition: DBScan3DAlg.h:63
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::rightptr_t valueptr_t
Type of art pointer to the associated (right) object.
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.
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.
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)
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
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.
Value box for use with pointer dereference operator->().
Tag tag
Tag of this association proxy.
Traits for a association iterator.
auto end() const -> decltype(auto)
Returns the end iterator of the range (next to the begin iterator).
std::size_t nRanges() const
Returns the number of ranges contained in the list.
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
ArtAssnsIterValue node_t
Type of the wrapped node.
auto operator[](std::size_t i) const -> decltype(auto)
auto operator[](std::size_t index) const -> decltype(auto)
Returns the range with the specified index (no check performed).
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.
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).
auto end() const -> decltype(auto)
Returns an iterator pointing past the last associated data range.
Data types for the specified association type (or its node).
Definition: AssnsTraits.h:98
IteratorWrapperBase()=default
Default constructor: default-constructs the underlying 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.
auto operator->() const -> decltype(auto)
Access the contained value via its pointer.
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.
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.
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.
AssnsNode_t const & operator()() const
Returns the full information the iterator points to.
AssociatedData(group_ranges_t &&groups)
static auto transform(data_iterator_t const &) -> decltype(auto)
Transforms and returns the value at the specified data iterator.
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.
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).
Iterator exposing elements of a boundary list as ranges.
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]
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
auto operator->() const -> decltype(auto)
Dereference operator; need to be redefined by derived classes.
ArtAssnsIterValue base_t
Base class type.
value_t const & operator*() const
Returns a reference to the associated value (alias of value()).
auto operator[](std::size_t index) const -> decltype(auto)
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:82
QuadExpr operator*(double v, const QuadExpr &e)
Definition: QuadExpr.h:44
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.
auto begin() const -> decltype(auto)
Returns the begin iterator of the range.