port LHCb MT developments to Gaudi master
among others we have
-
Gaudi::Functional
: base classes to write algorithms as pure functions -
AnyDataWrapper
/AnyDataHandle
: helper to store any type in the Transient Store (DataSvc) - fixes to
DataObjectHandle
- fixes to
GaudiHive
- new tests and examples
- modernization (range loops, removed empty destructors, ...)
Merge request reports
Activity
This is the same as !240 (closed), needed to fix the problem with the changes view (see INC1210087).
669 669 Gaudi::Property<std::vector<std::string>> m_requireObjs{ 670 670 this, "RequireObjects", {}, "execute only if one or more of these TES objects exist"}; 671 671 // ========================================================================== 672 673 public: 674 using Algorithm::declareProperty; 675 template <class T> 676 Gaudi::Details::PropertyBase* declareProperty( const std::string& name, DataObjectHandle<T>& hndl, you should end up automatically in the proper hook.
With the new implementation, if you have
class MyAlg: ... { DataObjectHandle<MyTracks> m_tracks{"path", Gaudi::DataHandle::Reader, this}; MyAlg(...) { declareProperty("Tracks", m_tracks); } };
it will call
PropertyHolder::declareProperty(const std::string& name, DataObjectHandleBase& ref)
.Note that the main problem, probably, is that now you must instantiate a
DataObjectHandle
with a pointer to an owner (and that will take care of the registration to the input/output lists.The next iteration shuold be that
DataObjectHandle<MyTracks> m_tracks{"path", Gaudi::DataHandle::Reader, this};
implies a call todeclareProperty
.Edited by Marco Clemencic
Thanks for re-opening. Yes, removing ranges as said in !240 (closed) would be great.
Validation started with lhcb-gaudi-merge#89
Mentioned in commit dc1b505f
Marco -
I've finally had a chance to test this against Atlas code, as I've spent the last 6 weeks trying to recover from the utter and complete clusterf*ck that was the seemingly benign "const ToolHandle enforcement" merge, and this also breaks Atlas code, as in our AthAlgTool and AthAlgorithm classes, when we override declareProperty for VarHandles (which inherit from DataHandle), we do a this->declareInput(handle), which is now gone.
What are we supposed to do in its place?
Algorithm
inherits fromIDataHandleHolder
which providesdeclare
-- so you should be be able to replacethis->declareInput(handle)
withthis->declare(handle)
; and behind the scenes this figures out whether theDataHandle
passed is either input or output, and it does the right thing accordingly.Edited by Gerhard Raven596 589 "flag to enforce the registration for Algorithm Context Service"}; 597 590 598 591 Gaudi::Property<bool> m_isClonable{this, "IsClonable", false, "thread-safe enough for cloning?"}; 599 Gaudi::Property<int> m_cardinality{this, "Cardinality", 1, "how many clones to create"}; 592 Gaudi::Property<int> m_cardinality{this, "Cardinality", 1, "how many clones to create - 0 means algo is reentrant"}; A long time ago, we decided that we would have a different inheritance structure for reentrant Algs, as detailed in !177 (closed) , so we don't actually want to check the cardinality of the Algs, especially in the AlgResourcePool, but rather check the isReEntrant() method.
That's where we should be going, but that is a quite an invasive change... so until then, this is quick way to support our migration to
Gaudi::Functional
as we haven't even migrated away fromGaudiAlgorithm
yet -- which we should do first, but that requires eg. all calls totool<T>
to be replaced byToolHandle<T>
which is on-going, but not yet finished...
@graven : the DataHandle::setOwner method is also gone. How is the Algorithm supposed to set the ownership of the handle now?
No, it's an invariant of the DataHandle that it has an owner, thus that ought to be established at construction, i.e. the constructor should construct an object in a valid state. What would/could you do with a DataHandle without owner? (and doing it this way avoids having code in the body of the constructor, and thus allows one to inherit the constructor from the baseclass, and thus have less boiler plate, and giving developers less chance of doing something wrong)
Edited by Gerhard Ravensee http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#a-namerc-ctorac40-define-a-constructor-if-a-class-has-an-invariant and http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#a-namerc-completeac41-a-constructor-should-create-a-fully-initialized-object and http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#a-namerc-defaultac45-dont-define-a-default-constructor-that-only-initializes-data-members-use-in-class-member-initializers-instead and http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#a-namerc-inheritingac52-use-inheriting-constructors-to-import-constructors-into-a-derived-class-that-does-not-need-further-explicit-initialization
If it's required at construction time, why is it an optional argument?
Also, we need to remember that we're not coding in a vacuum. In the end, there are lots of people who are going to use this code, and it's more important for us to make it easy to use, than to follow abstract coding guidelines. Here you're forcing every user to do a lot more work, with more opportunities for error (what if they forget to pass the this?), when instead it can be removed from their hands entirely. If every user has to do tons of extra, identical work, but we have a way of doing this work for them, then we SHOULD make their lives easier.
No problem in making it a required argument - if there is no corner case that would be killed by it. And that would make things entirely fool-proof. Because then I cannot forget anything w/o the compiler complaining.
Don't forget - the existing approach requires the user to call Algorithm::declare... explicitly within the constructor body. So in fact the current situation forces them to do some work - without any possiblity for checking.
Thus we are making the life of people easier in the end.
Good point -- owner should not be an optional argument, that's for historical reasons.. see !258 (closed)