-
Notifications
You must be signed in to change notification settings - Fork 157
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat!: Use strong types for context objects #673
feat!: Use strong types for context objects #673
Conversation
Move away from using a raw typedef to std::any. Doing that has certain drawbacks: std::any can be convert constructed from anything. This causes problems when constructing anything that only accepts a context any. GCC9 even has recursion trouble in the type_traits infrastructure leading to compile time failures. Moving to wrappers can alleviate this. They only have an explicit constructor, meaning that they are not autoconstructed by conversion. This is a little bit more cumbersome to use, but much more robust I believe. Performance should not be affected.
Codecov Report
@@ Coverage Diff @@
## master #673 +/- ##
==========================================
+ Coverage 49.06% 49.08% +0.01%
==========================================
Files 329 330 +1
Lines 16438 16443 +5
Branches 7657 7657
==========================================
+ Hits 8066 8071 +5
Misses 2998 2998
Partials 5374 5374
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
I approve, nice work Paul! Let's wait for the CI and merge then. |
I think I'm actually going to implement @benjaminhuth's suggestion before we merge this. |
Ok, I switched to an access method, and don't expose the |
@@ -84,7 +84,7 @@ inline const Acts::Transform3& AlignedDetectorElement::transform( | |||
// Check if a different transform than the nominal exists | |||
if (m_alignedTransforms.size()) { | |||
// cast into the right context object | |||
auto alignContext = std::any_cast<ContextType>(gctx); | |||
auto alignContext = gctx.get<ContextType>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, looks better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re-approving.
Move away from using a raw typedef to std::any. Doing that has certain drawbacks: std::any can be convert constructed from anything. This causes problems when constructing anything that only accepts a context any. GCC9 even has recursion trouble in the type_traits infrastructure leading to compile time failures. Moving to wrappers can alleviate this. They only have an explicit constructor, meaning that they are not autoconstructed by conversion. This is a little bit more cumbersome to use, but much more robust I believe. Performance should not be affected. Previously, to break the problems of converting constructors with a single std::any argument, we resorted to std::reference_wrapper<std::any>, which only resolved it to some degree. This PR also removes this workaround. std::reference_wrapper<const {Geometry,MagneticField}Context> is still retained when used to store a context reference as a member, as for example in the stepper state. BREAKING CHANGE: The public interface of the geometry and magnetic context type change. Before, they were raw std::anys, now they are of type Acts::ContextType. Construction needs to be explicit, and the contained std::any can be accessed via the Acts::ContextType::get() methods. std::any_cast to unpack the concrete context value is still supported, but needs to retrieve the internal std::any first. NOTE: If you forget to call .any() on the context object, std::any_cast will compile, but will throw std::bad_any_cast at runtime.
Move away from using a raw typedef to std::any. Doing that has certain drawbacks: std::any can be convert constructed from anything. This causes problems when constructing anything that only accepts a context any. GCC9 even has recursion trouble in the type_traits infrastructure leading to compile time failures.
Moving to wrappers can alleviate this. They only have an explicit constructor, meaning that they are not autoconstructed by conversion. This is a little bit more cumbersome to use, but much more robust I believe.
Performance should not be affected.
Previously, to break the problems of converting constructors with a single
std::any
argument, we resorted tostd::reference_wrapper<std::any>
, which only resolved it to some degree. This PR also removes this workaround.std::reference_wrapper<const {Geometry,MagneticField}Context>
is still retained when used to store a context reference as a member, as for example in the stepper state.BREAKING CHANGE: The public interface of the geometry and magnetic context type change. Before, they were raw
std::any
s, now they are of typeActs::ContextType
. Construction needs to be explicit, and the containedstd::any
can be accessed via theActs::ContextType::get()
methods.std::any_cast
to unpack the concrete context value is still supported, but needs to retrieve the internalstd::any
first. NOTE: If you forget to call.any()
on the context object,std::any_cast
will compile, but will throwstd::bad_any_cast
at runtime.