Go to the documentation of this file.
   11 #ifndef FUNCTIONAL_DETAILS_H 
   12 #define FUNCTIONAL_DETAILS_H 
   17 #include <type_traits> 
   29 #include <range/v3/version.hpp> 
   30 #include <range/v3/view/const.hpp> 
   31 #include <range/v3/view/zip.hpp> 
   33 #if RANGE_V3_VERSION < 900 
   35   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>
 
   94         mess << 
"Zipped containers have different sizes : ";
 
  101     template <
typename... Args>
 
  106       return ranges::views::zip( std::forward<Args>( 
args )... );
 
  110     template <
typename... Args>
 
  115       return ranges::views::const_( ranges::views::zip( std::forward<Args>( 
args )... ) );
 
  123                     []( 
const std::string& i ) { return DataObjID{ i }; } );
 
  129     template <
typename T>
 
  130     using is_optional_ = decltype( std::declval<T>().has_value(), std::declval<T>().value() );
 
  132     template <
typename T>
 
  136   template <
typename Arg>
 
  137   constexpr 
bool is_optional_v = Gaudi::cpp17::is_detected_v<details2::is_optional_, Arg>;
 
  139   template <
typename Arg>
 
  142   template <
typename Arg>
 
  145   template <
typename T>
 
  150     template <
typename F, 
typename Arg, 
typename = require_is_not_optional<Arg>>
 
  151     decltype( 
auto ) operator()( F&& f, Arg&& arg )
 const {
 
  152       return std::invoke( std::forward<F>( f ), std::forward<Arg>( arg ) );
 
  154     template <
typename F, 
typename Arg, 
typename = require_is_optional<Arg>>
 
  156       if ( arg ) std::invoke( std::forward<F>( f ), *std::forward<Arg>( arg ) );
 
  166   template <
typename Value, auto N>
 
  167   using RepeatValues_ = decltype( get_values_helper<Value>( std::make_index_sequence<N>() ) );
 
  171   template <
typename Out1, 
typename Out2,
 
  172             typename = std::enable_if_t<std::is_constructible_v<Out1, Out2> && std::is_base_of_v<DataObject, Out1>>>
 
  174     return out_handle.
put( std::make_unique<Out1>( std::forward<Out2>( 
out ) ) );
 
  177   template <
typename Out1, 
typename Out2, 
typename = std::enable_if_t<std::is_constructible_v<Out1, Out2>>>
 
  179     return out_handle.put( std::forward<Out2>( 
out ) );
 
  183   template <
typename OutHandle, 
typename OptOut, 
typename = require_is_optional<OptOut>>
 
  184   void put( 
const OutHandle& out_handle, OptOut&& 
out ) {
 
  185     if ( 
out ) 
put( out_handle, *std::forward<OptOut>( 
out ) );
 
  195     template <
typename Container>
 
  198     template <
typename Container, 
typename Value>
 
  200       return c.push_back( std::forward<Value>( 
v ) );
 
  203     template <
typename Container, 
typename Value>
 
  205       return c.insert( std::forward<Value>( 
v ) );
 
  209     template <
typename Container, 
typename Value,
 
  210               typename = std::enable_if_t<std::is_pointer_v<typename Container::value_type>>,
 
  211               typename = std::enable_if_t<std::is_convertible_v<Value, c_remove_ptr_t<Container>>>>
 
  221     template <
typename In, 
typename = std::enable_if_t<!std::is_po
inter_v<In>>>
 
  226     template <
typename In, 
typename = std::enable_if_t<!std::is_po
inter_v<std::decay_t<In>>>>
 
  228       return std::forward<In>( in );
 
  231     template <
typename In>
 
  233       assert( in != 
nullptr );
 
  241     template <
typename T>
 
  244     template <
typename T, 
typename IT>
 
  247     template <
typename T, 
typename IT>
 
  250     template <
typename T>
 
  253     template <
typename Container, 
typename Value>
 
  257     template <
typename Container, 
typename Value>
 
  262     template <
typename In>
 
  264       template <
template <
typename> 
class Handle, 
typename I, 
typename = std::enable_if_t<std::is_convertible_v<I, In>>>
 
  268       template <
template <
typename> 
class Handle, 
typename I, 
typename IT>
 
  272       template <
template <
typename> 
class Handle, 
typename I, 
typename IT>
 
  276       template <
template <
typename> 
class Handle, 
typename I,
 
  277                 typename = std::enable_if_t<std::is_convertible_v<I*, In>>>
 
  279         return h.getIfExists();
 
  283     template <
typename T>
 
  287     template <
typename T>
 
  293   template <
typename Container>
 
  295     static constexpr 
bool is_pointer = std::is_pointer_v<Container>;
 
  296     static constexpr 
bool is_range   = details2::is_gaudi_range_v<Container>;
 
  297     using val_t                      = std::add_const_t<std::remove_pointer_t<Container>>;
 
  298     using ptr_t                      = std::add_pointer_t<val_t>;
 
  299     using ref_t                      = std::add_lvalue_reference_t<val_t>;
 
  304     using value_type = std::conditional_t<is_pointer, ptr_t, val_t>;
 
  307       using it_t = 
typename ContainerVector::const_iterator;
 
  311       using ret_t = std::conditional_t<is_pointer, ptr_t, ref_t>;
 
  324         if constexpr ( is_range ) {
 
  339       explicit operator bool()
 const { 
return !is_null(); }
 
  343     template <
typename T> 
 
  346                            std::bool_constant < is_pointer || is_range > {} );
 
  352     template <
typename X = Container>
 
  353     std::enable_if_t<!std::is_pointer_v<X>, 
ref_t> 
front()
 const {
 
  354       return *m_containers.
front();
 
  356     template <
typename X = Container>
 
  357     std::enable_if_t<std::is_pointer_v<X>, 
ptr_t> 
front()
 const {
 
  358       return m_containers.
front();
 
  361     template <
typename X = Container>
 
  362     std::enable_if_t<!std::is_pointer_v<X>, 
ref_t> 
back()
 const {
 
  363       return *m_containers.
back();
 
  365     template <
typename X = Container>
 
  366     std::enable_if_t<std::is_pointer_v<X>, 
ptr_t> 
back()
 const {
 
  367       return m_containers.
back();
 
  370     template <
typename X = Container>
 
  372       return *m_containers[i];
 
  374     template <
typename X = Container>
 
  376       return m_containers[i];
 
  379     template <
typename X = Container>
 
  381       return *m_containers[i];
 
  383     template <
typename X = Container>
 
  385       return m_containers[i];
 
  393     template <
typename Tr>
 
  395     template <
typename Tr, 
typename T>
 
  397     template <
typename Tr, 
typename T>
 
  400     template <
typename T>
 
  401     constexpr 
auto is_tool_v = std::is_base_of_v<IAlgTool, std::decay_t<T>>;
 
  403     template <
typename T>
 
  406     template <
typename T>
 
  413   template <
typename Tr, 
typename Base = GaudiAlgorithm>
 
  420   template <
typename Tr, 
typename T>
 
  422   template <
typename Tr, 
typename T>
 
  425   template <
typename Traits>
 
  427       std::is_base_of_v<Gaudi::details::LegacyAlgorithmAdapter, details::BaseClass_t<Traits>>;
 
  430 #define GAUDI_FUNCTIONAL_MAKE_VECTOR_OF_HANDLES_USES_DATAOBJID 
  432   template <
typename Handles>
 
  435     handles.reserve( init.
size() );
 
  437                     [&]( 
const auto& loc ) -> 
typename Handles::value_type {
 
  438                       return { loc, owner };
 
  443   template <
typename Handle, 
typename Algo>
 
  450   template <
typename IFace, 
typename Algo>
 
  452     return handle.bind( 
ctx );
 
  455   template <
typename Handle>
 
  456   auto getKey( 
const Handle& 
h ) -> decltype( 
h.objKey() ) {
 
  462   template <
typename... In>
 
  467                    "EventContext can only appear as first argument" );
 
  469     template <
typename Algorithm, 
typename Handles>
 
  475     template <
typename Algorithm, 
typename Handles>
 
  477       return std::apply( [&]( 
const auto&... handle ) { 
return algo( 
get( handle, algo, 
ctx )... ); }, handles );
 
  482   template <
typename... In>
 
  487                    "EventContext can only appear as first argument" );
 
  489     template <
typename Algorithm, 
typename Handles>
 
  491       return std::apply( [&]( 
const auto&... handle ) { 
return algo( 
ctx, 
get( handle, algo, 
ctx )... ); }, handles );
 
  494     template <
typename Algorithm, 
typename Handles>
 
  500   template <
typename... In>
 
  503   template <
typename OutputSpec, 
typename InputSpec, 
typename Traits_>
 
  506   template <
typename Out, 
typename In, 
typename Tr>
 
  509     auto sc = parent.setProperty( prop, newLoc );
 
  510     if ( sc.isFailure() ) 
throw GaudiException( 
"Could not set Property", prop + 
" -> " + newLoc, sc );
 
  513   template <
typename Out, 
typename In, 
typename Tr>
 
  518         ss << 
'[', newLocs, 
", ", []( 
std::ostream & os, 
const auto& i ) -> 
auto& { 
return os << 
"'" << i << 
"'"; } )
 
  520     auto sc = parent.setProperty( prop, ss.
str() );
 
  521     if ( sc.isFailure() ) 
throw GaudiException( 
"Could not set Property", prop + 
" -> " + ss.
str(), sc );
 
  524   template <
typename... Out, 
typename... In, 
typename Traits_>
 
  530                      const OArgs& outputs, std::index_sequence<J...> )
 
  532         , m_inputs( 
std::tuple_cat( 
std::forward_as_tuple( this ), 
std::
get<I>( inputs ) )... )
 
  533         , m_outputs( 
std::tuple_cat( 
std::forward_as_tuple( this ), 
std::
get<J>( outputs ) )... ) {
 
  549                            std::index_sequence_for<Out...>{} ) {}
 
  565     template <std::
size_t N = 0>
 
  566     decltype( 
auto ) inputLocation()
 const {
 
  567       return getKey( std::get<N>( m_inputs ) );
 
  569     template <
typename T>
 
  570     decltype( 
auto ) inputLocation()
 const {
 
  575     template <std::
size_t N = 0>
 
  576     decltype( 
auto ) outputLocation()
 const {
 
  577       return getKey( std::get<N>( m_outputs ) );
 
  579     template <
typename T>
 
  580     decltype( 
auto ) outputLocation()
 const {
 
  592   template <
typename Traits_>
 
  611   template <
typename... In, 
typename Traits_>
 
  618         , m_inputs( 
std::tuple_cat( 
std::forward_as_tuple( this ), 
std::
get<I>( inputs ) )... ) {
 
  637     template <std::
size_t N = 0>
 
  638     decltype( 
auto ) inputLocation()
 const {
 
  639       return getKey( std::get<N>( m_inputs ) );
 
  641     template <
typename T>
 
  642     decltype( 
auto ) inputLocation()
 const {
 
  653   template <
typename Traits_>
 
  660   template <
typename... Out, 
typename Traits_>
 
  667         , m_outputs( 
std::tuple_cat( 
std::forward_as_tuple( this ), 
std::
get<J>( outputs ) )... ) {
 
  685     template <std::
size_t N = 0>
 
  686     decltype( 
auto ) outputLocation()
 const {
 
  687       return getKey( std::get<N>( m_outputs ) );
 
  698   template <
typename Fun, 
typename Container, 
typename... Args>
 
  700     static_assert( 
sizeof...( Args ) == 0, 
"Args should not be used!" );
 
  703   template <
typename Fun, 
typename Container>
 
  705     fun.postprocess( 
c );
 
  
 
typename Tr::BaseClass BaseClass_t
 
auto operator()(Container &c, Value &&v) const
 
std::enable_if_t< std::is_pointer_v< X >, ptr_t > operator[](size_type i) const
 
std::enable_if_t< std::is_pointer_v< X >, ptr_t > front() const
 
std::add_const_t< std::remove_pointer_t< Container > > val_t
 
const In & operator()(const In *in) const
 
constexpr auto size(const T &, Args &&...) noexcept
 
bool PyHelper() setProperty(IInterface *p, char *name, char *value)
 
std::tuple< details::InputHandle_t< Traits_, In >... > m_inputs
 
DataHandleMixin(std::string name, ISvcLocator *locator, const KeyValue &input, const KeyValue &output)
 
auto get(const ToolHandle< Gaudi::Interface::Bind::IBinder< IFace >> &handle, const Algo &, const EventContext &ctx)
 
std::enable_if_t<!is_optional_v< Arg > > require_is_not_optional
 
GAUDI_API const EventContext & currentContext()
 
bool isReEntrant() const override
 
DataHandleMixin(std::string name, ISvcLocator *locator, const KeyValue &output)
 
Gaudi::cpp17::detected_or_t< detail2::DefaultInputHandle< T >, detail2::InputHandle_t, Tr, T > InputHandle_t
 
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, RepeatValues_< KeyValue, N_out > const &outputs)
 
constexpr struct Gaudi::Functional::details::invoke_optionally_t invoke_optionally
 
std::enable_if_t<!std::is_pointer_v< X >, ref_t > front() const
 
bool isReEntrant() const override
 
auto operator()(Container &c, Value &&v) const -> decltype(c.push_back(v))
 
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, const IArgs &inputs, std::index_sequence< I... >)
 
T back_inserter(T... args)
 
ContainerVector m_containers
 
auto operator()(const Handle< I > &h) -> const In &
 
typename it_t::iterator_category iterator_category
 
std::tuple< details::InputHandle_t< Traits_, In >... > m_inputs
 
void reserve(size_type size)
 
constexpr unsigned int outputLocationSize() const
 
bool isReEntrant() const override
 
typename ContainerVector::size_type size_type
 
decltype(auto) const_range(Args &&... args)
Zips multiple containers together to form a single const range.
 
DataHandleMixin(std::string name, ISvcLocator *locator, RepeatValues_< KeyValue, N_in > const &inputs, const KeyValue &output)
 
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
 
std::enable_if_t<!std::is_pointer_v< X >, ref_t > operator[](size_type i) const
 
friend auto operator-(const iterator &lhs, const iterator &rhs)
 
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, const IArgs &inputs, std::index_sequence< I... >, const OArgs &outputs, std::index_sequence< J... >)
 
auto get_values_helper(std::index_sequence< I... >)
 
std::vector< DataObjID > to_DataObjID(const std::vector< std::string > &in)
 
In operator()(In &&in) const
 
auto operator()(const Handle< Gaudi::Range_< I, IT >> &h) -> const In
 
DataObjectHandle.h GaudiKernel/DataObjectHandle.h.
 
static auto apply(const Algorithm &algo, Handles &handles)
 
Handles make_vector_of_handles(IDataHandleHolder *owner, const std::vector< DataObjID > &init)
 
std::remove_pointer_t< typename Container::value_type > c_remove_ptr_t
 
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, RepeatValues_< KeyValue, N_in > const &inputs, RepeatValues_< KeyValue, N_out > const &outputs)
 
std::enable_if_t<!std::is_pointer_v< X >, ref_t > at(size_type i) const
 
constexpr unsigned int inputLocationSize() const
 
bool check_sizes(const A &a, const B &b, const C &... c) noexcept
Compare sizes of 3 or more containers.
 
void operator()(F &&f, Arg &&arg) const
 
static auto apply(const Algorithm &algo, const EventContext &ctx, Handles &handles)
 
typename Tr::template InputHandle< T > InputHandle_t
 
std::conditional_t< is_tool_v< T >, ToolHandle_t< T >, DataObjectReadHandle< T > > DefaultInputHandle
 
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, const OArgs &outputs, std::index_sequence< J... >)
 
std::conditional_t< is_pointer, ptr_t, val_t > value_type
 
std::enable_if_t< std::is_pointer_v< X >, ptr_t > back() const
 
typename details::detector< Default, void, Op, Args... >::type detected_or_t
 
Base class from which all concrete algorithm classes should be derived.
 
auto applyPostProcessing(const Fun &fun, Container &c) -> decltype(fun.postprocess(c), void())
 
constexpr unsigned int inputLocationSize() const
 
void put(const OutHandle &out_handle, OptOut &&out)
 
static auto apply(const Algorithm &algo, Handles &handles)
 
decltype(std::declval< T >().has_value(), std::declval< T >().value()) is_optional_
 
typename Tr::template OutputHandle< T > OutputHandle_t
 
constexpr struct Gaudi::Functional::details::deref_t deref
 
std::tuple< details::OutputHandle_t< Traits_, Out >... > m_outputs
 
std::enable_if_t< std::is_pointer_v< X >, ptr_t > at(size_type i) const
 
std::enable_if_t< is_optional_v< Arg > > require_is_optional
 
void push_back(T &&container)
 
void updateHandleLocation(DataHandleMixin< Out, In, Tr > &parent, const std::string &prop, const std::string &newLoc)
 
Header file for std:chrono::duration-based Counters.
 
friend bool operator==(const iterator &lhs, const iterator &rhs)
 
std::tuple< details::OutputHandle_t< Traits_, Out >... > m_outputs
 
std::enable_if_t<!std::is_pointer_v< X >, ref_t > back() const
 
bool isReEntrant() const override
 
const In & operator()(const In &in) const
 
typename is_detected< Op, Args... >::type detected_t
 
T * put(std::unique_ptr< T > object) const
Register object in transient store.
 
decltype(auto) verifySizes(Args &... args)
Verify the data container sizes have the same sizes.
 
static auto apply(const Algorithm &algo, const EventContext &ctx, Handles &handles)
 
friend bool operator!=(const iterator &lhs, const iterator &rhs)
 
typename it_t::difference_type difference_type
 
constexpr bool is_optional_v
 
void push_back(Container &c, const Value &v, std::false_type)
 
T & deref_if(T *const t, std::true_type)
 
decltype(get_values_helper< Value >(std::make_index_sequence< N >())) RepeatValues_
 
constexpr unsigned int outputLocationSize() const
 
typename it_t::iterator_category value_type
 
typename it_t::pointer pointer
 
typename ContainerVector::const_iterator it_t
 
void updateHandleLocations(DataHandleMixin< Out, In, Tr > &parent, const std::string &prop, const std::vector< std::string > &newLocs)
 
auto operator()(Container &c, Value &&v) const -> decltype(c.insert(v))
 
std::add_lvalue_reference_t< val_t > ref_t
 
typename it_t::reference reference
 
auto operator()(const Handle< Gaudi::NamedRange_< I, IT >> &h) -> const In
 
Gaudi::cpp17::detected_or_t< Base, detail2::BaseClass_t, Tr > BaseClass_t
 
void printSizes(OS &out, Arg &&arg, Args &&... args)
Print the parameters.
 
typename T::value_type value_type_of_t
 
constexpr static const auto FAILURE
 
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, std::tuple<>={}, std::tuple<>={})
 
std::conditional_t< is_pointer, ptr_t, ref_t > ret_t
 
constexpr struct Gaudi::Functional::details::insert_t insert
 
auto operator()(const Handle< I > &h) -> const In
 
Gaudi::cpp17::detected_or_t< DataObjectWriteHandle< T >, detail2::OutputHandle_t, Tr, T > OutputHandle_t
 
typename filter_evtcontext_t< In... >::type filter_evtcontext
 
DataHandleMixin(std::string name, ISvcLocator *pSvcLocator, RepeatValues_< KeyValue, N_in > const &inputs)
 
vector_of_const_()=default
 
std::add_pointer_t< val_t > ptr_t
 
DataHandleMixin(std::string name, ISvcLocator *locator, const KeyValue &input, RepeatValues_< KeyValue, N_out > const &outputs)
 
decltype(auto) range(Args &&... args)
Zips multiple containers together to form a single range.
 
Stream & ostream_joiner(Stream &os, Iterator first, Iterator last, Separator sep, OutputElement output=OutputElement{})
 
DataHandleMixin(std::string name, ISvcLocator *locator, const KeyValue &input)
 
auto getKey(const Handle &h) -> decltype(h.objKey())
 
std::conditional_t< is_optional_v< T >, Gaudi::cpp17::detected_t< details2::value_type_of_t, T >, T > remove_optional_t
 
bool is_null(size_type i) const