Skip to content
This repository was archived by the owner on Jan 26, 2024. It is now read-only.

Commit cc81f2c

Browse files
committed
Only overload vector operators for convertible types
This is necessary to avoid errors about ambiguous overloads in code such as ```` struct Point { float4 pos; float mass; }; template<typename T> Point operator+(Point const& p, T const& v) { return Point{p.pos + v, p.mass}; } int main() { float4 v = make_float4(0, 1, 2, 3); Point p{make_float4(3, 2, 1, 0), 1.0f}; Point q = p + v; } ```` when building with the host compiler. Closes hipamd issue #4
1 parent a99abc6 commit cc81f2c

File tree

1 file changed

+19
-12
lines changed

1 file changed

+19
-12
lines changed

include/hip/amd_detail/amd_hip_vector_types.h

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,13 @@ template <typename __T> struct is_scalar : public integral_constant<bool, __is_s
955955
}
956956
};
957957

958+
// comfort type to only enable an operator if U can be converted to
959+
// a HIP_vector_type<T, N>
960+
template<typename U, typename T, unsigned int n,
961+
typename R=HIP_vector_type<T, n> /* operator return value */>
962+
using enable_if_convertible = typename
963+
std::enable_if<std::is_convertible<U, HIP_vector_type<T, n>>::value, R>::type;
964+
958965
template<typename T, unsigned int n>
959966
__HOST_DEVICE__
960967
inline
@@ -968,7 +975,7 @@ template <typename __T> struct is_scalar : public integral_constant<bool, __is_s
968975
__HOST_DEVICE__
969976
inline
970977
constexpr
971-
HIP_vector_type<T, n> operator+(
978+
enable_if_convertible<U, T, n> operator+(
972979
const HIP_vector_type<T, n>& x, U y) noexcept
973980
{
974981
return HIP_vector_type<T, n>{x} += HIP_vector_type<T, n>{y};
@@ -977,7 +984,7 @@ template <typename __T> struct is_scalar : public integral_constant<bool, __is_s
977984
__HOST_DEVICE__
978985
inline
979986
constexpr
980-
HIP_vector_type<T, n> operator+(
987+
enable_if_convertible<U, T, n> operator+(
981988
U x, const HIP_vector_type<T, n>& y) noexcept
982989
{
983990
return HIP_vector_type<T, n>{x} += y;
@@ -996,7 +1003,7 @@ template <typename __T> struct is_scalar : public integral_constant<bool, __is_s
9961003
__HOST_DEVICE__
9971004
inline
9981005
constexpr
999-
HIP_vector_type<T, n> operator-(
1006+
enable_if_convertible<U, T, n> operator-(
10001007
const HIP_vector_type<T, n>& x, U y) noexcept
10011008
{
10021009
return HIP_vector_type<T, n>{x} -= HIP_vector_type<T, n>{y};
@@ -1005,7 +1012,7 @@ template <typename __T> struct is_scalar : public integral_constant<bool, __is_s
10051012
__HOST_DEVICE__
10061013
inline
10071014
constexpr
1008-
HIP_vector_type<T, n> operator-(
1015+
enable_if_convertible<U, T, n> operator-(
10091016
U x, const HIP_vector_type<T, n>& y) noexcept
10101017
{
10111018
return HIP_vector_type<T, n>{x} -= y;
@@ -1024,7 +1031,7 @@ template <typename __T> struct is_scalar : public integral_constant<bool, __is_s
10241031
__HOST_DEVICE__
10251032
inline
10261033
constexpr
1027-
HIP_vector_type<T, n> operator*(
1034+
enable_if_convertible<U, T, n> operator*(
10281035
const HIP_vector_type<T, n>& x, U y) noexcept
10291036
{
10301037
return HIP_vector_type<T, n>{x} *= HIP_vector_type<T, n>{y};
@@ -1033,7 +1040,7 @@ template <typename __T> struct is_scalar : public integral_constant<bool, __is_s
10331040
__HOST_DEVICE__
10341041
inline
10351042
constexpr
1036-
HIP_vector_type<T, n> operator*(
1043+
enable_if_convertible<U, T, n> operator*(
10371044
U x, const HIP_vector_type<T, n>& y) noexcept
10381045
{
10391046
return HIP_vector_type<T, n>{x} *= y;
@@ -1052,7 +1059,7 @@ template <typename __T> struct is_scalar : public integral_constant<bool, __is_s
10521059
__HOST_DEVICE__
10531060
inline
10541061
constexpr
1055-
HIP_vector_type<T, n> operator/(
1062+
enable_if_convertible<U, T, n> operator/(
10561063
const HIP_vector_type<T, n>& x, U y) noexcept
10571064
{
10581065
return HIP_vector_type<T, n>{x} /= HIP_vector_type<T, n>{y};
@@ -1061,7 +1068,7 @@ template <typename __T> struct is_scalar : public integral_constant<bool, __is_s
10611068
__HOST_DEVICE__
10621069
inline
10631070
constexpr
1064-
HIP_vector_type<T, n> operator/(
1071+
enable_if_convertible<U, T, n> operator/(
10651072
U x, const HIP_vector_type<T, n>& y) noexcept
10661073
{
10671074
return HIP_vector_type<T, n>{x} /= y;
@@ -1090,15 +1097,15 @@ template <typename __T> struct is_scalar : public integral_constant<bool, __is_s
10901097
__HOST_DEVICE__
10911098
inline
10921099
constexpr
1093-
bool operator==(const HIP_vector_type<T, n>& x, U y) noexcept
1100+
enable_if_convertible<U, T, n, bool> operator==(const HIP_vector_type<T, n>& x, U y) noexcept
10941101
{
10951102
return x == HIP_vector_type<T, n>{y};
10961103
}
10971104
template<typename T, unsigned int n, typename U>
10981105
__HOST_DEVICE__
10991106
inline
11001107
constexpr
1101-
bool operator==(U x, const HIP_vector_type<T, n>& y) noexcept
1108+
enable_if_convertible<U, T, n, bool> operator==(U x, const HIP_vector_type<T, n>& y) noexcept
11021109
{
11031110
return HIP_vector_type<T, n>{x} == y;
11041111
}
@@ -1116,15 +1123,15 @@ template <typename __T> struct is_scalar : public integral_constant<bool, __is_s
11161123
__HOST_DEVICE__
11171124
inline
11181125
constexpr
1119-
bool operator!=(const HIP_vector_type<T, n>& x, U y) noexcept
1126+
enable_if_convertible<U, T, n, bool> operator!=(const HIP_vector_type<T, n>& x, U y) noexcept
11201127
{
11211128
return !(x == y);
11221129
}
11231130
template<typename T, unsigned int n, typename U>
11241131
__HOST_DEVICE__
11251132
inline
11261133
constexpr
1127-
bool operator!=(U x, const HIP_vector_type<T, n>& y) noexcept
1134+
enable_if_convertible<U, T, n, bool> operator!=(U x, const HIP_vector_type<T, n>& y) noexcept
11281135
{
11291136
return !(x == y);
11301137
}

0 commit comments

Comments
 (0)