Skip to content

Commit 40f8f9f

Browse files
author
Chen, Brox
committed
refactor annotated_arg operator forwarding
1 parent 886ba05 commit 40f8f9f

File tree

2 files changed

+101
-343
lines changed

2 files changed

+101
-343
lines changed

sycl/doc/extensions/experimental/sycl_ext_oneapi_annotated_arg.asciidoc

Lines changed: 51 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -232,46 +232,17 @@ class annotated_arg {
232232
template<typename propertyT>
233233
static constexpr /*unspecified*/ get_property();
234234
235-
// Overloaded arithmetic operators
236-
template <typename T2, typename PropertyList2,
237-
typename R = decltype(std::declval<T>() + std::declval<T2>())>
238-
R operator+(const annotated_arg<T2, PropertyList2> &other) const;
239-
240-
template <typename T2, typename PropertyList2,
241-
typename R = decltype(std::declval<T>() - std::declval<T2>())>
242-
R operator-(const annotated_arg<T2, PropertyList2> &other) const;
243-
244-
template <typename T2, typename PropertyList2,
245-
typename R = decltype(std::declval<T>() * std::declval<T2>())>
246-
R operator*(const annotated_arg<T2, PropertyList2> &other) const;
247-
248-
template <typename T2, typename PropertyList2,
249-
typename R = decltype(std::declval<T>() / std::declval<T2>())>
250-
R operator/(const annotated_arg<T2, PropertyList2> &other) const;
251-
252-
template <typename T2, typename PropertyList2,
253-
typename R = decltype(std::declval<T>() % std::declval<T2>())>
254-
R operator%(const annotated_arg<T2, PropertyList2> &other) const;
255-
256-
template <typename T2, typename PropertyList2,
257-
typename R = decltype(std::declval<T>() & std::declval<T2>())>
258-
R operator&(const annotated_arg<T2, PropertyList2> &other) const;
259-
260-
template <typename T2, typename PropertyList2,
261-
typename R = decltype(std::declval<T>() | std::declval<T2>())>
262-
R operator|(const annotated_arg<T2, PropertyList2> &other) const;
263-
264-
template <typename T2, typename PropertyList2,
265-
typename R = decltype(std::declval<T>() ^ std::declval<T2>())>
266-
R operator^(const annotated_arg<T2, PropertyList2> &other) const;
267-
268-
template <typename T2, typename PropertyList2,
269-
typename R = decltype(std::declval<T>() >> std::declval<T2>())>
270-
R operator>>(const annotated_arg<T2, PropertyList2> &other) const;
271-
272-
template <typename T2, typename PropertyList2,
273-
typename R = decltype(std::declval<T>() << std::declval<T2>())>
274-
R operator<<(const annotated_arg<T2, PropertyList2> &other) const;
235+
// OP is: +, -, *, /, %, <<, >>, &, |, ^, <, <=, >, >=, ==, ~=, &&, ||
236+
template <typename O>
237+
auto friend operatorOP(O&& a, const annotated_arg& b) ->
238+
decltype(std::forward<O>(a) OP std::declval<T>());
239+
template <typename O> //available only if O is not an annotated_arg type
240+
auto friend operatorOP(const annotated_arg& a, O&& b) ->
241+
decltype(std::declval<T>() OP std::forward<O>(b));
242+
243+
// OP is: +, -, !, ~
244+
template <typename O=T>
245+
auto operatorOP() -> decltype(OP std::declval<O>());
275246
};
276247
277248
//Deduction guides
@@ -283,86 +254,6 @@ template <typename T, typename PropertiesA, typename PropertiesB>
283254
annotated_arg(annotated_arg<T, PropertiesA>, PropertiesB>) ->
284255
annotated_arg<T, /* a type that combines the properties of PropertiesA and PropertiesB */>;
285256
286-
// Overloaded operators for raw type
287-
template <typename T, typename PropertyList, typename T2,
288-
typename R = decltype(std::declval<T>() + std::declval<T2>())>
289-
R operator+(const annotated_arg<T, PropertyList> &a, const T2 &b);
290-
291-
template <typename T, typename PropertyList, typename T2,
292-
typename R = decltype(std::declval<T>() - std::declval<T2>())>
293-
R operator-(const annotated_arg<T, PropertyList> &a, const T2 &b);
294-
295-
template <typename T, typename PropertyList, typename T2,
296-
typename R = decltype(std::declval<T>() * std::declval<T2>())>
297-
R operator*(const annotated_arg<T, PropertyList> &a, const T2 &b);
298-
299-
template <typename T, typename PropertyList, typename T2,
300-
typename R = decltype(std::declval<T>() / std::declval<T2>())>
301-
R operator/(const annotated_arg<T, PropertyList> &a, const T2 &b);
302-
303-
template <typename T, typename PropertyList, typename T2,
304-
typename R = decltype(std::declval<T>() % std::declval<T2>())>
305-
R operator%(const annotated_arg<T, PropertyList> &a, const T2 &b);
306-
307-
template <typename T, typename PropertyList, typename T2,
308-
typename R = decltype(std::declval<T>() & std::declval<T2>())>
309-
R operator&(const annotated_arg<T, PropertyList> &a, const T2 &b);
310-
311-
template <typename T, typename PropertyList, typename T2,
312-
typename R = decltype(std::declval<T>() | std::declval<T2>())>
313-
R operator|(const annotated_arg<T, PropertyList> &a, const T2 &b);
314-
315-
template <typename T, typename PropertyList, typename T2,
316-
typename R = decltype(std::declval<T>() ^ std::declval<T2>())>
317-
R operator^(const annotated_arg<T, PropertyList> &a, const T2 &b);
318-
319-
template <typename T, typename PropertyList, typename T2,
320-
typename R = decltype(std::declval<T>() >> std::declval<T2>())>
321-
R operator>>(const annotated_arg<T, PropertyList> &a, const T2 &b);
322-
323-
template <typename T, typename PropertyList, typename T2,
324-
typename R = decltype(std::declval<T>() << std::declval<T2>())>
325-
R operator<<(const annotated_arg<T, PropertyList> &a, const T2 &b);
326-
327-
template <typename T, typename T2, typename PropertyList2,
328-
typename R = decltype(std::declval<T>() + std::declval<T2>())>
329-
R operator+(const T &a, const annotated_arg<T2, PropertyList2> &b);
330-
331-
template <typename T, typename T2, typename PropertyList2,
332-
typename R = decltype(std::declval<T>() - std::declval<T2>())>
333-
R operator-(const T &a, const annotated_arg<T2, PropertyList2> &b);
334-
335-
template <typename T, typename T2, typename PropertyList2,
336-
typename R = decltype(std::declval<T>() * std::declval<T2>())>
337-
R operator*(const T &a, const annotated_arg<T2, PropertyList2> &b);
338-
339-
template <typename T, typename T2, typename PropertyList2,
340-
typename R = decltype(std::declval<T>() / std::declval<T2>())>
341-
R operator/(const T &a, const annotated_arg<T2, PropertyList2> &b);
342-
343-
template <typename T, typename T2, typename PropertyList2,
344-
typename R = decltype(std::declval<T>() % std::declval<T2>())>
345-
R operator%(const T &a, const annotated_arg<T2, PropertyList2> &b);
346-
347-
template <typename T, typename T2, typename PropertyList2,
348-
typename R = decltype(std::declval<T>() & std::declval<T2>())>
349-
R operator&(const T &a, const annotated_arg<T2, PropertyList2> &b);
350-
351-
template <typename T, typename T2, typename PropertyList2,
352-
typename R = decltype(std::declval<T>() | std::declval<T2>())>
353-
R operator|(const T &a, const annotated_arg<T2, PropertyList2> &b);
354-
355-
template <typename T, typename T2, typename PropertyList2,
356-
typename R = decltype(std::declval<T>() ^ std::declval<T2>())>
357-
R operator^(const T &a, const annotated_arg<T2, PropertyList2> &b);
358-
359-
template <typename T, typename T2, typename PropertyList2,
360-
typename R = decltype(std::declval<T>() >> std::declval<T2>())>
361-
R operator>>(const T &a, const annotated_arg<T2, PropertyList2> &b);
362-
363-
template <typename T, typename T2, typename PropertyList2,
364-
typename R = decltype(std::declval<T>() << std::declval<T2>())>
365-
R operator<<(const T &a, const annotated_arg<T2, PropertyList2> &b);
366257
367258
} // namespace sycl::ext::oneapi::experimental
368259
----
@@ -512,41 +403,55 @@ constant property.
512403
a|
513404
[source,c++]
514405
----
515-
template <typename T2, typename PropertyList2,
516-
typename R = decltype(std::declval<T>() OP std::declval<T2>())>
517-
R operatorOP(const annotated_arg<T2, PropertyList2> &other) const;
406+
template <typename O>
407+
auto friend operatorOP(O&& a, const annotated_arg& b) ->
408+
decltype(std::forward<O>(a) OP std::declval<T>());
518409
----
519-
|
520-
Defines the overloaded operators for types `annotated_arg<T, ...>` and
521-
`annotated_arg<T2, ...>`. Let `operatorOP` denote the operator used.
522-
The overloaded operator `operatorOP` utilizes `operatorOP(T, T2)` and
523-
is available only if `operatorOP(T, T2)` is well formed. The value and result
524-
is the same as the result of `operatorOP(T, T2)` applied to the objects of
525-
type `T` and `T2`.
410+
a|
411+
Where [code]#OP# is: [code]#pass:[+]#, [code]#-#,[code]#*#, [code]#/#, [code]#%#, [code]#+<<+#, [code]#>>#, [code]#&#, [code]#\|#, [code]#\^#, [code]#<#, [code]#<=#, [code]#>#, [code]#>=#, [code]#==#, [code]#!=#, [code]#&&#, [code]#\|\|#.
526412

527-
`operatorOP` is any of the following: `operator+`, `operator-`, `operator*`, `operator/`,
528-
`operator%`, `operator&`, `operator\|`, `operator^`, `operator>>`, and `operator<<`.
413+
Defines a hidden friend operator `OP` overload for type `O` and `annotated_arg`.
529414

530-
|===
415+
Let `operatorOP` denotes the operator used. The overloaded operator `operatorOP` utilizes
416+
`operatorOP(O&&, T&&)` and is available only if `operatorOP(O&&, T&&)` is well formed. The value and result
417+
is the same as the result of `operatorOP(O&&, T&&)` applied to the objects of
418+
type `O` and `T`.
531419

532-
Free functions of the following form are defined for the overloaded operators for types
533-
`annotated_arg<T, ...>` and raw type `T2`. Let `operatorOP` denote the operator used.
534-
The overloaded operator `operatorOP` utilizes `operatorOP(T, T2)` and is available only
535-
if `operatorOP(T, T2)` is well formed. The value and result is the same as the result of
536-
`operatorOP(T, T2)` applied to the underlying objects of type `T` and `T2`.
420+
a|
421+
[source,c++]
422+
----
423+
template <typename O>
424+
auto friend operatorOP(const annotated_ref& a, O&& b) ->
425+
decltype(std::declval<T>() OP std::forward<O>(b));
426+
----
427+
a|
428+
Where [code]#OP# is: [code]#pass:[+]#, [code]#-#,[code]#*#, [code]#/#, [code]#%#, [code]#+<<+#, [code]#>>#, [code]#&#, [code]#\|#, [code]#\^#, [code]#<#, [code]#<=#, [code]#>#, [code]#>=#, [code]#==#, [code]#!=#, [code]#&&#, [code]#\|\|#.
429+
430+
Defines a hidden friend operator `OP` overload for type `annotated_arg` and `O`. `O` cannot be
431+
a type of `annotated_arg`.
537432

433+
Let `operatorOP` denotes the operator used. The overloaded operator `operatorOP` utilizes
434+
`operatorOP(T&&, O&&)` and is available only if `operatorOP(T&&, O&&)` is well formed. The value and result
435+
is the same as the result of `operatorOP(T&&, O&&)` applied to the objects of
436+
type `T` and `O`.
437+
438+
a|
538439
[source,c++]
539440
----
540-
template <typename T, typename PropertyList, typename T2,
541-
typename R = decltype(std::declval<T>() OP std::declval<T2>())>
542-
R operatorOP(const annotated_arg<T, PropertyList> &a, const T2 &b);
543-
template <typename T, typename T2, typename PropertyList2,
544-
typename R = decltype(std::declval<T>() OP std::declval<T2>())>
545-
R operatorOP(const T &a, const annotated_arg<T2, PropertyList2> &b);
441+
template <typename O=T>
442+
auto operatorOP() -> decltype(OP std::declval<O>());
546443
----
444+
a|
445+
Where [code]#OP# is: [code]#pass:[+]#, [code]#-#, [code]#!#, [code]#~#.
446+
447+
Defines a operator `OP` overload for types `O` where the default type is `T`.
547448

548-
`operatorOP` is any of the following: `operator+`, `operator-`, `operator*`, `operator/`,
549-
`operator%`, `operator&`, `operator\|`, `operator^`, `operator>>`, and `operator<<`.
449+
Let `operatorOP` denotes the operator used. The overloaded operator
450+
`operatorOP` utilizes `operatorOP(O)` and is available only if `operatorOP(O)`
451+
is well formed. The value and result is the same as the result of `operatorOP(O)`
452+
applied to the objects of type `O`.
453+
454+
|===
550455

551456
== Issues
552457

0 commit comments

Comments
 (0)