@@ -549,14 +549,32 @@ class annotated_ref {
549
549
public:
550
550
annotated_ref(const annotated_ref&) = delete;
551
551
operator T() const;
552
- T operator=(T) const;
552
+
553
+ template <typename O> //available only if O is not an annotated_ref type
554
+ T operator=(O&&) const;
553
555
T operator=(const annotated_ref&) const;
556
+
554
557
// OP is: +=, -=, *=, /=, %=, <<=, >>=, &=, |=, ^=
555
- T operatorOP(T) const;
558
+ template <typename O> //available only if O is not an annotated_ref type
559
+ T operatorOP(O&& a) const;
560
+ T operatorOP(const annotated_ref &b) const;
561
+
556
562
T operator++() const;
557
563
T operator++(int) const;
558
564
T operator--() const;
559
565
T operator--(int) const;
566
+
567
+ // OP is: +, -, *, /, %, <<, >>, &, |, ^, <, <=, >, >=, ==, ~=, &&, ||
568
+ template <typename O>
569
+ auto friend operatorOP(O&& a, const annotated_ref& b) ->
570
+ decltype(std::forward<O>(a) OP std::declval<T>());
571
+ template <typename O> //available only if O is not an annotated_ref type
572
+ auto friend operatorOP(const annotated_ref& a, O&& b) ->
573
+ decltype(std::declval<T>() OP std::forward<O>(b));
574
+
575
+ // OP is: +, -, !, ~
576
+ template <typename O=T>
577
+ auto operatorOP() -> decltype(OP std::declval<O>());
560
578
};
561
579
} // namespace sycl::ext::oneapi::experimental
562
580
```
@@ -581,10 +599,13 @@ annotations when the object is loaded from memory.
581
599
a|
582
600
[source,c++]
583
601
----
584
- T operator=(T) const;
602
+ template <typename O>
603
+ T operator=(O&&) const;
585
604
----
586
605
|
587
- Writes an object of type `T` to the location referenced by this wrapper,
606
+ Writes an object of type `O` to the location referenced by this wrapper.
607
+ `O` cannot be a type of `annotated_ref`.
608
+
588
609
applying the annotations when the object is stored to memory.
589
610
590
611
// --- ROW BREAK ---
@@ -608,18 +629,47 @@ Does not rebind the reference!
608
629
a|
609
630
[source,c++]
610
631
----
611
- T operatorOP(T) const;
632
+ template <typename O>
633
+ T operatorOP(O&& a) const;
612
634
----
613
635
a|
614
636
Where [code]#OP# is: [code]#pass:[+=]#, [code]#-=#,[code]#*=#, [code]#/=#, [code]#%=#, [code]#+<<=+#, [code]#>>=#, [code]#&=#, [code]#\|=#, [code]#^=#.
615
637
616
- Compound assignment operators. Return result by value.
638
+ Compound assignment operators for type `O`. `O` cannot be a type of `annotated_ref`.
639
+
640
+ Return result by value.
641
+
642
+ Available only if the corresponding assignment operator OP is available for `T` taking a type of `O`.
643
+ Equivalent to:
644
+ ```c++
645
+ T tmp = *this; // Reads from memory
646
+ // with annotations
647
+ tmp OP std::forward<O>(a);
648
+ *this = tmp; // Writes to memory
649
+ // with annotations
650
+ return tmp;
651
+ ```
652
+ // --- ROW BREAK ---
653
+ a|
654
+ [source,c++]
655
+ ----
656
+ T operatorOP(const annotated_ref &b) const;
657
+ ----
658
+ a|
659
+ Where [code]#OP# is: [code]#pass:[+=]#, [code]#-=#,[code]#*=#, [code]#/=#, [code]#%=#, [code]#+<<=+#, [code]#>>=#, [code]#&=#, [code]#\|=#, [code]#^=#.
660
+
661
+ Compound assignment operators for type `annotated_ref`.
662
+
663
+ Return result by value.
664
+
617
665
Available only if the corresponding assignment operator OP is available for `T`.
618
666
Equivalent to:
619
667
```c++
620
668
T tmp = *this; // Reads from memory
621
669
// with annotations
622
- tmp OP val;
670
+ T tmp2 = b; // Reads from memory
671
+ // with annotations
672
+ tmp OP b;
623
673
*this = tmp; // Writes to memory
624
674
// with annotations
625
675
return tmp;
@@ -638,6 +688,64 @@ Increment and decrement operator of annotated_ref. Increment/Decrement the objec
638
688
referenced by this wrapper via ``T``'s Increment/Decrement operator.
639
689
640
690
The annotations are applied when the object `T` is loaded and stored to the memory.
691
+
692
+ a|
693
+ [source,c++]
694
+ ----
695
+ template <typename O>
696
+ auto friend operatorOP(O&& a, const annotated_ref& b) ->
697
+ decltype(std::forward<O>(a) OP std::declval<T>());
698
+ ----
699
+ a|
700
+ Where [code]#OP# is: [code]#pass:[+]#, [code]#-#,[code]#*#, [code]#/#, [code]#%#, [code]#+<<+#, [code]#>>#, [code]#&#, [code]#\|#, [code]#\^#, [code]#<#, [code]#<=#, [code]#>#, [code]#>=#, [code]#==#, [code]#!=#, [code]#&&#, [code]#\|\|#.
701
+
702
+ Defines a hidden friend operator `OP` overload for type `O` and `annotated_ref`.
703
+
704
+ Let `operatorOP` denotes the operator used. The overloaded operator `operatorOP` utilizes
705
+ `operatorOP(O&&, T&&)` and is available only if `operatorOP(O&&, T&&)` is well formed. The value and result
706
+ is the same as the result of `operatorOP(O&&, T&&)` applied to the objects of
707
+ type `O` and `T`.
708
+
709
+ The annotations from `PropertyListT` are applied when the object `b` is loaded from memory.
710
+
711
+ a|
712
+ [source,c++]
713
+ ----
714
+ template <typename O>
715
+ auto friend operatorOP(const annotated_ref& a, O&& b) ->
716
+ decltype(std::declval<T>() OP std::forward<O>(b));
717
+ ----
718
+ a|
719
+ Where [code]#OP# is: [code]#pass:[+]#, [code]#-#,[code]#*#, [code]#/#, [code]#%#, [code]#+<<+#, [code]#>>#, [code]#&#, [code]#\|#, [code]#\^#, [code]#<#, [code]#<=#, [code]#>#, [code]#>=#, [code]#==#, [code]#!=#, [code]#&&#, [code]#\|\|#.
720
+
721
+ Defines a hidden friend operator `OP` overload for type `annotated_ref` and `O`. `O` cannot be
722
+ a type of `annotated_ref`.
723
+
724
+ Let `operatorOP` denotes the operator used. The overloaded operator `operatorOP` utilizes
725
+ `operatorOP(T&&, O&&)` and is available only if `operatorOP(T&&, O&&)` is well formed. The value and result
726
+ is the same as the result of `operatorOP(T&&, O&&)` applied to the objects of
727
+ type `T` and `O`.
728
+
729
+ The annotations from `PropertyListT` are applied when the object `a` is loaded from memory.
730
+
731
+ a|
732
+ [source,c++]
733
+ ----
734
+ template <typename O=T>
735
+ auto operatorOP() -> decltype(OP std::declval<O>());
736
+ ----
737
+ a|
738
+ Where [code]#OP# is: [code]#pass:[+]#, [code]#-#, [code]#!#, [code]#~#.
739
+
740
+ Defines a operator `OP` overload for types `O` where the default type is `T`.
741
+
742
+ Let `operatorOP` denotes the operator used. The overloaded operator
743
+ `operatorOP` utilizes `operatorOP(O)` and is available only if `operatorOP(O)`
744
+ is well formed. The value and result is the same as the result of `operatorOP(O)`
745
+ applied to the objects of type `O`.
746
+
747
+ The annotations from `PropertyListT` are applied when the object `a` is loaded from memory.
748
+
641
749
|===
642
750
643
751
== Issues related to `annotated_ptr`
@@ -685,6 +793,7 @@ the alignment is set up.
685
793
[options="header"]
686
794
|========================================
687
795
|Rev|Date|Author|Changes
796
+ |5|2023-11-30|Brox Chen|API fixes: operators fowarding for annnotated_ref
688
797
|4|2023-06-28|Roland Schulz|API fixes: constructors and annotated_ref assignment
689
798
|3|2022-04-05|Abhishek Tiwari|*Addressed review comments*
690
799
|2|2022-03-07|Abhishek Tiwari|*Corrected API and updated description*
0 commit comments