1 #ifndef FUNCTIONAL_DETAILS_H 2 #define FUNCTIONAL_DETAILS_H 18 #include <range/v3/view/const.hpp> 19 #include <range/v3/view/zip.hpp> 27 template <
typename OS,
typename Arg>
33 template <
typename OS,
typename Arg,
typename... Args>
47 template <
typename A,
typename B>
49 return a.size() == b.size();
53 template <
typename A,
typename B,
typename... C>
54 inline bool check_sizes(
const A& a,
const B& b,
const C&...
c ) noexcept {
59 template <
typename... Args>
63 mess <<
"Zipped containers have different sizes : ";
70 template <
typename... Args>
75 return ranges::view::zip( std::forward<Args>( args )... );
79 template <
typename... Args>
84 return ranges::view::const_( ranges::view::zip( std::forward<Args>( args )... ) );
93 using is_optional_ = decltype(
bool{std::declval<T>()}, std::declval<T>().value() );
95 template <
typename Arg>
96 constexpr
bool is_optional_v = Gaudi::cpp17::is_detected_v<details2::is_optional_, Arg>;
98 template <
typename Arg>
101 template <
typename Arg>
104 template <
typename T>
108 template <
typename F,
typename Arg,
typename = require_is_not_optional<Arg>>
109 decltype(
auto )
operator()( F&& f, Arg&& arg )
const {
110 return std::invoke( std::forward<F>( f ), std::forward<Arg>( arg ) );
112 template <
typename F,
typename Arg,
typename = require_is_optional<Arg>>
114 if ( arg ) std::invoke( std::forward<F>( f ), *std::forward<Arg>( arg ) );
119 template <
typename Out1,
typename Out2,
120 typename = std::enable_if_t<std::is_constructible_v<Out1, Out2> && std::is_base_of_v<DataObject, Out1>>>
122 return out_handle.
put( std::make_unique<Out1>( std::forward<Out2>( out ) ) );
125 template <
typename Out1,
typename Out2,
typename = std::enable_if_t<std::is_constructible_v<Out1, Out2>>>
127 out_handle.put( std::forward<Out2>( out ) );
131 template <
typename OutHandle,
typename OptOut,
typename = require_is_optional<OptOut>>
132 void put(
const OutHandle& out_handle, OptOut&& out ) {
133 if ( out )
put( out_handle, *std::forward<OptOut>( out ) );
142 template <
typename Container>
145 template <
typename Container,
typename Value>
147 return c.push_back( std::forward<Value>( v ) );
150 template <
typename Container,
typename Value>
152 return c.insert( std::forward<Value>( v ) );
156 template <
typename Container,
typename Value,
157 typename = std::enable_if_t<std::is_pointer_v<typename Container::value_type>>,
158 typename = std::enable_if_t<std::is_convertible_v<Value, c_remove_ptr_t<Container>>>>
168 template <
typename In,
typename = std::enable_if_t<!std::is_po
inter_v<In>>>
173 template <
typename In>
175 assert( in !=
nullptr );
183 template <
typename Container,
typename Value>
187 template <
typename Container,
typename Value>
192 template <
typename In>
194 template <
template <
typename>
class Handle,
typename I,
typename = std::enable_if_t<std::is_convertible_v<I, In>>>
198 template <
template <
typename>
class Handle,
typename I,
199 typename = std::enable_if_t<std::is_convertible_v<I*, In>>>
201 return h.getIfExists();
205 template <
typename T>
209 template <
typename T>
215 template <
typename Container>
217 static constexpr
bool is_pointer = std::is_pointer_v<Container>;
218 using val_t = std::add_const_t<std::remove_pointer_t<Container>>;
219 using ptr_t = std::add_pointer_t<val_t>;
220 using ref_t = std::add_lvalue_reference_t<val_t>;
225 using value_type = std::conditional_t<is_pointer, ptr_t, val_t>;
228 using it_t =
typename ContainerVector::const_iterator;
232 using ret_t = std::conditional_t<is_pointer, ptr_t, ref_t>;
254 explicit operator bool()
const {
return !is_null(); }
258 template <
typename T>
260 details2::push_back( m_containers, std::forward<T>( container ), std::bool_constant<is_pointer>{} );
266 template <
typename X = Container>
268 return *m_containers[i];
271 template <
typename X = Container>
273 return m_containers[i];
276 template <
typename X = Container>
278 return *m_containers[i];
281 template <
typename X = Container>
283 return m_containers[i];
291 template <
typename Tr>
293 template <
typename Tr,
typename T>
295 template <
typename Tr,
typename T>
302 template <
typename Tr>
303 using BaseClass_t = Gaudi::cpp17::detected_or_t<GaudiAlgorithm, detail2::BaseClass_t, Tr>;
308 template <
typename Tr,
typename T>
310 template <
typename Tr,
typename T>
313 template <
typename Traits>
315 std::is_base_of_v<Gaudi::details::LegacyAlgorithmAdapter, details::BaseClass_t<Traits>>;
319 template <
typename Handles>
322 handles.reserve( init.
size() );
331 template <
typename Handle,
typename Algo>
338 template <
typename Handle>
339 auto getKey(
const Handle& h ) -> decltype( h.objKey() ) {
345 template <
typename... In>
350 "EventContext can only appear as first argument" );
352 template <
typename Algorithm,
typename Handles>
354 return std::apply( [&](
const auto&... handle ) {
return algo(
details::deref( handle.get() )... ); }, handles );
356 template <
typename Algorithm,
typename Handles>
358 return std::apply( [&](
const auto&... handle ) {
return algo(
get( handle, algo, ctx )... ); }, handles );
363 template <
typename... In>
368 "EventContext can only appear as first argument" );
370 template <
typename Algorithm,
typename Handles>
373 [&](
const auto&... handle ) {
375 return algo( ctx,
get( handle, algo, ctx )... );
380 template <
typename Algorithm,
typename Handles>
382 return std::apply( [&](
const auto&... handle ) {
return algo( ctx,
get( handle, algo, ctx )... ); }, handles );
386 template <
typename... In>
389 template <
typename OutputSpec,
typename InputSpec,
typename Traits_>
392 template <
typename Out,
typename In,
typename Tr>
395 auto sc = parent.setProperty( prop, newLoc );
396 if ( sc.isFailure() )
throw GaudiException(
"Could not set Property", prop +
" -> " + newLoc, sc );
399 template <
typename Out,
typename In,
typename Tr>
404 ss <<
'[', newLocs,
", ", [](
std::ostream & os,
const auto& i ) ->
auto& {
return os <<
"'" << i <<
"'"; } )
406 auto sc = parent.setProperty( prop, ss.
str() );
407 if ( sc.isFailure() )
throw GaudiException(
"Could not set Property", prop +
" -> " + ss.
str(), sc );
410 template <
typename... Out,
typename... In,
typename Traits_>
416 const OArgs& outputs, std::index_sequence<J...> )
419 , m_outputs(
std::tuple_cat(
std::forward_as_tuple( this ),
std::
get<J>( outputs ) )... ) {
433 :
DataHandleMixin( name, pSvcLocator, inputs,
std::index_sequence_for<In...>{}, outputs,
434 std::index_sequence_for<Out...>{} ) {}
449 template <std::
size_t N = 0>
455 template <std::
size_t N = 0>
456 decltype(
auto ) outputLocation()
const {
457 return getKey( std::get<N>( m_outputs ) );
468 template <
typename Traits_>
483 template <
typename... In,
typename Traits_>
508 template <std::
size_t N = 0>
521 template <
typename... Out,
typename Traits_>
527 std::index_sequence<J...> )
529 , m_outputs(
std::tuple_cat(
std::forward_as_tuple( this ),
std::
get<J>( outputs ) )... ) {
546 template <std::
size_t N = 0>
547 decltype(
auto ) outputLocation()
const {
548 return getKey( std::get<N>( m_outputs ) );
559 template <
typename Fun,
typename Container,
typename... Args>
561 static_assert(
sizeof...( Args ) == 0,
"Args should not be used!" );
564 template <
typename Fun,
typename Container>
566 fun.postprocess(
c );
typename Tr::template InputHandle< T > InputHandle_t
DataHandleMixin(const std::string &name, ISvcLocator *pSvcLocator, const std::array< KeyValue, N_out > &outputs)
DataHandleMixin(const std::string &name, ISvcLocator *pSvcLocator, const std::array< KeyValue, N_in > &inputs)
typename it_t::difference_type difference_type
StatusCode setProperty(IProperty *component, const std::string &name, const TYPE &value, const std::string &doc)
simple function to set the property of the given object from the value
typename Tr::BaseClass BaseClass_t
auto get(const Handle &handle, const Algo &, const EventContext &) -> decltype(details::deref(handle.get()))
constexpr auto size(const T &, Args &&...) noexcept
DataHandleMixin(const std::string &name, ISvcLocator *pSvcLocator, const IArgs &inputs, std::index_sequence< I... >, const OArgs &outputs, std::index_sequence< J... >)
const In & operator()(const In &in) const
Define general base for Gaudi exception.
DataHandleMixin(const std::string &name, ISvcLocator *locator, const std::array< KeyValue, N_in > &inputs, const KeyValue &output)
friend bool operator==(const iterator &lhs, const iterator &rhs)
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
void reserve(size_type size)
auto operator()(const Handle< I > &h) -> const In &
constexpr unsigned int inputLocationSize() const
friend bool operator!=(const iterator &lhs, const iterator &rhs)
virtual Out operator()(const vector_of_const_< In > &inputs) const =0
auto operator()(Container &c, Value &&v) const
typename ContainerVector::const_iterator it_t
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
void printSizes(OS &out, Arg &&arg)
Print the parameter.
constexpr unsigned int outputLocationSize() const
void operator()(F &&f, Arg &&arg) const
constexpr struct Gaudi::Functional::details::insert_t insert
DataHandleMixin(const std::string &name, ISvcLocator *pSvcLocator, const std::array< KeyValue, N_in > &inputs, const std::array< KeyValue, N_out > &outputs)
Header file for class GaudiAlgorithm.
DataHandleMixin(const std::string &name, ISvcLocator *locator, const KeyValue &input, const KeyValue &output)
std::add_const_t< std::remove_pointer_t< Container >> val_t
typename it_t::iterator_category value_type
typename it_t::pointer pointer
bool is_null(size_type i) const
typename it_t::reference reference
typename filter_evtcontext_t< In... >::type filter_evtcontext
bool isReEntrant() const override
static auto apply(const Algorithm &algo, const EventContext &ctx, Handles &handles)
auto getKey(const Handle &h) -> decltype(h.objKey())
DataHandleMixin(const std::string &name, ISvcLocator *pSvcLocator, const OArgs &outputs, std::index_sequence< J... >)
bool isReEntrant() const override
void push_back(Container &c, const Value &v, std::true_type)
std::enable_if_t<!std::is_pointer_v< X >, ref_t > at(size_type i) const
std::remove_pointer_t< typename Container::value_type > c_remove_ptr_t
std::add_lvalue_reference_t< val_t > ref_t
This class represents an entry point to all the event specific data.
T * deref_if(T *const t, std::false_type)
constexpr struct Gaudi::Functional::details::deref_t deref
constexpr unsigned int outputLocationSize() const
std::vector< InputHandle_t< In > > m_inputs
constexpr unsigned int inputLocationSize() const
DataObjectHandle.h GaudiKernel/DataObjectHandle.h.
constexpr struct Gaudi::Functional::details::invoke_optionally_t invoke_optionally
typename Tr::template OutputHandle< T > OutputHandle_t
class MergingTransformer< Out(const vector_of_const_< In > Traits_
ContainerVector m_containers
constexpr void applyPostProcessing(const Fun &, Container &, Args...)
Gaudi::cpp17::detected_or_t< DataObjectReadHandle< T >, detail2::InputHandle_t, Tr, T > InputHandle_t
DataHandleMixin(const std::string &name, ISvcLocator *locator, const KeyValue &input, const std::array< KeyValue, N_out > &outputs)
void updateHandleLocations(DataHandleMixin< Out, In, Tr > &parent, const std::string &prop, const std::vector< std::string > &newLocs)
static auto apply(const Algorithm &algo, Handles &handles)
friend auto operator-(const iterator &lhs, const iterator &rhs)
T * put(std::unique_ptr< T > object) const
Register object in transient store.
GAUDI_API const EventContext & currentContext()
DataHandleMixin(const std::string &name, ISvcLocator *locator, const KeyValue &output)
static auto apply(const Algorithm &algo, Handles &handles)
decltype(auto) range(Args &&...args)
Zips multiple containers together to form a single range.
std::enable_if_t<!is_optional_v< Arg >> require_is_not_optional
std::conditional_t< is_pointer, ptr_t, ref_t > ret_t
decltype(bool{std::declval< T >()}, std::declval< T >().value()) is_optional_
auto operator()(Container &c, Value &&v) const -> decltype(c.insert(v))
std::conditional_t< is_optional_v< T >, typename T::value_type, T > remove_optional_t
std::conditional_t< is_pointer, ptr_t, val_t > value_type
Stream & ostream_joiner(Stream &os, Iterator first, Iterator last, Separator sep, OutputElement output=OutputElement{})
decltype(auto) verifySizes(Args &...args)
Verify the data container sizes have the same sizes.
DataHandleMixin(const std::string &name, ISvcLocator *pSvcLocator)
struct GAUDI_API array
Parametrisation class for redirection array - like implementation.
bool check_sizes(const A &) noexcept
Resolve case there is only one container in the range.
std::tuple< details::InputHandle_t< Traits_, In >... > m_inputs
void push_back(T &&container)
Gaudi::cpp17::detected_or_t< DataObjectWriteHandle< T >, detail2::OutputHandle_t, Tr, T > OutputHandle_t
auto operator()(Container &c, Value &&v) const -> decltype(c.push_back(v))
T back_inserter(T...args)
Out1 * put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
static auto apply(const Algorithm &algo, const EventContext &ctx, Handles &handles)
std::tuple< details::OutputHandle_t< Traits_, Out >... > m_outputs
Base class from which all concrete algorithm classes should be derived.
std::enable_if_t< is_optional_v< Arg >> require_is_optional
class MergingTransformer< Out(const vector_of_const_< In > void
typename it_t::iterator_category iterator_category
constexpr static const auto FAILURE
DataHandleMixin(const std::string &name, ISvcLocator *locator, const KeyValue &input)
bool isReEntrant() const override
std::enable_if_t< std::is_pointer_v< X >, ptr_t > at(size_type i) const
std::add_pointer_t< val_t > ptr_t
const std::string & inputLocation(unsigned int n) const
std::enable_if_t<!std::is_pointer_v< X >, ref_t > operator[](size_type i) const
const In & operator()(const In *in) const
decltype(auto) const_range(Args &&...args)
Zips multiple containers together to form a single const range.
Handles make_vector_of_handles(IDataHandleHolder *owner, const std::vector< std::string > &init)
bool isReEntrant() const override
std::tuple< details::InputHandle_t< Traits_, In >... > m_inputs
T & deref_if(T *const t, std::true_type)
auto operator()(const Handle< I > &h) -> const In
std::tuple< details::OutputHandle_t< Traits_, Out >... > m_outputs
constexpr bool is_optional_v
Gaudi::cpp17::detected_or_t< GaudiAlgorithm, detail2::BaseClass_t, Tr > BaseClass_t
void push_back(Container &c, const Value &v, std::false_type)
DataHandleMixin(const std::string &name, ISvcLocator *pSvcLocator, const IArgs &inputs, std::index_sequence< I... >)
void updateHandleLocation(DataHandleMixin< Out, In, Tr > &parent, const std::string &prop, const std::string &newLoc)
typename ContainerVector::size_type size_type
std::enable_if_t< std::is_pointer_v< X >, ptr_t > operator[](size_type i) const