22 #include <type_traits>
24 #if defined( __cpp_lib_ranges_zip ) && defined( __cpp_lib_ranges_as_const )
25 # define GAUDI_FUNCTIONAL_USES_STD_RANGES 1
28 # include <range/v3/version.hpp>
29 # include <range/v3/view/const.hpp>
30 # include <range/v3/view/zip.hpp>
32 # if RANGE_V3_VERSION < 900
34 using namespace ranges::view;
39 #if defined( __clang__ ) && ( __clang_major__ < 11 ) || defined( __APPLE__ ) && ( __clang_major__ < 12 )
40 # define GF_SUPPRESS_SPURIOUS_CLANG_WARNING_BEGIN \
41 _Pragma( "clang diagnostic push" ) _Pragma( "clang diagnostic ignored \"-Wunused-lambda-capture\"" )
42 # define GF_SUPPRESS_SPURIOUS_CLANG_WARNING_END _Pragma( "clang diagnostic pop" )
44 # define GF_SUPPRESS_SPURIOUS_CLANG_WARNING_BEGIN
45 # define GF_SUPPRESS_SPURIOUS_CLANG_WARNING_END
50 #define GAUDI_FUNCTIONAL_CONSTRUCTOR_USES_TUPLE
58 template <
typename OS,
typename Arg>
64 template <
typename OS,
typename Arg,
typename... Args>
78 template <
typename A,
typename B>
80 return a.size() == b.size();
84 template <
typename A,
typename B,
typename... C>
85 inline bool check_sizes(
const A& a,
const B& b,
const C&...
c ) noexcept {
90 template <
typename... Args>
93 std::ostringstream mess;
94 mess <<
"Zipped containers have different sizes : ";
101 template <
typename... Args>
106 #if defined( GAUDI_FUNCTIONAL_USES_STD_RANGES )
107 return std::ranges::zip_view( std::forward<Args>(
args )... );
109 return ranges::views::zip( std::forward<Args>(
args )... );
114 template <
typename... Args>
119 #if defined( GAUDI_FUNCTIONAL_USES_STD_RANGES )
120 return std::ranges::as_const_view( std::ranges::zip_view( std::forward<Args>(
args )... ) );
122 return ranges::views::const_( ranges::views::zip( std::forward<Args>(
args )... ) );
127 inline std::vector<DataObjID>
to_DataObjID(
const std::vector<std::string>& in ) {
128 std::vector<DataObjID>
out;
129 out.reserve( in.size() );
130 std::transform( in.begin(), in.end(), std::back_inserter(
out ),
131 [](
const std::string& i ) { return DataObjID{ i }; } );
136 template <
typename T>
140 typename T::value_type;
145 template <
typename T>
150 template <is_optional T>
157 template <
typename T>
161 template <
typename F,
typename Arg>
163 decltype( auto ) operator()( F&& f, Arg&& arg )
const {
164 return std::invoke( std::forward<F>( f ), std::forward<Arg>( arg ) );
166 template <
typename F,
typename Arg>
168 void operator()( F&& f, Arg&& arg )
const {
169 if ( arg ) std::invoke( std::forward<F>( f ), *std::forward<Arg>( arg ) );
174 template <
typename Value, std::size_t... I>
176 return std::make_tuple( ( (
void)I,
Value{} )... );
179 template <
typename Value, auto N>
180 using RepeatValues_ = decltype( get_values_helper<Value>( std::make_index_sequence<N>() ) );
183 template <std::derived_from<DataObject> Out1, std::convertible_to<Out1> Out2>
185 return out_handle.
put( std::make_unique<Out1>( std::forward<Out2>(
out ) ) );
188 template <
typename Out1, std::convertible_to<Out1> Out2>
190 return out_handle.put( std::forward<Out2>(
out ) );
194 template <
typename OutHandle,
typename OptOut>
196 void
put( const OutHandle& out_handle, OptOut&&
out ) {
197 if (
out )
put( out_handle, *std::forward<OptOut>(
out ) );
207 template <
typename Container>
210 template <
typename Container,
typename Value>
212 return c.push_back( std::forward<Value>(
v ) );
215 template <
typename Container,
typename Value>
217 return c.insert( std::forward<Value>(
v ) );
221 template <
typename Container,
typename Value>
222 requires( std::is_pointer_v<typename Container::value_type> &&
224 auto operator()( Container&
c,
Value&&
v )
const {
233 template <
typename In>
235 const In& operator()(
const In& in )
const {
239 template <
typename In>
241 In operator()( In&& in )
const {
242 return std::forward<In>( in );
245 template <
typename In>
247 assert( in !=
nullptr );
255 template <
typename T>
256 constexpr
static bool is_gaudi_range_v =
false;
258 template <
typename T>
259 constexpr
static bool is_gaudi_range_v<Gaudi::Range_<T>> =
true;
261 template <
typename T>
262 constexpr
static bool is_gaudi_range_v<Gaudi::NamedRange_<T>> =
true;
264 template <
typename T>
265 constexpr
static bool is_gaudi_range_v<std::optional<Gaudi::NamedRange_<T>>> =
true;
267 template <
typename Container,
typename Value>
271 template <
typename Container,
typename Value>
276 template <
typename In>
278 template <
template <
typename>
class Handle, std::convertible_to<In> I>
282 template <
template <
typename>
class Handle,
typename I>
286 template <
template <
typename>
class Handle,
typename I>
290 template <
template <
typename>
class Handle,
typename I>
294 template <
template <
typename>
class Handle,
typename I>
296 auto operator()(
const Handle<I>&
h ) ->
const In {
297 return h.getIfExists();
301 template <
typename T>
305 template <
typename T>
311 template <
typename Container>
313 static constexpr
bool is_pointer = std::is_pointer_v<Container>;
314 static constexpr
bool is_range = details2::is_gaudi_range_v<Container>;
315 using val_t = std::add_const_t<std::remove_pointer_t<Container>>;
316 using ptr_t = std::add_pointer_t<val_t>;
317 using ref_t = std::add_lvalue_reference_t<val_t>;
322 using value_type = std::conditional_t<is_pointer, ptr_t, val_t>;
325 using it_t =
typename ContainerVector::const_iterator;
329 using ret_t = std::conditional_t<is_pointer, ptr_t, ref_t>;
342 if constexpr ( is_range ) {
357 explicit operator bool()
const {
return !is_null(); }
361 template <
typename T>
364 std::bool_constant < is_pointer || is_range > {} );
370 template <
typename X = Container>
372 ref_t front()
const {
373 return *m_containers.front();
376 template <
typename X = Container>
378 ptr_t front()
const {
379 return m_containers.front();
382 template <
typename X = Container>
385 return *m_containers.back();
388 template <
typename X = Container>
391 return m_containers.back();
394 template <
typename X = Container>
397 return *m_containers[i];
400 template <
typename X = Container>
403 return m_containers[i];
406 template <
typename X = Container>
409 return *m_containers[i];
412 template <
typename X = Container>
415 return m_containers[i];
425 template <
typename Tr>
428 template <
typename Tr,
typename Default>
432 template <
typename Tr,
typename Default>
438 template <
typename T,
typename Tr,
template <
typename...>
typename Default>
442 template <
typename T,
typename Tr,
template <
typename...>
typename Default>
448 template <
typename T,
typename Tr,
template <
typename...>
typename Default>
452 template <
typename T,
typename Tr,
template <
typename...>
typename Default>
458 template <
typename T>
460 std::conditional_t<std::derived_from<std::decay_t<T>,
IAlgTool>,
467 template <
typename Tr,
typename Default = Gaudi::Algorithm>
473 template <
typename Tr,
typename T>
476 template <
typename Tr,
typename T>
479 template <
typename Traits>
481 std::is_base_of_v<Gaudi::details::LegacyAlgorithmAdapter, details::BaseClass_t<Traits>>;
484 #define GAUDI_FUNCTIONAL_MAKE_VECTOR_OF_HANDLES_USES_DATAOBJID
486 template <
typename Handles>
489 handles.reserve( init.size() );
490 std::transform( init.begin(), init.end(), std::back_inserter( handles ),
491 [&](
const auto& loc ) ->
typename Handles::value_type {
492 return { loc, owner };
497 template <
typename Handle,
typename Algo>
504 template <
typename IFace,
typename Algo>
506 return handle.bind(
ctx );
509 template <
typename Handle>
510 auto getKey(
const Handle&
h ) -> decltype(
h.objKey() ) {
516 template <
typename... In>
518 using type = std::tuple<In...>;
520 static_assert( !std::disjunction_v<std::is_same<EventContext, In>...>,
521 "EventContext can only appear as first argument" );
523 template <
typename Algorithm,
typename Handles>
529 template <
typename Algorithm,
typename Handles>
531 return std::apply( [&](
const auto&... handle ) {
return algo(
get( handle, algo,
ctx )... ); }, handles );
536 template <
typename... In>
538 using type = std::tuple<In...>;
540 static_assert( !std::disjunction_v<std::is_same<EventContext, In>...>,
541 "EventContext can only appear as first argument" );
543 template <
typename Algorithm,
typename Handles>
545 return std::apply( [&](
const auto&... handle ) {
return algo(
ctx,
get( handle, algo,
ctx )... ); }, handles );
548 template <
typename Algorithm,
typename Handles>
554 template <
typename... In>
557 template <
typename OutputSpec,
typename InputSpec,
typename Traits_>
560 template <
typename Out,
typename In,
typename Tr>
562 const std::string& newLoc ) {
563 auto sc = parent.setProperty( prop, newLoc );
564 if ( sc.isFailure() )
throw GaudiException(
"Could not set Property", prop +
" -> " + newLoc, sc );
567 template <
typename Out,
typename In,
typename Tr>
569 const std::vector<std::string>& newLocs ) {
570 std::ostringstream ss;
572 return os <<
"'" << i <<
"'";
574 auto sc = parent.setProperty( prop, ss.str() );
575 if ( sc.isFailure() )
throw GaudiException(
"Could not set Property", prop +
" -> " + ss.str(), sc );
578 template <
typename... Out,
typename... In,
typename Traits_>
582 template <
typename IArgs,
typename OArgs, std::size_t... I, std::size_t... J>
584 const OArgs& outputs, std::index_sequence<J...> )
586 , m_inputs(
std::tuple_cat(
std::forward_as_tuple( this ),
std::
get<I>( inputs ) )... )
587 , m_outputs(
std::tuple_cat(
std::forward_as_tuple( this ),
std::
get<J>( outputs ) )... ) {
593 constexpr
static std::size_t N_in =
sizeof...( In );
594 constexpr
static std::size_t N_out =
sizeof...( Out );
596 using KeyValue = std::pair<std::string, std::string>;
597 using KeyValues = std::pair<std::string, std::vector<std::string>>;
603 std::index_sequence_for<Out...>{} ) {}
619 template <std::
size_t N = 0>
620 decltype(
auto ) inputLocation()
const {
621 return getKey( std::get<N>( m_inputs ) );
623 template <
typename T>
624 decltype(
auto ) inputLocation()
const {
629 template <std::
size_t N = 0>
630 decltype(
auto ) outputLocation()
const {
631 return getKey( std::get<N>( m_outputs ) );
633 template <
typename T>
634 decltype(
auto ) outputLocation()
const {
642 std::tuple<details::InputHandle_t<Traits_, In>...>
m_inputs;
643 std::tuple<details::OutputHandle_t<Traits_, Out>...>
m_outputs;
646 template <
typename Traits_>
651 using KeyValue = std::pair<std::string, std::string>;
652 using KeyValues = std::pair<std::string, std::vector<std::string>>;
665 template <
typename... In,
typename Traits_>
669 template <
typename IArgs, std::size_t... I>
672 , m_inputs(
std::tuple_cat(
std::forward_as_tuple( this ),
std::
get<I>( inputs ) )... ) {
678 using KeyValue = std::pair<std::string, std::string>;
679 using KeyValues = std::pair<std::string, std::vector<std::string>>;
680 constexpr
static std::size_t N_in =
sizeof...( In );
691 template <std::
size_t N = 0>
692 decltype(
auto ) inputLocation()
const {
693 return getKey( std::get<N>( m_inputs ) );
695 template <
typename T>
696 decltype(
auto ) inputLocation()
const {
704 std::tuple<details::InputHandle_t<Traits_, In>...>
m_inputs;
707 template <
typename Traits_>
714 template <
typename... Out,
typename Traits_>
718 template <
typename OArgs, std::size_t... J>
721 , m_outputs(
std::tuple_cat(
std::forward_as_tuple( this ),
std::
get<J>( outputs ) )... ) {
727 constexpr
static std::size_t N_out =
sizeof...( Out );
728 using KeyValue = std::pair<std::string, std::string>;
729 using KeyValues = std::pair<std::string, std::vector<std::string>>;
739 template <std::
size_t N = 0>
740 decltype(
auto ) outputLocation()
const {
741 return getKey( std::get<N>( m_outputs ) );
748 std::tuple<details::OutputHandle_t<Traits_, Out>...>
m_outputs;
752 template <
typename Fun,
typename Container,
typename... Args>
754 static_assert(
sizeof...( Args ) == 0,
"Args should not be used!" );
757 template <
typename Fun,
typename Container>
759 fun.postprocess(
c );