ProviderPack.h
Go to the documentation of this file.
1 /**
2  * @file larcorealg/CoreUtils/ProviderPack.h
3  * @brief Data structure containing constant pointers to classes
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date November 20th, 2015
6  * @version 1.0
7  *
8  * This is a header-only library.
9  * It depends only on standard C++ and does not require additional linkage.
10  */
11 
12 
13 #ifndef LARCOREALG_COREUTILS_PROVIDERPACK_H
14 #define LARCOREALG_COREUTILS_PROVIDERPACK_H
15 
16 
17 // C/C++ standard library
18 #include <tuple>
19 #include <type_traits>
20 #include <limits>
21 
22 
23 namespace lar {
24 
25  namespace details {
26 
27  template <typename... Types>
29 
30 
31  /**
32  * @brief Index of the class among Bases which is base of Derived.
33  * @tparam Derived the class to be found
34  * @tparam Bases a list of classes candidate to be the base of Derived
35  * @return index of the class among Bases which is base of Derived
36  * @throw static_assert if multiple classes are base of `Derived`
37  * @see hasBaseOf(), findBaseOf()
38  *
39  * If no class among `Bases` is actually a base class of `Derived`, an
40  * invalid index is returned, greater than any valid index (that is,
41  * no smaller than `sizeof...(Bases)`).
42  */
43  template <typename Derived, typename... Bases>
44  constexpr std::size_t indexOfBaseOf();
45 
46  template <typename Derived, typename... Bases>
47  constexpr std::size_t indexOfDerivedFrom();
48 
49  /**
50  * @brief Index of the class among Bases which is base of Derived.
51  * @tparam Derived the class to be found
52  * @tparam Bases a list of classes candidate to be the base of Derived
53  * @return index of the class among Bases which is base of Derived
54  * @throw static_assert if none, or multiple classes, are base of `Derived`
55  * @see hasBaseOf(), indexOfBaseOf()
56  */
57  template <typename Derived, typename... Bases>
58  constexpr std::size_t findBaseOf();
59 
60  template <typename Derived, typename... Bases>
61  constexpr std::size_t findDerivedFrom();
62 
63  /**
64  * @brief Returns whether there is exactly one base class of `Derived` among
65  * `Bases`.
66  * @tparam Derived the class to be found
67  * @tparam Bases a list of classes candidate to be the base of Derived
68  * @return whether there is exactly one base class of `Derived`
69  * @throw static_assert if multiple classes are base of `Derived`
70  * @see indexOfBaseOf(), findBaseOf()
71  */
72  template <typename Derived, typename... Bases>
73  constexpr std::size_t hasBaseOf()
74  { return indexOfBaseOf<Derived, Bases...>() < sizeof...(Bases); }
75 
76  template <typename Derived, typename... Bases>
77  constexpr std::size_t hasDerivedFrom()
78  { return indexOfDerivedFrom<Derived, Bases...>() < sizeof...(Bases); }
79 
80 
81  /// Implementation detail for the extraction constructor
82  template
83  <typename DestPack, typename SourcePack, typename... ExtractProviders>
84  struct SetFrom;
85 
86  } // namespace details
87 
88 
89  /** **************************************************************************
90  * @brief Container for a list of pointers to providers
91  * @tparam Providers types of the providers in the parameter pack
92  *
93  * The pointers are stored as constant.
94  * Note that this container can host any type of objects, and it has
95  * "provider" in the name because the reason it was written was to provide
96  * a fast way to specify a set of LArSoft service providers.
97  * The only limitation is that there should be only one object per type.
98  * Pointed objects are not owned by this class.
99  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
100  * A a;
101  * B1 b; // derived from B
102  * C c;
103  * D d;
104  * ProviderPack<A, B, C> pack(&a, &b, &c);
105  *
106  * // obtain a constant pointer to b from pack:
107  * B const* b_ptr = pack.get<B>();
108  *
109  * if constexpr (pack.has<D>()) std::cerr << "Unexpected!" << std::endl;
110  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
111  * (note that in the latter check `constexpr` is supported only since C++17).
112  */
113  template <typename... Providers>
114  class ProviderPack {
116  "Providers in ProviderPack are repeated");
117 
118  using this_type = ProviderPack<Providers...>; ///< alias of this class
119 
120  /// type used for storage of the pointers
121  using tuple_type = std::tuple<Providers const*...>;
122 
123  public:
124 
125  /// Default constructor: a null provider pointer for each type
126  ProviderPack() = default;
127 
128  /// Constructor: stores a provider pointer for each type
129  ProviderPack(Providers const* ...provider_ptrs): providers(provider_ptrs...)
130  {}
131 
132  /**
133  * @brief Constructor: extracts the providers from another parameter pack
134  * @tparam OtherProviders list of the providers of the source provider pack
135  * @param from where to copy the information from
136  *
137  * This constructor requires all the providers we need to be present
138  * in the source provider pack.
139  */
140  template<typename... OtherProviders>
142  {
144  <this_type, ProviderPack<OtherProviders...>, Providers...>
145  (*this, from);
146  }
147 
148  /**
149  * @brief Constructor: picks the providers from the specified ones
150  * @tparam OtherProviders list of the type of providers offered
151  * @param providers all the providers needed (or more)
152  *
153  * This constructor will pick, among the offered providers, the ones that
154  * are needed.
155  */
156  template<typename... OtherProviders>
157  ProviderPack(OtherProviders const*... providers)
158  {
160  <this_type, ProviderPack<OtherProviders...>, Providers...>
161  (*this, ProviderPack<OtherProviders...>(providers...));
162  }
163 
164  /**
165  * @brief Constructor: picks the providers from a pack plus specified ones
166  * @tparam FromPack parameter pack to start from
167  * @tparam OtherProviders list of the type of providers offered
168  * @param fromPack providers to be picked
169  * @param providers all the remaining providers needed (or more)
170  * @see expandProviderPack()
171  *
172  * This constructor will pick all the providers from the specified pack,
173  * and the ones from the other providers.
174  * This constructor can be used to "expand" from another provider:
175  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
176  * A a;
177  * B b;
178  * C c;
179  * D d;
180  * ProviderPack<A, D> pack(&a, &d);
181  * ProviderPack<A, B, C, D> largerPack(pack, &c, &b);
182  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
183  */
184  template<typename... PackProviders, typename... OtherProviders>
185  ProviderPack(
186  ProviderPack<PackProviders...> const& fromPack,
187  OtherProviders const*... providers
188  );
189 
190 
191  /// Returns the provider with the specified type
192  template <typename Provider>
193  Provider const* get() const
194  {
195  constexpr auto providerIndex
196  = details::findDerivedFrom<Provider, Providers...>();
197  return std::get<providerIndex>(providers);
198  } // get<>()
199 
200 
201  /// Sets the provider with the specified type
202  template <typename Provider>
203  void set(Provider const* provider_ptr)
204  {
205  constexpr auto providerIndex
206  = details::findDerivedFrom<Provider, Providers...>();
207  std::get<providerIndex>(providers) = provider_ptr;
208  } // set<>()
209 
210  /// Returns whether there is a provider with the specified type
211  template <typename Provider>
212  static constexpr bool has()
213  { return details::hasDerivedFrom<Provider, Providers...>(); }
214 
215 
216  /// Returns whether other provider pack has all the same providers as this
217  template <typename... OtherProviders>
219 
220  /// Returns whether other provider pack and this have different providers
221  template <typename... OtherProviders>
222  bool operator!= (ProviderPack<OtherProviders...> const& other) const;
223 
224 
225  /**
226  * @brief Returns whether all our providers are in the OfferedProviders list
227  * @tparam OfferedProviders list of offered providers
228  *
229  * This static function returns true if all the providers in this provider
230  * pack are included among the OfferedProviders list. That list can contain
231  * additional provider types, which will not affect the result.
232  *
233  * Usage example:
234  *
235  * using providers_t
236  * = lar::ProviderPack<geo::GeometryCore, detinfo::LArProperties>;
237  * static_assert(
238  * providers_t::containsProviders
239  * <detinfo::LArProperties, detinfo::DetectorProperties>(),
240  * "Not all the required providers are present."
241  * );
242  *
243  * In this example, the assertion will fail because of the absence of
244  * `detinfo::DetectorProperties` from providers_t.
245  */
246  template <typename... OtherProviders>
247  static constexpr bool containsProviders();
248 
249  private:
250 
251  tuple_type providers; ///< container of the pointers, type-safe
252 
253  }; // class ProviderPack
254 
255 
256  /**
257  * @brief Function to create a ProviderPack from the function arguments
258  * @tparam Providers types of the providers in the parameter pack
259  * @param providers constant pointers to the providers
260  * @return a ProviderPack object containing all the specified providers
261  *
262  * This is an convenience function to reduce the typing needed to instantiate
263  * a ProviderPack. Example:
264  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
265  * A a;
266  * B b;
267  * auto pack = makeProviderPack(&a, &b);
268  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
269  * creates a `ProviderPack<A, B>`.
270  */
271  template <typename... Providers>
272  ProviderPack<Providers...> makeProviderPack(Providers const* ...providers)
273  { return ProviderPack<Providers...>(providers...); }
274 
275 
276  /**
277  * @brief Function to create a ProviderPack by adding to another
278  * @tparam PackProviders types of the providers in the original parameter pack
279  * @tparam MoreProviders types of the providers to be added
280  * @param pack parameter pack with the first providers
281  * @param providers constant pointers to the other providers to be added
282  * @return a ProviderPack object containing all the specified providers
283  *
284  * This is an convenience function to reduce the typing needed to instantiate
285  * a ProviderPack. Use it like:
286  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
287  * A a;
288  * B b;
289  * C c;
290  * D d;
291  * auto pack = makeProviderPack(&a, &d);
292  * auto largerPack = expandProviderPack(pack, &c, &b);
293  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
294  * creates a `ProviderPack<A, D, C, B>` including all the four objects.
295  */
296  template <typename... PackProviders, typename... MoreProviders>
297  ProviderPack<PackProviders..., MoreProviders...> expandProviderPack(
298  ProviderPack<PackProviders...> const& pack,
299  MoreProviders const* ...providers
300  )
301  { return { pack, providers... }; }
302 
303 
304 } // namespace lar
305 
306 
307 //------------------------------------------------------------------------------
308 //--- Implementation details
309 //---
310 namespace lar {
311  namespace details {
312 
313  template <bool Value>
314  using bool_constant = std::integral_constant<bool, Value>; // also in C++17
315 
316  template <std::size_t Value>
317  using index_constant = std::integral_constant<std::size_t, Value>;
318 
319  //--------------------------------------------------------------------------
320  //--- has_type, has_duplicate_types, are_same_types
321  //---
322  template <typename Target, typename... Types>
323  struct has_type;
324 
325  template <typename Target, typename First, typename... Others>
326  struct has_type<Target, First, Others...>: has_type<Target, Others...> {};
327 
328  template <typename Target, typename... Others>
329  struct has_type<Target, Target, Others...>: std::true_type {};
330 
331  template <typename Target>
332  struct has_type<Target>: std::false_type {};
333 
334 
335  //--------------------------------------------------------------------------
336  template <typename Key, typename... Types>
337  struct has_duplicate_types<Key, Types...>:
338  public bool_constant
339  <has_type<Key, Types...>() || has_duplicate_types<Types...>()>
340  {};
341 
342  template <>
343  struct has_duplicate_types<>: public std::false_type {};
344 
345 
346  //--------------------------------------------------------------------------
347  template <typename... Types>
349 
350  template <typename... Types>
351  struct are_same_types {
352 
353  template <typename... AsTypes>
354  static constexpr bool as()
355  {
356  return (sizeof...(Types) == sizeof...(AsTypes))
357  && are_types_contained<Types...>::template in<AsTypes...>();
358  }
359 
360  }; // are_same_types
361 
362 
363  template <typename First, typename... OtherTypes>
364  struct are_types_contained<First, OtherTypes...> {
365  template <typename... AsTypes>
366  static constexpr bool in()
367  {
368  return are_types_contained<OtherTypes...>::template in<AsTypes...>()
370  }
371  };
372 
373  template <typename First>
374  struct are_types_contained<First> {
375  template <typename... AsTypes>
376  static constexpr bool in()
377  { return has_type<First, AsTypes...>(); }
378  };
379 
380 
381  template <typename T>
382  struct is_provider_pack: public std::false_type {};
383 
384  template <typename... Providers>
385  struct is_provider_pack<ProviderPack<Providers...>>: public std::true_type
386  {};
387 
388 
389  template <typename APack, typename BPack>
390  struct have_same_provider_types: public std::false_type {};
391 
392  template <typename... AProviders, typename... BProviders>
394  <ProviderPack<AProviders...>, ProviderPack<BProviders...>>
395  : public std::integral_constant
396  <bool, are_same_types<AProviders...>::template as<BProviders...>()>
397  {};
398 
399 
400  // --- BEGIN impementation of findDerivedFrom() ----------------------------
401  //
402  // This is the implementation of findDerivedFrom() and findBaseOf().
403  // The functions are expected to assert that there is exactly one answer to
404  // a matching condition: for findDerivedFrom() that answer is which is the
405  // derived class of Base among Derived, for findBaseOf() is the opposite.
406  //
407  // The implementation finds and returns the index of first class matching
408  // the condition, and it asserts that the answer is valid.
409  // It also finds the index of the next class matching the condition, just to
410  // assert that it is not valid (that is, there is no other matching class).
411  //
412  // The class returning the index of the first matching class is implemented
413  // recursively, on a class taking the target class, the first of the
414  // candidate classes, and then all the others in a parameter pack.
415  // When the first candidate satisfies the condition, then the recursion is
416  // over. In the simplest case, where we are just looking for a specific
417  // class, the condition (the Target is the same as the First Candidate) can
418  // be implied and the compiler can implement it directly with parameter
419  // matching. In our cases the condition is non-trivial and we use a
420  // two-level recursion: the outer level, the "dispatcher", invokes a
421  // different "answer" class whether the condition is true or false. In the
422  // former case a result is presented; in the other case recursion ensues,
423  // back to the dispatcher. The dispatcher can also terminate the recursion
424  // when no answer is found. If recursion is terminated without a match, an
425  // invalid index is returned.
426  //
427  // The class returning the next matching class is simply skipping a number
428  // of candidates, and then behaving like the one looking for the first
429  // matching candidate.
430  //
431 
432  //
433  // class to find the first matching class
434  //
435  template <
436  template <typename A, typename B> class Match,
437  typename Target, bool IsMatch, typename... Candidates
438  >
440 
441  template <
442  template <typename A, typename B> class Match,
443  typename Target, typename... Candidates
444  >
445  struct findFirstMatching_answer<Match, Target, true, Candidates...>
446  : public index_constant<0U>
447  {};
448 
449  template <
450  template <typename A, typename B> class Match,
451  typename Target, typename... Candidates
452  >
454 
455  // end-of-recursion
456  template <
457  template <typename A, typename B> class Match,
458  typename Target
459  >
460  struct findFirstMatching_dispatcher<Match, Target>
461  : findFirstMatching_answer<Match, Target, true>
462  {};
463 
464  template <
465  template <typename A, typename B> class Match,
466  typename Target, typename FirstCandidate, typename... OtherCandidates
467  >
469  <Match, Target, FirstCandidate, OtherCandidates...>
470  : public findFirstMatching_answer<
471  Match,
472  Target,
473  Match<FirstCandidate, Target>::value,
474  FirstCandidate,
475  OtherCandidates...
476  >
477  {};
478 
479  template <
480  template <typename A, typename B> class Match,
481  typename Target, typename FirstCandidate, typename... OtherCandidates
482  >
484  <Match, Target, false, FirstCandidate, OtherCandidates...>
485  : public index_constant
486  <(1U + findFirstMatching_dispatcher<Match, Target, OtherCandidates...>::value)>
487  {};
488 
489  template <
490  template <typename A, typename B> class Match,
491  typename Target, typename... Candidates
492  >
494  : findFirstMatching_dispatcher<Match, Target, Candidates...>
495  {
496  private:
497  static constexpr auto _index
498  = findFirstMatching_dispatcher<Match, Target, Candidates...>();
499  }; // struct findFirstMatching_impl
500 
501 
502  //
503  // class to apply findFirstMatching_impl after skipping some candidates
504  //
505  template <
506  unsigned int NSkip,
507  template <typename A, typename B> class Match,
508  typename Target, typename... Candidates
509  >
511 
512  // recursion: peel one
513  template <
514  unsigned int NSkip,
515  template <typename A, typename B> class Match,
516  typename Target, typename FirstCandidate, typename... OtherCandidates
517  >
519  <NSkip, Match, Target, FirstCandidate, OtherCandidates...>
520  : index_constant<(
521  1U
522  + findNextMatching_impl
523  <(NSkip - 1U), Match, Target, OtherCandidates...>::value
524  )>
525  {
526  static_assert(NSkip > 0U, "Implementation error: no arguments to skip!");
527  };
528 
529  // end-of-recursion: skipped enough
530  template <
531  template <typename A, typename B> class Match,
532  typename Target, typename FirstCandidate, typename... OtherCandidates
533  >
535  <0U, Match, Target, FirstCandidate, OtherCandidates...>
537  <Match, Target, FirstCandidate, OtherCandidates...>
538  {};
539 
540  // end-of-recursion: all arguments skipped
541  template <
542  unsigned int NSkip,
543  template <typename A, typename B> class Match,
544  typename Target
545  >
546  struct findNextMatching_impl<NSkip, Match, Target>
547  : findFirstMatching_impl<Match, Target>
548  {};
549 
550  //
551  // class finding a match and asserting its existence and unicity
552  //
553  template <
554  template <typename A, typename B> class Match,
555  typename Target, typename... Candidates
556  >
558  : findFirstMatching_impl<Match, Target, Candidates...>
559  {
560  private:
561  static constexpr auto _index
562  = findFirstMatching_dispatcher<Match, Target, Candidates...>();
563 
564  static_assert(
566  >= sizeof...(Candidates),
567  "Multiple candidate classes match the Target one"
568  );
569  }; // struct findTheMatching_impl
570 
571  //
572  // implementations with concrete matching conditions
573  //
574  template <typename Derived, typename... Bases>
575  constexpr std::size_t indexOfBaseOf()
576  { return findTheMatching_impl<std::is_base_of, Derived, Bases...>(); }
577 
578  template <typename Derived, typename... Bases>
579  constexpr std::size_t findBaseOf()
580  {
581  constexpr std::size_t index = indexOfBaseOf<Derived, Bases...>();
582  static_assert(
583  index < sizeof...(Bases),
584  "Target is not derived from any of the available classes"
585  );
586  return index;
587  } // findBaseOf()
588 
589  // this matching condition is the mirror of std::is_base_of
590  template <typename Derived, typename Base>
591  struct is_derived_of: std::is_base_of<Base, Derived> {};
592 
593  template <typename Base, typename... Derived>
594  constexpr std::size_t indexOfDerivedFrom()
595  { return findTheMatching_impl<is_derived_of, Base, Derived...>(); }
596 
597  template <typename Base, typename... Derived>
598  constexpr std::size_t findDerivedFrom()
599  {
600  constexpr std::size_t index = indexOfDerivedFrom<Base, Derived...>();
601  static_assert(
602  index < sizeof...(Derived),
603  "Target is not base of any of the available classes"
604  );
605  return index;
606  } // findDerivedFrom()
607 
608  // --- END impementation of findDerivedFrom() ------------------------------
609 
610 
611  //--------------------------------------------------------------------------
612  //--- SetFrom
613  //---
614  template <
615  typename DestPack, typename SourcePack,
616  typename FirstProvider, typename... OtherProviders
617  >
618  struct SetFrom<DestPack, SourcePack, FirstProvider, OtherProviders...> {
619  SetFrom(DestPack& pack, SourcePack const& from)
620  {
621  pack.set(from.template get<FirstProvider>());
622  SetFrom<DestPack, SourcePack, OtherProviders...>(pack, from);
623  }
624  }; // SetFrom<First, Others...>
625 
626  template <typename DestPack, typename SourcePack>
627  struct SetFrom<DestPack, SourcePack> {
628  SetFrom(DestPack&, SourcePack const&) {}
629  };
630 
631  //--------------------------------------------------------------------------
632  //--- Compare
633  //---
634  template <typename Provider, typename APack, typename BPack>
635  bool haveSameProvider(APack const& a, BPack const& b) {
637  "This class needs two ProviderPack template types.");
638  return a.template get<Provider>() == b.template get<Provider>();
639  } // haveSameProvider()
640 
641 
642  template <typename APack, typename BPack>
644 
646  "The specified provider packs have different types.");
647 
648  }; // ProviderPackComparerBase
649 
650 
651  template <typename APack, typename BPack, typename... Providers>
653 
654  template
655  <typename APack, typename BPack, typename First, typename... Others>
656  struct ProviderPackComparer<APack, BPack, First, Others...>
657  : ProviderPackComparerBase<APack, BPack>
658  {
659  static bool compare (APack const& a, BPack const& b)
660  {
661  return haveSameProvider<First>(a, b)
663  }
664  }; // ProviderPackComparer<APack, BPack, First, Others...>
665 
666  template
667  <typename APack, typename BPack, typename First>
668  struct ProviderPackComparer<APack, BPack, First>
669  : ProviderPackComparerBase<APack, BPack>
670  {
671  static bool compare (APack const& a, BPack const& b)
672  { return haveSameProvider<First>(a, b); }
673  }; // ProviderPackComparer<APack, BPack, First>
674 
675 
676  //--------------------------------------------------------------------------
677 
678  } // namespace details
679 
680 
681  //----------------------------------------------------------------------------
682  //--- ProviderPack
683  //---
684 
685  template <typename... Providers>
686  template<typename... PackProviders, typename... OtherProviders>
688  ProviderPack<PackProviders...> const& fromPack,
689  OtherProviders const*... providers
690  )
691  {
692 
693  // verify that the list of providers in argument is the exact one we need
694  static_assert(
696  ::template as<PackProviders..., OtherProviders...>(),
697  "The providers types in the arguments do not match the ones needed."
698  );
699 
700  // copy all the providers from the provider pack
702  <this_type, ProviderPack<PackProviders...>, PackProviders...>
703  (*this, fromPack);
704 
705  // put the other providers in a temporary parameter pack, and copy it
706  // (this is convenience, a direct implementation would be probably better)
708  <this_type, ProviderPack<OtherProviders...>, OtherProviders...>
709  (*this, makeProviderPack(providers...));
710 
711  } // ProviderPack<Providers...>::ProviderPack(ProviderPack, OtherProviders...)
712 
713 
714  //----------------------------------------------------------------------------
715  template <typename... Providers>
716  template <typename... OtherProviders>
717  bool ProviderPack<Providers...>::operator==
718  (ProviderPack<OtherProviders...> const& other) const
719  {
721  ProviderPack<Providers...>, ProviderPack<OtherProviders...>, Providers...
722  >::compare(*this, other);
723  }
724 
725 
726  template <typename... Providers>
727  template <typename... OtherProviders>
728  bool ProviderPack<Providers...>::operator!=
729  (ProviderPack<OtherProviders...> const& other) const
730  { return !(*this == other); }
731 
732 
733  //----------------------------------------------------------------------------
734  template <typename... Providers>
735  template <typename... OfferedProviders>
737  return details::are_types_contained<Providers...>
738  ::template in<OfferedProviders...>();
739  } // ProviderPack<>::containsProviders()
740 
741 
742  //----------------------------------------------------------------------------
743 
744 } // namespace lar
745 
746 #endif // LARCOREALG_COREUTILS_PROVIDERPACK_H
static constexpr bool as()
Definition: ProviderPack.h:354
int compare(unsigned *r, sha1::digest_t const &d)
Definition: sha1_test_2.cc:60
ProviderPack< PackProviders..., MoreProviders... > expandProviderPack(ProviderPack< PackProviders... > const &pack, MoreProviders const *...providers)
Function to create a ProviderPack by adding to another.
Definition: ProviderPack.h:297
Implementation detail for the extraction constructor.
Definition: ProviderPack.h:84
ProviderPack(Providers const *...provider_ptrs)
Constructor: stores a provider pointer for each type.
Definition: ProviderPack.h:129
std::integral_constant< std::size_t, Value > index_constant
Definition: ProviderPack.h:317
#define Bases
Definition: code.cpp:12368
constexpr std::size_t hasDerivedFrom()
Definition: ProviderPack.h:77
static constexpr bool has()
Returns whether there is a provider with the specified type.
Definition: ProviderPack.h:212
std::integral_constant< bool, Value > bool_constant
Definition: ProviderPack.h:314
bool operator!=(ModuleKeyAndType const &a, ModuleKeyAndType const &b) noexcept
SetFrom(DestPack &, SourcePack const &)
Definition: ProviderPack.h:628
static constexpr bool containsProviders()
Returns whether all our providers are in the OfferedProviders list.
Definition: ProviderPack.h:736
ProviderPack(ProviderPack< OtherProviders... > const &from)
Constructor: extracts the providers from another parameter pack.
Definition: ProviderPack.h:141
bool haveSameProvider(APack const &a, BPack const &b)
Definition: ProviderPack.h:635
std::tuple< Providers const *... > tuple_type
type used for storage of the pointers
Definition: ProviderPack.h:121
ProviderPack()=default
Default constructor: a null provider pointer for each type.
tuple_type providers
container of the pointers, type-safe
Definition: ProviderPack.h:251
constexpr std::size_t indexOfBaseOf()
Index of the class among Bases which is base of Derived.
Definition: ProviderPack.h:575
constexpr std::size_t findDerivedFrom()
Definition: ProviderPack.h:598
constexpr std::size_t hasBaseOf()
Returns whether there is exactly one base class of Derived among Bases.
Definition: ProviderPack.h:73
const double a
ProviderPack< Providers... > makeProviderPack(Providers const *...providers)
Function to create a ProviderPack from the function arguments.
Definition: ProviderPack.h:272
constexpr std::size_t indexOfDerivedFrom()
Definition: ProviderPack.h:594
static bool compare(APack const &a, BPack const &b)
Definition: ProviderPack.h:671
ProviderPack(OtherProviders const *...providers)
Constructor: picks the providers from the specified ones.
Definition: ProviderPack.h:157
LArSoft-specific namespace.
Container for a list of pointers to providers.
Definition: ProviderPack.h:114
static bool * b
Definition: config.cpp:1043
constexpr std::size_t findBaseOf()
Index of the class among Bases which is base of Derived.
Definition: ProviderPack.h:579
bool operator==(ModuleKeyAndType const &a, ModuleKeyAndType const &b) noexcept