1 #ifndef FUNCTIONAL_DETAILS_H 2 #define FUNCTIONAL_DETAILS_H 20 #include "boost/optional.hpp" 23 #include <range/v3/view/const.hpp> 24 #include <range/v3/view/zip.hpp> 27 namespace Functional {
34 template <
typename OS,
typename Arg>
40 template <
typename OS,
typename Arg,
typename... Args>
54 template <
typename A,
typename B>
56 return a.size() == b.size();
60 template <
typename A,
typename B,
typename... C>
61 inline bool check_sizes(
const A& a,
const B& b,
const C&...
c ) noexcept {
66 template <
typename... Args>
70 mess <<
"Zipped containers have different sizes : ";
77 template <
typename... Args>
82 return ranges::view::zip( std::forward<Args>( args )... );
86 template <
typename... Args>
91 return ranges::view::const_( ranges::view::zip( std::forward<Args>( args )... ) );
95 #if __cplusplus < 201703L 98 constexpr std::add_const_t<T>&
as_const( T& t ) noexcept {
102 template <
typename T>
109 template <
class B1,
class... Bn>
110 struct disjunction<B1, Bn...> : std::conditional_t<bool( B1::value ), B1, disjunction<Bn...>> {};
114 using std::disjunction;
120 template <
typename T>
121 using is_optional_ = decltype(
bool( std::declval<T>() ), std::declval<T>().value() );
123 template <
typename Arg>
124 using is_optional =
typename Gaudi::cpp17::is_detected<details2::is_optional_, Arg>;
126 template <
typename Arg>
129 template <
typename Arg>
133 template <
typename T,
typename =
void>
138 template <
typename T>
140 using type =
typename T::value_type;
144 template <
typename T>
148 template <
typename F,
typename Arg,
typename = require_is_not_optional<Arg>>
149 decltype(
auto )
operator()( F&& f, Arg&& arg )
const {
150 return Gaudi::invoke( std::forward<F>( f ), std::forward<Arg>( arg ) );
152 template <
typename F,
typename Arg,
typename = require_is_optional<Arg>>
154 if ( arg )
Gaudi::invoke( std::forward<F>( f ), *std::forward<Arg>( arg ) );
159 template <
typename Out1,
typename Out2,
160 typename = std::enable_if_t<std::is_constructible<Out1, Out2>::value &&
163 return out_handle.
put( std::make_unique<Out1>( std::forward<Out2>( out ) ) );
166 template <typename Out1, typename Out2, typename = std::enable_if_t<std::is_constructible<Out1, Out2>::value>>
168 out_handle.put( std::forward<Out2>( out ) );
172 template <
typename OutHandle,
typename OptOut,
typename = require_is_optional<OptOut>>
173 void put( OutHandle& out_handle, OptOut&& out ) {
174 if ( out )
put( out_handle, *std::forward<OptOut>( out ) );
183 template <
typename Container>
186 template <
typename Container,
typename Value>
188 return c.push_back( std::forward<Value>( v ) );
191 template <
typename Container,
typename Value>
193 return c.insert( std::forward<Value>( v ) );
197 template <
typename Container,
198 typename = std::enable_if_t<std::is_pointer<typename Container::value_type>::value>>
208 template <typename In, typename = std::enable_if_t<!std::is_pointer<In>::value>>
213 template <
typename In>
215 assert( in !=
nullptr );
223 template <
typename Container,
typename Value>
227 template <
typename Container,
typename Value>
232 template <
typename In>
234 template <
template <
typename>
class Handle,
typename I,
235 typename = std::enable_if_t<std::is_convertible<I, In>::value>>
239 template <
template <
typename>
class Handle,
typename I,
240 typename = std::enable_if_t<std::is_convertible<I*, In>::value>>
242 return h.getIfExists();
246 template <
typename T>
250 template <
typename T>
256 template <
typename Container>
259 using val_t = std::add_const_t<std::remove_pointer_t<Container>>;
260 using ptr_t = std::add_pointer_t<val_t>;
261 using ref_t = std::add_lvalue_reference_t<val_t>;
266 using value_type = std::conditional_t<is_pointer, ptr_t, val_t>;
269 typename ContainerVector::const_iterator
m_i;
271 iterator(
typename ContainerVector::const_iterator iter ) : m_i( iter ) {}
272 using ret_t = std::conditional_t<is_pointer, ptr_t, ref_t>;
286 explicit operator bool()
const {
return !is_null(); }
290 template <
typename T>
298 template <
typename X = Container>
300 return *m_containers[i];
303 template <
typename X = Container>
305 return m_containers[i];
308 template <
typename X = Container>
310 return *m_containers[i];
313 template <
typename X = Container>
315 return m_containers[i];
323 template <
typename Tr>
325 template <
typename Tr,
typename T>
327 template <
typename Tr,
typename T>
334 template <
typename Tr>
335 using BaseClass_t = Gaudi::cpp17::detected_or_t<GaudiAlgorithm, detail2::BaseClass_t, Tr>;
340 template <
typename Tr,
typename T>
342 template <
typename Tr,
typename T>
347 template <
typename Handles>
350 handles.reserve( init.
size() );
360 template <
typename... In>
365 "EventContext can only appear as first argument" );
367 template <
typename Algorithm,
typename Handles>
375 template <
typename... In>
380 "EventContext can only appear as first argument" );
382 template <
typename Algorithm,
typename Handles>
385 [&](
const auto&... handle ) {
392 template <
typename... In>
395 template <
typename OutputSpec,
typename InputSpec,
typename Traits_>
398 template <
typename... Out,
typename... In,
typename Traits_>
401 "BaseClass must inherit from Algorithm" );
405 std::index_sequence<I...>,
const OArgs& outputs, std::index_sequence<J...> )
408 , m_outputs(
std::tuple_cat(
std::forward_as_tuple( this ),
std::
get<J>( outputs ) )... ) {
421 :
DataHandleMixin( name, pSvcLocator, inputs,
std::index_sequence_for<In...>{}, outputs,
422 std::index_sequence_for<Out...>{} ) {}
437 template <std::
size_t N = 0>
439 return std::get<N>(
m_inputs ).objKey();
443 template <std::
size_t N = 0>
445 return std::get<N>( m_outputs ).objKey();
456 template <
typename Traits_>
459 "BaseClass must inherit from Algorithm" );
474 template <
typename... In,
typename Traits_>
477 "BaseClass must inherit from Algorithm" );
481 std::index_sequence<I...> )
501 template <std::
size_t N = 0>
503 return std::get<N>(
m_inputs ).objKey();
513 template <
typename... Out,
typename Traits_>
516 "BaseClass must inherit from Algorithm" );
520 std::index_sequence<J...> )
522 , m_outputs(
std::tuple_cat(
std::forward_as_tuple( this ),
std::
get<J>( outputs ) )... ) {
539 template <std::
size_t N = 0>
541 return std::get<N>( m_outputs ).objKey();
552 template <
typename Fun,
typename Container,
typename... Args>
554 static_assert(
sizeof...( Args ) == 0,
"Args should not be used!" );
557 template <
typename Fun,
typename Container>
559 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)
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
std::enable_if_t< std::is_pointer< X >::value, ptr_t > at(size_type i) const
typename Tr::BaseClass BaseClass_t
std::enable_if_t<!std::is_pointer< X >::value, ref_t > operator[](size_type i) const
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)
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)
void as_const(T &&t)=delete
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
auto operator()(Container &c, c_remove_ptr_t< Container > &&v) const
Gaudi::cpp17::detected_or_t< DataObjectReadHandle< T >, detail2::InputHandle_t, Tr, T > InputHandle_t
void printSizes(OS &out, Arg &&arg)
Print the parameter.
constexpr unsigned int outputLocationSize() const
const std::string & outputLocation() const
std::enable_if_t<!std::is_pointer< X >::value, ref_t > at(size_type i) const
void operator()(F &&f, Arg &&arg) const
ContainerVector::const_iterator m_i
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
decltype(bool(std::declval< T >()), std::declval< T >().value()) is_optional_
typename Gaudi::cpp17::is_detected< details2::is_optional_, Arg > is_optional
bool is_null(size_type i) const
class MergingTransformer< Out(const vector_of_const_< In > void
decltype(auto) constexpr apply(F &&f, Tuple &&t) noexcept(noexcept( detail::apply_impl(std::forward< F >(f), std::forward< Tuple >(t), std::make_index_sequence< std::tuple_size< std::remove_reference_t< Tuple >>::value >{})))
typename filter_evtcontext_t< In... >::type filter_evtcontext
bool isReEntrant() const override
typename T::value_type type
const std::string & inputLocation() const
std::enable_if_t<!is_optional< Arg >::value > require_is_not_optional
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::remove_pointer_t< typename Container::value_type > c_remove_ptr_t
iterator(typename ContainerVector::const_iterator iter)
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 auto size(const C &c) noexcept(noexcept(c.size())) -> decltype(c.size())
constexpr unsigned int outputLocationSize() const
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
ContainerVector m_containers
const std::string & inputLocation() const
constexpr void applyPostProcessing(const Fun &, Container &, Args...)
DataHandleMixin(const std::string &name, ISvcLocator *locator, const KeyValue &input, const std::array< KeyValue, N_out > &outputs)
const std::string & outputLocation() const
class MergingTransformer< Out(const vector_of_const_< In > Traits_
static auto apply(const Algorithm &algo, Handles &handles)
typename details2::remove_optional< T >::type remove_optional_t
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::conditional_t< is_pointer, ptr_t, ref_t > ret_t
auto operator()(Container &c, Value &&v) const -> decltype(c.insert(v))
std::conditional_t< is_pointer, ptr_t, val_t > value_type
std::enable_if_t< std::is_pointer< X >::value, ptr_t > operator[](size_type i) const
decltype(auto) verifySizes(Args &...args)
Verify the data container sizes have the same sizes.
DataHandleMixin(const std::string &name, ISvcLocator *pSvcLocator)
constexpr std::add_const_t< T > & as_const(T &t) noexcept
std::enable_if_t< is_optional< Arg >::value > require_is_optional
std::vector< InputHandle_t< In > > m_inputs
struct GAUDI_API array
Parametrisation class for redirection array - like implementation.
virtual Out operator()(const vector_of_const_< In > &inputs) const =0
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)
std::tuple< details::OutputHandle_t< Traits_, Out >... > m_outputs
double fun(const std::vector< double > &x)
Base class from which all concrete algorithm classes should be derived.
constexpr static const auto FAILURE
DataHandleMixin(const std::string &name, ISvcLocator *locator, const KeyValue &input)
bool isReEntrant() const override
std::add_pointer_t< val_t > ptr_t
auto invoke(F &&f, ArgTypes &&...args) noexcept(noexcept(detail2::INVOKE(std::forward< F >(f), std::forward< ArgTypes >(args)...))) -> decltype(detail2::INVOKE(std::forward< F >(f), std::forward< ArgTypes >(args)...))
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
Helper functions to set/get the application return code.
std::tuple< details::OutputHandle_t< Traits_, Out >... > m_outputs
Gaudi::cpp17::detected_or_t< GaudiAlgorithm, detail2::BaseClass_t, Tr > BaseClass_t
Out1 * put(DataObjectHandle< Out1 > &out_handle, Out2 &&out)
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... >)
typename ContainerVector::size_type size_type