12 #ifndef LARCOREALG_COREUTILS_PROVIDERPACK_H 13 #define LARCOREALG_COREUTILS_PROVIDERPACK_H 18 #include <type_traits> 24 template <
typename... Types>
39 template <
typename Derived,
typename... Bases>
42 template <
typename Derived,
typename... Bases>
53 template <
typename Derived,
typename... Bases>
56 template <
typename Derived,
typename... Bases>
68 template <
typename Derived,
typename... Bases>
74 template <
typename Derived,
typename... Bases>
81 template <
typename DestPack,
typename SourcePack,
typename... ExtractProviders>
110 template <
typename... Providers>
113 "Providers in ProviderPack are repeated");
125 ProviderPack(Providers
const*... provider_ptrs) : providers(provider_ptrs...) {}
135 template <
typename... OtherProviders>
149 template <
typename... OtherProviders>
176 template <
typename... PackProviders,
typename... OtherProviders>
178 OtherProviders
const*... providers);
181 template <
typename Prov
ider>
182 Provider
const*
get()
const 185 return std::get<providerIndex>(providers);
189 template <
typename Prov
ider>
190 void set(Provider
const* provider_ptr)
193 std::get<providerIndex>(providers) = provider_ptr;
197 template <
typename Prov
ider>
198 static constexpr
bool has()
204 template <
typename... OtherProviders>
208 template <
typename... OtherProviders>
232 template <
typename... OtherProviders>
233 static constexpr
bool containsProviders();
255 template <
typename... Providers>
281 template <
typename... PackProviders,
typename... MoreProviders>
284 MoreProviders
const*... providers)
286 return {pack, providers...};
297 template <
bool Value>
300 template <std::
size_t Value>
306 template <
typename Target,
typename... Types>
309 template <
typename Target,
typename First,
typename... Others>
312 template <
typename Target,
typename... Others>
313 struct has_type<Target, Target, Others...> : std::true_type {};
315 template <
typename Target>
319 template <
typename Key,
typename... Types>
321 :
public bool_constant<has_type<Key, Types...>() || has_duplicate_types<Types...>()> {};
327 template <
typename... Types>
330 template <
typename... Types>
333 template <
typename... AsTypes>
334 static constexpr
bool as()
336 return (
sizeof...(Types) ==
sizeof...(AsTypes)) &&
342 template <
typename First,
typename... OtherTypes>
344 template <
typename... AsTypes>
345 static constexpr
bool in()
352 template <
typename First>
354 template <
typename... AsTypes>
355 static constexpr
bool in()
357 return has_type<First, AsTypes...>();
361 template <
typename T>
364 template <
typename... Providers>
367 template <
typename APack,
typename BPack>
370 template <
typename... AProviders,
typename... BProviders>
372 :
public std::integral_constant<bool,
373 are_same_types<AProviders...>::template as<BProviders...>()> {
411 template <
template <
typename A,
typename B>
class Match,
414 typename... Candidates>
417 template <
template <
typename A,
typename B>
class Match,
419 typename... Candidates>
423 template <
template <
typename A,
typename B>
class Match,
425 typename... Candidates>
429 template <
template <
typename A,
typename B>
class Match,
typename Target>
433 template <
template <
typename A,
typename B>
class Match,
435 typename FirstCandidate,
436 typename... OtherCandidates>
440 Match<FirstCandidate, Target>::value,
442 OtherCandidates...> {};
444 template <
template <
typename A,
typename B>
class Match,
446 typename FirstCandidate,
447 typename... OtherCandidates>
450 1U + findFirstMatching_dispatcher<Match, Target, OtherCandidates...>::value)> {};
452 template <
template <
typename A,
typename B>
class Match,
454 typename... Candidates>
463 template <
unsigned int NSkip,
464 template <
typename A,
typename B>
467 typename... Candidates>
471 template <
unsigned int NSkip,
472 template <
typename A,
typename B>
475 typename FirstCandidate,
476 typename... OtherCandidates>
479 1U + findNextMatching_impl<(NSkip - 1U), Match, Target, OtherCandidates...>::value)> {
480 static_assert(NSkip > 0U,
"Implementation error: no arguments to skip!");
484 template <
template <
typename A,
typename B>
class Match,
486 typename FirstCandidate,
487 typename... OtherCandidates>
492 template <
unsigned int NSkip,
template <
typename A,
typename B>
class Match,
typename Target>
498 template <
template <
typename A,
typename B>
class Match,
500 typename... Candidates>
506 sizeof...(Candidates),
507 "Multiple candidate classes match the Target one");
513 template <
typename Derived,
typename... Bases>
519 template <
typename Derived,
typename... Bases>
522 constexpr std::size_t index =
indexOfBaseOf<Derived, Bases...>();
523 static_assert(index <
sizeof...(Bases),
524 "Target is not derived from any of the available classes");
529 template <
typename Derived,
typename Base>
532 template <
typename Base,
typename... Derived>
538 template <
typename Base,
typename... Derived>
542 static_assert(index <
sizeof...(Derived),
543 "Target is not base of any of the available classes");
552 template <
typename DestPack,
554 typename FirstProvider,
555 typename... OtherProviders>
556 struct SetFrom<DestPack, SourcePack, FirstProvider, OtherProviders...> {
557 SetFrom(DestPack& pack, SourcePack
const& from)
559 pack.set(from.template get<FirstProvider>());
560 SetFrom<DestPack, SourcePack, OtherProviders...>(pack, from);
564 template <
typename DestPack,
typename SourcePack>
572 template <
typename Prov
ider,
typename APack,
typename BPack>
576 "This class needs two ProviderPack template types.");
577 return a.template get<Provider>() == b.template get<Provider>();
580 template <
typename APack,
typename BPack>
584 "The specified provider packs have different types.");
588 template <
typename APack,
typename BPack,
typename... Providers>
591 template <
typename APack,
typename BPack,
typename First,
typename... Others>
594 static bool compare(APack
const& a, BPack
const& b)
596 return haveSameProvider<First>(a, b) &&
601 template <
typename APack,
typename BPack,
typename First>
603 static bool compare(APack
const& a, BPack
const& b) {
return haveSameProvider<First>(a, b); }
614 template <
typename... Providers>
615 template <
typename... PackProviders,
typename... OtherProviders>
617 OtherProviders
const*... providers)
623 "The providers types in the arguments do not match the ones needed.");
636 template <
typename... Providers>
637 template <
typename... OtherProviders>
642 Providers...>::compare(*
this, other);
645 template <
typename... Providers>
646 template <
typename... OtherProviders>
649 return !(*
this ==
other);
653 template <
typename... Providers>
654 template <
typename... OfferedProviders>
664 #endif // LARCOREALG_COREUTILS_PROVIDERPACK_H
static constexpr bool as()
static constexpr bool in()
static constexpr bool in()
ProviderPack< PackProviders..., MoreProviders... > expandProviderPack(ProviderPack< PackProviders... > const &pack, MoreProviders const *...providers)
Function to create a ProviderPack by adding to another.
Implementation detail for the extraction constructor.
ProviderPack(Providers const *...provider_ptrs)
Constructor: stores a provider pointer for each type.
std::integral_constant< std::size_t, Value > index_constant
constexpr std::size_t hasDerivedFrom()
static constexpr bool has()
Returns whether there is a provider with the specified type.
std::integral_constant< bool, Value > bool_constant
SetFrom(DestPack &, SourcePack const &)
static constexpr bool containsProviders()
Returns whether all our providers are in the OfferedProviders list.
ProviderPack(ProviderPack< OtherProviders... > const &from)
Constructor: extracts the providers from another parameter pack.
bool haveSameProvider(APack const &a, BPack const &b)
std::tuple< Providers const *... > tuple_type
type used for storage of the pointers
ProviderPack()=default
Default constructor: a null provider pointer for each type.
tuple_type providers
container of the pointers, type-safe
constexpr std::size_t indexOfBaseOf()
Index of the class among Bases which is base of Derived.
constexpr std::size_t findDerivedFrom()
constexpr std::size_t hasBaseOf()
Returns whether there is exactly one base class of Derived among Bases.
ProviderPack< Providers... > makeProviderPack(Providers const *...providers)
Function to create a ProviderPack from the function arguments.
SetFrom(DestPack &pack, SourcePack const &from)
constexpr std::size_t indexOfDerivedFrom()
static bool compare(APack const &a, BPack const &b)
ProviderPack(OtherProviders const *...providers)
Constructor: picks the providers from the specified ones.
LArSoft-specific namespace.
Container for a list of pointers to providers.
static bool compare(APack const &a, BPack const &b)
bool operator!=(infinite_endcount_iterator< T > const &, count_iterator< T > const &)
Never admit a infinite_endcount_iterator to be equal to anything else.
constexpr std::size_t findBaseOf()
Index of the class among Bases which is base of Derived.
bool operator==(infinite_endcount_iterator< T > const &, count_iterator< T > const &)
bool operator==(ProviderPack< OtherProviders... > const &other) const
Returns whether other provider pack has all the same providers as this.
bool operator!=(ProviderPack< OtherProviders... > const &other) const
Returns whether other provider pack and this have different providers.