Skip to content
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

Enable binary comparison operations for internal tuple (second approach) #1481

Conversation

danhoeflinger
Copy link
Contributor

@danhoeflinger danhoeflinger commented Apr 5, 2024

This takes an alternative approach to #1472 to enable binary comparison using SFINAE.

It only needs a single overload per operator, as it uses SFINAE create the overloads to match the incoming types rather than partial specialization.

In this version we are able to use forwarding (universal references) for the inputs, forwarding into the static_cast.
Here we static_cast all inputs (which may be std::tuple or oneapi::dpl::__internal::tuple) to std::tuple with the same element types. I believe this cast should be converted to a noop at compile time in the case where the static_cast is the existing type of the input.

Signed-off-by: Dan Hoeflinger <dan.hoeflinger@intel.com>
operator==(Tuple1&& __lhs, Tuple2&& __rhs)
{
return static_cast<__get_std_tuple_t<Tuple1>>(std::forward<Tuple1>(__lhs)) ==
static_cast<__get_std_tuple_t<Tuple2>>(std::forward<Tuple2>(__rhs));
Copy link
Contributor

Choose a reason for hiding this comment

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

I double checked on Godbolt and this does not introduce a copy for the cast of a std::tuple to a std::tuple. I don't have anything to add; I just wanted to verify that there wasn't an unnecessary copy being introduced.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm still working it out. I think it may inject an extra copy for lvalue refs... still a work in progress.

…t...

Signed-off-by: Dan Hoeflinger <dan.hoeflinger@intel.com>
@SergeyKopienko
Copy link
Contributor

SergeyKopienko commented Apr 8, 2024

From my pointy of view, when we call

    template <typename U1, typename... U, ::std::size_t... _Ip>
    static ::std::tuple<U1, U...>
    to_std_tuple(const oneapi::dpl::__internal::tuple<U1, U...>& __t, ::std::index_sequence<_Ip...>)
    {
        return ::std::tuple<U1, U...>(oneapi::dpl::__internal::get_impl<_Ip>()(__t)...);
    }

from operator==(Tuple1&& __lhs, Tuple2&& __rhs) we will copy data. Am I correct?
If so, this approach probably should have not very good performance...

@danhoeflinger
Copy link
Contributor Author

danhoeflinger commented Apr 8, 2024

From my pointy of view, when we call

    template <typename U1, typename... U, ::std::size_t... _Ip>
    static ::std::tuple<U1, U...>
    to_std_tuple(const oneapi::dpl::__internal::tuple<U1, U...>& __t, ::std::index_sequence<_Ip...>)
    {
        return ::std::tuple<U1, U...>(oneapi::dpl::__internal::get_impl<_Ip>()(__t)...);
    }

from operator==(Tuple1&& __lhs, Tuple2&& __rhs) we will copy data. Am I correct? If so, this approach probably should have not very good performance...

Yes, it seems I've missed a fundamental issue with this PR. I was trying to avoid re-implementing the functionality of std::tuple but now I think there is no good way to take advantage of their implementation without copies.

I guess the appropriate thing to do is to just reimplement the functionality of the operators here... then no casting is necessary.

@danhoeflinger
Copy link
Contributor Author

Closing this in light of the issue discussed above in favor of changes in the main branch.

@danhoeflinger danhoeflinger deleted the dev/dhoeflin/tuple_binary_op_other_approach branch May 6, 2024 16:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants