-
Notifications
You must be signed in to change notification settings - Fork 47
Conditionally include resize methods / constructors depending on type traits #191
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
Conversation
barche
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 for the PR! Could you please also add a test to types.cpp that uses your NeverEmpty class in a method? Since this is preventing a compile error the method doesn't have to do anything not be called from the Julia side.
@barche I've added the test to types.cpp, and verified that compilation fails if the patch is removed. While I did this, I also looked into the type trait rules for the std::vector and std::deque constructors, and decided to To support these three new constructors, is anything else required aside from the calls to |
| namespace jlcxx | ||
| { | ||
| template<> struct IsMirroredType<cpp_types::DoubleData> : std::false_type { }; | ||
| template<> struct IsMirroredType<cpp_types::NeverEmpty> : std::false_type { }; |
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.
Why, specifically, is this required? There is a general lack of documentation on what exactly a mirrored type is. This compiles fine on my local machine without disabling mirroring for this type, but fails in the runners. Why? Is disabling mirroring correct here, or is the complaint indicative of an edge case I've not considered?
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 because this simple test class is detected as a "plain old data" type, and by default these are expected t be mapped to a Julia struct with the same layout, by using map_type instead of add_type. To override this, IsMirroredType can be specialized. Could be better documented, indeed :)
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.
Ah, that makes perfect sense. Thanks for the explanation!
|
Thanks for the PR, this is fine and the new constructors work. |
The current
std::vectorandstd::dequewrappers defineresizeand subsequently call::resizeon the inner containers. This is an issue whenvalue_typeis not default construtable. For example:Exposing bindings over
NeverEmptyVectorwill callNeverEmptyVector::resize, which will unjustly generate a compiler error due toNeverEmptynot being default constructable.This PR
if constexprgates the relevant::resizecalls behind a check tostd::is_default_constructible_v. Ifvalue_typeis not default constructable, bindings to::resizeare simply not generated.While I was at it, I also tweaked the exposed
appendonstd::vectorto only callreserveifvalue_typeis move insertable (as the standard requires).