23#if defined( __cpp_lib_ranges_zip ) && defined( __cpp_lib_ranges_as_const )
24# define GAUDI_FUNCTIONAL_USES_STD_RANGES 1
27# include <range/v3/view/const.hpp>
28# include <range/v3/view/zip.hpp>
37 template <
typename OS,
typename Arg>
39 out <<
"SizeOf'" <<
System::typeinfoName(
typeid( Arg ) ) <<
"'=" << std::forward<Arg>( arg ).size();
43 template <
typename OS,
typename Arg,
typename... Args>
57 template <
typename A,
typename B>
59 return a.size() == b.size();
63 template <
typename A,
typename B,
typename... C>
64 inline bool check_sizes(
const A& a,
const B& b,
const C&... c )
noexcept {
69 template <
typename... Args>
72 std::ostringstream mess;
73 mess <<
"Zipped containers have different sizes : ";
80 template <
typename... Args>
81 inline decltype( auto )
range( Args&&... args ) {
85#if defined( GAUDI_FUNCTIONAL_USES_STD_RANGES )
86 return std::ranges::zip_view( std::forward<Args>( args )... );
88 return ranges::views::zip( std::forward<Args>( args )... );
93 template <
typename... Args>
98#if defined( GAUDI_FUNCTIONAL_USES_STD_RANGES )
99 return std::ranges::as_const_view( std::ranges::zip_view( std::forward<Args>( args )... ) );
101 return ranges::views::const_( ranges::views::zip( std::forward<Args>( args )... ) );
106 inline std::vector<DataObjID>
to_DataObjID(
const std::vector<std::string>& in ) {
107 std::vector<DataObjID> out;
108 out.reserve( in.size() );
109 std::transform( in.begin(), in.end(), std::back_inserter( out ),
110 [](
const std::string& i ) { return DataObjID{ i }; } );
115 template <
typename T>
119 typename T::value_type;
124 template <
typename T>
129 template <is_optional T>
136 template <
typename T>
140 template <
typename F,
typename Arg>
143 return std::invoke( std::forward<F>( f ), std::forward<Arg>( arg ) );
145 template <
typename F, is_optional Arg>
147 if ( arg ) std::invoke( std::forward<F>( f ), *std::forward<Arg>( arg ) );
149 } invoke_optionally{};
152 template <
typename Value, std::size_t... I>
154 return std::make_tuple( ( (
void)I, Value{} )... );
157 template <
typename Value, auto N>
161 template <std::derived_from<DataObject> Out1, std::convertible_to<Out1> Out2>
163 return out_handle.
put( std::make_unique<Out1>( std::forward<Out2>( out ) ) );
166 template <
typename Out1, std::convertible_to<Out1> Out2>
168 return out_handle.put( std::forward<Out2>( out ) );
172 template <
typename OutHandle,
typename OptOut>
173 requires( is_optional<OptOut> )
174 void put(
const OutHandle& out_handle, OptOut&& out ) {
175 if ( out )
put( out_handle, *std::forward<OptOut>( out ) );
185 template <
typename Container>
188 template <
typename Container,
typename Value>
189 auto operator()( Container& c, Value&& v )
const ->
decltype( c.push_back( v ) ) {
190 return c.push_back( std::forward<Value>( v ) );
193 template <
typename Container,
typename Value>
194 auto operator()( Container& c, Value&& v )
const ->
decltype( c.insert( v ) ) {
195 return c.insert( std::forward<Value>( v ) );
199 template <
typename Container,
typename Value>
200 requires( std::is_pointer_v<typename Container::value_type> &&
201 std::is_convertible_v<Value, c_remove_ptr_t<Container>> )
202 auto operator()( Container& c, Value&& v )
const {
211 template <
typename In>
212 requires( !std::is_pointer_v<In> )
213 const In&
operator()(
const In& in )
const {
217 template <
typename In>
218 requires( !std::is_pointer_v<std::decay_t<In>> )
219 In
operator()( In&& in )
const {
220 return std::forward<In>( in );
223 template <
typename In>
225 assert( in !=
nullptr );
233 template <
typename T>
234 constexpr static bool is_gaudi_range_v =
false;
236 template <
typename T>
237 constexpr static bool is_gaudi_range_v<Gaudi::Range_<T>> =
true;
239 template <
typename T>
240 constexpr static bool is_gaudi_range_v<Gaudi::NamedRange_<T>> =
true;
242 template <
typename T>
243 constexpr static bool is_gaudi_range_v<std::optional<Gaudi::NamedRange_<T>>> =
true;
245 template <
typename In>
247 template <
template <
typename>
class Handle, std::convertible_to<In> I>
251 template <
template <
typename>
class Handle,
typename I>
255 template <
template <
typename>
class Handle,
typename I>
259 template <
template <
typename>
class Handle,
typename I>
263 template <
template <
typename>
class Handle,
typename I>
264 requires( std::is_convertible_v<I*, In> )
265 auto operator()(
const Handle<I>& h ) ->
const In {
266 return h.getIfExists();
270 template <
typename Iterator>
272 using traits = std::iterator_traits<Iterator>;
276 using iterator_category [[maybe_unused]] =
typename traits::iterator_category;
277 using difference_type [[maybe_unused]] =
typename traits::difference_type;
279 using value_type [[maybe_unused]] = std::remove_reference_t<reference>;
280 using pointer [[maybe_unused]] = std::add_pointer_t<value_type>;
307 requires std::bidirectional_iterator<Iterator>
316 requires std::random_access_iterator<Iterator>
322 requires std::random_access_iterator<Iterator>
328 requires std::random_access_iterator<Iterator>
334 requires std::random_access_iterator<Iterator>
340 requires std::random_access_iterator<Iterator>
342 return m_iter - other.m_iter;
345 requires std::random_access_iterator<Iterator>
353 template <
typename Container>
355 static constexpr bool is_pointer = std::is_pointer_v<Container>;
356 static constexpr bool is_range = details2::is_gaudi_range_v<Container>;
358 using val_t = std::add_const_t<std::remove_pointer_t<Container>>;
359 using ptr_t = std::add_pointer_t<val_t>;
363 constexpr static decltype( auto )
wrap( ContainerVector::const_reference t ) {
370 constexpr static auto wrap( ContainerVector::const_iterator i ) {
379 using value_type = std::conditional_t<is_pointer, ptr_t, val_t>;
384 template <
typename T>
406 template <
typename Tr>
409 template <
typename Tr,
typename Default>
413 template <
typename Tr,
typename Default>
414 requires requires {
typename Tr::BaseClass; }
419 template <
typename T,
typename Tr,
template <
typename...>
typename Default>
423 template <
typename T,
typename Tr,
template <
typename...>
typename Default>
429 template <
typename T,
typename Tr,
template <
typename...>
typename Default>
433 template <
typename T,
typename Tr,
template <
typename...>
typename Default>
439 template <
typename T>
441 std::conditional_t<std::derived_from<std::decay_t<T>,
IAlgTool>,
448 template <
typename Tr,
typename Default = Gaudi::Algorithm>
454 template <
typename Tr,
typename T>
457 template <
typename Tr,
typename T>
460 template <
typename Traits>
462 std::is_base_of_v<Gaudi::details::LegacyAlgorithmAdapter, details::BaseClass_t<Traits>>;
466 template <
typename Handles>
469 handles.reserve( init.size() );
470 std::transform( init.begin(), init.end(), std::back_inserter( handles ),
471 [&](
const auto& loc ) ->
typename Handles::value_type {
472 return { loc, owner };
477 template <
typename Handle,
typename Algo>
478 auto get(
const Handle& handle,
const Algo&,
484 template <
typename IFace,
typename Algo>
486 return handle.bind( ctx );
489 template <
typename Handle>
490 auto getKey(
const Handle& h ) ->
decltype( h.objKey() ) {
496 template <
typename... In>
498 using type = std::tuple<In...>;
500 static_assert( !std::disjunction_v<std::is_same<EventContext, In>...>,
501 "EventContext can only appear as first argument" );
503 template <
typename Algorithm,
typename Handles>
505 return std::apply( [&](
const auto&... handle ) {
return algo(
get( handle, algo, ctx )... ); }, handles );
508 template <
typename Algorithm,
typename Handles>
515 template <
typename... In>
517 using type = std::tuple<In...>;
519 static_assert( !std::disjunction_v<std::is_same<EventContext, In>...>,
520 "EventContext can only appear as first argument" );
522 template <
typename Algorithm,
typename Handles>
524 return std::apply( [&](
const auto&... handle ) {
return algo( ctx,
get( handle, algo, ctx )... ); }, handles );
527 template <
typename Algorithm,
typename Handles>
533 template <
typename... In>
536 template <
typename OutputSpec,
typename InputSpec,
typename Traits_>
539 template <
typename Out,
typename In,
typename Tr>
541 const std::string& newLoc ) {
542 auto sc = parent.setProperty( prop, newLoc );
543 if ( sc.isFailure() )
throw GaudiException(
"Could not set Property", prop +
" -> " + newLoc, sc );
546 template <
typename Out,
typename In,
typename Tr>
548 const std::vector<std::string>& newLocs ) {
549 std::ostringstream ss;
551 return os <<
"'" << i <<
"'";
553 auto sc = parent.setProperty( prop, ss.str() );
554 if ( sc.isFailure() )
throw GaudiException(
"Could not set Property", prop +
" -> " + ss.str(), sc );
557 template <
typename... Out,
typename... In,
typename Traits_>
559 static_assert( std::is_base_of_v<Algorithm, BaseClass_t<Traits_>>,
"BaseClass must inherit from Algorithm" );
561 template <
typename IArgs,
typename OArgs, std::size_t... I, std::size_t... J>
563 const OArgs& outputs, std::index_sequence<J...> )
572 constexpr static std::size_t
N_in =
sizeof...( In );
573 constexpr static std::size_t
N_out =
sizeof...( Out );
575 using KeyValue = std::pair<std::string, std::string>;
576 using KeyValues = std::pair<std::string, std::vector<std::string>>;
581 :
DataHandleMixin(
std::move( name ), pSvcLocator, inputs,
std::index_sequence_for<In...>{}, outputs,
582 std::index_sequence_for<Out...>{} ) {}
588 std::forward_as_tuple( output ) ) {}
598 template <std::
size_t N = 0>
602 template <
typename T>
608 template <std::
size_t N = 0>
612 template <
typename T>
621 std::tuple<details::InputHandle_t<Traits_, In>...>
m_inputs;
622 std::tuple<details::OutputHandle_t<Traits_, Out>...>
m_outputs;
625 template <
typename Traits_>
627 static_assert( std::is_base_of_v<Algorithm, BaseClass_t<Traits_>>,
"BaseClass must inherit from Algorithm" );
630 using KeyValue = std::pair<std::string, std::string>;
631 using KeyValues = std::pair<std::string, std::vector<std::string>>;
644 template <
typename... In,
typename Traits_>
646 static_assert( std::is_base_of_v<Algorithm, BaseClass_t<Traits_>>,
"BaseClass must inherit from Algorithm" );
648 template <
typename IArgs, std::size_t... I>
657 using KeyValue = std::pair<std::string, std::string>;
658 using KeyValues = std::pair<std::string, std::vector<std::string>>;
659 constexpr static std::size_t
N_in =
sizeof...( In );
670 template <std::
size_t N = 0>
674 template <
typename T>
683 std::tuple<details::InputHandle_t<Traits_, In>...>
m_inputs;
686 template <
typename Traits_>
693 template <
typename... Out,
typename Traits_>
695 static_assert( std::is_base_of_v<Algorithm, BaseClass_t<Traits_>>,
"BaseClass must inherit from Algorithm" );
697 template <
typename OArgs, std::size_t... J>
706 constexpr static std::size_t
N_out =
sizeof...( Out );
707 using KeyValue = std::pair<std::string, std::string>;
708 using KeyValues = std::pair<std::string, std::vector<std::string>>;
718 template <std::
size_t N = 0>
727 std::tuple<details::OutputHandle_t<Traits_, Out>...>
m_outputs;
731 template <
typename Fun,
typename Container,
typename... Args>
733 static_assert(
sizeof...( Args ) == 0,
"Args should not be used!" );
736 template <
typename Fun,
typename Container>
738 fun.postprocess( c );
Gaudi::Functional::Traits::BaseClass_t< Gaudi::Algorithm > BaseClass_t
bool PyHelper setProperty(IInterface *p, char *name, char *value)
boost::spirit::classic::position_iterator2< ForwardIterator > Iterator
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.
bool isReEntrant() const override
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, const IArgs &inputs, std::index_sequence< I... >)
static constexpr std::size_t N_out
std::pair< std::string, std::string > KeyValue
bool isReEntrant() const override
constexpr unsigned int inputLocationSize() const
static constexpr std::size_t N_out
DataHandleMixin(std::string name, ISvcLocator *locator, const KeyValue &input, RepeatValues_< KeyValue, N_out > const &outputs)
constexpr unsigned int outputLocationSize() const
std::pair< std::string, std::vector< std::string > > KeyValues
decltype(auto) inputLocation() const
std::pair< std::string, std::string > KeyValue
constexpr unsigned int outputLocationSize() const
std::pair< std::string, std::string > 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 *pSvcLocator, const OArgs &outputs, std::index_sequence< J... >)
std::pair< std::string, std::vector< std::string > > KeyValues
DataHandleMixin(std::string name, ISvcLocator *locator, RepeatValues_< KeyValue, N_in > const &inputs, const KeyValue &output)
static constexpr std::size_t N_in
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, RepeatValues_< KeyValue, N_in > const &inputs, RepeatValues_< KeyValue, N_out > const &outputs)
std::pair< std::string, std::vector< std::string > > KeyValues
decltype(auto) outputLocation() const
bool isReEntrant() const override
static constexpr std::size_t N_in
std::pair< std::string, std::string > KeyValue
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, std::tuple<>={}, std::tuple<>={})
bool isReEntrant() const override
std::tuple< details::InputHandle_t< Traits_, In >... > m_inputs
std::pair< std::string, std::vector< std::string > > KeyValues
std::tuple< details::OutputHandle_t< Traits_, Out >... > m_outputs
decltype(auto) inputLocation() const
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, RepeatValues_< KeyValue, N_out > const &outputs)
DataHandleMixin(std::string name, ISvcLocator *locator, const KeyValue &input)
std::tuple< details::InputHandle_t< Traits_, In >... > m_inputs
std::tuple< details::OutputHandle_t< Traits_, Out >... > m_outputs
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, RepeatValues_< KeyValue, N_in > const &inputs)
DataHandleMixin(std::string name, ISvcLocator *locator, const KeyValue &output)
decltype(auto) outputLocation() const
DataHandleMixin(std::string name, ISvcLocator *locator, const KeyValue &input, const KeyValue &output)
constexpr unsigned int inputLocationSize() 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
vector_of_const_()=default
void push_back(T &&container)
void reserve(size_type size)
std::add_const_t< std::remove_pointer_t< Container > > val_t
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
decltype(auto) at(size_type i) const
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.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
constexpr static const auto FAILURE
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
decltype(auto) verifySizes(Args &... args)
Verify the data container sizes have the same sizes.
decltype(auto) const_range(Args &&... args)
Zips multiple containers together to form a single const range.
bool check_sizes(const A &) noexcept
Resolve case there is only one container in the range.
decltype(auto) range(Args &&... args)
Zips multiple containers together to form a single range.
void printSizes(OS &out, Arg &&arg)
Print the parameter.
auto get(const Handle &handle, const Algo &, const EventContext &) -> decltype(details::deref(handle.get()))
auto getKey(const Handle &h) -> decltype(h.objKey())
constexpr void applyPostProcessing(const Fun &, Container &, Args...)
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)
Handles make_vector_of_handles(IDataHandleHolder *owner, const std::vector< DataObjID > &init)
typename detail2::OutputHandle< T, Tr, DataObjectWriteHandle >::type OutputHandle_t
void updateHandleLocation(DataHandleMixin< Out, In, Tr > &parent, const std::string &prop, const std::string &newLoc)
constexpr struct Gaudi::Functional::details::deref_t deref
void updateHandleLocations(DataHandleMixin< Out, In, Tr > &parent, const std::string &prop, const std::vector< std::string > &newLocs)
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_
auto get_values_helper(std::index_sequence< I... >)
typename filter_evtcontext_t< In... >::type filter_evtcontext
GAUDI_API const EventContext & currentContext()
Stream & ostream_joiner(Stream &os, Iterator first, Iterator last, Separator sep, OutputElement output=OutputElement{})
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
const In & operator()(const In *in) const
Tr::template OutputHandle< T > type
auto operator()(const Handle< Gaudi::NamedRange_< I > > &h) -> const In
auto operator()(const Handle< I > &h) -> const In &
auto operator()(const Handle< Gaudi::Range_< I > > &h) -> const In
auto operator()(const Handle< std::optional< Gaudi::NamedRange_< I > > > &h) -> const In
static auto apply(const Algorithm &algo, const EventContext &ctx, Handles &handles)
static auto apply(const Algorithm &algo, Handles &handles)
static auto apply(const Algorithm &algo, const EventContext &ctx, Handles &handles)
static auto apply(const Algorithm &algo, 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