Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When playing with OpenCV it became clear to me that Rice really needs to support construtor and method overloading. This PR is quite large, but it can be broken down into four key changes:
First, update the NativeRegistry to be keyed on Ruby class and method id and to store a vector of Native instances (NativeFunction, NativeIterator, NativeAttributeGet, NativeAttributeSet). If a method is overridden, there will be more than one native stored.
Second, create a base class Native for NativeFunction, NativeIterator, NativeAttributeGet and NativeAttributeSet. This allows the NativeRegistry to store unique_ptrs instead of std::any, which is hopefully a bit clearer and more importantly allows memory to be cleaned up via the use of std::unique_ptr (Natives are allocated on the heap but previously were never freed). It also reduces the amount of code by sharing it via the base Native class. Also NativeAttribute was split into NativeAttributeGet and NativeAttributeSet so they could share more code with Native.
Third, update From_Ruby#is_convertible's return type from bool to a new enum called Convertible which has three values - Exact, TypeCast or None. Exact means the Ruby type and C++ type are the same (example float), TypeCast means the Ruby type can be casted to the C++ type (example integer to float) and None means the Ruby and C++ types are not compatible. This is a backwards incompatible change for anyone who implemented their own version of From_Ruby#is_convertible but that seems fairly unlikely because it was previously used only for updating std::variants.
Fourth, update Natives to resolve overloaded methods at runtime by comparing the types of Ruby VALUEs to the C++ types using From_Ruby#is_convertible as described above. Exact matches take precedence over TypeCast matches. If no matches are found an exception is thrown.