1 #ifndef FUNCTIONAL_DETAILS_H 2 #define FUNCTIONAL_DETAILS_H 17 #include "boost/optional.hpp" 20 #include <range/v3/view/zip.hpp> 21 #include <range/v3/view/const.hpp> 23 namespace Gaudi {
namespace Functional {
namespace details {
30 template <
typename OS,
typename Arg>
34 <<
"'=" << std::forward<Arg>(arg).size();
38 template <
typename OS,
typename Arg,
typename... Args>
45 template <
typename A >
49 template <
typename A,
typename B >
52 return a.size() == b.size();
56 template <
typename A,
typename B,
typename... C >
57 inline bool check_sizes(
const A& a,
const B& b,
const C& ...
c ) noexcept
63 template<
typename... Args >
69 mess <<
"Zipped containers have different sizes : ";
72 "Gaudi::Functional::details::zip::verifySizes",
78 template<
typename... Args >
83 return ranges::view::zip( std::forward<Args>(args)... );
87 template<
typename... Args >
92 return ranges::view::const_( ranges::view::zip( std::forward<Args>(args)... ) );
102 template <
typename T>
107 template <
typename Out1,
typename Out2,
110 return out_handle.
put(
new Out1( std::forward<Out2>(out) ) );
113 template <
typename Out1,
typename Out2,
116 out_handle.
put( std::forward<Out2>(out) );
120 template <
typename OutHandle,
typename Out>
121 void put( OutHandle& out_handle, boost::optional<Out>&& out) {
131 template <
typename Container>
134 template <
typename Container,
typename Value>
135 auto operator()(Container&
c, Value&& v) const -> decltype( c.
push_back(v) ) {
return c.push_back( std::forward<Value>(v) ); }
137 template <
typename Container,
typename Value>
138 auto operator()(Container&
c, Value&& v) const -> decltype( c.
insert(v) ) {
return c.insert( std::forward<Value>(v) ); }
141 template <typename Container, typename = typename std::enable_if< std::is_pointer<typename Container::value_type>::value >
::type >
145 template <
typename Container,
typename Value>
152 template <typename In, typename = typename std::enable_if< !std::is_pointer<In>::value>
::type>
155 template <
typename In>
156 In&
operator()( In* in )
const { assert(in!=
nullptr);
return *in; }
175 template <
typename Container,
typename Value>
177 template <
typename Container,
typename Value>
180 template <
typename In>
183 auto operator()(
const Handle<I>&
h ) ->
const In& {
return *
h.get(); }
185 auto operator()(
const Handle<I>&
h ) ->
const In {
return h.getIfExists(); }
192 template <
typename Container>
195 using val_t = std::add_const_t<std::remove_pointer_t<Container>>;
196 using ptr_t = std::add_pointer_t<val_t>;
197 using ref_t = std::add_lvalue_reference_t<val_t>;
201 using value_type = std::conditional_t<is_optional,ptr_t,val_t>;
204 typename ContainerVector::const_iterator
m_i;
206 iterator(
typename ContainerVector::const_iterator iter) : m_i(iter) {}
207 using ret_t = std::conditional_t<is_optional,ptr_t,ref_t>;
214 explicit operator bool()
const {
return !is_null(); }
218 template <
typename T>
246 template<
typename Default,
typename AlwaysVoid,
247 template<
typename...>
class Op,
typename... Args>
254 template<
typename...>
class Op,
typename... Args>
262 template<
typename...>
class Op,
typename... Args>
266 template<
template<
typename...>
class Default,
267 template<
typename...>
class Op,
268 typename Tr,
typename T>
274 template <
typename Tr>
using BaseClass_ =
typename Tr::BaseClass;
278 template <
typename Tr,
typename T>
using OutputHandle_ =
typename Tr::template OutputHandle<T>;
279 template <
typename Tr,
typename T>
using InputHandle_ =
typename Tr::template InputHandle<T>;
296 template <std::
size_t N,
typename Tuple >
307 std::get<I>(props) ),0)...
312 template <
typename Tuple,
typename KeyValues >
314 return details2::make_tuple_of_handles_helper<Tuple>( owner, initvalue, mode, std::make_index_sequence<std::tuple_size<Tuple>::value>{} );
317 template <
typename KeyValues,
typename Properties>
319 constexpr
auto N = std::tuple_size<KeyValues>::value;
320 static_assert( N == std::tuple_size<Properties>::value,
"Inconsistent lengths" );
324 template <
typename Handles>
326 Handles handles; handles.reserve(init.
size());
328 [&](
const std::string& loc) ->
typename Handles::value_type
329 {
return {loc,mode, owner}; });
336 template <
typename OutputSpec,
typename InputSpec,
typename Traits_>
class DataHandleMixin;
338 template <
typename... Out,
typename... In,
typename Traits_>
341 "BaseClass must inherit from Algorithm");
381 template <std::
size_t N=0>
385 template <std::
size_t N=0>
394 template <
typename... In,
typename Traits_>
397 "BaseClass must inherit from Algorithm");
420 template <std::
size_t N=0>
428 template <
typename... Out,
typename Traits_>
431 "BaseClass must inherit from Algorithm");
453 template <std::
size_t N=0>
462 template <
typename Fun,
typename Container,
typename... Args >
464 { static_assert(
sizeof...(Args)==0,
"Args should not be used!");}
466 template <
typename Fun,
typename Container>
468 {
fun.postprocess(
c); }
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
Tuple make_tuple_of_handles_helper(IDataHandleHolder *o, const KeyValues &initvalue, Gaudi::DataHandle::Mode m, std::index_sequence< I... >)
std::tuple< details::InputHandle_t< Traits_, In >... > m_inputs
std::tuple< details::InputHandle_t< Traits_, In >... > m_inputs
constexpr std::add_const< T >::type & as_const(T &t) noexcept
In & operator()(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)
detected_or_t< GaudiAlgorithm, detail2::BaseClass_, Tr > BaseClass_t
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 &
Handles make_vector_of_handles(IDataHandleHolder *owner, const std::vector< std::string > &init, Gaudi::DataHandle::Mode mode)
The namespace threadpool contains a thread pool and related utility classes.
friend bool operator!=(const iterator &lhs, const iterator &rhs)
void declare_tuple_of_properties(Algorithm &owner, const KeyValues &inputs, Properties &props)
unsigned int inputLocationSize() const
std::tuple< details::OutputHandle_t< Traits_, Out >... > m_outputs
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
void declare_tuple_of_properties_helper(Algorithm &owner, const KeyValues &inputs, Properties &props, std::index_sequence< I... >)
decltype(auto) verifySizes(Args &...args)
Verify the data container sizes have the same sizes.
decltype(auto) range(Args &&...args)
Zips multiple containers together to form a single range.
auto operator()(Container &c, c_remove_ptr_t< Container > &&v) const
void printSizes(OS &out, Arg &&arg)
Print the parameter.
const std::string & outputLocation() 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)
typename Tr::template InputHandle< T > InputHandle_
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 std::remove_pointer< typename Container::value_type >::type c_remove_ptr_t
bool is_null(size_type i) const
class MergingTransformer< Out(const vector_of_const_< In > void
const std::string & inputLocation() const
void push_back(Container &c, const Value &v, std::true_type)
std::vector< Gaudi::Details::PropertyBase * > Properties
iterator(typename ContainerVector::const_iterator iter)
std::add_lvalue_reference_t< val_t > ref_t
std::tuple< details::OutputHandle_t< Traits_, Out >... > m_outputs
T * deref_if(T *const t, std::false_type)
typename void_t_< T... >::type void_t
const Container & operator[](size_type i) const
constexpr struct Gaudi::Functional::details::deref_t deref
const T * put(T &&object)
Register object in transient store.
typename std::conditional< std::is_base_of< DataObject, T >::value, DataObjectHandle< T >, AnyDataHandle< T >>::type defaultHandle_
DataObjectHandle.h GaudiKernel/DataObjectHandle.h.
Implementation of the detection idiom (negative case).
detected_or_t_< detail2::defaultHandle_, detail2::InputHandle_, Tr, T > InputHandle_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_
In & operator()(In &in) const
T * put(T *object)
Register object in transient store.
typename details2::remove_optional< T >::type remove_optional_t
DataHandleMixin(const std::string &name, ISvcLocator *locator, const KeyValue &output)
Tuple make_tuple_of_handles(IDataHandleHolder *owner, const KeyValues &initvalue, Gaudi::DataHandle::Mode mode)
unsigned int outputLocationSize() const
auto operator()(Container &c, Value &&v) const -> decltype(c.insert(v))
unsigned int inputLocationSize() const
detected_or_t_< detail2::defaultHandle_, detail2::OutputHandle_, Tr, T > OutputHandle_t
Base class from which all concrete algorithm classes should be derived.
std::conditional_t< is_optional, ptr_t, val_t > value_type
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
detected_or_t< Default< Tr, T >, Op, Tr, T > detected_or_t_
void operator()(Container &c, boost::optional< Value > &&v) const
std::conditional_t< is_optional, ptr_t, ref_t > ret_t
bool check_sizes(const A &) noexcept
Resolve case there is only one container in the range.
void push_back(T &&container)
auto operator()(Container &c, Value &&v) const -> decltype(c.push_back(v))
T back_inserter(T...args)
const Container & at(size_type i) const
typename std::tuple_element< N, Tuple >::type element_t
double fun(const std::vector< double > &x)
decltype(auto) const_range(Args &&...args)
Zips multiple containers together to form a single const range.
DataHandleMixin(const std::string &name, ISvcLocator *locator, const KeyValue &input)
typename Tr::template OutputHandle< T > OutputHandle_
Gaudi::Details::PropertyBase * declareProperty(const std::string &name, ToolHandle< T > &hndl, const std::string &doc="none")
std::add_pointer_t< val_t > ptr_t
typename Tr::BaseClass BaseClass_
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.
def Reader(readerType, filename, qacross, qToEngine)
Out1 * put(DataObjectHandle< Out1 > &out_handle, Out2 &&out)
void push_back(Container &c, const Value &v, std::false_type)
typename detail2::detector< Default, void, Op, Args... >::type detected_or_t
std::pair< std::string, std::vector< std::string >> KeyValues
typename ContainerVector::size_type size_type
unsigned int outputLocationSize() const