Repository navigation
Conversation
teor2345
left a comment
There was a problem hiding this comment.
Today I updated the PR template to make it clear that all overloads need to be covered, so I updated this PR's description to match it. I also fixed the GitHub checklist formatting.
For this class constructor, there are many overloads, so we can just wrap the ones that are more likely to conflict.
No need to add any more overloaded methods, the constructor and the insert method have enough overloads.
| StdUnorderedMultiset::from_slice(items) | ||
| } | ||
|
|
||
| pub fn new(a: T, b: T) -> StdUnorderedMultiset { |
There was a problem hiding this comment.
To check that an overload set works in Rust, we need to wrap all of the C++ constructor overloads.
There are 14 constructor overloads in C++, excluding overloads that only differ by an allocator argument:
https://en.cppreference.com/cpp/container/unordered_multiset/unordered_multiset
That's a lot of overloads, so you don't have to implement them all. Instead, pick overloads that are very different from each other. For example, you could add one overload starting with these arguments:
- bucket_count
- unordered_multiset
- from_range_t
It would also be interesting to use C++ default arguments to call an overload with just one argument of type:
- hash
- key_equal
This would be enough to cover the constructor overload set reasonably well.
Please document the lack of default argument values in Rust as a limitation.
| overload! { | ||
| impl StdUnorderedMultiset { | ||
| /// Insert a single value into the set. | ||
| pub fn insert(&mut self, value: T) { |
There was a problem hiding this comment.
There's a lot of insert overloads as well, feel free to update this PR in stages, and ask for a review after every stage.
This comment was marked as resolved.
This comment was marked as resolved.
|
@teor2345 I didnnt add the hash and key_equal constructor overloads because they would require tag types to disambiguate in Rust. Should I add them using the approach you mentioned or is the current set of constructors sufficient? Thank you. |
If you think the full set of overloaded arguments will fail, then they can wait until step 2 (an example with some failing overloads). We are currently at step 1 in this PR (working overloads). I think it would be useful to show at least one working example with C++ optional/default argument values. Since Rust doesn't have optional/default argument values, please write that up as a limitation, and explain what it would take to represent all the different combinations of optional/default argument values in Rust. |
I tried to add the hash/key_equal overloads, but the cpp! macro doesn't work inside the overload! macro body, so I couldn't implement them. I've documented the default arguments limitation in detail instead as you requested. |
Please use the same workaround you used for constructors, call a method with a unique name that contains the cpp! macro: |
|
Ah, I see you are specifically concerned about function types. Here is an example of passing a function type: overloading-macros/cpp-overload-test/src/stdcpp/forward_list.rs Lines 25 to 31 in 5c6b8f3 overloading-macros/cpp-overload-test/src/stdcpp/forward_list.rs Lines 426 to 432 in 5c6b8f3 overloading-macros/cpp-overload-test/src/stdcpp/forward_list.rs Lines 668 to 669 in 5c6b8f3 |
I have added the hash and key_equal constructor overloads using the helper method pattern you suggested. Please review and let me know if thereis anything else. Thank you. |
teor2345
left a comment
There was a problem hiding this comment.
The goal of wrapping an overload set is to expose different and interesting behaviours to Rust.
| /// This demonstrates calling a C++ constructor with default arguments. | ||
| /// In C++, this would be `unordered_multiset(0, std::hash<int>(), std::equal_to<int>())` | ||
| /// where the remaining arguments use their default values. | ||
| pub fn new(_tag: DefaultKeyEqual) -> StdUnorderedMultiset { |
There was a problem hiding this comment.
The constructors you just added seem to do the same thing as the constructor with no arguments. If they have different behaviour, please add a test that shows the different behaviour. If they behave the same as another constructor, please remove them.
Have a look at my previous suggestion again. It can help you add overloads that allow the user to supply custom Rust functions as the hash and equal functions.
Feel free to remove the tag type, it shouldn't be needed. But if it helps you to get the code working, you can use it, and we can work on removing it later.
|
I tried adding overloads that accept custom Rust functions for hash and key_equal, but from my research, C++ templates are complex - |
Added a wrapper for std::unordered_multiset with 5 overloads (constructors and insert).
Limitationsdoc sectionErgonomicsdoc sectionIncompatibilitiesdoc sectionWorkaroundsdoc sectionInexpressible Overloadsdoc sectionMark items in this checklist as done by clicking the box next to each item.
Focus on Interesting Overloads
Only wrap functions that have overloads. (It is ok to wrap non-overloaded functions just for testing.)
Ignore these overloads:
noexcept: not an interesting differenceswap: no equivalent in Rust (which uses memcpy for assignment/swaps)Only code one example of overloads that:
const/non-const,&/&&(or&/&mut)before_begin/begin,end)You can look at stdcpp/forward_list.rs (working overloads) and stdcpp-forward-list.rs (failing overloads) for example code.
Closes #41