Skip to content
Snippets Groups Projects
Commit 49c12028 authored by Marco Clemencic's avatar Marco Clemencic
Browse files

Merge branch 'allow-algorithm-as-functional-base' into 'master'

Allow Algorithm as baseclass of Gaudi::Functional algorithms

See merge request !326
parents 878c38fa 12306059
No related branches found
No related tags found
1 merge request!326Allow Algorithm as baseclass of Gaudi::Functional algorithms
Pipeline #
......@@ -10,6 +10,7 @@
#include "GaudiKernel/DataObjectHandle.h"
#include "GaudiKernel/AnyDataHandle.h"
#include "GaudiKernel/GaudiException.h"
#include "GaudiKernel/Algorithm.h"
#include "GaudiAlg/GaudiAlgorithm.h"
// Boost
......@@ -300,13 +301,10 @@ namespace Gaudi { namespace Functional { namespace details {
return std::make_tuple( element_t<I,Tuple>{std::get<I>(initvalue).second, m, o} ... );
}
template <typename KeyValues, typename Properties, std::size_t... I>
void declare_tuple_of_properties_helper(GaudiAlgorithm* owner, const KeyValues& inputs, Properties& props, std::index_sequence<I...>) {
// note: be very careful here! Only GaudiAlgorithm has a declareProperty that works with a DataObjectHandleBase.
// However, Algorithm does have a template that also matches (unless it is constrained explicitly against matching)
// so if 'owner' is of type Algorithm instead of GaudiAlgortihm, this ends up calling the wrong declareProperty...
void declare_tuple_of_properties_helper(Algorithm& owner, const KeyValues& inputs, Properties& props, std::index_sequence<I...>) {
(void) std::initializer_list<int>{
( owner->declareProperty( std::get<I>(inputs).first,
std::get<I>(props) ),0)...
( owner.declareProperty( std::get<I>(inputs).first,
std::get<I>(props) ),0)...
};
}
}
......@@ -317,9 +315,9 @@ namespace Gaudi { namespace Functional { namespace details {
}
template <typename KeyValues, typename Properties>
void declare_tuple_of_properties(GaudiAlgorithm* owner, const KeyValues& inputs, Properties& props) {
static_assert( std::tuple_size<KeyValues>::value == std::tuple_size<Properties>::value, "Inconsistent lengths" );
void declare_tuple_of_properties(Algorithm& owner, const KeyValues& inputs, Properties& props) {
constexpr auto N = std::tuple_size<KeyValues>::value;
static_assert( N == std::tuple_size<Properties>::value, "Inconsistent lengths" );
details2::declare_tuple_of_properties_helper( owner, inputs, props, std::make_index_sequence<N>{} );
}
......@@ -339,8 +337,8 @@ namespace Gaudi { namespace Functional { namespace details {
template <typename... Out, typename... In, typename Traits_>
class DataHandleMixin<std::tuple<Out...>, std::tuple<In...>,Traits_> : public BaseClass_t<Traits_> {
static_assert( std::is_base_of<GaudiAlgorithm, BaseClass_t<Traits_>>::value,
"BaseClass must inherit from GaudiAlgorithm");
static_assert( std::is_base_of<Algorithm, BaseClass_t<Traits_>>::value,
"BaseClass must inherit from Algorithm");
public:
using KeyValue = std::pair<std::string, std::string>;
constexpr static std::size_t N_in = sizeof...(In);
......@@ -348,14 +346,14 @@ namespace Gaudi { namespace Functional { namespace details {
// generic constructor: N -> M
DataHandleMixin(const std::string& name, ISvcLocator* pSvcLocator,
const std::array<KeyValue,N_in>& inputs,
const std::array<KeyValue,N_out>& outputs)
const std::array<KeyValue,N_in>& inputs,
const std::array<KeyValue,N_out>& outputs)
: BaseClass_t<Traits_>( name , pSvcLocator ),
m_inputs( make_tuple_of_handles<decltype(m_inputs)>( this, inputs, Gaudi::DataHandle::Reader ) ),
m_outputs( make_tuple_of_handles<decltype(m_outputs)>( this, outputs, Gaudi::DataHandle::Writer ) )
{
declare_tuple_of_properties( this, inputs, m_inputs );
declare_tuple_of_properties( this, outputs, m_outputs );
declare_tuple_of_properties( *this, inputs, m_inputs );
declare_tuple_of_properties( *this, outputs, m_outputs );
// make sure this algorithm is seen as reentrant by Gaudi
BaseClass_t<Traits_>::setProperty("Cardinality", 0);
}
......@@ -395,8 +393,8 @@ namespace Gaudi { namespace Functional { namespace details {
template <typename... In, typename Traits_>
class DataHandleMixin<void, std::tuple<In...>,Traits_> : public BaseClass_t<Traits_> {
static_assert( std::is_base_of<GaudiAlgorithm, BaseClass_t<Traits_>>::value,
"BaseClass must inherit from GaudiAlgorithm");
static_assert( std::is_base_of<Algorithm, BaseClass_t<Traits_>>::value,
"BaseClass must inherit from Algorithm");
public:
using KeyValue = std::pair<std::string, std::string>;
constexpr static std::size_t N_in = sizeof...(In);
......@@ -407,7 +405,7 @@ namespace Gaudi { namespace Functional { namespace details {
: BaseClass_t<Traits_>( name , pSvcLocator ),
m_inputs( make_tuple_of_handles<decltype(m_inputs)>( this, inputs, Gaudi::DataHandle::Reader ) )
{
declare_tuple_of_properties( this, inputs, m_inputs );
declare_tuple_of_properties( *this, inputs, m_inputs );
// make sure this algorithm is seen as reentrant by Gaudi
BaseClass_t<Traits_>::setProperty("Cardinality", 0);
}
......@@ -429,8 +427,8 @@ namespace Gaudi { namespace Functional { namespace details {
template <typename... Out, typename Traits_>
class DataHandleMixin<std::tuple<Out...>, void,Traits_> : public BaseClass_t<Traits_> {
static_assert( std::is_base_of<GaudiAlgorithm, BaseClass_t<Traits_>>::value,
"BaseClass must inherit from GaudiAlgorithm");
static_assert( std::is_base_of<Algorithm, BaseClass_t<Traits_>>::value,
"BaseClass must inherit from Algorithm");
public:
using KeyValue = std::pair<std::string, std::string>;
constexpr static std::size_t N_out = sizeof...(Out);
......@@ -441,7 +439,7 @@ namespace Gaudi { namespace Functional { namespace details {
: BaseClass_t<Traits_>( name , pSvcLocator ),
m_outputs( make_tuple_of_handles<decltype(m_outputs)>( this, outputs, Gaudi::DataHandle::Writer ) )
{
declare_tuple_of_properties( this, outputs, m_outputs );
declare_tuple_of_properties( *this, outputs, m_outputs );
// make sure this algorithm is seen as reentrant by Gaudi
BaseClass_t<Traits_>::setProperty("Cardinality", 0);
}
......
......@@ -4,47 +4,44 @@
#include <GaudiAlg/Transformer.h>
#include <GaudiKernel/MsgStream.h>
namespace Gaudi { namespace Examples {
class IntDataProducer : public Gaudi::Functional::Producer<int()> {
public:
using BaseClass_t = Gaudi::Functional::Traits::BaseClass_t<Algorithm>;
struct IntDataProducer : Gaudi::Functional::Producer<int(),BaseClass_t> {
IntDataProducer(const std::string& name, ISvcLocator* svcLoc)
: Producer( name, svcLoc,
KeyValue("OutputLocation", {"MyInt"})) {}
KeyValue("OutputLocation", "MyInt")) {}
int operator()() const override {
info() << "executing IntDataProducer, storing 7 into " << outputLocation() << endmsg;
return 7;
}
};
DECLARE_COMPONENT(IntDataProducer)
class IntDataConsumer : public Gaudi::Functional::Consumer<void(const int&)> {
public:
struct IntDataConsumer : Gaudi::Functional::Consumer<void(const int&),BaseClass_t> {
IntDataConsumer(const std::string& name, ISvcLocator* svcLoc)
: Consumer( name, svcLoc,
KeyValue("InputLocation", {"MyInt"})) {}
KeyValue("InputLocation", "MyInt")) {}
void operator()(const int& input) const override {
info() << "executing IntDataConsumer, consuming " << input
<< " from " << inputLocation() << endmsg;
}
};
DECLARE_COMPONENT(IntDataConsumer)
class IntToFloatData : public Gaudi::Functional::Transformer<float(const int&)> {
public:
struct IntToFloatData : Gaudi::Functional::Transformer<float(const int&), BaseClass_t> {
IntToFloatData(const std::string& name, ISvcLocator* svcLoc)
: Transformer(name, svcLoc,
KeyValue("InputLocation", {"MyInt"}),
KeyValue("OutputLocation", {"MyFloat"})) {}
KeyValue("InputLocation", "MyInt"),
KeyValue("OutputLocation", "MyFloat")) {}
float operator() (const int& input) const override {
info() << "Converting: " << input << " from " << inputLocation()
......@@ -56,7 +53,7 @@ public:
DECLARE_COMPONENT(IntToFloatData)
class IntIntToFloatFloatData : public Gaudi::Functional::MultiTransformer
<std::tuple<float, float>(const int&, const int&)> {
<std::tuple<float, float>(const int&, const int&), BaseClass_t> {
public:
IntIntToFloatFloatData(const std::string& name, ISvcLocator* svcLoc)
: MultiTransformer(name, svcLoc,
......@@ -78,11 +75,11 @@ public:
DECLARE_COMPONENT(IntIntToFloatFloatData)
class FloatDataConsumer : public Gaudi::Functional::Consumer<void(const float&)> {
public:
struct FloatDataConsumer : Gaudi::Functional::Consumer<void(const float&), BaseClass_t> {
FloatDataConsumer(const std::string& name, ISvcLocator* svcLoc)
: Consumer( name, svcLoc,
KeyValue("InputLocation", {"MyFloat"})) {}
KeyValue("InputLocation", "MyFloat")) {}
void operator()(const float& input) const override {
info() << "executing FloatDataConsumer: " << input << endmsg;
......@@ -91,5 +88,3 @@ public:
DECLARE_COMPONENT(FloatDataConsumer)
}}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment