-
Notifications
You must be signed in to change notification settings - Fork 43
Cleanup main model: Clean up templates and variadics #1109
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
base: main
Are you sure you want to change the base?
Cleanup main model: Clean up templates and variadics #1109
Conversation
Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
template <typename Tuple> struct tuple_type_identities_to_tuple_types; | ||
|
||
template <typename... Ts> struct tuple_type_identities_to_tuple_types<std::tuple<std::type_identity<Ts>...>> { | ||
using type = std::tuple<Ts...>; | ||
}; |
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.
😮
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.
This is very cool!
template <typename Tuple, std::size_t... Is> | ||
void register_all_components_impl(auto const& components, ComponentTopology& comp_topo, std::index_sequence<Is...>) { | ||
(detail::register_topology_components<std::tuple_element_t<Is, Tuple>>(components, comp_topo), ...); | ||
} | ||
|
||
template <typename Tuple> void register_all_components(auto const& components, ComponentTopology& comp_topo) { | ||
register_all_components_impl<Tuple>(components, comp_topo, std::make_index_sequence<std::tuple_size_v<Tuple>>{}); | ||
} |
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.
awesome
(detail::register_topology_components<std::tuple_element_t<Is, Tuple>>(components, comp_topo), ...); | ||
} | ||
|
||
template <typename Tuple> void register_all_components(auto const& components, ComponentTopology& comp_topo) { |
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.
We can have a common run_functor_with_tuple too.
template <class T, class U> struct MainModelType; | ||
|
||
template <class... ExtraRetrievableType, class... ComponentType> | ||
struct MainModelType<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentList<ComponentType...>> { |
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.
A struct which should contain all information about the MainModel being created.
The above utilities can be incorporated here as well.
One downside is the addition of typename
at many places since this is a struct.
Also this is start of the experiment, it might be possible to clean up or come up with different ways altogether.
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.
For future reference: We also have similar utility of get_cls_pos in container (Which is not container specific). They can be combined. (Also I read addressing via tuple is better than recursive)
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.
One downside is the addition of typename at many places since this is a struct.
for most standard library objects, foo_t
is a shorthand for typename foo::type
. maybe that can clean up that part a little bit? I personally am not really concerned about the amount of typenames
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.
Also I read addressing via tuple is better than recursive
100% 💯
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.
I don't mind this at all, I actually find it very neat.
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.
for most standard library objects, foo_t is a shorthand for typename foo::type. maybe that can clean up that part a little bit? I personally am not really concerned about the amount of typenames
I meant in the usage that we see in main_model_impl.hpp. We have typename MainModelType::SequenceIdx
.
But now that the changes are done, I dont see it cluttering a lot.
The build/tests seem to fail. I had cleaned up before pushing. Checking issues. |
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.
I really like where this PR is going :). Very good ideas here.
using TopologyTypesTuple = | ||
std::tuple<std::type_identity<Node>, std::type_identity<Branch>, std::type_identity<Branch3>, | ||
std::type_identity<Source>, std::type_identity<Shunt>, std::type_identity<GenericLoadGen>, | ||
std::type_identity<GenericVoltageSensor>, std::type_identity<GenericPowerSensor>, | ||
std::type_identity<GenericCurrentSensor>, std::type_identity<Regulator>>; | ||
// using TopologyConnectionTypes = std::tuple<std::type_identity<Branch>, std::type_identity<Branch3>, | ||
// std::type_identity<Source>>; |
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.
Just a thought, but since this is very verbose/explicit, maybe it can be code generated so we don't forget to add stuff manually here. Or somehow link it to a list elsewhere, so we have only one explicit list, like in all_components.hpp
. Just a thought for later cleanup.
template <typename Tuple> struct tuple_type_identities_to_tuple_types; | ||
|
||
template <typename... Ts> struct tuple_type_identities_to_tuple_types<std::tuple<std::type_identity<Ts>...>> { | ||
using type = std::tuple<Ts...>; | ||
}; |
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.
This is very cool!
template <class T, class U> struct MainModelType; | ||
|
||
template <class... ExtraRetrievableType, class... ComponentType> | ||
struct MainModelType<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentList<ComponentType...>> { |
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.
I don't mind this at all, I actually find it very neat.
@@ -205,23 +205,24 @@ constexpr void register_connections_components(ComponentContainer components, Co | |||
[](Source const& source) { return source.status(); }); | |||
} | |||
|
|||
template <typename Tuple, std::size_t... Is> |
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.
Nitpick: Can you rename Is
to something more expresive?
using ComponentContainer = Container<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentType...>; | ||
// using MainModelState = main_core::MainModelState<ComponentContainer>; |
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.
Maybe these two (included the commented out line) can potentially be used "more" in main_model_impl.hpp
to clean it up a bit (there is some "duplication" in the other file now); just like it is done with MainModelType
.
Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
power_grid_model_c/power_grid_model/include/power_grid_model/main_core/core_utils.hpp
Outdated
Show resolved
Hide resolved
using ExtraRetrievableTypesTuple = std::tuple<std::type_identity<ExtraRetrievableType>...>; | ||
using ComponentTypesTuple = std::tuple<ComponentType...>; |
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.
Should we make a distinction in the naming when something is just a tuple
or a tuple
of std::type_identity
s? Or did you mean using ComponentTypesTuple = std::tuple<std::type_identity<ComponentType>...>;
?
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.
The alias here are the ones which shall be used outside. Ive changed the rest to *_ values signifying private members (and added private specifier too).
// _AllTypesTupleUnique = typename tuple_type_identities_to_tuple_types<decltype(filter_tuple_types( | ||
// _TopologyTypesTuple{}, _AllTypesTuple{}))>::type; | ||
|
||
using _ComponentTypesTuple = std::tuple<std::type_identity<ComponentType>...>; |
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.
This and around, tied to f717e8c#r2329356329. Maybe _*
is not descriptive enough when using std::type_identity
in the tuple
s.
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.
Marked them with private. They are named only to make the logic clear.
It looks like Sonar isn't identifying c++23 https://github.com/PowerGridModel/power-grid-model/actions/runs/17494449107/job/49691592601?pr=1109 (see complain about c.c @mgovers |
that's exactly the intention of #1116 indeed 😬 |
static_assert(std::is_same_v<typename ModelType::TopologyConnectionTypesTuple, std::tuple<Branch, Source>>); | ||
static_assert(ModelType::n_component_types == 3); | ||
} | ||
SUBCASE("Different component order: Line Source Node") { |
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.
So this one proves with the current implementation, the order doesn't matter, right? awesome!
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.
static_assert
s don't need to be in a subcase/test case (because they are static)- only that the main model template itself can be instantiated with arbitrary order, not that the model itself can be correctly created
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.
static_asserts don't need to be in a subcase/test case (because they are static)
True. I understand that the subcase/test case is redundant here. Intention was to classify them instead of plain statements because I thought there would be way too many. What would be the way to go about classification?
static_assert(std::is_same_v<typename ModelType::TopologyConnectionTypesTuple, std::tuple<Branch, Source>>); | ||
static_assert(ModelType::n_component_types == 3); | ||
} | ||
SUBCASE("Bad case: Line Source") { |
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.
Shouldn't this fail already as Node
isn't present? shouldn't the model be not "constructible" according to our discussions?
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.
I suppose the answer to this is related to #1109 (comment) item 2? It is still fine to instantiate this, but now we have to show that it can't be constructed? Would it be possible to make it fail at this stage, would that be desirable? I would guess so.
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.
this is about whether the type is valid, not about whether the code actually works. if you want to make this static_assert
s, you'll also have to make the constructor constexpr
and actually instantiate
Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
} | ||
}; | ||
|
||
/////////////////// To remove /////////////////// |
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.
The usage of these utils with ComponentTypes...
is for now (and mostly in future) limited only to ComponentTypes. So nice to just move them inside.
Signed-off-by: Nitish Bharambe <[email protected]>
…experiment Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
Goals: