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");
140 template<
typename... OtherProviders>
156 template<
typename... OtherProviders>
184 template<
typename... PackProviders,
typename... OtherProviders>
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>
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...> {
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()
ProviderPack< Providers...> this_type
alias of this class
static constexpr bool in()
static constexpr auto _index
static bool compare(APack const &a, BPack const &b)
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.
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.
static constexpr auto _index
ProviderPack< PackProviders..., MoreProviders...> expandProviderPack(ProviderPack< PackProviders...> const &pack, MoreProviders const *...providers)
Function to create a ProviderPack by adding to another.
bool operator==(ProviderPack< OtherProviders...> const &other) const
Returns whether other provider pack has all the same providers as this.
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.
if &&[-z"$BASH_VERSION"] then echo Attempting to switch to bash bash shellSwitch exit fi &&["$1"= 'shellSwitch'] shift declare a IncludeDirectives for Dir in
Container for a list of pointers to providers.
constexpr std::size_t findBaseOf()
Index of the class among Bases which is base of Derived.
ProviderPack(ProviderPack< OtherProviders...> const &from)
Constructor: extracts the providers from another parameter pack.
bool operator!=(ProviderPack< OtherProviders...> const &other) const
Returns whether other provider pack and this have different providers.
BEGIN_PROLOG don t mess with this pandoraTrackGausCryoW true
void set(Provider const *provider_ptr)
Sets the provider with the specified type.
SetFrom(DestPack &pack, SourcePack const &from)