25#include <source_location>
39 inline std::vector<DataObjID>
to_DataObjID(
const std::vector<std::string>& in ) {
40 std::vector<DataObjID> out;
41 out.reserve( in.size() );
42 std::transform( in.begin(), in.end(), std::back_inserter( out ),
43 [](
const std::string& i ) { return DataObjID{ i }; } );
52 typename T::value_type;
62 template <is_optional T>
64 using type = T::value_type;
73 template <
typename F,
typename Arg>
76 return std::invoke( std::forward<F>( f ), std::forward<Arg>( arg ) );
78 template <
typename F, is_optional Arg>
80 if ( arg ) std::invoke( std::forward<F>( f ), *std::forward<Arg>( arg ) );
82 } invoke_optionally{};
85 template <
typename Value, auto>
86 using repeat_t = Value;
87 template <
typename Value, auto N>
89 decltype( []<std::size_t... I>( std::index_sequence<I...> ) -> std::tuple<repeat_t<Value, I>...> {
90 }( std::make_index_sequence<N>{} ) );
92 template <
typename Value, std::size_t... I>
94 return std::make_tuple( ( (
void)I, Value{} )... );
97 template <
typename Value, auto N>
102 template <std::derived_from<DataObject> Out1, std::convertible_to<Out1> Out2>
104 return out_handle.
put( std::make_unique<Out1>( std::forward<Out2>( out ) ) );
107 template <
typename Out1, std::convertible_to<Out1> Out2>
109 return out_handle.put( std::forward<Out2>( out ) );
113 template <
typename OutHandle,
typename OptOut>
114 requires( is_optional<OptOut> )
115 void put(
const OutHandle& out_handle, OptOut&& out ) {
116 if ( out )
put( out_handle, *std::forward<OptOut>( out ) );
126 template <
typename Container>
129 template <
typename Container,
typename Value>
130 auto operator()( Container& c, Value&& v )
const ->
decltype( c.push_back( v ) ) {
131 return c.push_back( std::forward<Value>( v ) );
134 template <
typename Container,
typename Value>
135 auto operator()( Container& c, Value&& v )
const ->
decltype( c.insert( v ) ) {
136 return c.insert( std::forward<Value>( v ) );
140 template <
typename Container,
typename Value>
141 requires( std::is_pointer_v<typename Container::value_type> &&
142 std::is_convertible_v<Value, c_remove_ptr_t<Container>> )
143 auto operator()( Container& c, Value&& v )
const {
152 template <
typename In>
153 requires( !std::is_pointer_v<In> )
154 const In&
operator()(
const In& in )
const {
158 template <
typename In>
159 requires( !std::is_pointer_v<std::decay_t<In>> )
160 In
operator()( In&& in )
const {
161 return std::forward<In>( in );
164 template <
typename In>
166 assert( in !=
nullptr );
174 template <
typename T>
175 constexpr static bool is_gaudi_range_v =
false;
177 template <
typename T>
178 constexpr static bool is_gaudi_range_v<Gaudi::Range_<T>> =
true;
180 template <
typename T>
181 constexpr static bool is_gaudi_range_v<Gaudi::NamedRange_<T>> =
true;
183 template <
typename T>
184 constexpr static bool is_gaudi_range_v<std::optional<Gaudi::NamedRange_<T>>> =
true;
186 template <
typename In>
188 template <
template <
typename>
class Handle, std::convertible_to<In> I>
192 template <
template <
typename>
class Handle,
typename I>
196 template <
template <
typename>
class Handle,
typename I>
200 template <
template <
typename>
class Handle,
typename I>
204 template <
template <
typename>
class Handle,
typename I>
205 requires( std::is_convertible_v<I*, In> )
206 auto operator()(
const Handle<I>& h ) -> In {
207 return h.getIfExists();
211 template <
typename Iterator>
213 using traits = std::iterator_traits<Iterator>;
217 using iterator_category [[maybe_unused]] =
typename traits::iterator_category;
218 using difference_type [[maybe_unused]] =
typename traits::difference_type;
220 using value_type [[maybe_unused]] = std::remove_reference_t<reference>;
221 using pointer [[maybe_unused]] = std::add_pointer_t<value_type>;
248 requires std::bidirectional_iterator<Iterator>
257 requires std::random_access_iterator<Iterator>
263 requires std::random_access_iterator<Iterator>
269 requires std::random_access_iterator<Iterator>
275 requires std::random_access_iterator<Iterator>
281 requires std::random_access_iterator<Iterator>
283 return m_iter - other.m_iter;
286 requires std::random_access_iterator<Iterator>
294 template <
typename Container>
296 static constexpr bool is_pointer = std::is_pointer_v<Container>;
297 static constexpr bool is_range = details2::is_gaudi_range_v<Container>;
298 template <
typename C>
302 using ptr_t = std::add_pointer_t<val_t>;
306 constexpr static decltype( auto )
wrap( ContainerVector::const_reference t ) {
313 constexpr static auto wrap( ContainerVector::const_iterator i ) {
322 using value_type = std::conditional_t<is_pointer, ptr_t, val_t>;
327 template <
typename T>
328 requires( is_pointer || is_range )
332 template <
typename C = Container>
333 requires( !std::is_pointer_v<C> && !details2::is_gaudi_range_v<C> )
338 template <
typename C = Container>
339 requires( !std::is_pointer_v<C> && !details2::is_gaudi_range_v<C> )
351 template <
template <
typename>
class Handle,
typename I>
357 template <
typename Algorithm>
360 [ptr = &
handles, parent]( auto& self_ ) {
363 ptr->reserve( self.value().size() );
364 std::ranges::transform( self.value(), std::back_inserter( *ptr ),
365 [&](
const auto& location ) -> Handle<I> {
366 return { location, parent };
379 template <
typename Algorithm>
384 template <
typename A,
typename K>
393 template <
typename Out>
394 void put( Out&& out )
const {
395 auto const n =
size();
396 if ( out.size() != n ) {
398 std::string{ std::source_location::current().function_name() } +
": expected " +
399 std::to_string( n ) +
" containers, got " + std::to_string( out.size() ) +
" instead",
411 template <
template <
typename>
class Handle,
typename... I,
typename Algorithm,
typename InKeys>
414 [parent](
auto const&... key ) {
415 static_assert(
sizeof...( key ) ==
sizeof...( I ) );
421 template <
template <
typename>
class Handle,
typename... I>
424 [i](
auto const&... elems ) ->
decltype(
auto ) {
return *std::array{ &elems.locations()... }.at( i ); },
428 template <
typename F>
431 return std::forward<F>( f )();
442 template <
typename Tr>
445 template <
typename Tr,
typename Default>
449 template <
typename Tr,
typename Default>
450 requires requires {
typename Tr::BaseClass; }
455 template <
typename T,
typename Tr,
template <
typename...>
typename Default>
459 template <
typename T,
typename Tr,
template <
typename...>
typename Default>
465 template <
typename T,
typename Tr,
template <
typename...>
typename Default>
469 template <
typename T,
typename Tr,
template <
typename...>
typename Default>
475 template <
typename T>
477 std::conditional_t<std::derived_from<std::decay_t<T>,
IAlgTool>,
484 template <
typename Tr,
typename Default = Gaudi::Algorithm>
490 template <
typename Tr,
typename T>
493 template <
typename Tr,
typename T>
496 template <
typename Traits>
498 std::is_base_of_v<Gaudi::details::LegacyAlgorithmAdapter, details::BaseClass_t<Traits>>;
502 template <
typename Handle,
typename Algo>
503 auto get(
const Handle& handle,
const Algo&,
509 template <
typename IFace,
typename Algo>
511 return handle.bind( ctx );
514 template <
typename Handle>
515 auto getKey(
const Handle& h ) ->
decltype( h.objKey() ) {
521 template <
typename... In>
523 using type = std::tuple<In...>;
525 static_assert( !std::disjunction_v<std::is_same<EventContext, In>...>,
526 "EventContext can only appear as first argument" );
528 template <
typename Algorithm,
typename Handles>
530 return std::apply( [&](
const auto&... handle ) {
return algo(
get( handle, algo, ctx )... ); }, handles );
535 template <
typename... In>
537 using type = std::tuple<In...>;
539 static_assert( !std::disjunction_v<std::is_same<EventContext, In>...>,
540 "EventContext can only appear as first argument" );
542 template <
typename Algorithm,
typename Handles>
544 return std::apply( [&](
const auto&... handle ) {
return algo( ctx,
get( handle, algo, ctx )... ); }, handles );
548 template <
typename... In>
551 template <
typename OutputSpec,
typename InputSpec,
typename Traits_>
554 template <
typename... Out,
typename... In,
typename Traits_>
555 requires std::derived_from<BaseClass_t<Traits_>,
Algorithm>
558 template <
typename IArgs,
typename OArgs, std::size_t... I, std::size_t... J>
560 const OArgs& outputs, std::index_sequence<J...> )
569 constexpr static std::size_t
N_in =
sizeof...( In );
570 constexpr static std::size_t
N_out =
sizeof...( Out );
572 using KeyValue = std::pair<std::string, std::string>;
573 using KeyValues = std::pair<std::string, std::vector<std::string>>;
579 :
DataHandleMixin(
std::move( name ), pSvcLocator, inputs,
std::index_sequence_for<In...>{}, outputs,
580 std::index_sequence_for<Out...>{} ) {}
585 requires( N_in == 0 && N_out == 0 )
586 : DataHandleMixin(
std::move( name ), locator,
std::tuple<>{}, std::index_sequence<>{}, std::tuple<>{},
587 std::index_sequence<>{} ) {}
592 std::tuple<>{}, std::index_sequence<>{} ) {}
597 std::forward_as_tuple( output ), std::index_sequence<0>{} ) {}
602 std::index_sequence<size_t{ 0 }>{}, std::forward_as_tuple( output ),
603 std::index_sequence<
size_t{ 0 }>{} ) {}
609 std::index_sequence<size_t{ 0 }>{}, outputs, std::index_sequence_for<Out...>{} ) {}
615 std::forward_as_tuple( output ), std::index_sequence<
size_t{ 0 }>{} ) {}
619 :
DataHandleMixin(
std::move( name ), pSvcLocator, inputs,
std::index_sequence_for<In...>{}, std::tuple<>{},
620 std::index_sequence<>{} ) {}
625 std::index_sequence_for<Out...>{} ) {}
627 template <std::
size_t N = 0>
633 template <
typename T>
641 template <std::
size_t N = 0>
643 requires(
N_out > 0 )
647 template <
typename T>
649 requires(
N_out > 0 )
658 std::tuple<details::InputHandle_t<Traits_, In>...>
m_inputs;
659 std::tuple<details::OutputHandle_t<Traits_, Out>...>
m_outputs;
662 template <
typename Traits_>
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.
static constexpr std::size_t N_out
DataHandleMixin(std::string name, ISvcLocator *locator, const KeyValue &output)
constexpr unsigned int outputLocationSize() const
decltype(auto) inputLocation() const
DataHandleMixin(std::string name, ISvcLocator *locator, std::tuple<>={}, std::tuple<>={})
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, RepeatValues_< KeyValue, N_in > const &inputs)
std::pair< std::string, std::vector< std::string > > KeyValues
DataHandleMixin(std::string name, ISvcLocator *locator, const KeyValue &input, RepeatValues_< KeyValue, N_out > const &outputs)
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, RepeatValues_< KeyValue, N_in > const &inputs, RepeatValues_< KeyValue, N_out > const &outputs)
std::pair< std::string, std::string > KeyValue
DataHandleMixin(std::string name, ISvcLocator *locator, const KeyValue &input)
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, const IArgs &inputs, std::index_sequence< I... >, const OArgs &outputs, std::index_sequence< J... >)
decltype(auto) outputLocation() const
DataHandleMixin(std::string name, ISvcLocator *locator, RepeatValues_< KeyValue, N_in > const &inputs, const KeyValue &output)
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, RepeatValues_< KeyValue, N_out > const &outputs)
DataHandleMixin(std::string name, ISvcLocator *locator, const KeyValue &input, const KeyValue &output)
static constexpr std::size_t N_in
bool isReEntrant() const override
std::tuple< details::InputHandle_t< Traits_, In >... > m_inputs
std::tuple< details::OutputHandle_t< Traits_, Out >... > m_outputs
constexpr unsigned int inputLocationSize() const
HandleVector(std::tuple< A, K > &&tup)
std::unique_ptr< Payload > m_payload
DataObjID const & at(size_t i) const
HandleVector(Algorithm *parent, std::pair< std::string, std::vector< std::string > > const &keys)
void put(Out &&out) const
std::vector< DataObjID > const & locations() const
vector_of_const_< I > get(EventContext const &) const
std::vector< Handle< I > > const & handles() const
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
constexpr indirect_iterator operator-(difference_type n) const
constexpr difference_type operator-(const indirect_iterator &other) const
constexpr reference operator[](difference_type n) const
indirect_iterator()=default
constexpr indirect_iterator operator++(int)
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
Implementation of property with value of concrete type.
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
Gaudi::tagged_bool< class ImmediatelyInvokeHandler_tag > ImmediatelyInvokeHandler
typename Tr::BaseClass BaseClass_t
std::conditional_t< std::derived_from< std::decay_t< T >, IAlgTool >, ToolHandle< Gaudi::Interface::Bind::IBinder< std::decay_t< T > > >, DataObjectReadHandle< T > > DefaultInputHandle
auto get(const Handle &handle, const Algo &, const EventContext &) -> decltype(details::deref(handle.get()))
auto getKey(const Handle &h) -> decltype(h.objKey())
std::vector< DataObjID > to_DataObjID(const std::vector< std::string > &in)
typename detail2::InputHandle< T, Tr, detail2::DefaultInputHandle >::type InputHandle_t
auto put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
auto make_HandleVectorTuple(Algorithm *parent, InKeys const &keys)
typename detail2::OutputHandle< T, Tr, DataObjectWriteHandle >::type OutputHandle_t
constexpr struct Gaudi::Functional::details::deref_t deref
typename details2::value_type_of< T >::type remove_optional_t
detail2::BaseClass< Tr, Default >::type BaseClass_t
decltype(get_values_helper< Value >(std::make_index_sequence< N >())) RepeatValues_
decltype(auto) getLocations(std::tuple< HandleVector< Handle, I >... > const &vectors, unsigned int i)
auto get_values_helper(std::index_sequence< I... >)
StatusCode execute(CommonMessagingBase const &alg, F &&f)
typename filter_evtcontext_t< In... >::type filter_evtcontext
Payload & operator=(Payload const &)=delete
std::vector< Handle< I > > handles
Gaudi::Property< std::vector< DataObjID > > property
Payload(Algorithm *parent, std::pair< std::string, std::vector< std::string > > const &keys)
Payload(Payload &&)=delete
Payload(Payload const &)=delete
Payload & operator=(Payload &&)=delete
const In & operator()(const In *in) const
Tr::template OutputHandle< T > 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
static auto apply(const Algorithm &algo, const EventContext &ctx, Handles &handles)
static auto apply(const Algorithm &algo, const EventContext &ctx, Handles &handles)
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