The Gaudi Framework  v30r4 (9b837755)
FunctionalDetails.h
Go to the documentation of this file.
1 #ifndef FUNCTIONAL_DETAILS_H
2 #define FUNCTIONAL_DETAILS_H
3 
4 #include <cassert>
5 #include <sstream>
6 #include <stdexcept>
7 #include <type_traits>
8 
9 // TODO: fwd declare instead?
11 #include "GaudiKernel/Algorithm.h"
15 #include "GaudiKernel/apply.h"
16 #include "GaudiKernel/detected.h"
17 #include "GaudiKernel/invoke.h"
18 
19 // Boost
20 #include "boost/optional.hpp"
21 
22 // Range V3
23 #include <range/v3/view/const.hpp>
24 #include <range/v3/view/zip.hpp>
25 
26 namespace Gaudi
27 {
28  namespace Functional
29  {
30  namespace details
31  {
32 
33  // CRJ : Stuff for zipping
34  namespace zip
35  {
36 
38  template <typename OS, typename Arg>
39  void printSizes( OS& out, Arg&& arg )
40  {
41  out << "SizeOf'" << System::typeinfoName( typeid( Arg ) ) << "'=" << std::forward<Arg>( arg ).size();
42  }
43 
45  template <typename OS, typename Arg, typename... Args>
46  void printSizes( OS& out, Arg&& arg, Args&&... args )
47  {
48  printSizes( out, arg );
49  out << ", ";
50  printSizes( out, args... );
51  }
52 
54  template <typename A>
55  inline bool check_sizes( const A& ) noexcept
56  {
57  return true;
58  }
59 
61  template <typename A, typename B>
62  inline bool check_sizes( const A& a, const B& b ) noexcept
63  {
64  return a.size() == b.size();
65  }
66 
68  template <typename A, typename B, typename... C>
69  inline bool check_sizes( const A& a, const B& b, const C&... c ) noexcept
70  {
71  return ( check_sizes( a, b ) && check_sizes( b, c... ) );
72  }
73 
75  template <typename... Args>
76  inline decltype( auto ) verifySizes( Args&... args )
77  {
78  if ( UNLIKELY( !check_sizes( args... ) ) ) {
79  std::ostringstream mess;
80  mess << "Zipped containers have different sizes : ";
81  printSizes( mess, args... );
82  throw GaudiException( mess.str(), "Gaudi::Functional::details::zip::verifySizes", StatusCode::FAILURE );
83  }
84  }
85 
87  template <typename... Args>
88  inline decltype( auto ) range( Args&&... args )
89  {
90 #ifndef NDEBUG
91  verifySizes( args... );
92 #endif
93  return ranges::view::zip( std::forward<Args>( args )... );
94  }
95 
97  template <typename... Args>
98  inline decltype( auto ) const_range( Args&&... args )
99  {
100 #ifndef NDEBUG
101  verifySizes( args... );
102 #endif
103  return ranges::view::const_( ranges::view::zip( std::forward<Args>( args )... ) );
104  }
105  }
106 
107 #if __cplusplus < 201703L
108  // implementation of C++17 std::as_const, see http://en.cppreference.com/w/cpp/utility/as_const
109  template <typename T>
110  constexpr std::add_const_t<T>& as_const( T& t ) noexcept
111  {
112  return t;
113  }
114 
115  template <typename T>
116  void as_const( T&& t ) = delete;
117 
118  template <class...>
120  };
121  template <class B1>
122  struct disjunction<B1> : B1 {
123  };
124  template <class B1, class... Bn>
125  struct disjunction<B1, Bn...> : std::conditional_t<bool( B1::value ), B1, disjunction<Bn...>> {
126  };
127 
128 #else
129  using std::as_const;
130  using std::disjunction;
131 #endif
132  namespace details2
134  {
135  // note: boost::optional in boost 1.66 does not have 'has_value()'...
136  // that requires boost 1.68 or later... so for now, use operator bool() instead ;-(
137  template <typename T>
138  using is_optional_ = decltype( bool( std::declval<T>() ), std::declval<T>().value() );
139  }
140  template <typename Arg>
141  using is_optional = typename Gaudi::cpp17::is_detected<details2::is_optional_, Arg>;
142 
143  template <typename Arg>
144  using require_is_optional = std::enable_if_t<is_optional<Arg>::value>;
145 
146  template <typename Arg>
147  using require_is_not_optional = std::enable_if_t<!is_optional<Arg>::value>;
148 
149  namespace details2
150  {
151  template <typename T, typename = void>
153  using type = T;
154  };
155 
156  template <typename T>
157  struct remove_optional<T, std::enable_if_t<is_optional<T>::value>> {
158  using type = typename T::value_type;
159  };
160  }
161 
162  template <typename T>
164 
165  constexpr struct invoke_optionally_t {
166  template <typename F, typename Arg, typename = require_is_not_optional<Arg>>
167  decltype( auto ) operator()( F&& f, Arg&& arg ) const
168  {
169  return Gaudi::invoke( std::forward<F>( f ), std::forward<Arg>( arg ) );
170  }
171  template <typename F, typename Arg, typename = require_is_optional<Arg>>
172  void operator()( F&& f, Arg&& arg ) const
173  {
174  if ( arg ) Gaudi::invoke( std::forward<F>( f ), *std::forward<Arg>( arg ) );
175  }
176  } invoke_optionally{};
178 
179  template <typename Out1, typename Out2, typename = std::enable_if_t<std::is_constructible<Out1, Out2>::value &&
181  Out1* put( DataObjectHandle<Out1>& out_handle, Out2&& out )
182  {
183  return out_handle.put( std::make_unique<Out1>( std::forward<Out2>( out ) ) );
184  }
185 
186  template <typename Out1, typename Out2, typename = std::enable_if_t<std::is_constructible<Out1, Out2>::value>>
187  void put( DataObjectHandle<AnyDataWrapper<Out1>>& out_handle, Out2&& out )
188  {
189  out_handle.put( std::forward<Out2>( out ) );
190  }
191 
192  // optional put
193  template <typename OutHandle, typename OptOut, typename = require_is_optional<OptOut>>
194  void put( OutHandle& out_handle, OptOut&& out )
195  {
196  if ( out ) put( out_handle, *std::forward<OptOut>( out ) );
197  }
199  // adapt to differences between eg. std::vector (which has push_back) and KeyedContainer (which has insert)
200  // adapt to getting a T, and a container wanting T* by doing new T{ std::move(out) }
201  // adapt to getting a optional<T>
202 
203  constexpr struct insert_t {
204  // for Container<T*>, return T
205  template <typename Container>
206  using c_remove_ptr_t = std::remove_pointer_t<typename Container::value_type>;
207 
208  template <typename Container, typename Value>
209  auto operator()( Container& c, Value&& v ) const -> decltype( c.push_back( v ) )
210  {
211  return c.push_back( std::forward<Value>( v ) );
212  }
213 
214  template <typename Container, typename Value>
215  auto operator()( Container& c, Value&& v ) const -> decltype( c.insert( v ) )
216  {
217  return c.insert( std::forward<Value>( v ) );
218  }
219 
220  // Container<T*> with T&& as argument
221  template <typename Container,
222  typename = std::enable_if_t<std::is_pointer<typename Container::value_type>::value>>
223  auto operator()( Container& c, c_remove_ptr_t<Container>&& v ) const
224  {
225  return operator()( c, new c_remove_ptr_t<Container>{std::move( v )} );
226  }
227 
228  } insert{};
229 
231 
232  constexpr struct deref_t {
233  template <typename In, typename = std::enable_if_t<!std::is_pointer<In>::value>>
234  const In& operator()( const In& in ) const
235  {
236  return in;
237  }
238 
239  template <typename In>
240  const In& operator()( const In* in ) const
241  {
242  assert( in != nullptr );
243  return *in;
244  }
245  } deref{};
246 
248  // if Container is a pointer, then we're optional items
249  namespace details2
250  {
251  template <typename Container, typename Value>
252  void push_back( Container& c, const Value& v, std::true_type )
253  {
254  c.push_back( v );
255  }
256  template <typename Container, typename Value>
257  void push_back( Container& c, const Value& v, std::false_type )
258  {
259  c.push_back( &v );
260  }
261 
262  template <typename In>
264  template <template <typename> class Handle, typename I,
265  typename = std::enable_if_t<std::is_convertible<I, In>::value>>
266  auto operator()( const Handle<I>& h ) -> const In&
267  {
268  return *h.get();
269  }
270  template <template <typename> class Handle, typename I,
271  typename = std::enable_if_t<std::is_convertible<I*, In>::value>>
272  auto operator()( const Handle<I>& h ) -> const In
273  {
274  return h.getIfExists();
275  } // In is-a pointer
276  };
277 
278  template <typename T>
279  T* deref_if( T* const t, std::false_type )
280  {
281  return t;
282  }
283  template <typename T>
284  T& deref_if( T* const t, std::true_type )
285  {
286  return *t;
287  }
288  }
289 
290  template <typename Container>
292  {
293  static constexpr bool is_pointer = std::is_pointer<Container>::value;
294  using val_t = std::add_const_t<std::remove_pointer_t<Container>>;
295  using ptr_t = std::add_pointer_t<val_t>;
296  using ref_t = std::add_lvalue_reference_t<val_t>;
299 
300  public:
301  using value_type = std::conditional_t<is_pointer, ptr_t, val_t>;
302  using size_type = typename ContainerVector::size_type;
303  class iterator
304  {
305  typename ContainerVector::const_iterator m_i;
306  friend class vector_of_const_;
307  iterator( typename ContainerVector::const_iterator iter ) : m_i( iter ) {}
308  using ret_t = std::conditional_t<is_pointer, ptr_t, ref_t>;
309 
310  public:
311  friend bool operator!=( const iterator& lhs, const iterator& rhs ) { return lhs.m_i != rhs.m_i; }
314  {
315  ++m_i;
316  return *this;
317  }
319  {
320  --m_i;
321  return *this;
322  }
323  bool is_null() const { return !*m_i; }
324  explicit operator bool() const { return !is_null(); }
325  };
326  vector_of_const_() = default;
327  void reserve( size_type size ) { m_containers.reserve( size ); }
328  template <typename T> // , typename = std::is_convertible<T,std::conditional_t<is_pointer,ptr_t,val_t>>
329  void push_back( T&& container )
330  {
331  details2::push_back( m_containers, std::forward<T>( container ), std::integral_constant<bool, is_pointer>{} );
332  } // note: does not copy its argument, so we're not really a container...
333  iterator begin() const { return m_containers.begin(); }
334  iterator end() const { return m_containers.end(); }
335  size_type size() const { return m_containers.size(); }
336 
337  template <typename X = Container>
338  std::enable_if_t<!std::is_pointer<X>::value, ref_t> operator[]( size_type i ) const
339  {
340  return *m_containers[i];
341  }
342 
343  template <typename X = Container>
344  std::enable_if_t<std::is_pointer<X>::value, ptr_t> operator[]( size_type i ) const
345  {
346  return m_containers[i];
347  }
348 
349  template <typename X = Container>
350  std::enable_if_t<!std::is_pointer<X>::value, ref_t> at( size_type i ) const
351  {
352  return *m_containers[i];
353  }
354 
355  template <typename X = Container>
356  std::enable_if_t<std::is_pointer<X>::value, ptr_t> at( size_type i ) const
357  {
358  return m_containers[i];
359  }
360 
361  bool is_null( size_type i ) const { return !m_containers[i]; }
362  };
363 
365  namespace detail2
366  { // utilities for detected_or_t{,_} usage
367  template <typename Tr>
368  using BaseClass_t = typename Tr::BaseClass;
369  template <typename Tr, typename T>
370  using OutputHandle_t = typename Tr::template OutputHandle<T>;
371  template <typename Tr, typename T>
372  using InputHandle_t = typename Tr::template InputHandle<T>;
373  }
374 
375  // check whether Traits::BaseClass is a valid type,
376  // if so, define BaseClass_t<Traits> as being Traits::BaseClass
377  // else define as being GaudiAlgorithm
378  template <typename Tr>
379  using BaseClass_t = Gaudi::cpp17::detected_or_t<GaudiAlgorithm, detail2::BaseClass_t, Tr>;
380 
381  // check whether Traits::{Input,Output}Handle<T> is a valid type,
382  // if so, define {Input,Output}Handle_t<Traits,T> as being Traits::{Input,Output}Handle<T>
383  // else define as being DataObject{Read,,Write}Handle<T>
384  template <typename Tr, typename T>
385  using OutputHandle_t = Gaudi::cpp17::detected_or_t<DataObjectWriteHandle<T>, detail2::OutputHandle_t, Tr, T>;
386  template <typename Tr, typename T>
387  using InputHandle_t = Gaudi::cpp17::detected_or_t<DataObjectReadHandle<T>, detail2::InputHandle_t, Tr, T>;
388 
390 
391  template <typename Handles>
393  {
394  Handles handles;
395  handles.reserve( init.size() );
396  std::transform( init.begin(), init.end(), std::back_inserter( handles ),
397  [&]( const std::string& loc ) -> typename Handles::value_type {
398  return {loc, owner};
399  } );
400  return handles;
401  }
402 
404  // given a pack, return a corresponding tuple
405  template <typename... In>
407  using type = std::tuple<In...>;
408 
409  static_assert( !details::disjunction<std::is_same<EventContext, In>...>::value,
410  "EventContext can only appear as first argument" );
411 
412  template <typename Algorithm, typename Handles>
413  static auto apply( const Algorithm& algo, Handles& handles )
414  {
415  return Gaudi::apply( [&]( const auto&... handle ) { return algo( details::deref( handle.get() )... ); },
416  handles );
417  }
418  };
419 
420  // except when it starts with EventContext, then drop it
421  template <typename... In>
423  using type = std::tuple<In...>;
424 
425  static_assert( !details::disjunction<std::is_same<EventContext, In>...>::value,
426  "EventContext can only appear as first argument" );
427 
428  template <typename Algorithm, typename Handles>
429  static auto apply( const Algorithm& algo, Handles& handles )
430  {
431  return Gaudi::apply(
432  [&]( const auto&... handle ) {
433  return algo( Gaudi::Hive::currentContext(), details::deref( handle.get() )... );
434  },
435  handles );
436  }
437  };
438 
439  template <typename... In>
441 
442  template <typename OutputSpec, typename InputSpec, typename Traits_>
444 
445  template <typename... Out, typename... In, typename Traits_>
446  class DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_> : public BaseClass_t<Traits_>
447  {
448  static_assert( std::is_base_of<Algorithm, BaseClass_t<Traits_>>::value,
449  "BaseClass must inherit from Algorithm" );
450 
451  template <typename IArgs, typename OArgs, std::size_t... I, std::size_t... J>
452  DataHandleMixin( const std::string& name, ISvcLocator* pSvcLocator, const IArgs& inputs,
453  std::index_sequence<I...>, const OArgs& outputs, std::index_sequence<J...> )
454  : BaseClass_t<Traits_>( name, pSvcLocator )
455  , m_inputs( std::tuple_cat( std::forward_as_tuple( this ), std::get<I>( inputs ) )... )
456  , m_outputs( std::tuple_cat( std::forward_as_tuple( this ), std::get<J>( outputs ) )... )
457  {
458  // make sure this algorithm is seen as reentrant by Gaudi
459  this->setProperty( "Cardinality", 0 );
460  }
461 
462  public:
464  constexpr static std::size_t N_in = sizeof...( In );
465  constexpr static std::size_t N_out = sizeof...( Out );
466 
467  // generic constructor: N -> M
469  const std::array<KeyValue, N_out>& outputs )
470  : DataHandleMixin( name, pSvcLocator, inputs, std::index_sequence_for<In...>{}, outputs,
471  std::index_sequence_for<Out...>{} )
472  {
473  }
474 
475  // special cases: forward to the generic case...
476  // 1 -> 1
477  DataHandleMixin( const std::string& name, ISvcLocator* locator, const KeyValue& input, const KeyValue& output )
478  : DataHandleMixin( name, locator, std::array<KeyValue, 1>{input}, std::array<KeyValue, 1>{output} )
479  {
480  }
481  // 1 -> N
482  DataHandleMixin( const std::string& name, ISvcLocator* locator, const KeyValue& input,
483  const std::array<KeyValue, N_out>& outputs )
484  : DataHandleMixin( name, locator, std::array<KeyValue, 1>{input}, outputs )
485  {
486  }
487  // N -> 1
489  const KeyValue& output )
490  : DataHandleMixin( name, locator, inputs, std::array<KeyValue, 1>{output} )
491  {
492  }
493 
494  template <std::size_t N = 0>
495  const std::string& inputLocation() const
496  {
497  return std::get<N>( m_inputs ).objKey();
498  }
499  constexpr unsigned int inputLocationSize() const { return N_in; }
500 
501  template <std::size_t N = 0>
503  {
504  return std::get<N>( m_outputs ).objKey();
505  }
506  constexpr unsigned int outputLocationSize() const { return N_out; }
507 
508  protected:
511  };
512 
513  template <typename Traits_>
514  class DataHandleMixin<void, std::tuple<>, Traits_> : public BaseClass_t<Traits_>
515  {
516  static_assert( std::is_base_of<Algorithm, BaseClass_t<Traits_>>::value,
517  "BaseClass must inherit from Algorithm" );
518 
519  public:
520  DataHandleMixin( const std::string& name, ISvcLocator* pSvcLocator ) : BaseClass_t<Traits_>( name, pSvcLocator )
521  {
522  // make sure this algorithm is seen as reentrant by Gaudi
523  this->setProperty( "Cardinality", 0 );
524  }
525 
526  protected:
528  };
529 
530  template <typename... In, typename Traits_>
531  class DataHandleMixin<void, std::tuple<In...>, Traits_> : public BaseClass_t<Traits_>
532  {
533  static_assert( std::is_base_of<Algorithm, BaseClass_t<Traits_>>::value,
534  "BaseClass must inherit from Algorithm" );
535 
536  template <typename IArgs, std::size_t... I>
537  DataHandleMixin( const std::string& name, ISvcLocator* pSvcLocator, const IArgs& inputs,
538  std::index_sequence<I...> )
539  : BaseClass_t<Traits_>( name, pSvcLocator )
540  , m_inputs( std::tuple_cat( std::forward_as_tuple( this ), std::get<I>( inputs ) )... )
541  {
542  // make sure this algorithm is seen as reentrant by Gaudi
543  this->setProperty( "Cardinality", 0 );
544  }
545 
546  public:
548  constexpr static std::size_t N_in = sizeof...( In );
549 
550  // generic constructor: N -> 0
552  : DataHandleMixin( name, pSvcLocator, inputs, std::index_sequence_for<In...>{} )
553  {
554  }
555 
556  // special cases: forward to the generic case...
557  // 1 -> 0
558  DataHandleMixin( const std::string& name, ISvcLocator* locator, const KeyValue& input )
559  : DataHandleMixin( name, locator, std::array<KeyValue, 1>{input} )
560  {
561  }
562 
563  template <std::size_t N = 0>
564  const std::string& inputLocation() const
565  {
566  return std::get<N>( m_inputs ).objKey();
567  }
568  constexpr unsigned int inputLocationSize() const { return N_in; }
569 
570  protected:
572  };
573 
574  template <typename... Out, typename Traits_>
575  class DataHandleMixin<std::tuple<Out...>, void, Traits_> : public BaseClass_t<Traits_>
576  {
577  static_assert( std::is_base_of<Algorithm, BaseClass_t<Traits_>>::value,
578  "BaseClass must inherit from Algorithm" );
579 
580  template <typename OArgs, std::size_t... J>
581  DataHandleMixin( const std::string& name, ISvcLocator* pSvcLocator, const OArgs& outputs,
582  std::index_sequence<J...> )
583  : BaseClass_t<Traits_>( name, pSvcLocator )
584  , m_outputs( std::tuple_cat( std::forward_as_tuple( this ), std::get<J>( outputs ) )... )
585  {
586  // make sure this algorithm is seen as reentrant by Gaudi
587  this->setProperty( "Cardinality", 0 );
588  }
589 
590  public:
592  constexpr static std::size_t N_out = sizeof...( Out );
593 
594  // generic constructor: 0 -> N
596  : DataHandleMixin( name, pSvcLocator, outputs, std::index_sequence_for<Out...>{} )
597  {
598  }
599 
600  // 0 -> 1
602  : DataHandleMixin( name, locator, std::array<KeyValue, 1>{output} )
603  {
604  }
605 
606  template <std::size_t N = 0>
608  {
609  return std::get<N>( m_outputs ).objKey();
610  }
611  constexpr unsigned int outputLocationSize() const { return N_out; }
612 
613  protected:
615  };
616 
618  template <typename Fun, typename Container, typename... Args>
619  constexpr void applyPostProcessing( const Fun&, Container&, Args... )
620  {
621  static_assert( sizeof...( Args ) == 0, "Args should not be used!" );
622  }
623 
624  template <typename Fun, typename Container>
625  auto applyPostProcessing( const Fun& fun, Container& c ) -> decltype( fun.postprocess( c ), void() )
626  {
627  fun.postprocess( c );
628  }
629 
631  }
632  }
633 }
634 
635 #endif
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)
auto operator()(Container &c, Value &&v) const -> decltype(c.insert(v))
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
Definition: Property.h:1305
std::enable_if_t< std::is_pointer< X >::value, ptr_t > at(size_type i) const
#define UNLIKELY(x)
Definition: Kernel.h:89
constexpr static const auto FAILURE
Definition: StatusCode.h:88
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...
Definition: ISvcLocator.h:25
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.
Definition: System.cpp:332
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.
std::enable_if_t<!std::is_pointer< X >::value, ref_t > at(size_type i) 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
decltype(bool(std::declval< T >()), std::declval< T >().value()) is_optional_
typename Gaudi::cpp17::is_detected< details2::is_optional_, Arg > is_optional
STL namespace.
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 >{})))
Definition: apply.h:31
typename filter_evtcontext_t< In... >::type filter_evtcontext
auto operator()(Container &c, Value &&v) const -> decltype(c.push_back(v))
T end(T...args)
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... >)
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.
Definition: EventContext.h:31
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())
STL class.
DataObjectHandle.h GaudiKernel/DataObjectHandle.h.
Definition: AlgTool.h:26
constexpr struct Gaudi::Functional::details::invoke_optionally_t invoke_optionally
typename Tr::template OutputHandle< T > OutputHandle_t
Entity which holds DataHandles and can track the associated data dependencies for the Scheduler...
constexpr void applyPostProcessing(const Fun &, Container &, Args...)
DataHandleMixin(const std::string &name, ISvcLocator *locator, const KeyValue &input, const std::array< KeyValue, N_out > &outputs)
auto operator()(const Handle< I > &h) -> const In &
static auto apply(const Algorithm &algo, Handles &handles)
typename details2::remove_optional< T >::type remove_optional_t
GAUDI_API const EventContext & currentContext()
auto operator()(const Handle< I > &h) -> const In
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
T move(T...args)
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
Base class from which all concrete algorithm classes should be derived.
Definition: Algorithm.h:79
std::enable_if_t< is_optional< Arg >::value > require_is_optional
T size(T...args)
T * put(std::unique_ptr< T > object)
Register object in transient store.
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
T begin(T...args)
bool check_sizes(const A &) noexcept
Resolve case there is only one container in the range.
Gaudi::cpp17::detected_or_t< DataObjectWriteHandle< T >, detail2::OutputHandle_t, Tr, T > OutputHandle_t
T back_inserter(T...args)
std::tuple< details::OutputHandle_t< Traits_, Out >... > m_outputs
double fun(const std::vector< double > &x)
Definition: PFuncTest.cpp:26
STL class.
DataHandleMixin(const std::string &name, ISvcLocator *locator, const KeyValue &input)
struct[[deprecated("use MergingTransformer instead")]] Traits_
T transform(T...args)
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)...))
Definition: invoke.h:93
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)
T & deref_if(T *const t, std::true_type)
Helper functions to set/get the application return code.
Definition: __init__.py:1
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... >)
T reserve(T...args)
typename ContainerVector::size_type size_type