Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  master (f31105fd)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
details.h
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 #pragma once
12 
13 #include <Gaudi/Algorithm.h>
14 #include <GaudiKernel/Algorithm.h>
17 #include <GaudiKernel/IBinder.h>
19 #include <GaudiKernel/detected.h>
20 #include <cassert>
21 #include <range/v3/version.hpp>
22 #include <range/v3/view/const.hpp>
23 #include <range/v3/view/zip.hpp>
24 #include <sstream>
25 #include <type_traits>
26 
27 // upstream has renamed namespace ranges::view ranges::views
28 #if RANGE_V3_VERSION < 900
29 namespace ranges::views {
30  using namespace ranges::view;
31 }
32 #endif
33 
34 #if defined( __clang__ ) && ( __clang_major__ < 11 ) || defined( __APPLE__ ) && ( __clang_major__ < 12 )
35 # define GF_SUPPRESS_SPURIOUS_CLANG_WARNING_BEGIN \
36  _Pragma( "clang diagnostic push" ) _Pragma( "clang diagnostic ignored \"-Wunused-lambda-capture\"" )
37 # define GF_SUPPRESS_SPURIOUS_CLANG_WARNING_END _Pragma( "clang diagnostic pop" )
38 #else
39 # define GF_SUPPRESS_SPURIOUS_CLANG_WARNING_BEGIN
40 # define GF_SUPPRESS_SPURIOUS_CLANG_WARNING_END
41 #endif
42 
43 // temporary hack to help in transition to updated constructor
44 // allows to write code which is forward and backwards compatible
45 #define GAUDI_FUNCTIONAL_CONSTRUCTOR_USES_TUPLE
46 
48 
49  // CRJ : Stuff for zipping
50  namespace zip {
51 
53  template <typename OS, typename Arg>
54  void printSizes( OS& out, Arg&& arg ) {
55  out << "SizeOf'" << System::typeinfoName( typeid( Arg ) ) << "'=" << std::forward<Arg>( arg ).size();
56  }
57 
59  template <typename OS, typename Arg, typename... Args>
60  void printSizes( OS& out, Arg&& arg, Args&&... args ) {
61  printSizes( out, arg );
62  out << ", ";
63  printSizes( out, args... );
64  }
65 
67  template <typename A>
68  inline bool check_sizes( const A& ) noexcept {
69  return true;
70  }
71 
73  template <typename A, typename B>
74  inline bool check_sizes( const A& a, const B& b ) noexcept {
75  return a.size() == b.size();
76  }
77 
79  template <typename A, typename B, typename... C>
80  inline bool check_sizes( const A& a, const B& b, const C&... c ) noexcept {
81  return ( check_sizes( a, b ) && check_sizes( b, c... ) );
82  }
83 
85  template <typename... Args>
86  inline decltype( auto ) verifySizes( Args&... args ) {
87  if ( !check_sizes( args... ) ) {
88  std::ostringstream mess;
89  mess << "Zipped containers have different sizes : ";
90  printSizes( mess, args... );
91  throw GaudiException( mess.str(), "Gaudi::Functional::details::zip::verifySizes", StatusCode::FAILURE );
92  }
93  }
94 
96  template <typename... Args>
97  inline decltype( auto ) range( Args&&... args ) {
98 #ifndef NDEBUG
99  verifySizes( args... );
100 #endif
101  return ranges::views::zip( std::forward<Args>( args )... );
102  }
103 
105  template <typename... Args>
106  inline decltype( auto ) const_range( Args&&... args ) {
107 #ifndef NDEBUG
108  verifySizes( args... );
109 #endif
110  return ranges::views::const_( ranges::views::zip( std::forward<Args>( args )... ) );
111  }
112  } // namespace zip
113 
116  out.reserve( in.size() );
118  []( const std::string& i ) { return DataObjID{ i }; } );
119  return out;
120  }
121 
123  namespace details2 {
124  template <typename T>
125  using is_optional_ = decltype( std::declval<T>().has_value(), std::declval<T>().value() );
126 
127  template <typename T>
128  using value_type_of_t = typename T::value_type;
129 
130  } // namespace details2
131  template <typename Arg>
132  constexpr bool is_optional_v = Gaudi::cpp17::is_detected_v<details2::is_optional_, Arg>;
133 
134  template <typename T>
136  std::conditional_t<is_optional_v<T>, Gaudi::cpp17::detected_t<details2::value_type_of_t, T>, T>;
137 
138  constexpr struct invoke_optionally_t {
139  template <typename F, typename Arg>
140  requires( !is_optional_v<Arg> )
141  decltype( auto ) operator()( F&& f, Arg&& arg ) const {
142  return std::invoke( std::forward<F>( f ), std::forward<Arg>( arg ) );
143  }
144  template <typename F, typename Arg>
145  requires( is_optional_v<Arg> )
146  void operator()( F&& f, Arg&& arg ) const {
147  if ( arg ) std::invoke( std::forward<F>( f ), *std::forward<Arg>( arg ) );
148  }
151 
152  template <typename Value, std::size_t... I>
153  auto get_values_helper( std::index_sequence<I...> ) {
154  return std::make_tuple( ( (void)I, Value{} )... );
155  }
156 
157  template <typename Value, auto N>
158  using RepeatValues_ = decltype( get_values_helper<Value>( std::make_index_sequence<N>() ) );
159 
161  template <std::derived_from<DataObject> Out1, std::convertible_to<Out1> Out2>
162  auto put( const DataObjectHandle<Out1>& out_handle, Out2&& out ) {
163  return out_handle.put( std::make_unique<Out1>( std::forward<Out2>( out ) ) );
164  }
165 
166  template <typename Out1, std::convertible_to<Out1> Out2>
167  auto put( const DataObjectHandle<AnyDataWrapper<Out1>>& out_handle, Out2&& out ) {
168  return out_handle.put( std::forward<Out2>( out ) );
169  }
170 
171  // optional put
172  template <typename OutHandle, typename OptOut>
173  requires( is_optional_v<OptOut> )
174  void put( const OutHandle& out_handle, OptOut&& out ) {
175  if ( out ) put( out_handle, *std::forward<OptOut>( out ) );
176  }
177 
179  // adapt to differences between eg. std::vector (which has push_back) and KeyedContainer (which has insert)
180  // adapt to getting a T, and a container wanting T* by doing new T{ std::move(out) }
181  // adapt to getting a optional<T>
182 
183  constexpr struct insert_t {
184  // for Container<T*>, return T
185  template <typename Container>
186  using c_remove_ptr_t = std::remove_pointer_t<typename Container::value_type>;
187 
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 ) );
191  }
192 
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 ) );
196  }
197 
198  // Container<T*> with T&& as argument
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 {
203  return operator()( c, new c_remove_ptr_t<Container>{ std::forward<Value>( v ) } );
204  }
205 
206  } insert{};
207 
209 
210  constexpr struct deref_t {
211  template <typename In>
212  requires( !std::is_pointer_v<In> )
213  const In& operator()( const In& in ) const {
214  return in;
215  }
216 
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 );
221  }
222 
223  template <typename In>
224  const In& operator()( const In* in ) const {
225  assert( in != nullptr );
226  return *in;
227  }
228  } deref{};
229 
231  // if Container is a pointer, then we're optional items
232  namespace details2 {
233  template <typename T>
234  constexpr static bool is_gaudi_range_v = false;
235 
236  template <typename T>
237  constexpr static bool is_gaudi_range_v<Gaudi::Range_<T>> = true;
238 
239  template <typename T>
240  constexpr static bool is_gaudi_range_v<Gaudi::NamedRange_<T>> = true;
241 
242  template <typename T>
243  constexpr static bool is_gaudi_range_v<std::optional<Gaudi::NamedRange_<T>>> = true;
244 
245  template <typename Container, typename Value>
246  void push_back( Container& c, const Value& v, std::true_type ) {
247  c.push_back( v );
248  }
249  template <typename Container, typename Value>
250  void push_back( Container& c, const Value& v, std::false_type ) {
251  c.push_back( &v );
252  }
253 
254  template <typename In>
256  template <template <typename> class Handle, std::convertible_to<In> I>
257  auto operator()( const Handle<I>& h ) -> const In& {
258  return *h.get();
259  }
260  template <template <typename> class Handle, typename I>
261  auto operator()( const Handle<Gaudi::Range_<I>>& h ) -> const In {
262  return h.get();
263  }
264  template <template <typename> class Handle, typename I>
265  auto operator()( const Handle<Gaudi::NamedRange_<I>>& h ) -> const In {
266  return h.get();
267  }
268  template <template <typename> class Handle, typename I>
269  auto operator()( const Handle<std::optional<Gaudi::NamedRange_<I>>>& h ) -> const In {
270  return h.get();
271  }
272  template <template <typename> class Handle, typename I>
273  requires( std::is_convertible_v<I*, In> )
274  auto operator()( const Handle<I>& h ) -> const In {
275  return h.getIfExists();
276  } // In is-a pointer
277  };
278 
279  template <typename T>
280  T* deref_if( T* const t, std::false_type ) {
281  return t;
282  }
283  template <typename T>
284  T& deref_if( T* const t, std::true_type ) {
285  return *t;
286  }
287  } // namespace details2
288 
289  template <typename Container>
291  static constexpr bool is_pointer = std::is_pointer_v<Container>;
292  static constexpr bool is_range = details2::is_gaudi_range_v<Container>;
293  using val_t = std::add_const_t<std::remove_pointer_t<Container>>;
294  using ptr_t = std::add_pointer_t<val_t>;
295  using ref_t = std::add_lvalue_reference_t<val_t>;
298 
299  public:
300  using value_type = std::conditional_t<is_pointer, ptr_t, val_t>;
301  using size_type = typename ContainerVector::size_type;
302  class iterator {
303  using it_t = typename ContainerVector::const_iterator;
305  friend class vector_of_const_;
306  iterator( it_t iter ) : m_i( iter ) {}
307  using ret_t = std::conditional_t<is_pointer, ptr_t, ref_t>;
308 
309  public:
310  using iterator_category = typename it_t::iterator_category;
311  using value_type = typename it_t::iterator_category;
312  using reference = typename it_t::reference;
313  using pointer = typename it_t::pointer;
314  using difference_type = typename it_t::difference_type;
315 
316  friend bool operator!=( const iterator& lhs, const iterator& rhs ) { return lhs.m_i != rhs.m_i; }
317  friend bool operator==( const iterator& lhs, const iterator& rhs ) { return lhs.m_i == rhs.m_i; }
318  friend auto operator-( const iterator& lhs, const iterator& rhs ) { return lhs.m_i - rhs.m_i; }
319  ret_t operator*() const {
320  if constexpr ( is_range ) {
321  return *m_i;
322  } else {
323  return details2::deref_if( *m_i, std::bool_constant<!is_pointer>{} );
324  }
325  }
327  ++m_i;
328  return *this;
329  }
331  --m_i;
332  return *this;
333  }
334  bool is_null() const { return !*m_i; }
335  explicit operator bool() const { return !is_null(); }
336  };
337  vector_of_const_() = default;
338  void reserve( size_type size ) { m_containers.reserve( size ); }
339  template <typename T> // , typename = std::is_convertible<T,std::conditional_t<is_pointer,ptr_t,val_t>>
340  void push_back( T&& container ) {
341  details2::push_back( m_containers, std::forward<T>( container ),
342  std::bool_constant < is_pointer || is_range > {} );
343  } // note: does not copy its argument, so we're not really a container...
344  iterator begin() const { return m_containers.begin(); }
345  iterator end() const { return m_containers.end(); }
346  size_type size() const { return m_containers.size(); }
347 
348  template <typename X = Container>
349  requires( !std::is_pointer_v<X> )
350  ref_t front() const {
351  return *m_containers.front();
352  }
353 
354  template <typename X = Container>
355  requires( std::is_pointer_v<X> )
356  ptr_t front() const {
357  return m_containers.front();
358  }
359 
360  template <typename X = Container>
361  requires( !std::is_pointer_v<X> )
362  ref_t back() const {
363  return *m_containers.back();
364  }
365 
366  template <typename X = Container>
367  requires( std::is_pointer_v<X> )
368  ptr_t back() const {
369  return m_containers.back();
370  }
371 
372  template <typename X = Container>
373  requires( !std::is_pointer_v<X> )
374  ref_t operator[]( size_type i ) const {
375  return *m_containers[i];
376  }
377 
378  template <typename X = Container>
379  requires( std::is_pointer_v<X> )
380  ptr_t operator[]( size_type i ) const {
381  return m_containers[i];
382  }
383 
384  template <typename X = Container>
385  requires( !std::is_pointer_v<X> )
386  ref_t at( size_type i ) const {
387  return *m_containers[i];
388  }
389 
390  template <typename X = Container>
391  requires( std::is_pointer_v<X> )
392  ptr_t at( size_type i ) const {
393  return m_containers[i];
394  }
395 
396  bool is_null( size_type i ) const { return !m_containers[i]; }
397  };
398 
400  namespace detail2 { // utilities for detected_or_t{,_} usage
401  template <typename Tr>
402  using BaseClass_t = typename Tr::BaseClass;
403  template <typename Tr, typename T>
404  using OutputHandle_t = typename Tr::template OutputHandle<T>;
405  template <typename Tr, typename T>
406  using InputHandle_t = typename Tr::template InputHandle<T>;
407 
408  template <typename T>
409  constexpr auto is_tool_v = std::is_base_of_v<IAlgTool, std::decay_t<T>>;
410 
411  template <typename T>
413 
414  template <typename T>
415  using DefaultInputHandle = std::conditional_t<is_tool_v<T>, ToolHandle_t<T>, DataObjectReadHandle<T>>;
416  } // namespace detail2
417 
418  // check whether Traits::BaseClass is a valid type,
419  // if so, define BaseClass_t<Traits> as being Traits::BaseClass
420  // else define as being Gaudi::Algorithm
421  template <typename Tr, typename Base = Gaudi::Algorithm>
423 
424  // check whether Traits::{Input,Output}Handle<T> is a valid type,
425  // if so, define {Input,Output}Handle_t<Traits,T> as being Traits::{Input,Output}Handle<T>
426  // else define as being DataObject{Read,,Write}Handle<T>
427 
428  template <typename Tr, typename T>
430  template <typename Tr, typename T>
432 
433  template <typename Traits>
434  inline constexpr bool isLegacy =
435  std::is_base_of_v<Gaudi::details::LegacyAlgorithmAdapter, details::BaseClass_t<Traits>>;
436 
438 #define GAUDI_FUNCTIONAL_MAKE_VECTOR_OF_HANDLES_USES_DATAOBJID
439 
440  template <typename Handles>
442  Handles handles;
443  handles.reserve( init.size() );
444  std::transform( init.begin(), init.end(), std::back_inserter( handles ),
445  [&]( const auto& loc ) -> typename Handles::value_type {
446  return { loc, owner };
447  } );
448  return handles;
449  }
450 
451  template <typename Handle, typename Algo>
452  auto get( const Handle& handle, const Algo&, const EventContext& )
453  -> decltype( details::deref( handle.get() ) ) // make it SFINAE friendly...
454  {
455  return details::deref( handle.get() );
456  }
457 
458  template <typename IFace, typename Algo>
459  auto get( const ToolHandle<Gaudi::Interface::Bind::IBinder<IFace>>& handle, const Algo&, const EventContext& ctx ) {
460  return handle.bind( ctx );
461  }
462 
463  template <typename Handle>
464  auto getKey( const Handle& h ) -> decltype( h.objKey() ) {
465  return h.objKey();
466  }
467 
469  // given a pack, return a corresponding tuple
470  template <typename... In>
472  using type = std::tuple<In...>;
473 
474  static_assert( !std::disjunction_v<std::is_same<EventContext, In>...>,
475  "EventContext can only appear as first argument" );
476 
477  template <typename Algorithm, typename Handles>
478  static auto apply( const Algorithm& algo, Handles& handles ) {
479  return std::apply(
480  [&]( const auto&... handle ) { return algo( get( handle, algo, Gaudi::Hive::currentContext() )... ); },
481  handles );
482  }
483  template <typename Algorithm, typename Handles>
484  static auto apply( const Algorithm& algo, const EventContext& ctx, Handles& handles ) {
485  return std::apply( [&]( const auto&... handle ) { return algo( get( handle, algo, ctx )... ); }, handles );
486  }
487  };
488 
489  // except when it starts with EventContext, then drop it
490  template <typename... In>
492  using type = std::tuple<In...>;
493 
494  static_assert( !std::disjunction_v<std::is_same<EventContext, In>...>,
495  "EventContext can only appear as first argument" );
496 
497  template <typename Algorithm, typename Handles>
498  static auto apply( const Algorithm& algo, const EventContext& ctx, Handles& handles ) {
499  return std::apply( [&]( const auto&... handle ) { return algo( ctx, get( handle, algo, ctx )... ); }, handles );
500  }
501 
502  template <typename Algorithm, typename Handles>
503  static auto apply( const Algorithm& algo, Handles& handles ) {
504  return apply( algo, Gaudi::Hive::currentContext(), handles );
505  }
506  };
507 
508  template <typename... In>
510 
511  template <typename OutputSpec, typename InputSpec, typename Traits_>
513 
514  template <typename Out, typename In, typename Tr>
516  const std::string& newLoc ) {
517  auto sc = parent.setProperty( prop, newLoc );
518  if ( sc.isFailure() ) throw GaudiException( "Could not set Property", prop + " -> " + newLoc, sc );
519  }
520 
521  template <typename Out, typename In, typename Tr>
523  const std::vector<std::string>& newLocs ) {
525  GaudiUtils::details::ostream_joiner( ss << '[', newLocs, ", ", []( std::ostream& os, const auto& i ) -> auto& {
526  return os << "'" << i << "'";
527  } ) << ']';
528  auto sc = parent.setProperty( prop, ss.str() );
529  if ( sc.isFailure() ) throw GaudiException( "Could not set Property", prop + " -> " + ss.str(), sc );
530  }
531 
532  template <typename... Out, typename... In, typename Traits_>
533  class DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_> : public BaseClass_t<Traits_> {
534  static_assert( std::is_base_of_v<Algorithm, BaseClass_t<Traits_>>, "BaseClass must inherit from Algorithm" );
535 
536  template <typename IArgs, typename OArgs, std::size_t... I, std::size_t... J>
537  DataHandleMixin( std::string name, ISvcLocator* pSvcLocator, const IArgs& inputs, std::index_sequence<I...>,
538  const OArgs& outputs, std::index_sequence<J...> )
539  : BaseClass_t<Traits_>( std::move( name ), pSvcLocator )
540  , m_inputs( std::tuple_cat( std::forward_as_tuple( this ), std::get<I>( inputs ) )... )
541  , m_outputs( std::tuple_cat( std::forward_as_tuple( this ), std::get<J>( outputs ) )... ) {
542  // make sure this algorithm is seen as reentrant by Gaudi
543  this->setProperty( "Cardinality", 0 ).ignore();
544  }
545 
546  public:
547  constexpr static std::size_t N_in = sizeof...( In );
548  constexpr static std::size_t N_out = sizeof...( Out );
549 
552 
553  // generic constructor: N -> M
555  RepeatValues_<KeyValue, N_out> const& outputs )
556  : DataHandleMixin( std::move( name ), pSvcLocator, inputs, std::index_sequence_for<In...>{}, outputs,
557  std::index_sequence_for<Out...>{} ) {}
558 
559  // special cases: forward to the generic case...
560  // 1 -> 1
562  : DataHandleMixin( std::move( name ), locator, std::forward_as_tuple( input ),
563  std::forward_as_tuple( output ) ) {}
564  // 1 -> N
566  RepeatValues_<KeyValue, N_out> const& outputs )
567  : DataHandleMixin( std::move( name ), locator, std::forward_as_tuple( input ), outputs ) {}
568  // N -> 1
570  const KeyValue& output )
571  : DataHandleMixin( std::move( name ), locator, inputs, std::forward_as_tuple( output ) ) {}
572 
573  template <std::size_t N = 0>
574  decltype( auto ) inputLocation() const {
575  return getKey( std::get<N>( m_inputs ) );
576  }
577  template <typename T>
578  decltype( auto ) inputLocation() const {
579  return getKey( std::get<details::InputHandle_t<Traits_, std::decay_t<T>>>( m_inputs ) );
580  }
581  constexpr unsigned int inputLocationSize() const { return N_in; }
582 
583  template <std::size_t N = 0>
584  decltype( auto ) outputLocation() const {
585  return getKey( std::get<N>( m_outputs ) );
586  }
587  template <typename T>
588  decltype( auto ) outputLocation() const {
589  return getKey( std::get<details::OutputHandle_t<Traits_, std::decay_t<T>>>( m_outputs ) );
590  }
591  constexpr unsigned int outputLocationSize() const { return N_out; }
592 
593  protected:
594  bool isReEntrant() const override { return true; }
595 
598  };
599 
600  template <typename Traits_>
601  class DataHandleMixin<std::tuple<>, std::tuple<>, Traits_> : public BaseClass_t<Traits_> {
602  static_assert( std::is_base_of_v<Algorithm, BaseClass_t<Traits_>>, "BaseClass must inherit from Algorithm" );
603 
604  public:
608  : BaseClass_t<Traits_>( std::move( name ), pSvcLocator ) {
609  // make sure this algorithm is seen as reentrant by Gaudi
610  this->setProperty( "Cardinality", 0 ).ignore();
611  }
612 
613  protected:
614  bool isReEntrant() const override { return true; }
615 
617  };
618 
619  template <typename... In, typename Traits_>
620  class DataHandleMixin<std::tuple<>, std::tuple<In...>, Traits_> : public BaseClass_t<Traits_> {
621  static_assert( std::is_base_of_v<Algorithm, BaseClass_t<Traits_>>, "BaseClass must inherit from Algorithm" );
622 
623  template <typename IArgs, std::size_t... I>
624  DataHandleMixin( std::string name, ISvcLocator* pSvcLocator, const IArgs& inputs, std::index_sequence<I...> )
625  : BaseClass_t<Traits_>( std::move( name ), pSvcLocator )
626  , m_inputs( std::tuple_cat( std::forward_as_tuple( this ), std::get<I>( inputs ) )... ) {
627  // make sure this algorithm is seen as reentrant by Gaudi
628  this->setProperty( "Cardinality", 0 ).ignore();
629  }
630 
631  public:
634  constexpr static std::size_t N_in = sizeof...( In );
635 
636  // generic constructor: N -> 0
638  : DataHandleMixin( std::move( name ), pSvcLocator, inputs, std::index_sequence_for<In...>{} ) {}
639 
640  // special cases: forward to the generic case...
641  // 1 -> 0
643  : DataHandleMixin( std::move( name ), locator, std::forward_as_tuple( input ) ) {}
644 
645  template <std::size_t N = 0>
646  decltype( auto ) inputLocation() const {
647  return getKey( std::get<N>( m_inputs ) );
648  }
649  template <typename T>
650  decltype( auto ) inputLocation() const {
651  return getKey( std::get<details::InputHandle_t<Traits_, std::decay_t<T>>>( m_inputs ) );
652  }
653  constexpr unsigned int inputLocationSize() const { return N_in; }
654 
655  protected:
656  bool isReEntrant() const override { return true; }
657 
659  };
660 
661  template <typename Traits_>
662  class DataHandleMixin<std::tuple<void>, std::tuple<>, Traits_>
663  : public DataHandleMixin<std::tuple<>, std::tuple<>, Traits_> {
664  public:
666  };
667 
668  template <typename... Out, typename Traits_>
669  class DataHandleMixin<std::tuple<Out...>, std::tuple<>, Traits_> : public BaseClass_t<Traits_> {
670  static_assert( std::is_base_of_v<Algorithm, BaseClass_t<Traits_>>, "BaseClass must inherit from Algorithm" );
671 
672  template <typename OArgs, std::size_t... J>
673  DataHandleMixin( std::string name, ISvcLocator* pSvcLocator, const OArgs& outputs, std::index_sequence<J...> )
674  : BaseClass_t<Traits_>( std::move( name ), pSvcLocator )
675  , m_outputs( std::tuple_cat( std::forward_as_tuple( this ), std::get<J>( outputs ) )... ) {
676  // make sure this algorithm is seen as reentrant by Gaudi
677  this->setProperty( "Cardinality", 0 ).ignore();
678  }
679 
680  public:
681  constexpr static std::size_t N_out = sizeof...( Out );
684 
685  // generic constructor: 0 -> N
687  : DataHandleMixin( std::move( name ), pSvcLocator, outputs, std::index_sequence_for<Out...>{} ) {}
688 
689  // 0 -> 1
691  : DataHandleMixin( std::move( name ), locator, std::forward_as_tuple( output ) ) {}
692 
693  template <std::size_t N = 0>
694  decltype( auto ) outputLocation() const {
695  return getKey( std::get<N>( m_outputs ) );
696  }
697  constexpr unsigned int outputLocationSize() const { return N_out; }
698 
699  protected:
700  bool isReEntrant() const override { return true; }
701 
703  };
704 
706  template <typename Fun, typename Container, typename... Args>
707  constexpr void applyPostProcessing( const Fun&, Container&, Args... ) {
708  static_assert( sizeof...( Args ) == 0, "Args should not be used!" );
709  }
710 
711  template <typename Fun, typename Container>
712  auto applyPostProcessing( const Fun& fun, Container& c ) -> decltype( fun.postprocess( c ), void() ) {
713  fun.postprocess( c );
714  }
715 
716 } // namespace Gaudi::Functional::details
IDataHandleHolder
Definition: IDataHandleHolder.h:24
Gaudi::Functional::details::detail2::BaseClass_t
typename Tr::BaseClass BaseClass_t
Definition: details.h:402
Gaudi::Functional::details::invoke_optionally_t
Definition: details.h:138
Gaudi::Functional::details::vector_of_const_::val_t
std::add_const_t< std::remove_pointer_t< Container > > val_t
Definition: details.h:293
Gaudi::Functional::details::vector_of_const_::iterator::is_null
bool is_null() const
Definition: details.h:334
Gaudi::Functional::details::vector_of_const_::iterator
Definition: details.h:302
Gaudi::Functional::details::deref_t::operator()
const In & operator()(const In *in) const
Definition: details.h:224
std::is_same
Gaudi::Functional::details::vector_of_const_::iterator::operator*
ret_t operator*() const
Definition: details.h:319
std::make_tuple
T make_tuple(T... args)
std::true_type
std::string
STL class.
details::size
constexpr auto size(const T &, Args &&...) noexcept
Definition: AnyDataWrapper.h:23
setProperty
bool PyHelper() setProperty(IInterface *p, char *name, char *value)
Definition: Bootstrap.cpp:247
Gaudi::Functional::details::DataHandleMixin< std::tuple<>, std::tuple< In... >, Traits_ >::m_inputs
std::tuple< details::InputHandle_t< Traits_, In >... > m_inputs
Definition: details.h:658
Gaudi::Functional::details::DataHandleMixin< std::tuple< Out... >, std::tuple< In... >, Traits_ >::DataHandleMixin
DataHandleMixin(std::string name, ISvcLocator *locator, const KeyValue &input, const KeyValue &output)
Definition: details.h:561
Gaudi::Functional::details::get
auto get(const ToolHandle< Gaudi::Interface::Bind::IBinder< IFace >> &handle, const Algo &, const EventContext &ctx)
Definition: details.h:459
Gaudi::Functional::details
Definition: Consumer.h:21
Gaudi::NamedRange_
Definition: NamedRange.h:52
Gaudi::Functional::details::vector_of_const_::requires
requires(std::is_pointer_v< X >) ptr_t at(size_type i) const
Definition: details.h:391
std::move
T move(T... args)
Gaudi::Hive::currentContext
GAUDI_API const EventContext & currentContext()
Definition: ThreadLocalContext.cpp:30
Gaudi::Functional::details::DataHandleMixin< std::tuple< Out... >, std::tuple< In... >, Traits_ >::isReEntrant
bool isReEntrant() const override
Definition: details.h:594
Gaudi::Functional::details::DataHandleMixin< std::tuple< Out... >, std::tuple<>, Traits_ >::DataHandleMixin
DataHandleMixin(std::string name, ISvcLocator *locator, const KeyValue &output)
Definition: details.h:690
Gaudi::Functional::details::details2::get_from_handle::operator()
auto operator()(const Handle< I > &h) -> const In &
Definition: details.h:257
Gaudi::Functional::details::InputHandle_t
Gaudi::cpp17::detected_or_t< detail2::DefaultInputHandle< T >, detail2::InputHandle_t, Tr, T > InputHandle_t
Definition: details.h:431
Gaudi::Functional::details::DataHandleMixin< std::tuple< Out... >, std::tuple<>, Traits_ >::DataHandleMixin
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, RepeatValues_< KeyValue, N_out > const &outputs)
Definition: details.h:686
Gaudi::Functional::details::details2::get_from_handle::operator()
auto operator()(const Handle< std::optional< Gaudi::NamedRange_< I >>> &h) -> const In
Definition: details.h:269
Gaudi::Functional::details::invoke_optionally
constexpr struct Gaudi::Functional::details::invoke_optionally_t invoke_optionally
Gaudi::Functional::details::vector_of_const_::iterator::operator--
iterator & operator--()
Definition: details.h:330
Gaudi::Functional::details::DataHandleMixin< std::tuple< Out... >, std::tuple<>, Traits_ >::isReEntrant
bool isReEntrant() const override
Definition: details.h:700
std::pair< std::string, std::string >
std::vector::reserve
T reserve(T... args)
GaudiException.h
Gaudi::Functional::details::insert_t::operator()
auto operator()(Container &c, Value &&v) const -> decltype(c.push_back(v))
Definition: details.h:189
Gaudi::Functional::details::isLegacy
constexpr bool isLegacy
Definition: details.h:434
Gaudi::Functional::details::DataHandleMixin< std::tuple<>, std::tuple< In... >, Traits_ >::DataHandleMixin
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, const IArgs &inputs, std::index_sequence< I... >)
Definition: details.h:624
std::vector< DataObjID >
std::string::size
T size(T... args)
Gaudi::Functional::details::deref_t::requires
requires(!std::is_pointer_v< In >) const In &operator()(const In &in) const
Definition: details.h:212
Gaudi::Functional::details::deref_t
Definition: details.h:210
ISvcLocator
Definition: ISvcLocator.h:46
std::back_inserter
T back_inserter(T... args)
GaudiException
Definition: GaudiException.h:32
Gaudi::Functional::details::vector_of_const_::m_containers
ContainerVector m_containers
Definition: details.h:297
Algorithm.h
Gaudi::Functional::details::vector_of_const_::iterator::iterator_category
typename it_t::iterator_category iterator_category
Definition: details.h:310
Gaudi::Functional::details::DataHandleMixin< std::tuple< Out... >, std::tuple< In... >, Traits_ >::m_inputs
std::tuple< details::InputHandle_t< Traits_, In >... > m_inputs
Definition: details.h:596
Gaudi::Functional::details::vector_of_const_::reserve
void reserve(size_type size)
Definition: details.h:338
Gaudi::Functional::details::DataHandleMixin< std::tuple< Out... >, std::tuple<>, Traits_ >::outputLocationSize
constexpr unsigned int outputLocationSize() const
Definition: details.h:697
Gaudi::Functional::details::DataHandleMixin< std::tuple<>, std::tuple<>, Traits_ >::isReEntrant
bool isReEntrant() const override
Definition: details.h:614
Gaudi::Functional::details::vector_of_const_::size_type
typename ContainerVector::size_type size_type
Definition: details.h:301
std::tuple
Gaudi::Functional::details::zip::const_range
decltype(auto) const_range(Args &&... args)
Zips multiple containers together to form a single const range.
Definition: details.h:106
Gaudi::Functional::details::DataHandleMixin< std::tuple< Out... >, std::tuple< In... >, Traits_ >::DataHandleMixin
DataHandleMixin(std::string name, ISvcLocator *locator, RepeatValues_< KeyValue, N_in > const &inputs, const KeyValue &output)
Definition: details.h:569
gaudirun.c
c
Definition: gaudirun.py:525
std::vector::back
T back(T... args)
ranges::views
Definition: details.h:29
System::typeinfoName
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:315
Gaudi::Functional::details::vector_of_const_
Definition: details.h:290
gaudirun.output
output
Definition: gaudirun.py:521
Gaudi::Functional::details::vector_of_const_::requires
requires(std::is_pointer_v< X >) ptr_t operator[](size_type i) const
Definition: details.h:379
Gaudi::Functional::details::vector_of_const_::iterator::operator-
friend auto operator-(const iterator &lhs, const iterator &rhs)
Definition: details.h:318
Gaudi::Functional::details::DataHandleMixin< std::tuple< Out... >, std::tuple< In... >, Traits_ >::DataHandleMixin
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, const IArgs &inputs, std::index_sequence< I... >, const OArgs &outputs, std::index_sequence< J... >)
Definition: details.h:537
MultiMergers.Value
Value
Definition: MultiMergers.py:15
Gaudi::Functional::details::get_values_helper
auto get_values_helper(std::index_sequence< I... >)
Definition: details.h:153
Gaudi::Functional::details::to_DataObjID
std::vector< DataObjID > to_DataObjID(const std::vector< std::string > &in)
Definition: details.h:114
std::vector::front
T front(T... args)
DataObjectHandle
DataObjectHandle.h GaudiKernel/DataObjectHandle.h.
Definition: AlgTool.h:36
Gaudi::Functional::details::vector_of_const_::requires
requires(std::is_pointer_v< X >) ptr_t front() const
Definition: details.h:355
Gaudi::Functional::details::vector_of_const_::iterator::iterator
iterator(it_t iter)
Definition: details.h:306
Gaudi::Functional::details::filter_evtcontext_t< EventContext, In... >::apply
static auto apply(const Algorithm &algo, Handles &handles)
Definition: details.h:503
Gaudi::Functional::details::make_vector_of_handles
Handles make_vector_of_handles(IDataHandleHolder *owner, const std::vector< DataObjID > &init)
Definition: details.h:441
Gaudi::Functional::details::vector_of_const_::requires
requires(std::is_pointer_v< X >) ptr_t back() const
Definition: details.h:367
Gaudi::Functional::details::insert_t
Definition: details.h:183
Gaudi::Functional::details::insert_t::c_remove_ptr_t
std::remove_pointer_t< typename Container::value_type > c_remove_ptr_t
Definition: details.h:186
bug_34121.t
t
Definition: bug_34121.py:31
ToolHandle
Definition: ToolHandle.h:136
Gaudi::Functional::details::deref_t::requires
requires(!std::is_pointer_v< std::decay_t< In >>) In operator()(In &&in) const
Definition: details.h:218
Gaudi::Functional::details::DataHandleMixin< std::tuple< Out... >, std::tuple< In... >, Traits_ >::DataHandleMixin
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, RepeatValues_< KeyValue, N_in > const &inputs, RepeatValues_< KeyValue, N_out > const &outputs)
Definition: details.h:554
Gaudi::Functional::details::details2::get_from_handle::requires
requires(std::is_convertible_v< I *, In >) auto operator()(const Handle< I > &h) -> const In
Definition: details.h:273
Gaudi::Functional::details::put
auto put(const DataObjectHandle< AnyDataWrapper< Out1 >> &out_handle, Out2 &&out)
Definition: details.h:167
Gaudi::Functional::details::DataHandleMixin< std::tuple< Out... >, std::tuple< In... >, Traits_ >::inputLocationSize
constexpr unsigned int inputLocationSize() const
Definition: details.h:581
GaudiPython.Pythonizations.ctx
ctx
Definition: Pythonizations.py:578
Gaudi::Functional::details::zip::check_sizes
bool check_sizes(const A &a, const B &b, const C &... c) noexcept
Compare sizes of 3 or more containers.
Definition: details.h:80
Gaudi::Functional::details::filter_evtcontext_t< EventContext, In... >::apply
static auto apply(const Algorithm &algo, const EventContext &ctx, Handles &handles)
Definition: details.h:498
Gaudi::Functional::details::insert_t::requires
requires(std::is_pointer_v< typename Container::value_type > &&std::is_convertible_v< Value, c_remove_ptr_t< Container >>) auto operator()(Container &c
Gaudi::Functional::details::vector_of_const_::iterator::m_i
it_t m_i
Definition: details.h:304
std::ostream
STL class.
Gaudi::Functional::details::detail2::InputHandle_t
typename Tr::template InputHandle< T > InputHandle_t
Definition: details.h:406
Gaudi::Functional::details::detail2::DefaultInputHandle
std::conditional_t< is_tool_v< T >, ToolHandle_t< T >, DataObjectReadHandle< T > > DefaultInputHandle
Definition: details.h:415
Gaudi::Functional::details::DataHandleMixin< std::tuple< Out... >, std::tuple<>, Traits_ >::DataHandleMixin
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, const OArgs &outputs, std::index_sequence< J... >)
Definition: details.h:673
Gaudi::Functional::details::vector_of_const_::value_type
std::conditional_t< is_pointer, ptr_t, val_t > value_type
Definition: details.h:300
Gaudi::cpp17::detected_or_t
typename details::detector< Default, void, Op, Args... >::type detected_or_t
Definition: detected.h:50
Gaudi::Algorithm
Base class from which all concrete algorithm classes should be derived.
Definition: Algorithm.h:90
DataObjectReadHandle
Definition: DataObjectHandle.h:448
AlgSequencer.h
h
Definition: AlgSequencer.py:31
Gaudi::Functional::details::applyPostProcessing
auto applyPostProcessing(const Fun &fun, Container &c) -> decltype(fun.postprocess(c), void())
Definition: details.h:712
Gaudi::Functional::details::DataHandleMixin< std::tuple<>, std::tuple< In... >, Traits_ >::inputLocationSize
constexpr unsigned int inputLocationSize() const
Definition: details.h:653
Gaudi::Functional::details::vector_of_const_::requires
requires(!std::is_pointer_v< X >) ref_t operator[](size_type i) const
Definition: details.h:373
Gaudi::Functional::details::filter_evtcontext_t::apply
static auto apply(const Algorithm &algo, Handles &handles)
Definition: details.h:478
Gaudi::Functional::details::details2::is_optional_
decltype(std::declval< T >().has_value(), std::declval< T >().value()) is_optional_
Definition: details.h:125
Gaudi::Functional::details::vector_of_const_::requires
requires(!std::is_pointer_v< X >) ref_t back() const
Definition: details.h:361
Gaudi::Functional::details::detail2::OutputHandle_t
typename Tr::template OutputHandle< T > OutputHandle_t
Definition: details.h:404
Gaudi::Functional::details::details2::get_from_handle::operator()
auto operator()(const Handle< Gaudi::NamedRange_< I >> &h) -> const In
Definition: details.h:265
Gaudi::Functional::details::deref
constexpr struct Gaudi::Functional::details::deref_t deref
Algorithm.h
Gaudi::Functional::details::DataHandleMixin< std::tuple< Out... >, std::tuple<>, Traits_ >::m_outputs
std::tuple< details::OutputHandle_t< Traits_, Out >... > m_outputs
Definition: details.h:702
Gaudi::Functional::details::vector_of_const_::iterator::operator++
iterator & operator++()
Definition: details.h:326
AnyDataWrapper
Definition: AnyDataWrapper.h:55
Gaudi::Functional::details::vector_of_const_::push_back
void push_back(T &&container)
Definition: details.h:340
Gaudi::Functional::details::details2::get_from_handle::operator()
auto operator()(const Handle< Gaudi::Range_< I >> &h) -> const In
Definition: details.h:261
std::transform
T transform(T... args)
Gaudi::Functional::details::updateHandleLocation
void updateHandleLocation(DataHandleMixin< Out, In, Tr > &parent, const std::string &prop, const std::string &newLoc)
Definition: details.h:515
Gaudi::Functional::details::vector_of_const_::iterator::operator==
friend bool operator==(const iterator &lhs, const iterator &rhs)
Definition: details.h:317
Gaudi::Functional::details::DataHandleMixin< std::tuple< Out... >, std::tuple< In... >, Traits_ >::m_outputs
std::tuple< details::OutputHandle_t< Traits_, Out >... > m_outputs
Definition: details.h:597
IBinder.h
Gaudi::Functional::details::filter_evtcontext_t
Definition: details.h:471
Gaudi::Range_
Definition: Range.h:94
std::ostringstream
STL class.
Gaudi::Functional::details::DataHandleMixin< std::tuple<>, std::tuple< In... >, Traits_ >::isReEntrant
bool isReEntrant() const override
Definition: details.h:656
Gaudi::Functional::details::DataHandleMixin< std::tuple<>, std::tuple<>, Traits_ >::m_inputs
std::tuple m_inputs
Definition: details.h:616
gaudirun.type
type
Definition: gaudirun.py:160
ThreadLocalContext.h
Gaudi::cpp17::detected_t
typename is_detected< Op, Args... >::type detected_t
Definition: detected.h:46
DataObjectHandle::put
T * put(std::unique_ptr< T > object) const
Register object in transient store.
Definition: DataObjectHandle.h:176
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
Gaudi::Functional::details::zip::verifySizes
decltype(auto) verifySizes(Args &... args)
Verify the data container sizes have the same sizes.
Definition: details.h:86
Gaudi::Functional::details::filter_evtcontext_t::apply
static auto apply(const Algorithm &algo, const EventContext &ctx, Handles &handles)
Definition: details.h:484
Gaudi::Functional::details::details2::get_from_handle
Definition: details.h:255
Gaudi::Functional::details::vector_of_const_::iterator::operator!=
friend bool operator!=(const iterator &lhs, const iterator &rhs)
Definition: details.h:316
gaudirun.args
args
Definition: gaudirun.py:336
Gaudi::Functional::details::vector_of_const_::begin
iterator begin() const
Definition: details.h:344
std::vector::begin
T begin(T... args)
std
STL namespace.
Gaudi::Functional::details::vector_of_const_::iterator::difference_type
typename it_t::difference_type difference_type
Definition: details.h:314
Gaudi::Functional::details::is_optional_v
constexpr bool is_optional_v
Definition: details.h:132
Gaudi::Functional::details::details2::push_back
void push_back(Container &c, const Value &v, std::false_type)
Definition: details.h:250
Gaudi::Functional::details::detail2::is_tool_v
constexpr auto is_tool_v
Definition: details.h:409
Gaudi::Functional::details::details2::deref_if
T & deref_if(T *const t, std::true_type)
Definition: details.h:284
EventContext
Definition: EventContext.h:34
Gaudi::Functional::details::RepeatValues_
decltype(get_values_helper< Value >(std::make_index_sequence< N >())) RepeatValues_
Definition: details.h:158
Gaudi::Functional::details::DataHandleMixin< std::tuple< Out... >, std::tuple< In... >, Traits_ >::outputLocationSize
constexpr unsigned int outputLocationSize() const
Definition: details.h:591
Gaudi::Functional::Traits::BaseClass_t
Definition: utilities.h:38
Gaudi::Functional::details::vector_of_const_::iterator::value_type
typename it_t::iterator_category value_type
Definition: details.h:311
detected.h
Gaudi::Functional::details::vector_of_const_::iterator::pointer
typename it_t::pointer pointer
Definition: details.h:313
fixtures.reference
Generator[dict, None, None] reference(request, Optional[Path] reference_path)
Definition: fixtures.py:211
Gaudi::Functional::details::vector_of_const_::iterator::it_t
typename ContainerVector::const_iterator it_t
Definition: details.h:303
Gaudi::Functional::details::updateHandleLocations
void updateHandleLocations(DataHandleMixin< Out, In, Tr > &parent, const std::string &prop, const std::vector< std::string > &newLocs)
Definition: details.h:522
Gaudi::Functional::details::insert_t::operator()
auto operator()(Container &c, Value &&v) const -> decltype(c.insert(v))
Definition: details.h:194
Gaudi::Functional::details::vector_of_const_::ref_t
std::add_lvalue_reference_t< val_t > ref_t
Definition: details.h:295
Gaudi::Functional::details::vector_of_const_::iterator::reference
typename it_t::reference reference
Definition: details.h:312
Properties.v
v
Definition: Properties.py:122
Gaudi::Functional::details::DataHandleMixin
Definition: details.h:512
Gaudi::Functional::details::vector_of_const_::end
iterator end() const
Definition: details.h:345
std::ostringstream::str
T str(T... args)
Gaudi::Functional::details::requires
requires(is_optional_v< OptOut >) void put(const OutHandle &out_handle
std::size_t
Gaudi::Functional::details::invoke_optionally_t::requires
requires(is_optional_v< Arg >) void operator()(F &&f
std::vector::end
T end(T... args)
Gaudi::Functional::details::BaseClass_t
Gaudi::cpp17::detected_or_t< Base, detail2::BaseClass_t, Tr > BaseClass_t
Definition: details.h:422
Gaudi::Functional::details::zip::printSizes
void printSizes(OS &out, Arg &&arg, Args &&... args)
Print the parameters.
Definition: details.h:60
Gaudi::Functional::details::details2::value_type_of_t
typename T::value_type value_type_of_t
Definition: details.h:128
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
Gaudi::Functional::details::DataHandleMixin< std::tuple<>, std::tuple<>, Traits_ >::DataHandleMixin
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, std::tuple<>={}, std::tuple<>={})
Definition: details.h:607
Gaudi::Functional::details::vector_of_const_::requires
requires(!std::is_pointer_v< X >) ref_t front() const
Definition: details.h:349
Gaudi::Functional::details::vector_of_const_::iterator::ret_t
std::conditional_t< is_pointer, ptr_t, ref_t > ret_t
Definition: details.h:307
Gaudi::Functional::details::insert
constexpr struct Gaudi::Functional::details::insert_t insert
Gaudi::Interface::Bind::IBinder
Definition: IBinder.h:56
DataObjectHandle.h
Gaudi::Functional::details::OutputHandle_t
Gaudi::cpp17::detected_or_t< DataObjectWriteHandle< T >, detail2::OutputHandle_t, Tr, T > OutputHandle_t
Definition: details.h:429
Gaudi::Functional::details::filter_evtcontext
typename filter_evtcontext_t< In... >::type filter_evtcontext
Definition: details.h:509
Gaudi::Functional::details::DataHandleMixin< std::tuple<>, std::tuple< In... >, Traits_ >::DataHandleMixin
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, RepeatValues_< KeyValue, N_in > const &inputs)
Definition: details.h:637
Gaudi::Functional::details::vector_of_const_::vector_of_const_
vector_of_const_()=default
Gaudi::Functional::details::vector_of_const_::ptr_t
std::add_pointer_t< val_t > ptr_t
Definition: details.h:294
Gaudi::Functional::details::DataHandleMixin< std::tuple< Out... >, std::tuple< In... >, Traits_ >::DataHandleMixin
DataHandleMixin(std::string name, ISvcLocator *locator, const KeyValue &input, RepeatValues_< KeyValue, N_out > const &outputs)
Definition: details.h:565
Gaudi::Functional::details::vector_of_const_::requires
requires(!std::is_pointer_v< X >) ref_t at(size_type i) const
Definition: details.h:385
Gaudi::Functional::details::zip::range
decltype(auto) range(Args &&... args)
Zips multiple containers together to form a single range.
Definition: details.h:97
GaudiUtils::details::ostream_joiner
Stream & ostream_joiner(Stream &os, Iterator first, Iterator last, Separator sep, OutputElement output=OutputElement{})
Definition: SerializeSTL.h:87
Gaudi::Functional::details::DataHandleMixin< std::tuple<>, std::tuple< In... >, Traits_ >::DataHandleMixin
DataHandleMixin(std::string name, ISvcLocator *locator, const KeyValue &input)
Definition: details.h:642
Gaudi::Functional::details::out
OptOut && out
Definition: details.h:174
Gaudi::Functional::details::getKey
auto getKey(const Handle &h) -> decltype(h.objKey())
Definition: details.h:464
Gaudi::Functional::details::remove_optional_t
std::conditional_t< is_optional_v< T >, Gaudi::cpp17::detected_t< details2::value_type_of_t, T >, T > remove_optional_t
Definition: details.h:136
Gaudi::Functional::details::invoke_optionally_t::requires
requires(!is_optional_v< Arg >) decltype(auto) operator()(F &&f
Gaudi::Functional::details::vector_of_const_::is_null
bool is_null(size_type i) const
Definition: details.h:396
Gaudi::Functional::details::vector_of_const_::size
size_type size() const
Definition: details.h:346