13 #ifndef LARCOREALG_COREUTILS_PROVIDERPACK_H 14 #define LARCOREALG_COREUTILS_PROVIDERPACK_H 19 #include <type_traits> 27 template <
typename... Types>
43 template <
typename Derived,
typename... Bases>
46 template <
typename Derived,
typename... Bases>
57 template <
typename Derived,
typename... Bases>
60 template <
typename Derived,
typename... Bases>
72 template <
typename Derived,
typename... Bases>
74 {
return indexOfBaseOf<Derived, Bases...>() <
sizeof...(Bases); }
76 template <
typename Derived,
typename... Bases>
83 <
typename DestPack,
typename SourcePack,
typename... ExtractProviders>
113 template <
typename... Providers>
116 "Providers in ProviderPack are repeated");
129 ProviderPack(Providers
const* ...provider_ptrs): providers(provider_ptrs...)
140 template<
typename... OtherProviders>
156 template<
typename... OtherProviders>
184 template<
typename... PackProviders,
typename... OtherProviders>
187 OtherProviders
const*... providers
192 template <
typename Prov
ider>
193 Provider
const*
get()
const 195 constexpr
auto providerIndex
197 return std::get<providerIndex>(providers);
202 template <
typename Prov
ider>
203 void set(Provider
const* provider_ptr)
205 constexpr
auto providerIndex
207 std::get<providerIndex>(providers) = provider_ptr;
211 template <
typename Prov
ider>
212 static constexpr
bool has()
217 template <
typename... OtherProviders>
221 template <
typename... OtherProviders>
246 template <
typename... OtherProviders>
247 static constexpr
bool containsProviders();
271 template <
typename... Providers>
296 template <
typename... PackProviders,
typename... MoreProviders>
299 MoreProviders
const* ...providers
301 {
return { pack, providers... }; }
313 template <
bool Value>
316 template <std::
size_t Value>
322 template <
typename Target,
typename... Types>
325 template <
typename Target,
typename First,
typename... Others>
328 template <
typename Target,
typename... Others>
329 struct has_type<Target, Target, Others...>: std::true_type {};
331 template <
typename Target>
336 template <
typename Key,
typename... Types>
339 <has_type<Key, Types...>() || has_duplicate_types<Types...>()>
347 template <
typename... Types>
350 template <
typename... Types>
353 template <
typename... AsTypes>
354 static constexpr
bool as()
356 return (
sizeof...(Types) ==
sizeof...(AsTypes))
363 template <
typename First,
typename... OtherTypes>
365 template <
typename... AsTypes>
366 static constexpr
bool in()
373 template <
typename First>
375 template <
typename... AsTypes>
376 static constexpr
bool in()
377 {
return has_type<First, AsTypes...>(); }
381 template <
typename T>
384 template <
typename... Providers>
389 template <
typename APack,
typename BPack>
392 template <
typename... AProviders,
typename... BProviders>
395 :
public std::integral_constant
396 <bool, are_same_types<AProviders...>::template as<BProviders...>()>
436 template <
typename A,
typename B>
class Match,
437 typename Target,
bool IsMatch,
typename... Candidates
442 template <
typename A,
typename B>
class Match,
443 typename Target,
typename... Candidates
450 template <
typename A,
typename B>
class Match,
451 typename Target,
typename... Candidates
457 template <
typename A,
typename B>
class Match,
465 template <
typename A,
typename B>
class Match,
466 typename Target,
typename FirstCandidate,
typename... OtherCandidates
469 <Match, Target, FirstCandidate, OtherCandidates...>
473 Match<FirstCandidate, Target>::value,
480 template <
typename A,
typename B>
class Match,
481 typename Target,
typename FirstCandidate,
typename... OtherCandidates
484 <Match, Target, false, FirstCandidate, OtherCandidates...>
486 <(1U + findFirstMatching_dispatcher<Match, Target, OtherCandidates...>::value)>
490 template <
typename A,
typename B>
class Match,
491 typename Target,
typename... Candidates
497 static constexpr
auto _index
507 template <
typename A,
typename B>
class Match,
508 typename Target,
typename... Candidates
515 template <
typename A,
typename B>
class Match,
516 typename Target,
typename FirstCandidate,
typename... OtherCandidates
519 <NSkip, Match, Target, FirstCandidate, OtherCandidates...>
522 + findNextMatching_impl
523 <(NSkip - 1U), Match, Target, OtherCandidates...>::value
526 static_assert(NSkip > 0U,
"Implementation error: no arguments to skip!");
531 template <
typename A,
typename B>
class Match,
532 typename Target,
typename FirstCandidate,
typename... OtherCandidates
535 <0U, Match, Target, FirstCandidate, OtherCandidates...>
537 <Match, Target, FirstCandidate, OtherCandidates...>
543 template <
typename A,
typename B>
class Match,
554 template <
typename A,
typename B>
class Match,
555 typename Target,
typename... Candidates
561 static constexpr
auto _index
566 >=
sizeof...(Candidates),
567 "Multiple candidate classes match the Target one" 574 template <
typename Derived,
typename... Bases>
578 template <
typename Derived,
typename... Bases>
581 constexpr std::size_t index =
indexOfBaseOf<Derived, Bases...>();
583 index <
sizeof...(Bases),
584 "Target is not derived from any of the available classes" 590 template <
typename Derived,
typename Base>
593 template <
typename Base,
typename... Derived>
597 template <
typename Base,
typename... Derived>
602 index <
sizeof...(Derived),
603 "Target is not base of any of the available classes" 615 typename DestPack,
typename SourcePack,
616 typename FirstProvider,
typename... OtherProviders
618 struct SetFrom<DestPack, SourcePack, FirstProvider, OtherProviders...> {
619 SetFrom(DestPack& pack, SourcePack
const& from)
621 pack.set(from.template get<FirstProvider>());
622 SetFrom<DestPack, SourcePack, OtherProviders...>(pack, from);
626 template <
typename DestPack,
typename SourcePack>
634 template <
typename Prov
ider,
typename APack,
typename BPack>
637 "This class needs two ProviderPack template types.");
638 return a.template get<Provider>() == b.template get<Provider>();
642 template <
typename APack,
typename BPack>
646 "The specified provider packs have different types.");
651 template <
typename APack,
typename BPack,
typename... Providers>
655 <
typename APack,
typename BPack,
typename First,
typename... Others>
659 static bool compare (APack
const& a, BPack
const& b)
661 return haveSameProvider<First>(a, b)
667 <
typename APack,
typename BPack,
typename First>
671 static bool compare (APack
const& a, BPack
const& b)
672 {
return haveSameProvider<First>(a, b); }
685 template <
typename... Providers>
686 template<
typename... PackProviders,
typename... OtherProviders>
689 OtherProviders
const*... providers
696 ::
template as<PackProviders..., OtherProviders...>(),
697 "The providers types in the arguments do not match the ones needed." 708 <this_type,
ProviderPack<OtherProviders...>, OtherProviders...>
715 template <
typename... Providers>
716 template <
typename... OtherProviders>
722 >::compare(*
this,
other);
726 template <
typename... Providers>
727 template <
typename... OtherProviders>
730 {
return !(*
this ==
other); }
734 template <
typename... Providers>
735 template <
typename... OfferedProviders>
738 ::template
in<OfferedProviders...>();
746 #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)
bool operator!=(geometry_element_iterator< GEOIDITER > const &iter, GEOIDITER const &id_iter)
Comparison operator: geometry ID and element point to different IDs.
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)
constexpr std::size_t findBaseOf()
Index of the class among Bases which is base of Derived.
bool operator==(geometry_element_iterator< GEOIDITER > const &iter, GEOIDITER const &id_iter)
Comparison operator: geometry ID and element point to the same ID.