Skip to content

Commit d6a5ee7

Browse files
committed
Introduce [parallel.simd.whereexpr]
1 parent a5c3e96 commit d6a5ee7

File tree

1 file changed

+280
-0
lines changed

1 file changed

+280
-0
lines changed

data_parallel_types.html

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,286 @@ <h1><ins><code>simd</code> type traits</ins></h1>
545545
</p>
546546
</cxx-section>
547547

548+
<cxx-section id="parallel.simd.whereexpr">
549+
<h1><ins>Class templates <code>const_where_expression</code> and <code>where_expression</code></ins></h1>
550+
<ins>
551+
<pre>
552+
namespace std::experimental {
553+
inline namespace parallelism_v2 {
554+
template&lt;class M, class T&gt; class const_where_expression {
555+
const M mask; // exposition only
556+
T& data; // exposision only
557+
558+
public:
559+
const_where_expression(const const_where_expression&) = delete;
560+
const_where_expression& operator=(const const_where_expression&) = delete;
561+
562+
T operator-() const &&;
563+
T operator+() const &&;
564+
T operator~() const &&;
565+
566+
template&lt;class U, class Flags&gt; void copy_to(U* mem, Flags f) const &&;
567+
};
568+
569+
template&lt;class M, class T&gt;
570+
class where_expression : public const_where_expression&lt;M, T&gt; {
571+
public:
572+
template&lt;class U&gt; void operator=(U&& x) &&;
573+
template&lt;class U&gt; void operator+=(U&& x) &&;
574+
template&lt;class U&gt; void operator-=(U&& x) &&;
575+
template&lt;class U&gt; void operator*=(U&& x) &&;
576+
template&lt;class U&gt; void operator/=(U&& x) &&;
577+
template&lt;class U&gt; void operator%=(U&& x) &&;
578+
template&lt;class U&gt; void operator&=(U&& x) &&;
579+
template&lt;class U&gt; void operator|=(U&& x) &&;
580+
template&lt;class U&gt; void operator^=(U&& x) &&;
581+
template&lt;class U&gt; void operator&lt;&lt;=(U&& x) &&;
582+
template&lt;class U&gt; void operator&gt;&gt;=(U&& x) &&;
583+
void operator++() &&
584+
void operator++(int) &&
585+
void operator--() &&
586+
void operator--(int) &&
587+
588+
template&lt;class U, class Flags&gt; void copy_from(const U* mem, Flags) &&;
589+
};
590+
}
591+
}
592+
</pre>
593+
</ins>
594+
595+
<p>
596+
<ins>
597+
The class templates <code>const_where_expression</code> and <code>where_expression</code> abstract the notion of selecting elements of a given object of arithmetic or data-parallel type.
598+
</ins>
599+
</p>
600+
601+
<p>
602+
<ins>
603+
The first templates argument <code>M</code> shall be cv-unqualified <code>bool</code> or a cv-unqualified <code>simd_mask</code> specialization.
604+
</ins>
605+
</p>
606+
607+
<p>
608+
<ins>
609+
If <code>M</code> is <code>bool</code>, <code>T</code> shall be a cv-unqualified arithmetic type. Otherwise, <code>T</code> shall either be <code>M</code> or <code>typename M::simd_type</code>.
610+
</ins>
611+
</p>
612+
613+
<p>
614+
<ins>
615+
In this subclause, <code>data[0]</code> is used interchangably for <code>data</code>, <code>mask[0]</code> is used interchangably for <code>mask</code>, and <code>M::size()</code> is used interchangably for <code>1</code>.
616+
</ins>
617+
</p>
618+
619+
<p>
620+
<ins>
621+
The <em>selected indices</em> signify the integers <code>i</code> &#8714; {<em>j</em> &#8714; &#8469;<sub>0</sub> &#8739; <em>j</em> &lt; <code>M::size()</code> &#8896; <code>mask[</code><em>j</em><code>]</code> }. The <em>selected elements</em> signify the elements <code>data[i]</code> for all selected indices <code>i</code>.
622+
</ins>
623+
</p>
624+
625+
<p>
626+
<ins>
627+
In this subclause, the <code>value_type</code> is an alias for <code>T</code> if <code>M</code> is <code>bool</code>, or an alias for <code>typename T::value_type</code> if <code>is_simd_mask_v&lt;M&gt;</code> is <code>true</code>.
628+
</ins>
629+
<p>
630+
631+
<p>
632+
<ins>
633+
<cxx-note>The <code>where</code> functions <cxx-ref to="parallel.simd.mask.where"></cxx-ref> initialize <code>mask</code> with the first argument to <code>where</code> and <code>data</code> with the second argument to <code>where</code>.</cxx-note>
634+
</ins>
635+
</p>
636+
637+
<cxx-function>
638+
<cxx-signature><ins>
639+
T operator-() const &&;
640+
T operator+() const &&;
641+
T operator~() const &&;
642+
</ins>
643+
</cxx-signature>
644+
645+
<ins>
646+
<cxx-returns>
647+
<ins>
648+
A copy of <code>data</code> with the indicated unary operator applied to all selected elements.
649+
</ins>
650+
</cxx-returns>
651+
</ins>
652+
653+
<ins>
654+
<cxx-throws>
655+
<ins>
656+
Nothing.
657+
</ins>
658+
</cxx-throws>
659+
</ins>
660+
</cxx-function>
661+
662+
<cxx-function>
663+
<cxx-signature>
664+
<ins>
665+
template&lt;class U, class Flags&gt; void copy_to(U* mem, Flags) const &&;
666+
</ins>
667+
</cxx-signature>
668+
669+
<cxx-requires>
670+
<ins>
671+
If the template parameter <code>Flags</code> is <code>vector_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>memory_alignment_v&lt;T, U&gt;</code>. If the template parameter <code>flags</code> is <code>overaligned_tag&lt;N&gt;</code>, <code>mem</code> shall point to storage aligned by <code>N</code>. If the template parameter <code>Flags</code> is <code>element_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>alignof(U)</code>. If <code>M</code> is not <code>bool</code>, the largest <em>i</em> &#8714; <code>[0, M::size())</code> where <code>mask[i]</code> is <code>true</code> is less than the number of values pointed to by <code>mem</code>.
672+
</ins>
673+
</cxx-requires>
674+
675+
<cxx-effects>
676+
<ins>
677+
Copies the selected elements as if <code>mem[i] = static_cast&lt;U&gt;(data[i])</code> for all selected indices <code>i</code>.
678+
</ins>
679+
</cxx-effects>
680+
681+
<cxx-throws>
682+
<ins>
683+
Nothing.
684+
</ins>
685+
</cxx-throws>
686+
687+
<cxx-remarks>
688+
<ins>
689+
This function shall not participate in overload resolution unless
690+
691+
<bl>
692+
<li>
693+
<code>is_simd_flag_type_v&lt;Flags&gt;</code> is <code>true</code>, and
694+
</li>
695+
696+
<li>
697+
either
698+
699+
<ul>
700+
<li>
701+
<code>U</code> is <code>bool</code> and <code>value_type</code> is <code>bool</code>, or
702+
</li>
703+
704+
<li>
705+
<code>U</code> is a vectorizable type and <code>value_type</code> is not <code>bool</code>.
706+
</li>
707+
</ul>
708+
</li>
709+
</bl>
710+
</ins>
711+
</cxx-remarks>
712+
</cxx-function>
713+
714+
<cxx-function>
715+
<cxx-signature><ins>
716+
template&lt;class U&gt; void operator=(U&& x) &&;
717+
</ins>
718+
</cxx-signature>
719+
720+
<cxx-effects>
721+
<ins>
722+
Replaces <code>data[i]</code> with <code>static_cast&lt;T&gt;(std::forward&lt;U&gt;(x))[i]</code> for all selected indices <code>i</code>.
723+
</ins>
724+
</cxx-effects>
725+
726+
<cxx-remarks>
727+
<ins>
728+
This operator shall not participate in overload resolution unless <code>U</code> is convertible to <code>T</code>.
729+
</ins>
730+
</cxx-remarks>
731+
</cxx-function>
732+
733+
<cxx-function>
734+
<cxx-signature><ins>
735+
template&lt;class U&gt; void operator+=(U&& x) &&;
736+
template&lt;class U&gt; void operator-=(U&& x) &&;
737+
template&lt;class U&gt; void operator*=(U&& x) &&;
738+
template&lt;class U&gt; void operator/=(U&& x) &&;
739+
template&lt;class U&gt; void operator%=(U&& x) &&;
740+
template&lt;class U&gt; void operator&=(U&& x) &&;
741+
template&lt;class U&gt; void operator|=(U&& x) &&;
742+
template&lt;class U&gt; void operator^=(U&& x) &&;
743+
template&lt;class U&gt; void operator&lt;&lt;=(U&& x) &&;
744+
template&lt;class U&gt; void operator&gt;&gt;=(U&& x) &&;</ins>
745+
</cxx-signature>
746+
747+
<cxx-effects>
748+
<ins>
749+
Replaces <code>data[i]</code> with <code>static_cast&lt;T&gt;(data @ std::forward&lt;U&gt;(x))[i]</code> (where <code>@</code> denotes the indicated operator) for all selected indices <code>i</code>.
750+
</ins>
751+
</cxx-effects>
752+
753+
<cxx-remarks>
754+
<ins>
755+
Each of these operators shall not participate in overload resolution unless the return type of <code>data @ std::forward&lt;U&gt;(x)</code> is convertible to <code>T</code>. It is unspecified whether the binary operator, implied by the compound assignment operator, is executed on all elements or only on the selected elements.
756+
</ins>
757+
</cxx-remarks>
758+
</cxx-function>
759+
760+
<cxx-function>
761+
<cxx-signature><ins>
762+
void operator++() &&;
763+
void operator++(int) &&;
764+
void operator--() &&;
765+
void operator--(int) &&;
766+
</ins>
767+
</cxx-signature>
768+
769+
<cxx-effects>
770+
<ins>
771+
Applies the indicated operator to the selected elements.
772+
</ins>
773+
</cxx-effects>
774+
775+
<cxx-remarks>
776+
<ins>
777+
Each of these operators shall not participate in overload resolution unless the indicated operator can be applied to objects of type <code>T</code>.
778+
</ins>
779+
</cxx-remarks>
780+
</cxx-signature>
781+
</cxx-function>
782+
783+
<cxx-function>
784+
<cxx-signature><ins>
785+
template&lt;class U, class Flags&gt; void copy_from(const U* mem, Flags) &&;</ins>
786+
</cxx-signature>
787+
788+
<cxx-requires>
789+
<ins>
790+
If the template parameter <code>Flags</code> is <code>vector_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>memory_alignment_v&lt;T, U&gt;</code>. If the template parameter <code>Flags</code> is <code>overaligned_tag&lt;N&gt;</code>, <code>mem</code> shall point to storage aligned by <code>N</code>. If the template parameter <code>Flags</code> is <code>element_aligned_tag</code>, <code>mem</code> shall point to storage aligned by <code>alignon(U)</code>. If <code>is_simd_flag_type_v&lt;U&gt;</code> is <code>true</code>, for all selected indices <em>i</em>, <em>i</em> shall be less than the number of values pointed to by <code>mem</code>.
791+
</ins>
792+
</cxx-requires>
793+
794+
<cxx-effects>
795+
<ins>
796+
Replaces the selected elements as if <code>data[i] = static_cast&lt;value_type&gt;(mem[i])</code> for all selected indices <code>i</code>.
797+
</ins>
798+
</cxx-effects>
799+
800+
<cxx-remarks>
801+
<ins>
802+
This function shall not participate in overload resolution unless
803+
804+
<bl>
805+
<li>
806+
<code>is_simd_flag_type_v&lt;Flags&gt;</code> is <code>true</code>, and
807+
</li>
808+
809+
<li>
810+
either
811+
812+
<ul>
813+
<li>
814+
<code>U</code> is <code>bool</code> and <code>value_type</code> is <code>bool</code>, or
815+
</li>
816+
817+
<li>
818+
<code>U</code> is a vectorizable type and <code>value_type</code> is not <code>bool</code>.
819+
</li>
820+
</ul>
821+
</li>
822+
</bl>
823+
</ins>
824+
</cxx-remarks>
825+
</cxx-function>
826+
</cxx-section>
827+
548828
<cxx-section id="parallel.simd.overview">
549829
</cxx-section>
550830
</cxx-clause>

0 commit comments

Comments
 (0)