Skip to content

Conversation

nitbharambe
Copy link
Member

@nitbharambe nitbharambe commented Sep 2, 2025

Goals:

  • Clean MainModelImpl of duplicate/repeated templates.
  • Make MainModelImpl Testable for any collection of components.

Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
@nitbharambe nitbharambe self-assigned this Sep 2, 2025
@nitbharambe nitbharambe added the improvement Improvement on internal implementation label Sep 2, 2025
Comment on lines 33 to 37
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...>;
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😮

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very cool!

Comment on lines 208 to 215
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>>{});
}
Copy link
Member

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) {
Copy link
Member Author

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...>> {
Copy link
Member Author

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.

Copy link
Member Author

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)

Copy link
Member

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

Copy link
Member

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% 💯

Copy link
Contributor

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.

Copy link
Member Author

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.

@nitbharambe
Copy link
Member Author

The build/tests seem to fail. I had cleaned up before pushing. Checking issues.

Copy link
Contributor

@figueroa1395 figueroa1395 left a 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.

Comment on lines 58 to 64
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>>;
Copy link
Contributor

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.

Comment on lines 33 to 37
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...>;
};
Copy link
Contributor

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...>> {
Copy link
Contributor

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>
Copy link
Contributor

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?

Comment on lines 54 to 55
using ComponentContainer = Container<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentType...>;
// using MainModelState = main_core::MainModelState<ComponentContainer>;
Copy link
Contributor

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]>
Comment on lines 68 to 69
using ExtraRetrievableTypesTuple = std::tuple<std::type_identity<ExtraRetrievableType>...>;
using ComponentTypesTuple = std::tuple<ComponentType...>;
Copy link
Contributor

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_identitys? Or did you mean using ComponentTypesTuple = std::tuple<std::type_identity<ComponentType>...>;?

Copy link
Member Author

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>...>;
Copy link
Contributor

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 tuples.

Copy link
Member Author

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.

@figueroa1395
Copy link
Contributor

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 std::ranges::to)? Maybe it can be configured correctly? Perhaps #1116 will fix it.

c.c @mgovers

@mgovers
Copy link
Member

mgovers commented Sep 8, 2025

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 std::ranges::to)? Maybe it can be configured correctly? Perhaps #1116 will fix it.

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") {
Copy link
Contributor

@figueroa1395 figueroa1395 Sep 8, 2025

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!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. static_asserts don't need to be in a subcase/test case (because they are static)
  2. only that the main model template itself can be instantiated with arbitrary order, not that the model itself can be correctly created

Copy link
Member Author

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") {
Copy link
Contributor

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?

Copy link
Contributor

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.

Copy link
Member

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_asserts, you'll also have to make the constructor constexpr and actually instantiate

}
};

/////////////////// To remove ///////////////////
Copy link
Member Author

@nitbharambe nitbharambe Sep 9, 2025

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]>
nitbharambe and others added 7 commits September 9, 2025 17:52
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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
improvement Improvement on internal implementation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants