From 08586e7e66e618012d2472e9e498d20223af221d Mon Sep 17 00:00:00 2001 From: Greg Lueck Date: Wed, 27 Nov 2024 15:55:57 -0500 Subject: [PATCH] Allow "std::byte" as "vec" element type This is change 7 of 9 that fix problems with the specification of the `vec` class. An implementation that follows the existing specification would not accept common code patterns and would not pass the CTS. None of the existing implementations actually follow the existing specification. This change clarifies that `std::byte` is a legal element type for `vec`. This is one possible interpretation of the previous wording where we said that the element data type must be a "basic scalar type". We think that phrase included `sycl::byte`. However, `sycl::byte` was deprecated in SYCL 2020 saying that `std::byte` is a replacement. If we allow `std::byte`, we need to adjust the constraints for the various `vec` operators. We decided to allow these operators on `vec` of `std::byte`, which mostly follows the C++ rules for operators on plain `std::byte`: * Comparison: ==, !=, <, <=, >, >= * Bitwise: &, |, ^, ~, &=, |=, ^= I decided it was clearer to rephrase the constraints to say which types are allowed rather than listing the types that are not allowed. For example, this results in phrasing like: > Available only when DataT is an integral type. Rather than: > Available only when: DataT != float && DataT != double && > DataT != half && DataT != std::byte. These changes correspond to slide 26 of the presentation that was discussed in the WG meetings. --- adoc/chapters/programming_interface.adoc | 179 +++++++++++++++-------- adoc/headers/vec.h | 37 +++-- 2 files changed, 143 insertions(+), 73 deletions(-) diff --git a/adoc/chapters/programming_interface.adoc b/adoc/chapters/programming_interface.adoc index 5f2b2f9c5..fe029cf8b 100644 --- a/adoc/chapters/programming_interface.adoc +++ b/adoc/chapters/programming_interface.adoc @@ -17760,8 +17760,9 @@ The [code]#vec# class is templated on its number of elements and its element type. The number of elements parameter, _NumElements_, can be one of: 1, 2, 3, 4, 8 or 16. Any other value shall produce a compilation failure. -The element type parameter, _DataT_, must be one of the basic scalar types -supported in device code. +The element type parameter, [code]#DataT#, must be the cv-unqualified version of +one of the following: one of the built-in scalar data types listed in +<>, [code]#half#, [code]#sycl::byte#, or [code]#std::byte#. The SYCL [code]#vec# class template provides interoperability with the underlying vector type defined by [code]#vector_t# which is available only when @@ -18154,7 +18155,11 @@ a@ ---- vec operatorOP(const vec& lhs, const vec& rhs) ---- - a@ If [code]#OP# is [code]#%#, available only when: [code]#DataT != float && DataT != double && DataT != half#. +a@ _Constraints:_ + +* If [code]#OP# is not [code]#%#, [code]#DataT# is an arithmetic type or + [code]#half#, and +* If [code]#OP# is [code]#%#, [code]#DataT# is an integral type. Construct a new instance of the SYCL [code]#vec# class template with the same template parameters as [code]#lhs# [code]#vec# with each element of the new SYCL [code]#vec# instance the result of an element-wise [code]#OP# arithmetic operation between each element of [code]#lhs# [code]#vec# and each element of the [code]#rhs# SYCL [code]#vec#. @@ -18165,7 +18170,11 @@ a@ ---- vec operatorOP(const vec& lhs, const DataT& rhs) ---- - a@ If [code]#OP# is [code]#%#, available only when: [code]#DataT != float && DataT != double && DataT != half#. +a@ _Constraints:_ + +* If [code]#OP# is not [code]#%#, [code]#DataT# is an arithmetic type or + [code]#half#, and +* If [code]#OP# is [code]#%#, [code]#DataT# is an integral type. Construct a new instance of the SYCL [code]#vec# class template with the same template parameters as [code]#lhs# [code]#vec# with each element of the new SYCL [code]#vec# instance the result of an element-wise [code]#OP# arithmetic operation between each element of [code]#lhs# [code]#vec# and the [code]#rhs# scalar. @@ -18176,7 +18185,11 @@ a@ ---- vec operatorOP(const DataT& lhs, const vec& rhs) ---- - a@ If [code]#OP# is [code]#%#, available only when: [code]#DataT != float && DataT != double && DataT != half#. +a@ _Constraints:_ + +* If [code]#OP# is not [code]#%#, [code]#DataT# is an arithmetic type or + [code]#half#, and +* If [code]#OP# is [code]#%#, [code]#DataT# is an integral type. Construct a new instance of the SYCL [code]#vec# class template with the same template parameters as the [code]#rhs# SYCL [code]#vec# @@ -18193,7 +18206,11 @@ a@ ---- vec& operatorOP(vec& lhs, const vec& rhs) ---- - a@ If [code]#OP# is [code]#%=#, available only when: [code]#DataT != float && DataT != double && DataT != half#. +a@ _Constraints:_ + +* If [code]#OP# is not [code]#%=#, [code]#DataT# is an arithmetic type or + [code]#half#, and +* If [code]#OP# is [code]#%=#, [code]#DataT# is an integral type. Perform an in-place element-wise [code]#OP# arithmetic operation between each element of [code]#lhs# [code]#vec# and each element of the [code]#rhs# SYCL [code]#vec# and return [code]#lhs# [code]#vec#. @@ -18204,7 +18221,11 @@ a@ ---- vec& operatorOP(vec& lhs, const DataT& rhs) ---- - a@ If [code]#OP# is [code]#%=#, available only when: [code]#DataT != float && DataT != double && DataT != half#. +a@ _Constraints:_ + +* If [code]#OP# is not [code]#%=#, [code]#DataT# is an arithmetic type or + [code]#half#, and +* If [code]#OP# is [code]#%=#, [code]#DataT# is an integral type. Perform an in-place element-wise [code]#OP# arithmetic operation between each element of [code]#lhs# [code]#vec# and [code]#rhs# scalar and return [code]#lhs# [code]#vec#. @@ -18215,7 +18236,8 @@ a@ ---- vec& operatorOP(vec& v) ---- - a@ Available only when: [code]#DataT != bool#. +a@ _Constraints:_ [code]#DataT# is an arithmetic type or [code]#half# but +[code]#DataT# is not [code]#bool#. Perform an in-place element-wise [code]#OP# prefix arithmetic operation on each element of [code]#v# and return [code]#v#. @@ -18226,7 +18248,8 @@ a@ ---- vec operatorOP(vec& v, int) ---- - a@ Available only when: [code]#DataT != bool#. +a@ _Constraints:_ [code]#DataT# is an arithmetic type or [code]#half# but +[code]#DataT# is not [code]#bool#. Perform an in-place element-wise [code]#OP# postfix arithmetic operation on each element of [code]#v# and return a copy of [code]#v# before the operation is performed. @@ -18237,7 +18260,9 @@ a@ ---- vec operatorOP(const vec& v) ---- - a@ Construct a new instance of the SYCL [code]#vec# class template with the same template parameters as this SYCL [code]#vec# with each element of the new SYCL [code]#vec# instance the result of an element-wise [code]#OP# unary arithmetic operation on each element of this SYCL [code]#vec#. +a@ _Constraints:_ [code]#DataT# is an arithmetic type or [code]#half#. + +Construct a new instance of the SYCL [code]#vec# class template with the same template parameters as this SYCL [code]#vec# with each element of the new SYCL [code]#vec# instance the result of an element-wise [code]#OP# unary arithmetic operation on each element of this SYCL [code]#vec#. Where [code]#OP# is: [code]#pass:[+]#, [code]#-#. @@ -18246,7 +18271,7 @@ a@ ---- vec operatorOP(const vec& lhs, const vec& rhs) ---- - a@ Available only when: [code]#DataT != float && DataT != double && DataT != half#. +a@ _Constraints:_ [code]#DataT# is an integral type or [code]#std::byte#. Construct a new instance of the SYCL [code]#vec# class template with the same template parameters as [code]#lhs# [code]#vec# with each element of the new SYCL [code]#vec# instance the result of an element-wise [code]#OP# bitwise operation between each element of [code]#lhs# [code]#vec# and each element of the [code]#rhs# SYCL [code]#vec#. @@ -18257,7 +18282,7 @@ a@ ---- vec operatorOP(const vec& lhs, const DataT& rhs) ---- - a@ Available only when: [code]#DataT != float && DataT != double && DataT != half#. +a@ _Constraints:_ [code]#DataT# is an integral type or [code]#std::byte#. Construct a new instance of the SYCL [code]#vec# class template with the same template parameters as [code]#lhs# [code]#vec# with each element of the new SYCL [code]#vec# instance the result of an element-wise [code]#OP# bitwise operation between each element of [code]#lhs# [code]#vec# and the [code]#rhs# scalar. @@ -18268,7 +18293,7 @@ a@ ---- vec operatorOP(const DataT& lhs, const vec& rhs) ---- - a@ Available only when: [code]#DataT != float && DataT != double && DataT != half#. +a@ _Constraints:_ [code]#DataT# is an integral type or [code]#std::byte#. Construct a new instance of the SYCL [code]#vec# class template with the same template parameters as the [code]#rhs# SYCL [code]#vec# @@ -18282,7 +18307,7 @@ a@ ---- vec& operatorOP(vec& lhs, const vec& rhs) ---- - a@ Available only when: [code]#DataT != float && DataT != double && DataT != half#. +a@ _Constraints:_ [code]#DataT# is an integral type or [code]#std::byte#. Perform an in-place element-wise [code]#OP# bitwise operation between each element of [code]#lhs# [code]#vec# and the [code]#rhs# SYCL [code]#vec# and return [code]#lhs# [code]#vec#. @@ -18293,7 +18318,7 @@ a@ ---- vec& operatorOP(vec& lhs, const DataT& rhs) ---- - a@ Available only when: [code]#DataT != float && DataT != double && DataT != half#. +a@ _Constraints:_ [code]#DataT# is an integral type or [code]#std::byte#. Perform an in-place element-wise [code]#OP# bitwise operation between each element of [code]#lhs# [code]#vec# and the [code]#rhs# scalar and return a [code]#lhs# [code]#vec#. @@ -18304,7 +18329,7 @@ a@ ---- vec operatorOP(const vec& lhs, const vec& rhs) ---- - a@ Available only when: [code]#DataT != float && DataT != double && DataT != half#. +a@ _Constraints:_ [code]#DataT# is an integral type. Construct a new instance of the SYCL [code]#vec# class template with the same template parameters as [code]#lhs# [code]#vec# with each element of the new SYCL [code]#vec# instance the result of an element-wise [code]#OP# bitshift operation between each element of [code]#lhs# [code]#vec# and each element of the [code]#rhs# SYCL [code]#vec#. If [code]#OP# is [code]#>>#, [code]#DataT# is a signed type and [code]#lhs# [code]#vec# has a negative value any vacated bits viewed as an unsigned integer must be assigned the value [code]#1#, otherwise any vacated bits viewed as an unsigned integer must be assigned the value [code]#0#. @@ -18315,7 +18340,7 @@ a@ ---- vec operatorOP(const vec& lhs, const DataT& rhs) ---- - a@ Available only when: [code]#DataT != float && DataT != double && DataT != half#. +a@ _Constraints:_ [code]#DataT# is an integral type. Construct a new instance of the SYCL [code]#vec# class template with the same template parameters as [code]#lhs# [code]#vec# with each element of the new SYCL [code]#vec# instance the result of an element-wise [code]#OP# bitshift operation between each element of [code]#lhs# [code]#vec# and the [code]#rhs# scalar. If [code]#OP# is [code]#>>#, [code]#DataT# is a signed type and [code]#lhs# [code]#vec# has a negative value any vacated bits viewed as an unsigned integer must be assigned the value [code]#1#, otherwise any vacated bits viewed as an unsigned integer must be assigned the value [code]#0#. @@ -18326,15 +18351,17 @@ a@ ---- vec operatorOP(const DataT& lhs, const vec& rhs) ---- - a@ Construct a new instance of the SYCL [code]#vec# class template with - the same template parameters as the [code]#rhs# SYCL [code]#vec# - with each element of the new SYCL [code]#vec# instance the result of - an element-wise [code]#OP# bitshift operation between the [code]#lhs# scalar and each element of the [code]#rhs# SYCL [code]#vec#. - If [code]#OP# is [code]#>>#, [code]#DataT# is a signed type - and this SYCL [code]#vec# has a negative value any vacated bits viewed - as an unsigned integer must be assigned the value [code]#1#, otherwise - any vacated bits viewed as an unsigned integer must be assigned the value - [code]#0#. +a@ _Constraints:_ [code]#DataT# is an integral type. + +Construct a new instance of the SYCL [code]#vec# class template with +the same template parameters as the [code]#rhs# SYCL [code]#vec# +with each element of the new SYCL [code]#vec# instance the result of +an element-wise [code]#OP# bitshift operation between the [code]#lhs# scalar and each element of the [code]#rhs# SYCL [code]#vec#. +If [code]#OP# is [code]#>>#, [code]#DataT# is a signed type +and this SYCL [code]#vec# has a negative value any vacated bits viewed +as an unsigned integer must be assigned the value [code]#1#, otherwise +any vacated bits viewed as an unsigned integer must be assigned the value +[code]#0#. Where [code]#OP# is: [code]#<<#, [code]#>>#. @@ -18343,7 +18370,7 @@ a@ ---- vec& operatorOP(vec& lhs, const vec& rhs) ---- - a@ Available only when: [code]#DataT != float && DataT != double && DataT != half#. +a@ _Constraints:_ [code]#DataT# is an integral type. Perform an in-place element-wise [code]#OP# bitshift operation between each element of [code]#lhs# [code]#vec# and the [code]#rhs# SYCL [code]#vec# and returns [code]#lhs# [code]#vec#. If [code]#OP# is [code]#>>=#, [code]#DataT# is a signed type and [code]#lhs# [code]#vec# has a negative value any vacated bits viewed as an unsigned integer must be assigned the value [code]#1#, otherwise any vacated bits viewed as an unsigned integer must be assigned the value [code]#0#. @@ -18354,7 +18381,7 @@ a@ ---- vec& operatorOP(vec& lhs, const DataT& rhs) ---- - a@ Available only when: [code]#DataT != float && DataT != double && DataT != half#. +a@ _Constraints:_ [code]#DataT# is an integral type. Perform an in-place element-wise [code]#OP# bitshift operation between each element of [code]#lhs# [code]#vec# and the [code]#rhs# scalar and returns a reference to this SYCL [code]#vec#. If [code]#OP# is [code]#>>=#, [code]#DataT# is a signed type and [code]#lhs# [code]#vec# has a negative value any vacated bits viewed as an unsigned integer must be assigned the value [code]#1#, otherwise any vacated bits viewed as an unsigned integer must be assigned the value [code]#0#. @@ -18365,7 +18392,9 @@ a@ ---- vec operatorOP(const vec& lhs, const vec& rhs) ---- - a@ Construct a new instance of the SYCL [code]#vec# class template with the same template parameters as [code]#lhs# [code]#vec# with each element of the new SYCL [code]#vec# instance the result of an element-wise [code]#OP# logical operation between each element of [code]#lhs# [code]#vec# and each element of the [code]#rhs# SYCL [code]#vec#. +a@ _Constraints:_ [code]#DataT# is an arithmetic type or [code]#half#. + +Construct a new instance of the SYCL [code]#vec# class template with the same template parameters as [code]#lhs# [code]#vec# with each element of the new SYCL [code]#vec# instance the result of an element-wise [code]#OP# logical operation between each element of [code]#lhs# [code]#vec# and each element of the [code]#rhs# SYCL [code]#vec#. The [code]#DataT# template parameter of the constructed SYCL [code]#vec#, [code]#RET#, varies depending on the [code]#DataT# template parameter of this SYCL [code]#vec#. For a SYCL [code]#vec# with [code]#DataT# of type [code]#int8_t# or [code]#uint8_t# [code]#RET# must be [code]#int8_t#. For a SYCL [code]#vec# with [code]#DataT# of type [code]#int16_t#, [code]#uint16_t# or [code]#half# [code]#RET# must be [code]#int16_t#. For a SYCL [code]#vec# with [code]#DataT# of type [code]#int32_t#, [code]#uint32_t# or [code]#float# [code]#RET# must be [code]#int32_t#. For a SYCL [code]#vec# with [code]#DataT# of type [code]#int64_t#, [code]#uint64_t# or [code]#double# [code]#RET# must be [code]#int64_t#. @@ -18376,7 +18405,9 @@ a@ ---- vec operatorOP(const vec& lhs, const DataT& rhs) ---- - a@ Construct a new instance of the SYCL [code]#vec# class template with the same template parameters as this SYCL [code]#vec# with each element of the new SYCL [code]#vec# instance the result of an element-wise [code]#OP# logical operation between each element of [code]#lhs# [code]#vec# and the [code]#rhs# scalar. +a@ _Constraints:_ [code]#DataT# is an arithmetic type or [code]#half#. + +Construct a new instance of the SYCL [code]#vec# class template with the same template parameters as this SYCL [code]#vec# with each element of the new SYCL [code]#vec# instance the result of an element-wise [code]#OP# logical operation between each element of [code]#lhs# [code]#vec# and the [code]#rhs# scalar. The [code]#DataT# template parameter of the constructed SYCL [code]#vec#, [code]#RET#, varies depending on the [code]#DataT# template parameter of this SYCL [code]#vec#. For a SYCL [code]#vec# with [code]#DataT# of type [code]#int8_t# or [code]#uint8_t# [code]#RET# must be [code]#int8_t#. For a SYCL [code]#vec# with [code]#DataT# of type [code]#int16_t#, [code]#uint16_t# or [code]#half# [code]#RET# must be [code]#int16_t#. For a SYCL [code]#vec# with [code]#DataT# of type [code]#int32_t#, [code]#uint32_t# or [code]#float# [code]#RET# must be [code]#int32_t#. For a SYCL [code]#vec# with [code]#DataT# of type [code]#int64_t#, [code]#uint64_t# or [code]#double# [code]#RET# must be [code]#uint64_t#. @@ -18387,7 +18418,9 @@ a@ ---- vec operatorOP(const DataT& lhs, const vec& rhs) ---- - a@ Construct a new instance of the SYCL [code]#vec# class template with +a@ _Constraints:_ [code]#DataT# is an arithmetic type or [code]#half#. + +Construct a new instance of the SYCL [code]#vec# class template with the same template parameters as the [code]#rhs# SYCL [code]#vec# with each element of the new SYCL [code]#vec# instance the result of an element-wise [code]#OP# logical operation between the [code]#lhs# scalar and each element of the [code]#rhs# SYCL [code]#vec#. @@ -18454,7 +18487,7 @@ a@ ---- vec operator~(const vec& v) ---- - a@ Available only when: [code]#DataT != float && DataT != double && DataT != half#. +a@ _Constraints:_ [code]#DataT# is an integral type or [code]#std::byte#. Construct a new instance of the SYCL [code]#vec# class template with the same template parameters as [code]#v# [code]#vec# with each element of the new SYCL [code]#vec# instance the result of an element-wise bitwise NOT operation on each element of [code]#v# [code]#vec#. @@ -18463,7 +18496,9 @@ a@ ---- vec operator!(const vec& v) ---- - a@ Construct a new instance of the SYCL [code]#vec# class template with the same template parameters as [code]#v# [code]#vec# with each element of the new SYCL [code]#vec# instance the result of an element-wise logical NOT operation on each element of [code]#v# [code]#vec#. Each element of the SYCL [code]#vec# that is returned must be [code]#-1# if the operation results in [code]#true# and [code]#0# if the operation results in [code]#false# or this SYCL [code]#vec# is a NaN. +a@ _Constraints:_ [code]#DataT# is an arithmetic type or [code]#half#. + +Construct a new instance of the SYCL [code]#vec# class template with the same template parameters as [code]#v# [code]#vec# with each element of the new SYCL [code]#vec# instance the result of an element-wise logical NOT operation on each element of [code]#v# [code]#vec#. Each element of the SYCL [code]#vec# that is returned must be [code]#-1# if the operation results in [code]#true# and [code]#0# if the operation results in [code]#false# or this SYCL [code]#vec# is a NaN. The [code]#DataT# template parameter of the constructed SYCL [code]#vec#, [code]#RET#, varies depending on the [code]#DataT# template parameter of this SYCL [code]#vec#. For a SYCL [code]#vec# with [code]#DataT# of type [code]#int8_t# or [code]#uint8_t# [code]#RET# must be [code]#int8_t#. For a SYCL [code]#vec# with [code]#DataT# of type [code]#int16_t#, [code]#uint16_t# or [code]#half# [code]#RET# must be [code]#int16_t#. For a SYCL [code]#vec# with [code]#DataT# of type [code]#int32_t#, [code]#uint32_t# or [code]#float# [code]#RET# must be [code]#int32_t#. For a SYCL [code]#vec# with [code]#DataT# of type [code]#int64_t#, [code]#uint64_t# or [code]#double# [code]#RET# must be [code]#int64_t#. @@ -18949,14 +18984,17 @@ friends of [code]#+__writeable_swizzle__+#. Overloads (4), (6), (8), (10), and (12) are hidden friends of [code]#+__const_swizzle__+#. -_Constraints:_ If [code]#OP# is one of the following: [code]#%#, [code]#&#, -[code]#|#, [code]#^#, [code]#<<#, [code]#>>#; available only when: [code]#DataT -!= float && DataT != double && DataT != half#. +_Constraints:_ -In addition, overloads (1) - (4) are available only when the element data type -of [code]#lhs# is the same as the element data type of [code]#rhs# and when the -number of elements in the [code]#lhs# view is equal to the number of elements in -the [code]#rhs# view. +* If [code]#OP# is [code]#pass:[+]#, [code]#-#, [code]#*#, [code]#/#; + [code]#DataT# is an arithmetic type or [code]#half#, and +* If [code]#OP# is [code]#%#, [code]#<<#, [code]#>>#; [code]#DataT# is an + integral type, and +* If [code]#OP# is [code]#&#, [code]#|#, [code]#^#; [code]#DataT# is an integral + type or [code]#std::byte#, and +* For overloads (1) - (4), the element data type of [code]#lhs# is the same as + the element data type of [code]#rhs# and the number of elements in the + [code]#lhs# view is equal to the number of elements in the [code]#rhs# view. _Effects:_ These functions behave as though the swizzle operation represented by each [code]#+__writeable_swizzle__+# or [code]#+__const_swizzle__+# parameter @@ -18995,17 +19033,19 @@ Where [code]#OP# is: [code]#pass:[+=]#, [code]#-=#, [code]#*=#, [code]#/=#, _Availability:_ These are hidden friend functions only in [code]#+__writeable_swizzle__+#. -_Constraints:_ Available only when the left hand side -[code]#+__writeable_swizzle__+# view does not contain any repeated elements. +_Constraints:_ -If [code]#OP# is one of the following: [code]#%=#, [code]#&=#, [code]#|=#, -[code]#^=#, [code]#+<<=+#, [code]#>>=#; available only when: [code]#DataT != -float && DataT != double && DataT != half#. - -In addition, overloads (1) and (2) are available only when the element data type -of [code]#lhs# is the same as the element data type of [code]#rhs# and when the -number of elements in the [code]#lhs# view is equal to the number of elements in -the [code]#rhs# view. +* The left hand side [code]#+__writeable_swizzle__+# view does not contain any + repeated elements, and +* If [code]#OP# is [code]#pass:[+=]#, [code]#-=#, [code]#*=#, [code]#/=#; + [code]#DataT# is an arithmetic type or [code]#half#, and +* If [code]#OP# is [code]#%=#, [code]#+<<=+#, [code]#>>=#; [code]#DataT# is an + integral type, and +* If [code]#OP# is [code]#&=#, [code]#|=#, [code]#^=#; [code]#DataT# is an + integral type or [code]#std::byte#, and +* For overloads (1) and (2), the element data type of [code]#lhs# is the same as + the element data type of [code]#rhs# and the number of elements in the + [code]#lhs# view is equal to the number of elements in the [code]#rhs# view. _Effects:_ These functions operate as follow. @@ -19041,9 +19081,12 @@ Where [code]#OP# is: [code]#pass:[++]#, [code]#--#. _Availability:_ These are hidden friend functions only in [code]#+__writeable_swizzle__+#. -_Constraints:_ Available only when the [code]#+__writeable_swizzle__+# view does -not contain any repeated elements. -Available only when [code]#DataT# is not [code]#bool#. +_Constraints:_ + +* The [code]#+__writeable_swizzle__+# view does not contain any repeated + elements, and +* [code]#DataT# is an arithmetic type or [code]#half# but [code]#DataT# is not + [code]#bool#. _Effects:_ Perform an in-place element-wise [code]#OP# prefix arithmetic operation on those elements of the [code]#vec# object that have corresponding @@ -19068,9 +19111,12 @@ Where [code]#OP# is: [code]#pass:[++]#, [code]#--#. _Availability:_ These are hidden friend functions only in [code]#+__writeable_swizzle__+#. -_Constraints:_ Available only when the [code]#+__writeable_swizzle__+# view does -not contain any repeated elements. -Available only when [code]#DataT# is not [code]#bool#. +_Constraints:_ + +* The [code]#+__writeable_swizzle__+# view does not contain any repeated + elements, and +* [code]#DataT# is an arithmetic type or [code]#half# but [code]#DataT# is not + [code]#bool#. _Effects:_ Perform an in-place element-wise [code]#OP# postfix arithmetic operation on those elements of the [code]#vec# object that have corresponding @@ -19099,6 +19145,8 @@ _Availability:_ Functions (1) are hidden friends in [code]#+__writeable_swizzle__+#. Functions (2) are hidden friends in [code]#+__const_swizzle__+#. +_Constraints:_ [code]#DataT# is an arithmetic type or [code]#half#. + _Effects:_ These functions behave as though the swizzle operation represented by the [code]#sv# parameter was first evaluated into a temporary [code]#vec# object, and then [code]#operatorOP# was applied to the temporary [code]#vec# @@ -19165,10 +19213,14 @@ friends of [code]#+__writeable_swizzle__+#. Overloads (4), (6), (8), (10), and (12) are hidden friends of [code]#+__const_swizzle__+#. -_Constraints:_ Overloads (1) - (4) are available only when the element data type -of [code]#lhs# is the same as the element data type of [code]#rhs# and when the -number of elements in the [code]#lhs# view is equal to the number of elements in -the [code]#rhs# view. +_Constraints:_ + +* For overloads (1) - (4), the element data type of [code]#lhs# is the same as + the element data type of [code]#rhs# and the number of elements in the + [code]#lhs# view is equal to the number of elements in the [code]#rhs# view, + and +* If [code]#OP# is [code]#&&#, [code]#||#; [code]#DataT# is an arithmetic type + or [code]#half#. _Effects:_ These functions behave as though the swizzle operation represented by each [code]#+__writeable_swizzle__+# or [code]#+__const_swizzle__+# parameter @@ -19195,8 +19247,11 @@ _Availability:_ Overloads (1) and (3) are hidden friends of [code]#+__writeable_swizzle__+#. Overloads (2) and (4) are hidden friends of [code]#+__const_swizzle__+#. -_Constraints:_ Overloads (1) - (2) are available only when: [code]#DataT != -float && DataT != double && DataT != half#. +_Constraints:_ + +* For overloads (1) - (2), [code]#DataT# is an integral type or + [code]#std::byte#, and +* For overloads (3) - (4), [code]#DataT# is an arithmetic type or [code]#half#. _Effects:_ These functions behave as though the swizzle operation represented by the [code]#+__writeable_swizzle__+# or [code]#+__const_swizzle__+# parameter was diff --git a/adoc/headers/vec.h b/adoc/headers/vec.h index 854294e22..a67c78d76 100644 --- a/adoc/headers/vec.h +++ b/adoc/headers/vec.h @@ -144,52 +144,66 @@ template class vec { vec& operator=(const DataT& rhs); // OP is: +, -, *, /, % - /* If OP is %, available only when: DataT != float && DataT != double - && DataT != half. */ + // + // If OP is not %, available only when DataT is an arithmetic type or half. + // If OP is %, available only when DataT is an integral type. friend vec operatorOP(const vec& lhs, const vec& rhs); friend vec operatorOP(const vec& lhs, const DataT& rhs); friend vec operatorOP(const DataT& lhs, const vec& rhs); // OP is: +=, -=, *=, /=, %= - /* If OP is %=, available only when: DataT != float && DataT != double - && DataT != half. */ + // + // If OP is not %=, available only when DataT is an arithmetic type or half. + // If OP is %=, available only when DataT is an integral type. friend vec& operatorOP(vec& lhs, const vec& rhs); friend vec& operatorOP(vec& lhs, const DataT& rhs); // OP is prefix ++, -- - // Available only when: DataT != bool + // + // Available only when DataT is an arithmetic type or half but not when DataT + // is bool. friend vec& operatorOP(vec& rhs); // OP is postfix ++, -- - // Available only when: DataT != bool + // + // Available only when DataT is an arithmetic type or half but not when DataT + // is bool. friend vec operatorOP(vec& lhs, int); // OP is unary +, - + // + // Available only when DataT is an arithmetic type or half. friend vec operatorOP(const vec& rhs); // OP is: &, |, ^ - /* Available only when: DataT != float && DataT != double && DataT != half. */ + // + // Available only when DataT is an integral type or std::byte. friend vec operatorOP(const vec& lhs, const vec& rhs); friend vec operatorOP(const vec& lhs, const DataT& rhs); friend vec operatorOP(const DataT& lhs, const vec& rhs); // OP is: &=, |=, ^= - /* Available only when: DataT != float && DataT != double && DataT != half. */ + // + // Available only when DataT is an integral type or std::byte. friend vec& operatorOP(vec& lhs, const vec& rhs); friend vec& operatorOP(vec& lhs, const DataT& rhs); // OP is: <<, >> - /* Available only when: DataT != float && DataT != double && DataT != half. */ + // + // Available only when DataT is an integral type. friend vec operatorOP(const vec& lhs, const vec& rhs); friend vec operatorOP(const vec& lhs, const DataT& rhs); friend vec operatorOP(const DataT& lhs, const vec& rhs); // OP is: <<=, >>= - /* Available only when: DataT != float && DataT != double && DataT != half. */ + // + // Available only when DataT is an integral type. friend vec& operatorOP(vec& lhs, const vec& rhs); friend vec& operatorOP(vec& lhs, const DataT& rhs); // OP is: &&, || + // + // Available only when DataT is an arithmetic type or half. friend vec operatorOP(const vec& lhs, const vec& rhs); friend vec operatorOP(const vec& lhs, const DataT& rhs); friend vec operatorOP(const DataT& lhs, const vec& rhs); @@ -199,9 +213,10 @@ template class vec { friend vec operatorOP(const vec& lhs, const DataT& rhs); friend vec operatorOP(const DataT& lhs, const vec& rhs); - /* Available only when: DataT != float && DataT != double && DataT != half. */ + // Available only when DataT is an integral type or std::byte. friend vec operator~(const vec& v); + // Available only when DataT is an arithmetic type or half. friend vec operator!(const vec& v); };