-
Notifications
You must be signed in to change notification settings - Fork 228
Umbrella strategies. #726
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
Umbrella strategies. #726
Conversation
0d78c07 to
c8eb74c
Compare
vissarion
left a comment
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.
Thanks I am ok with the design!
I am not sure that I understand the need of two interfaces, one with algorithm specific strategies and one for all algorithms.
I have also 2 proposals which I'd like to discuss along with this:
* removal of spherical-polar CS and making `spherical` CS an alias of `spherical_equatorial` * the rationale for this proposal is that the support for this CS is limited anyway, there are no users requesting an improvement in this area, and that if a user had data in this CS he/she could simply implement get/access converting to `spherical_equatorial` on the fly.
I strongly agree.
* including strategies for an algorithm automatically, together with the algorithm * this is in order to be conformant with the boost header policy. AFAIU if a user includes an algorithm this algorithm should compile. Our default strategy design prevents that because the user also has to include the default strategy for a coordinate system, he/she has to know which strategy is the default one which is not clear so I think in practice means that either the main `geometry.hpp` or all of the `strategies.hpp` are included anyway. Plus I don't understand what is the reason behind separating algorithms from strategies. AFAIU the compilation time is mostly affected when templates are actually instantiated and adding more files for parsing doesn't change much. This could be tested if needed because this is only my informed guess.
I am not sure that I understand this question clearly, is it ok for all algorithms to just include the headers of the respective default strategies?
It's the same interface. The difference is the one umbrella strategy groups strategies that are used only by one algorithm. And the other umbrella strategy groups strategies that are used by all algorithms. So if you were using only one algorithm you could #include only this one algorithm and umbrella strategy for only this one algorithm. Buf if you used more algorithms at the same time you could #include the whole library and create only one strategy for all of them and e.g. keep it somewhere and reuse it everywhere. |
Currently the only thing that is included by an algorithm is non-specialized So currently this will compile: But if you add the following line the code will not compile even though the algorithm is included: even though the algorithm is included and any strategy is not created nor used explicitly by the user. The user would also have to include even though no strategy is created in the user's code: So for each algorithm the users has to know which strategy is the default one for the coordinate system they're using and include it. |
21aa1ce to
0516e1a
Compare
|
To give you a better overview of the design of umbrella strategies I decided to implement it for one more algorithm, i.e. |
| apply(boost::begin(multirange), boost::end(multirange), mbr, strategy); | ||
| using range_t = typename boost::range_value<MultiRange>::type; | ||
| using strategy_t = decltype(strategy.envelope(std::declval<range_t>(), mbr)); | ||
| using state_t = typename strategy_t::template multi_state<Box>; |
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 new approach uses C++14 - OK for me.
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, though this particular part is C++11.
I think the only thing from C++14 I used is auto return type in umbrella strategies.
Another thing I could use is type_traits's template aliases, so e.g. std::enable_if_t instead of std::enable_if, but for now I'm using C++11 versions.
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'm fine with either - but is there a particular reason to use the C++11 version here?
| Strategy::apply(point, mbr); | ||
| // strategy.envelope(point, mbr).apply(point, mbr); | ||
| using strategy_t = decltype(strategy.envelope(point, mbr)); | ||
| strategy_t::apply(point, mbr); |
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.
It looks good.
But this way strategy state is lost. That might of course be solveable, but it might be good to have an example of that.
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, I simply replaced the already existing line. It was and it is implemented like that because in case of points the only information that is needed is the CS because envelope for points doesn't use radius nor ellipsoid. But yes, if we want to be fully correct then the line that is currently commented out should be used instead.
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 tested with area and indeed, the strategy is not lost, so it works really well
OK for me, we can do that right away I think. It's not really related to this strategy topic.
Thanks for this and the explanation, yes, I think that will be an improvement. So I agree with that. I would like to play with this new approach next week, can you create a complete version? I already downloaded a patch but it is incomplete now. No problem, because I was busy with my other patch today, but next week I would like to dive a bit more into this. Thanks for the start, looks promising! |
|
@barendgehrels Ok, I'll polish it, make sure that the full library compiles. I'll also add implementation for |
Thank you! |
6373cb4 to
61859cf
Compare
|
@barendgehrels Ok, done. The library compiles. Umbrella strategies are backward compatible. There are some temporary parts gluing old and new strategies. |
| geometry::strategies::area::services::strategy_converter | ||
| < | ||
| Strategy | ||
| >::get(strategy)), |
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 know why but it seems my IDE put tabs instead of spaces. I'll fix it tomorrow. And btw you can see here how to convert simple strategy to umbrella strategy if needed.
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.
OK, no problem - and indeed, I notice the converter, really convenient
| geometry::strategies::area::services::strategy_converter | ||
| < | ||
| decltype(strategy.get_area_strategy()) | ||
| >::get(strategy.get_area_strategy())); |
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.
Here is another place. Note decltype instead of getting the type from the strategy type.
@awulkiew great, thanks a lot for preparing this, appreciated! |
|
Although I did not really review the code, but I was tracking the discussion and I like the idea. It solves real issues. |
barendgehrels
left a comment
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 love it! So I approve right away (though I realize it still need some minor changes such as TEMP comments - but those will come).
I played with it, passing the umbrella strategy and passing individual strategies and passing a geographic strategy with another spheroid model, and these all works well - it also takes over the model correctly (I actually didn't expect that already - so: great).
I understand how it works, broadly, and agree with the approach.
And the mainline is: this is a big improvement above the previous approach without the umbrella. Really good and I think we can extend this to all strategies we need in all our code.
Well done! 👍 👍
| geometry::strategies::area::services::strategy_converter | ||
| < | ||
| Strategy | ||
| >::get(strategy)), |
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.
OK, no problem - and indeed, I notice the converter, really convenient
| Strategy::apply(point, mbr); | ||
| // strategy.envelope(point, mbr).apply(point, mbr); | ||
| using strategy_t = decltype(strategy.envelope(point, mbr)); | ||
| strategy_t::apply(point, mbr); |
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 tested with area and indeed, the strategy is not lost, so it works really well
| apply(boost::begin(multirange), boost::end(multirange), mbr, strategy); | ||
| using range_t = typename boost::range_value<MultiRange>::type; | ||
| using strategy_t = decltype(strategy.envelope(std::declval<range_t>(), mbr)); | ||
| using state_t = typename strategy_t::template multi_state<Box>; |
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'm fine with either - but is there a particular reason to use the C++11 version here?
| Strategy::apply(box_out, box_in); | ||
| // strategy.expand(box_out, box_in).apply(box_out, box_in); | ||
| using strategy_t = decltype(strategy.expand(box_out, box_in)); | ||
| strategy_t::apply(box_out, box_in); |
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.
In the past I opposed to the _t suffix, but I'm OK with it now. It's standard. No objection.
61859cf to
c525dae
Compare
|
Thanks for the reviews! I'm glad you're ok with the PR. I don't consider it to be ready to be merged yet. I only wanted to get your feedback if you agree with the approach. It needs more polishing. Regarding your question @barendgehrels:
I also fixed the tabs. This is why I'm answering here to your question. |
c525dae to
e8b2d3b
Compare
a97aff3 to
97c657d
Compare
97c657d to
e63d0be
Compare
e63d0be to
a5b46d0
Compare
|
@barendgehrels @mloskot I'm currently relocating the old and new strategies and I'm wondering about the reason for inconsistency of namespaces and directory structure. Do you remember what is the reason for:
@barendgehrels @vissarion @mloskot I'm thinking about moving existing strategies to directory |
I am ok with both, slightly prefer the latter maybe because I have used to that structure of files. |
Yes, you can make it consistent - and I understand you need to discern old and new and can use the other (which should then probably be our final choice). I'm OK either way, and at this moment I don't remember how it became like it was now - but consistent is fine, thanks for the efforts. |
I'm more concerned about the namespaces because my guess is that the users typically don't see the directory structure. They include the whole library and don't care where the files are actually located. I think we should pick the better hierarchy of namespaces taking into account that there could be several strategies for the same algorithm and CS. And only after that when we know which one would be better put the files in the corresponding directories. |
|
@vissarion @barendgehrels I think it makes more sense to group strategies first by algorithm and then by CS, so as it is now. It allows to have nicely named strategies for all algorithms as I mentioned earlier, so e.g.: An alternative would be to first group by CS ( From these two I prefer the former because the naming is consistent and clear. And this means that the directory structure would be adapted to this namespace structure. Unless you have a different idea or see something I do not? |
|
I do not have any objections, the first choice seems fine. |
2ec84d8 to
8d77196
Compare
|
Ok, I relocated the strategies:
So the structure is slightly different than it was. As I mentioned some time ago I propose to include files containing default strategies for all coordinate systems with corresponding algorithms so e.g. the user including Alternatively we could consider adding include files for algorithms in Another issue. When I moved the old strategies I preserved the old directory structure. However I could also change it to match the namespaces like I did with umbrella |
8d77196 to
e839ff4
Compare
e839ff4 to
52cceae
Compare
I am OK.
OK with living it as is for now.
I am OK with the old structure. |
|
Thanks for reviews. I'll merge it now so we can start testing it. If needed I'll make changes afterwards. |
Followup of issue #717.
I prepared a preliminary version of umbrella strategies for
area()algorithm. The purpose is to use this simple example to discuss whether or not you agree with the approach at the early stage, agree about naming conventions, etc.The current design allows to
bg::strategies::area, e.g.bg::strategies::area::cartesian<>bg::strategies, e.g.bg::strategies::spherical<>bg::strategy::area, e.g.bg::strategy::area::geographic<>, which is converted to umbrella strategy and passed toarea()For now I placed the umbrella strategies in the separate directory
strategies2. Later I think both directories could be merged preserving backward compatibility of includes.I have also 2 proposals which I'd like to discuss along with this:
sphericalCS an alias ofspherical_equatorialspherical_equatorialon the fly.geometry.hppor all of thestrategies.hppare included anyway. Plus I don't understand what is the reason behind separating algorithms from strategies. AFAIU the compilation time is mostly affected when templates are actually instantiated and adding more files for parsing doesn't change much. This could be tested if needed because this is only my informed guess.