LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
OneTo01Data.h
Go to the documentation of this file.
1 
11 #ifndef LARDATA_RECOBASEPROXY_PROXYBASE_ONETO01DATA_H
12 #define LARDATA_RECOBASEPROXY_PROXYBASE_ONETO01DATA_H
13 
14 // LArSoft libraries
16 #include "lardata/Utilities/TupleLookupByTag.h" // util::add_tag_t(), ...
17 
18 // framework libraries
21 
22 // C/C++ standard
23 #include <vector>
24 #include <tuple> // std::tuple_element_t<>, std::get()
25 #include <iterator> // std::cbegin(), std::cend()
26 #include <utility> // std::move()
27 #include <type_traits> // std::is_convertible<>
28 #include <cstdlib> // std::size_t
29 
30 
31 namespace proxy {
32 
33  namespace details {
34 
67  template <
68  typename Main, typename Aux, typename Metadata /* = void */,
69  typename Tag /* = Aux */
70  >
71  class OneTo01Data {
73 
74  public:
76  using aux_t = Aux;
77 
79  using metadata_t = Metadata;
80 
82  using tag = Tag;
83 
85  using main_t = Main;
86 
89 
92 
94  using aux_coll_t = std::vector<aux_ptr_t>;
95 
98 
99 
100  OneTo01Data(aux_coll_t&& data): auxData(std::move(data)) {}
101 
103  bool has(std::size_t i) const
104  { return get(i) == aux_ptr_t(); }
105 
107  auxiliary_data_t get(std::size_t i) const
108  { return auxiliary_data_t(auxData[i]); }
109 
110 
112  auto operator[] (std::size_t index) const -> decltype(auto)
113  {
114  static_assert(
115  std::is_convertible<decltype(get(index)), auxiliary_data_t>(),
116  "Inconsistent data types."
117  );
118  return get(index);
119  }
120 
121  private:
123 
124  }; // class OneTo01Data<>
125 
126  } // namespace details
127 
128 
130 
164  template <typename Tag, typename Assns>
165  auto makeOneTo01data(Assns const& assns, std::size_t minSize = 0);
166 
167  template <typename Assns>
168  auto makeOneTo01data(Assns const& assns, std::size_t minSize = 0)
169  { return makeOneTo01data<typename Assns::right_t>(assns, minSize); }
171 
173 
191  template <typename Tag, typename MainColl, typename Assns>
192  auto makeOneTo01data(MainColl const& mainColl, Assns const& assns)
193  { return makeOneTo01data<Tag>(assns, mainColl.size()); }
194 
195  template <typename MainColl, typename Assns>
196  auto makeOneTo01data(MainColl const& mainColl, Assns const& assns)
197  { return makeOneTo01data<typename Assns::right_t>(mainColl, assns); }
199 
200 } // namespace proxy
201 
202 
203 //------------------------------------------------------------------------------
204 //--- template implementation
205 //------------------------------------------------------------------------------
206 namespace proxy {
207 
208  namespace details {
209 
210  //--------------------------------------------------------------------------
211  // Extends vector v with default-constructed data
212  // and executes v[index]=value
213  template <typename T>
215  std::vector<T>& v,
216  typename std::vector<T>::size_type index,
217  typename std::vector<T>::value_type const& value
218  ) {
219  if (index >= v.size()) {
220  v.reserve(index + 1);
221  v.resize(index);
222  v.push_back(value);
223  }
224  else v[index] = value;
225  } // extendAndAssign()
226 
227  // Extends vector v with default-constructed data
228  // and executes v[index]=move(value)
229  template <typename T>
231  std::vector<T>& v,
232  typename std::vector<T>::size_type index,
233  typename std::vector<T>::value_type&& value
234  ) {
235  if (index >= v.size()) {
236  v.reserve(index + 1);
237  v.resize(index);
238  v.push_back(std::move(value));
239  }
240  else v[index] = std::move(value);
241  } // extendAndAssign()
242 
243 
244  //--------------------------------------------------------------------------
245  template <std::size_t Key, std::size_t Data, typename Iter>
246  auto associationOneToOneFullSequence(Iter begin, Iter end, std::size_t n) {
247  //
248  // Here we are actually not using the assumption that the keys are in
249  // increasing order; which is just as good as long as we use a fast random
250  // access container as STL vector.
251  // We do assume the key side of the association to be valid, though.
252  //
253  using value_type = typename Iter::value_type;
254  using data_t = std::tuple_element_t<Data, value_type>;
255  std::vector<data_t> data(n); // all default-constructed
256  for (auto it = begin; it != end; ++it) {
257  auto const& keyPtr = std::get<Key>(*it);
258  extendAndAssign(data, keyPtr.key(), std::get<Data>(*it));
259  }
260  return data;
261  } // associationOneToOneFullSequence(Iter, Iter, std::size_t)
262 
263  } // namespace details
264 
265 
266  //----------------------------------------------------------------------------
267  //--- makeOneTo01data() implementation
268  //----------------------------------------------------------------------------
269  template <typename Tag, typename Assns>
270  auto makeOneTo01data(Assns const& assns, std::size_t minSize /* = 0 */)
271  {
272  using Main_t = typename Assns::left_t;
273  using Aux_t = typename Assns::right_t;
274  using Metadata_t = lar::util::assns_metadata_t<Assns>;
275  using AssociatedData_t
277 
278  using std::cbegin;
279  using std::cend;
280  return AssociatedData_t(
281  details::associationOneToOneFullSequence<0U, 1U>
282  (cbegin(assns), cend(assns), minSize)
283  );
284  } // makeOneTo01data(assns)
285 
286  //----------------------------------------------------------------------------
287 
288 } // namespace proxy
289 
290 
291 #endif // LARDATA_RECOBASEPROXY_PROXYBASE_ONETO01DATA_H
auto makeOneTo01data(Assns const &assns, std::size_t minSize=0)
Processes and returns an one-to-(zero/one) associated data object.
Definition: OneTo01Data.h:270
art::Ptr< aux_t > aux_ptr_t
Type of art pointer to associated datum.
Definition: OneTo01Data.h:88
bool has(std::size_t i) const
Returns whether the element i is associated with auxiliary datum.
Definition: OneTo01Data.h:103
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.
OneTo01Data(aux_coll_t &&data)
Definition: OneTo01Data.h:100
Main main_t
Type of main datum.
Definition: OneTo01Data.h:85
typename add_tag< T, Tag >::type add_tag_t
auto operator[](std::size_t index) const -> decltype(auto)
Returns the range with the specified index (no check performed).
Definition: OneTo01Data.h:112
Tag tag
Type of tag.
Definition: OneTo01Data.h:82
Object for one-to-zero/or/one associated data interface.
Definition: OneTo01Data.h:71
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
Encloses LArSoft data product proxy objects and utilities.See this doxygen module for an introduction...
Aux aux_t
Type of associated datum.
Definition: OneTo01Data.h:76
std::string value(boost::any const &)
Utilities to address elements of a tuple-like class by tag.
Traits for art associations.
Metadata metadata_t
Type of associated metadata.
Definition: OneTo01Data.h:79
Char_t n[5]
void extendAndAssign(std::vector< T > &v, typename std::vector< T >::size_type index, typename std::vector< T >::value_type const &value)
Definition: OneTo01Data.h:214
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
std::vector< aux_ptr_t > aux_coll_t
Type of collection of auxiliary data for all main elements.
Definition: OneTo01Data.h:94
aux_coll_t auxData
Data associated to the main collection.
Definition: OneTo01Data.h:122
util::add_tag_t< aux_ptr_t, tag > auxiliary_data_t
Type of auxiliary data associated with a main item.
Definition: OneTo01Data.h:91
Definition: fwd.h:25
auto associationOneToOneFullSequence(Iter begin, Iter end, std::size_t n)
Definition: OneTo01Data.h:246