LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
proxy::CollectionProxyElement< CollProxy > Struct Template Reference

An element of a collection proxy. More...

#include "CollectionProxyElement.h"

Inheritance diagram for proxy::CollectionProxyElement< CollProxy >:
proxy::SpacePointWithCharge< CollProxy > proxy::TrackCollectionProxyElement< CollProxy >

Public Types

using collection_proxy_t = CollProxy
 
using main_element_t = typename collection_proxy_t::main_element_t
 
using aux_elements_t = typename details::SubstituteWithAuxList< typename collection_proxy_t::aux_collections_t >::type
 Tuple of elements (expected to be tagged types). More...
 

Public Member Functions

 CollectionProxyElement (std::size_t index, main_element_t const &main, aux_elements_t &&auxData)
 
main_element_t const * operator-> () const
 Returns a pointer to the main element. More...
 
main_element_t const & operator* () const
 Returns a reference to the main element. More...
 
std::size_t index () const
 Returns the index of this element in the collection. More...
 
template<typename Tag >
auto get () const -> decltype(auto)
 Returns the auxiliary data specified by type (Tag). More...
 
template<typename Tag , typename T = Tag const&>
auto getIf () const -> decltype(auto)
 Returns the auxiliary data specified by type (Tag). More...
 

Static Public Member Functions

template<typename Tag >
static constexpr bool has ()
 Returns whether this class knowns about the specified type (Tag). More...
 

Private Member Functions

template<typename Tag , typename >
auto getIfHas (std::bool_constant< true >) const -> decltype(auto)
 
template<typename Tag , typename T >
auto getIfHas (std::bool_constant< false >) const -> T
 

Private Attributes

std::size_t fIndex
 Index of this element in the proxy. More...
 
main_element_t const * fMain
 Pointer to the main object of the element. More...
 
aux_elements_t fAuxData
 Data associated to the main object. More...
 

Detailed Description

template<typename CollProxy>
struct proxy::CollectionProxyElement< CollProxy >

An element of a collection proxy.

Template Parameters
CollProxythe type of collection proxy this is the element of

The collection proxy element represents, unsurprisingly, a single element of the collection proxy. It exposes all the connections between the components merged into the collection proxy, for a specific element.

The interface of a proxy element allows it to access the main and auxiliary data as follows:

  • main data element (always present!):
    • the whole object, by dereference method (*track)
    • methods and fields, by member access (track->Length())
  • auxiliary data: accessed by tag (usually it's the default, that is the same as the data type):
    • check if available: has() method, static (track.has<recob::Hit>())
    • get the data:
      • get() method; the data must be available or this call will not compile (track.get<recob::Hit>())
      • getIf() method; if the data is not available, an exception is thrown
  • index of the element in the collection (a bonus!): index() method

The for loop block illustrates how to use some of them:

auto tracks = proxy::getCollection<std::vector<recob::Track>>
(event, tracksTag, proxy::withAssociated<recob::Hit>());
for (auto track: tracks) {
recob::Track const& trackObj = *track; // access to the track
double const length = track->Length(); // access to track members
// access to associated data
// (returns random-access collection-like object)
decltype(auto) hits = track.get<recob::Hit>();
double charge = 0.0;
for (auto const& hitPtr: hits) charge += hitPtr->Integral();
std::vector<recob::TrackFitHitInfo> const* fitInfo
= track.has<std::vector<recob::TrackFitHitInfo>>()
? &(track.getIf<std::vector<recob::TrackFitHitInfo>>())
: nullptr
;
mf::LogVerbatim("Info")
<< "[#" << trackInfo.index() << "] track ID=" << trackObj.ID()
<< " (" << length << " cm) deposited charge=" << charge
<< " with " << hits.size() << " hits and"
<< (fitInfo? "": " no") << " fit information";
} // for tracks

Please note that getIf() method is not easy to use correctly. In this example, we rely on the knowledge that track.getIf() would return a reference to a (non-temporary) object, and we take the address of that object: this is not necessarily the case (e.g., it is not the case for getIf<recob::Hit>()).

Customization

A proxy element class can (and should) be derived from proxy::CollectionProxyElement. On top of it, the derived class can extend or completely rewrite the interface:

template <typename CollProxy>
class TrackProxy: public proxy::CollectionProxyElement<CollProxy> {
public:
unsigned int nHits() const
{ return base_t::template get<recob::Hit>().size(); }
}; // class TrackProxy

Specialization is also possible, but discouraged.

A proxy::CollectionProxyElement has knowledge of the type of collection proxy it's an element of, but it has no connection to a collection proxy object and in fact it never interacts with any, not even during construction.

Once the element is customized, a proxy::CollectionProxy can use it by having it as first template argument:

template <typename MainColl, typename... AuxColl>
using Proxy_t
= proxy::CollectionProxyBase<TrackProxy, MainColl, AuxColl...>;

A CollectionProxyMaker specialization will have to make() such objects.

Note
There is an indirect dependency of this class on the whole collection proxy class it is an element of. The type of that collection proxy is the template argument CollProxy. This class uses CollProxy to discovers some types it needs, but it does not contain or link to CollProxy itself. It should be possible therefore to have CollProxy types and CollectionProxyElement depend on a third, "trait" type delivering the relevant data types to both objects.

Definition at line 158 of file CollectionProxyElement.h.

Member Typedef Documentation

template<typename CollProxy >
using proxy::CollectionProxyElement< CollProxy >::aux_elements_t = typename details::SubstituteWithAuxList<typename collection_proxy_t::aux_collections_t>::type

Tuple of elements (expected to be tagged types).

Definition at line 166 of file CollectionProxyElement.h.

template<typename CollProxy >
using proxy::CollectionProxyElement< CollProxy >::collection_proxy_t = CollProxy

Definition at line 161 of file CollectionProxyElement.h.

template<typename CollProxy >
using proxy::CollectionProxyElement< CollProxy >::main_element_t = typename collection_proxy_t::main_element_t

Definition at line 162 of file CollectionProxyElement.h.

Constructor & Destructor Documentation

template<typename CollProxy >
proxy::CollectionProxyElement< CollProxy >::CollectionProxyElement ( std::size_t  index,
main_element_t const &  main,
aux_elements_t &&  auxData 
)
inline

Constructor: sets the element index, the main element and steals auxiliary data.

Definition at line 170 of file CollectionProxyElement.h.

171  : fIndex(index), fMain(&main), fAuxData(std::move(auxData))
172  {}
int main()
Definition: example_main.cc:17
aux_elements_t fAuxData
Data associated to the main object.
main_element_t const * fMain
Pointer to the main object of the element.
std::size_t index() const
Returns the index of this element in the collection.
std::size_t fIndex
Index of this element in the proxy.

Member Function Documentation

template<typename CollProxy >
template<typename Tag >
auto proxy::CollectionProxyElement< CollProxy >::get ( ) const -> decltype(auto)
inline

Returns the auxiliary data specified by type (Tag).

Definition at line 185 of file CollectionProxyElement.h.

186  {
187  return std::get<util::index_of_tag_v<Tag, aux_elements_t>>(fAuxData);
188  }
aux_elements_t fAuxData
Data associated to the main object.
template<typename CollProxy >
template<typename Tag , typename T >
auto proxy::CollectionProxyElement< CollProxy >::getIf ( ) const -> decltype(auto)

Returns the auxiliary data specified by type (Tag).

Template Parameters
Tagtag of the data to fetch (usually, its type)
Ttype to return (by default, a constant reference to Tag)
Returns
the auxiliary data specified by type (Tag).
Exceptions
std::logic_errorif the tag is not available.
See also
get(), has()
Deprecated:
C++17 if constexpr should be used instead (see the example below)

This method is a get() which forgives when the requested type is not available (because this proxy was configured not to hold it).

The difference with get() is the following:

decltype(auto) elem = tracks[0];
if (elem.has<recob::Hit>()) {
auto hits = elem.get<recob::Hit>();
// ...
}
if (elem.has<recob::SpacePoint>()) {
auto spacepoints = elem.getIf<recob::SpacePoint>();
// ...
}

If the proxy tracks has not been coded with recob::Hit data, the code snippet will not compile, because get() will not compile for tags that were not coded in. On the other end, if recob::Hit is coded in tracks but recob::SpacePoint is not, the snippet will compile. In that case, if the has() check had been omitted, getIt() would throw a std::logic_error exception when executed. With C++17, this will not be necessary any more by using "constexpr if":

decltype(auto) elem = tracks[0];
if constexpr (elem.has<recob::Hit>()) {
auto hits = elem.get<recob::Hit>();
// ...
}
if constexpr (elem.has<recob::SpacePoint>()) {
auto spacepoints = elem.get<recob::SpacePoint>();
// ...
}
Note
The second template argument contains the exact type returned by the function. That information is needed because this method needs to return the same type (or compatible types) whether the required tag is present or not, in order for user code like
if (elem.has<recob::SpacePoint>()) {
recob::SpacePoint const* spacepoints
= elem.getIf<recob::SpacePoint>(); // won't do
// ...
}
to work; it becomes:
if (elem.has<recob::SpacePoint>()) {
recob::SpacePoint const* spacepoints
= elem.getIf<recob::SpacePoint, recob::SpacePoint const*>();
// ...
}
This is necessary because when the tag (in the example, recob::SpacePoint) is not registered in the proxy, getIf() has no clue of what the return value should be ("which is the type of the data that does not exist?").

Definition at line 351 of file CollectionProxyElement.h.

352  {
353  return getIfHas<Tag, T>(std::bool_constant<has<Tag>()>{});
354  }
template<typename CollProxy >
template<typename Tag , typename >
auto proxy::CollectionProxyElement< CollProxy >::getIfHas ( std::bool_constant< true >  ) const -> decltype(auto)
private

Definition at line 359 of file CollectionProxyElement.h.

360  {
361  return get<Tag>();
362  }
template<typename CollProxy >
template<typename Tag , typename T >
auto proxy::CollectionProxyElement< CollProxy >::getIfHas ( std::bool_constant< false >  ) const -> T
private

Definition at line 366 of file CollectionProxyElement.h.

367  {
368  throw std::logic_error("Tag '" + lar::debug::demangle<Tag>() + "' not available.");
369  }
template<typename CollProxy >
template<typename Tag >
static constexpr bool proxy::CollectionProxyElement< CollProxy >::has ( )
inlinestatic

Returns whether this class knowns about the specified type (Tag).

Definition at line 266 of file CollectionProxyElement.h.

267  {
268  return util::has_tag_v<Tag, aux_elements_t>;
269  }
template<typename CollProxy >
std::size_t proxy::CollectionProxyElement< CollProxy >::index ( ) const
inline

Returns the index of this element in the collection.

Definition at line 181 of file CollectionProxyElement.h.

181 { return fIndex; };
std::size_t fIndex
Index of this element in the proxy.
template<typename CollProxy >
main_element_t const& proxy::CollectionProxyElement< CollProxy >::operator* ( ) const
inline

Returns a reference to the main element.

Definition at line 178 of file CollectionProxyElement.h.

178 { return *fMain; }
main_element_t const * fMain
Pointer to the main object of the element.
template<typename CollProxy >
main_element_t const* proxy::CollectionProxyElement< CollProxy >::operator-> ( ) const
inline

Returns a pointer to the main element.

Definition at line 175 of file CollectionProxyElement.h.

175 { return fMain; }
main_element_t const * fMain
Pointer to the main object of the element.

Member Data Documentation

template<typename CollProxy >
aux_elements_t proxy::CollectionProxyElement< CollProxy >::fAuxData
private

Data associated to the main object.

Definition at line 277 of file CollectionProxyElement.h.

template<typename CollProxy >
std::size_t proxy::CollectionProxyElement< CollProxy >::fIndex
private

Index of this element in the proxy.

Definition at line 272 of file CollectionProxyElement.h.

template<typename CollProxy >
main_element_t const* proxy::CollectionProxyElement< CollProxy >::fMain
private

Pointer to the main object of the element.

Definition at line 273 of file CollectionProxyElement.h.


The documentation for this struct was generated from the following file: