23#include <initializer_list>
27#include <source_location>
36 inline std::vector<DataObjID>
to_DataObjID(
const std::vector<std::string>& in ) {
37 std::vector<DataObjID> out;
38 out.reserve( in.size() );
39 std::transform( in.begin(), in.end(), std::back_inserter( out ),
40 [](
const std::string& i ) { return DataObjID{ i }; } );
49 typename T::value_type;
59 template <is_optional T>
61 using type = T::value_type;
70 template <
typename F,
typename Arg>
73 return std::invoke( std::forward<F>( f ), std::forward<Arg>( arg ) );
75 template <
typename F, is_optional Arg>
77 if ( arg ) std::invoke( std::forward<F>( f ), *std::forward<Arg>( arg ) );
79 } invoke_optionally{};
82 template <
typename Value, auto>
83 using repeat_t = Value;
84 template <
typename Value, auto N>
86 decltype( []<std::size_t... I>( std::index_sequence<I...> ) -> std::tuple<repeat_t<Value, I>...> {
87 }( std::make_index_sequence<N>{} ) );
89 template <
typename Value, std::size_t... I>
91 return std::make_tuple( ( (
void)I, Value{} )... );
94 template <
typename Value, auto N>
99 template <std::derived_from<DataObject> Out1, std::convertible_to<Out1> Out2>
101 return out_handle.
put( std::make_unique<Out1>( std::forward<Out2>( out ) ) );
104 template <
typename Out1, std::convertible_to<Out1> Out2>
106 return out_handle.put( std::forward<Out2>( out ) );
109 template <
template <
typename>
class Handle,
typename Out,
typename Value>
111 auto const n = out_handle.
size();
112 if ( out.size() != n ) {
114 std::string{ std::source_location::current().function_name() } +
": expected " +
115 std::to_string( n ) +
" containers, got " + std::to_string( out.size() ) +
" instead",
118 for ( std::size_t i = 0; i != n; ++i )
details::put( out_handle.
handles()[i], std::move( out[i] ) );
122 template <
typename OutHandle,
typename OptOut>
123 requires( is_optional<OptOut> )
124 void put(
const OutHandle& out_handle, OptOut&& out ) {
125 if ( out )
put( out_handle, *std::forward<OptOut>( out ) );
135 template <
typename Container>
138 template <
typename Container,
typename Value>
139 auto operator()( Container& c, Value&& v )
const ->
decltype( c.push_back( v ) ) {
140 return c.push_back( std::forward<Value>( v ) );
143 template <
typename Container,
typename Value>
144 auto operator()( Container& c, Value&& v )
const ->
decltype( c.insert( v ) ) {
145 return c.insert( std::forward<Value>( v ) );
149 template <
typename Container,
typename Value>
150 requires( std::is_pointer_v<typename Container::value_type> &&
151 std::is_convertible_v<Value, c_remove_ptr_t<Container>> )
152 auto operator()( Container& c, Value&& v )
const {
161 template <
typename In>
162 requires( !std::is_pointer_v<In> )
163 const In&
operator()(
const In& in )
const {
167 template <
typename In>
168 requires( !std::is_pointer_v<std::decay_t<In>> )
169 In
operator()( In&& in )
const {
170 return std::forward<In>( in );
173 template <
typename In>
175 assert( in !=
nullptr );
183 template <
typename T>
184 constexpr static bool is_gaudi_range_v =
false;
186 template <
typename T>
187 constexpr static bool is_gaudi_range_v<Gaudi::Range_<T>> =
true;
189 template <
typename T>
190 constexpr static bool is_gaudi_range_v<Gaudi::NamedRange_<T>> =
true;
192 template <
typename T>
193 constexpr static bool is_gaudi_range_v<std::optional<Gaudi::NamedRange_<T>>> =
true;
195 template <
typename In>
197 template <
template <
typename>
class Handle, std::convertible_to<In> I>
201 template <
template <
typename>
class Handle,
typename I>
205 template <
template <
typename>
class Handle,
typename I>
209 template <
template <
typename>
class Handle,
typename I>
213 template <
template <
typename>
class Handle,
typename I>
214 requires( std::is_convertible_v<I*, In> )
215 auto operator()(
const Handle<I>& h ) -> In {
216 return h.getIfExists();
220 template <
typename Iterator>
222 using traits = std::iterator_traits<Iterator>;
229 using value_type [[maybe_unused]] = std::remove_reference_t<reference>;
230 using pointer [[maybe_unused]] = std::add_pointer_t<value_type>;
257 requires std::bidirectional_iterator<Iterator>
266 requires std::random_access_iterator<Iterator>
272 requires std::random_access_iterator<Iterator>
278 requires std::random_access_iterator<Iterator>
284 requires std::random_access_iterator<Iterator>
290 requires std::random_access_iterator<Iterator>
292 return m_iter - other.m_iter;
295 requires std::random_access_iterator<Iterator>
303 template <
typename Container>
305 static constexpr bool is_pointer = std::is_pointer_v<Container>;
306 static constexpr bool is_range = details2::is_gaudi_range_v<Container>;
307 template <
typename C>
311 using ptr_t = std::add_pointer_t<val_t>;
315 constexpr static decltype( auto )
wrap( ContainerVector::const_reference t ) {
322 constexpr static auto wrap( ContainerVector::const_iterator i ) {
331 using value_type = std::conditional_t<is_pointer, ptr_t, val_t>;
336 template <
typename T>
337 requires( is_pointer || is_range )
341 template <
typename C = Container>
342 requires( !std::is_pointer_v<C> && !details2::is_gaudi_range_v<C> )
347 template <
typename C = Container>
348 requires( !std::is_pointer_v<C> && !details2::is_gaudi_range_v<C> )
360 template <
typename T>
362 template <
typename T>
365 template <
typename Arg>
370 template <
typename T>
375 template <
typename Arg>
377 template <
typename Arg>
379 template <
typename... Args>
382 template <
typename... T>
385 template <
typename H>
391 template <
typename Vectors>
392 decltype( auto )
getKeys( Vectors
const& vectors,
unsigned int i ) {
394 [i](
auto const&... elems ) ->
decltype(
auto ) {
return *std::array{ &elems.keys()... }.at( i ); }, vectors );
397 template <
typename F>
400 return std::forward<F>( f )();
409 template <
typename Algo>
416 template <
typename Tr>
419 template <
typename Tr,
typename Default>
423 template <
typename Tr,
typename Default>
424 requires requires {
typename Tr::BaseClass; }
429 template <
typename T,
typename Tr,
template <
typename...>
typename Default>
433 template <
typename T,
typename Tr,
template <
typename...>
typename Default>
438 template <
typename Tr,
template <
typename...>
typename Default>
440 template <
typename T>
443 template <
typename T,
typename Tr,
template <
typename...>
typename Default>
448 template <
typename T,
typename Tr,
template <
typename...>
typename Default>
452 template <
typename T,
typename Tr,
template <
typename...>
typename Default>
457 template <
typename Tr,
template <
typename...>
typename Default>
459 template <
typename T>
462 template <
typename T,
typename Tr,
template <
typename...>
typename Default>
467 template <
typename T>
470 template <
typename T>
474 template <algtool_
interface T>
482 template <
typename T>
489 template <
typename Tr,
typename Default = Gaudi::Algorithm>
495 template <
typename Tr,
typename T>
498 template <
typename Tr,
typename T>
501 template <
typename T>
505 using KeyValue = std::pair<std::string, std::string>;
506 using KeyValues = std::pair<std::string, std::vector<std::string>>;
512 :
value{
std::move( name_ ), { std::move( location_ ) } } {}
517 LocationSpec( std::string name_, std::initializer_list<std::string> locations_ )
522 throw GaudiException(
"Expected a scalar location specification",
"Gaudi::Functional::details::LocationSpec",
530 template <
typename Arg>
538 template <
typename T>
542 template <
typename T>
546 template <
typename Arg>
549 template <
typename... Args>
552 template <
typename... Args>
556 template <
typename First,
typename... Rest>
560 template <
typename... Args>
563 template <
typename Tuple>
567 template <
typename First,
typename... Rest>
571 template <
typename Tuple>
574 template <
typename Tuple,
typename T>
576 template <
typename T,
typename... Elements>
579 template <
typename Tuple,
typename T>
581 template <
typename T,
typename... Elements>
583 ( std::constructible_from<Elements, T> && ... );
585 template <
typename... Args>
587 template <
typename First,
typename... Rest>
590 template <
bool starts_with_event_context,
typename InputSpecTuple>
592 std::conditional_t<starts_with_event_context, InputSpecTuple, std::tuple<>>{};
594 template <
typename Tuple,
typename Spec, std::size_t... I>
595 Tuple
location_specs_tuple( std::initializer_list<Spec> specs, std::index_sequence<I...>,
const char* component ) {
596 if constexpr (
sizeof...( I ) == 1 ) {
597 if ( specs.size() == 0 )
return Tuple{ Spec{} };
599 if ( specs.size() !=
sizeof...( I ) ) {
602 return Tuple{ *std::next( specs.begin(), I )... };
605 template <
typename Tuple>
610 static constexpr auto indices = std::make_index_sequence<std::tuple_size_v<Tuple>>{};
613 requires( std::tuple_size_v<Tuple> == 0 )
616 template <
typename... Specs>
618 requires(
sizeof...( Specs ) > 0 && std::constructible_from<Tuple, Specs...> )
619 :
m_specs{
std::forward<Specs>( specs )... } {}
620 template <
typename... Args>
622 requires(
sizeof...( Args ) > 1 && std::tuple_size_v<Tuple> == 1 && std::constructible_from<
First, Args...> )
625 requires( std::tuple_size_v<Tuple> == 1 && std::constructible_from<First, std::string, std::string> )
628 requires( std::tuple_size_v<Tuple> == 1 && std::constructible_from<First, std::string, std::vector<std::string>> )
645 template <
typename Traits>
647 std::is_base_of_v<Gaudi::details::LegacyAlgorithmAdapter, details::BaseClass_t<Traits>>;
651 template <
typename Handle,
typename Algo>
652 auto get(
const Handle& handle,
const Algo&,
658 template <
typename Algo>
663 template <
template <
typename>
class Handle,
typename In,
typename Algo>
671 template <
typename IFace,
typename Algo>
673 return handle.bind( ctx );
676 template <
typename Handle>
677 auto getKey(
const Handle& h ) ->
decltype( h.objKey() ) {
681 template <
template <
typename>
class Handle,
typename T>
686 template <
typename OutputSpec,
typename InputSpec,
typename Traits_>
687 class DataHandleMixin;
689 template <
typename Outputs,
typename Traits_,
typename... Args>
692 template <
typename... Out,
typename... In,
typename Traits_>
693 requires( std::derived_from<BaseClass_t<Traits_>,
Algorithm> && !std::disjunction_v<std::is_void<Out>...> )
697 constexpr static std::size_t
N_in =
sizeof...( In );
698 constexpr static std::size_t
N_out =
sizeof...( Out );
701 template <
typename IArgs,
typename OArgs, std::size_t... I, std::size_t... J>
703 const OArgs& outputs, std::index_sequence<J...> )
711 using InputHandles = std::tuple<details::InputHandle_t<Traits_, In>...>;
722 template <std::
size_t N>
724 template <std::
size_t N>
726 template <std::size_t... I>
733 template <std::size_t... I>
744 requires( N_in == 0 && N_out == 0 )
745 : DataHandleMixin(
std::move( name ), locator,
std::tuple<>{}, InputSpecs::indices, std::tuple<>{},
746 OutputSpecs::indices ) {}
752 InputSpecs::indices,
std::tuple<>{}, OutputSpecs::indices ) {}
758 OutputSpecs::indices ) {}
764 OutputSpecs::indices ) {}
770 InputSpecs::indices, outputs.tuple(), outputs.indices ) {}
774 requires(
N_out != 0 )
775 :
DataHandleMixin(
std::move( name ), locator, inputs.tuple(), inputs.indices, outputs.tuple(),
784 template <std::
size_t N = 0>
790 template <
typename T>
796 template <std::
size_t N = 0>
800 return std::get<input_handle_index<N>>(
m_inputs ).at( n ).key();
810 auto size = [](
const auto& handle ) {
812 return static_cast<unsigned int>( handle.size() );
818 size](
const auto&... handles ) {
return std::array{ size( handles )... }.at( i ); },
836 template <std::
size_t N = 0>
838 requires(
N_out > 0 )
842 template <
typename T>
844 requires(
N_out > 0 )
848 template <std::
size_t N = 0>
852 return std::get<N>(
m_outputs ).at( n ).key();
862 template <
typename Algorithm>
865 [&](
const auto&... handle ) ->
decltype(
auto ) {
return algo(
get( handle, algo, ctx )... ); },
m_inputs );
874 template <
typename InputSpec,
typename Traits_>
880 template <
typename OutHandles,
typename Outputs>
881 void put_results(
const OutHandles& out_handles, Outputs&& outputs ) {
882 [&]<std::size_t... I>( std::index_sequence<I...> ) {
883 (
put( std::get<I>( out_handles ), std::get<I>( std::forward<Outputs>( outputs ) ) ), ... );
884 }( std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Outputs>>>{} );
887 template <
typename Algorithm,
typename OutHandles = std::tuple<>>
889 requires( std::tuple_size_v<OutHandles> <= 1 )
891 return execute( algo, [&] {
892 if constexpr ( std::tuple_size_v<OutHandles> == 0 ) {
893 algo.invoke( algo, ctx );
895 put( std::get<0>( out_handles ), algo.invoke( algo, ctx ) );
897 return FilterDecision::PASSED;
901 template <
typename Algorithm,
typename OutHandles>
904 put_results( out_handles, algo.invoke( algo, ctx ) );
909 template <
typename Algorithm,
typename OutHandles>
913 [&](
bool passed,
auto&&... data ) {
914 put_results( out_handles, std::forward_as_tuple( std::forward<
decltype( data )>( data )... ) );
917 algo.invoke( algo, ctx ) )
bool PyHelper setProperty(IInterface *p, char *name, char *value)
boost::spirit::classic::position_iterator2< ForwardIterator > Iterator
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
DataObjectHandle.h GaudiKernel/DataObjectHandle.h.
T * put(std::unique_ptr< T > object) const
Register object in transient store.
This class represents an entry point to all the event specific data.
Base class from which all concrete algorithm classes should be derived.
A configurable, dynamically sized sequence of homogeneous data handles.
const std::vector< Handle< T > > & handles() const
Typed handles, in property order.
auto size() const
Number of configured handles.
static constexpr bool all_input_locations_are_vectors
unsigned int outputLocationSize() const
std::tuple< details::OutputHandle_t< Traits_, Out >... > OutputHandles
static constexpr bool starts_with_event_context
static constexpr std::size_t N_in
LocationSpec::KeyValue KeyValue
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, const IArgs &inputs, std::index_sequence< I... >, const OArgs &outputs, std::index_sequence< J... >)
DataHandleMixin(std::string name, ISvcLocator *locator, LegacyInputSpecs const &inputs)
decltype(auto) inputLocation(unsigned int i, unsigned int j) const
decltype(auto) outputLocation() const
DataHandleMixin(std::string name, ISvcLocator *locator, LegacyInputSpecs const &inputs, OutputSpecs const &outputs)
DataHandleMixin(std::string name, ISvcLocator *locator, InputSpecs const &inputs)
TailLocationSpecs_t< In... > LegacyInputSpecTuple
bool isReEntrant() const override
decltype(auto) inputLocation() const
LocationSpecs_t< Out... > OutputSpecTuple
static constexpr std::size_t input_handle_index
DataHandleMixin(std::string name, ISvcLocator *locator, InputSpecs const &inputs, OutputSpecs const &outputs)
static constexpr std::size_t N_input_locations
DataHandleMixin(std::string name, ISvcLocator *locator, OutputSpecs const &outputs)
auto input_location_handles(std::index_sequence< I... >) const
static constexpr std::size_t input_location_offset
static constexpr std::size_t N_out
unsigned int inputLocationSize(unsigned int i) const
static constexpr bool input_locations_are_vectors(std::index_sequence< I... >)
details::LocationSpecs< LegacyInputSpecTuple > LegacyInputSpecs
decltype(auto) inputLocation() const
details::LocationSpecs< InputSpecTuple > InputSpecs
decltype(auto) invoke(const Algorithm &algo, const EventContext &ctx) const
details::LocationSpecs< OutputSpecTuple > OutputSpecs
std::tuple_element_t< input_handle_index< N >, InputHandles > InputLocationHandle
decltype(auto) outputLocation(unsigned int n) const
decltype(auto) inputLocation(unsigned int n) const
unsigned int inputLocationSize() const
std::tuple< details::InputHandle_t< Traits_, In >... > InputHandles
DataHandleMixin(std::string name, ISvcLocator *locator)
LocationSpecs_t< In... > InputSpecTuple
DataHandleMixin(std::string name, ISvcLocator *locator, std::tuple<>={}, std::tuple<>={})
LocationSpec::KeyValues KeyValues
LocationSpecs(Args &&... args)
LocationSpecs(std::string name, std::string loc)
first_or_empty_t< Tuple > First
LocationSpecs(Tuple specs)
LocationSpecs(std::string name, std::vector< std::string > locs)
LocationSpecs(std::initializer_list< LocationSpec > specs)
auto with_context() const
Tuple const & tuple() const
static constexpr auto indices
LocationSpecs(Specs &&... specs)
LocationSpecs(std::initializer_list< First > specs)
constexpr indirect_iterator & operator+=(difference_type n)
constexpr indirect_iterator operator--(int)
constexpr indirect_iterator & operator++()
constexpr indirect_iterator & operator-=(difference_type n)
constexpr reference operator*() const
constexpr indirect_iterator(Iterator i)
constexpr indirect_iterator operator+(difference_type n) const
constexpr bool operator==(const indirect_iterator &rhs) const
std::iterator_traits< Iterator > traits
std::add_pointer_t< value_type > pointer
constexpr indirect_iterator operator-(difference_type n) const
constexpr difference_type operator-(const indirect_iterator &other) const
typename traits::difference_type difference_type
constexpr reference operator[](difference_type n) const
indirect_iterator()=default
constexpr indirect_iterator operator++(int)
typename traits::iterator_category iterator_category
std::remove_reference_t< reference > value_type
constexpr indirect_iterator & operator--()
decltype(**m_iter) reference
static constexpr decltype(auto) wrap(ContainerVector::const_reference t)
static constexpr bool is_range
static constexpr auto wrap(ContainerVector::const_iterator i)
static constexpr bool is_pointer
std::add_pointer_t< val_t > ptr_t
ContainerVector m_containers
decltype(auto) back() const
void push_back(borrowed_value_t< C > &&)=delete
std::add_const_t< std::remove_pointer_t< C > > borrowed_value_t
vector_of_const_()=default
void push_back(T &&container)
void reserve(size_type size)
typename ContainerVector::size_type size_type
std::vector< std::conditional_t< is_range, std::remove_const_t< val_t >, ptr_t > > ContainerVector
std::conditional_t< is_pointer, ptr_t, val_t > value_type
borrowed_value_t< Container > val_t
decltype(auto) at(size_type i) const
void push_back(borrowed_value_t< C > &container)
decltype(auto) front() const
Useful class for representation of "sequence" of the objects through the range of valid iterators.
Define general base for Gaudi exception.
virtual const std::string & message() const
error message to be printed
virtual const StatusCode & code() const
StatusCode for Exception.
virtual const std::string & tag() const
name tag for the exception, or exception type
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
This class is used for returning status codes from appropriate routines.
constexpr static const auto FAILURE
typename Tr::BaseClass BaseClass_t
typename DefaultInputHandle< T >::type DefaultInputHandle_t
StatusCode execute_outputs(const Algorithm &algo, const EventContext &ctx, const OutHandles &out_handles)
typename detail2::InputHandle< T, Tr, detail2::DefaultInputHandle_t >::type InputHandle_t
auto get(const Handle &handle, const Algo &, const EventContext &) -> decltype(details::deref(handle.get()))
typename first_or_empty< Tuple >::type first_or_empty_t
auto getKey(const Handle &h) -> decltype(h.objKey())
constexpr auto empty_input_specs
typename TailLocationSpecs< Args... >::type TailLocationSpecs_t
std::vector< DataObjID > to_DataObjID(const std::vector< std::string > &in)
typename handle_vector_input< Arg >::type handle_vector_input_t
auto put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
constexpr bool tuple_elements_are_v
decltype(auto) getKeys(Vectors const &vectors, unsigned int i)
std::tuple< LocationSpec_t< Args >... > LocationSpecs_t
typename detail2::OutputHandle< T, Tr, DataObjectWriteHandle >::type OutputHandle_t
StatusCode execute_single_output(const Algorithm &algo, const EventContext &ctx, const OutHandles &out_handles={})
constexpr bool first_is_event_context_v
constexpr struct Gaudi::Functional::details::deref_t deref
constexpr bool is_handle_vector_input_v
typename LocationSpecFor< std::remove_cvref_t< Arg > >::type LocationSpec_t
typename details2::value_type_of< T >::type remove_optional_t
constexpr bool is_event_context_v
detail2::BaseClass< Tr, Default >::type BaseClass_t
decltype(get_values_helper< Value >(std::make_index_sequence< N >())) RepeatValues_
StatusCode execute_filtered_outputs(const Algorithm &algo, const EventContext &ctx, const OutHandles &out_handles)
auto get_values_helper(std::index_sequence< I... >)
DataHandleMixin< Outputs, type_list< handle_vector_input_t< Args >... >, Traits_ > DataHandleVectorMixin
StatusCode execute(CommonMessagingBase const &alg, F &&f)
void put_results(const OutHandles &out_handles, Outputs &&outputs)
Tuple location_specs_tuple(std::initializer_list< Spec > specs, std::index_sequence< I... >, const char *component)
constexpr bool tuple_elements_constructible_from_v
EventContextHandle(std::tuple< Algo >)
LocationSpec::KeyValues type
LocationSpec::KeyValue type
LocationSpec(std::string name_, std::vector< std::string > locations_)
std::pair< std::string, std::string > KeyValue
std::pair< std::string, std::vector< std::string > > KeyValues
LocationSpec(std::string name_, std::initializer_list< std::string > locations_)
LocationSpec(std::string name_, const char *location_)
LocationSpec(std::string name_, std::string location_)
LocationSpecs_t< Rest... > type
const In & operator()(const In *in) const
Tr::template OutputHandle< T > type
Gaudi::DataHandleVector< OutputHandleFor< Tr, Default >::template type, T > type
typename OutputHandle< remove_optional_t< T >, Tr, Default >::type type
auto operator()(const Handle< std::optional< Gaudi::NamedRange_< I > > > &h) -> In
auto operator()(const Handle< I > &h) -> const In &
auto operator()(const Handle< Gaudi::NamedRange_< I > > &h) -> In
auto operator()(const Handle< Gaudi::Range_< I > > &h) -> In
std::remove_pointer_t< typename Container::value_type > c_remove_ptr_t
auto operator()(Container &c, Value &&v) const -> decltype(c.push_back(v))
auto operator()(Container &c, Value &&v) const -> decltype(c.insert(v))
decltype(auto) operator()(F &&f, Arg &&arg) const
void operator()(F &&f, Arg &&arg) const