xref: /aosp_15_r20/external/libcxx/include/experimental/simd (revision 58b9f456b02922dfdb1fad8a988d5fd8765ecb80)
1*58b9f456SAndroid Build Coastguard Worker// -*- C++ -*-
2*58b9f456SAndroid Build Coastguard Worker//===------------------------------- simd ---------------------------------===//
3*58b9f456SAndroid Build Coastguard Worker//
4*58b9f456SAndroid Build Coastguard Worker//                     The LLVM Compiler Infrastructure
5*58b9f456SAndroid Build Coastguard Worker//
6*58b9f456SAndroid Build Coastguard Worker// This file is dual licensed under the MIT and the University of Illinois Open
7*58b9f456SAndroid Build Coastguard Worker// Source Licenses. See LICENSE.TXT for details.
8*58b9f456SAndroid Build Coastguard Worker//
9*58b9f456SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
10*58b9f456SAndroid Build Coastguard Worker#ifndef _LIBCPP_EXPERIMENTAL_SIMD
11*58b9f456SAndroid Build Coastguard Worker#define _LIBCPP_EXPERIMENTAL_SIMD
12*58b9f456SAndroid Build Coastguard Worker
13*58b9f456SAndroid Build Coastguard Worker/*
14*58b9f456SAndroid Build Coastguard Worker    experimental/simd synopsis
15*58b9f456SAndroid Build Coastguard Worker
16*58b9f456SAndroid Build Coastguard Workernamespace std::experimental {
17*58b9f456SAndroid Build Coastguard Worker
18*58b9f456SAndroid Build Coastguard Workerinline namespace parallelism_v2 {
19*58b9f456SAndroid Build Coastguard Worker
20*58b9f456SAndroid Build Coastguard Workernamespace simd_abi {
21*58b9f456SAndroid Build Coastguard Worker
22*58b9f456SAndroid Build Coastguard Workerstruct scalar {};
23*58b9f456SAndroid Build Coastguard Workertemplate <int N> struct fixed_size {};
24*58b9f456SAndroid Build Coastguard Workertemplate <typename T> inline constexpr int max_fixed_size = implementation-defined;
25*58b9f456SAndroid Build Coastguard Workertemplate <typename T> using compatible = implementation-defined;
26*58b9f456SAndroid Build Coastguard Workertemplate <typename T> using native = implementation-defined;
27*58b9f456SAndroid Build Coastguard Worker
28*58b9f456SAndroid Build Coastguard Worker} // simd_abi
29*58b9f456SAndroid Build Coastguard Worker
30*58b9f456SAndroid Build Coastguard Workerstruct element_aligned_tag {};
31*58b9f456SAndroid Build Coastguard Workerstruct vector_aligned_tag {};
32*58b9f456SAndroid Build Coastguard Workertemplate <size_t> struct overaligned_tag {};
33*58b9f456SAndroid Build Coastguard Workerinline constexpr element_aligned_tag element_aligned{};
34*58b9f456SAndroid Build Coastguard Workerinline constexpr vector_aligned_tag vector_aligned{};
35*58b9f456SAndroid Build Coastguard Workertemplate <size_t N> inline constexpr overaligned_tag<N> overaligned{};
36*58b9f456SAndroid Build Coastguard Worker
37*58b9f456SAndroid Build Coastguard Worker// traits [simd.traits]
38*58b9f456SAndroid Build Coastguard Workertemplate <class T> struct is_abi_tag;
39*58b9f456SAndroid Build Coastguard Workertemplate <class T> inline constexpr bool is_abi_tag_v = is_abi_tag<T>::value;
40*58b9f456SAndroid Build Coastguard Worker
41*58b9f456SAndroid Build Coastguard Workertemplate <class T> struct is_simd;
42*58b9f456SAndroid Build Coastguard Workertemplate <class T> inline constexpr bool is_simd_v = is_simd<T>::value;
43*58b9f456SAndroid Build Coastguard Worker
44*58b9f456SAndroid Build Coastguard Workertemplate <class T> struct is_simd_mask;
45*58b9f456SAndroid Build Coastguard Workertemplate <class T> inline constexpr bool is_simd_mask_v = is_simd_mask<T>::value;
46*58b9f456SAndroid Build Coastguard Worker
47*58b9f456SAndroid Build Coastguard Workertemplate <class T> struct is_simd_flag_type;
48*58b9f456SAndroid Build Coastguard Workertemplate <class T> inline constexpr bool is_simd_flag_type_v = is_simd_flag_type<T>::value;
49*58b9f456SAndroid Build Coastguard Worker
50*58b9f456SAndroid Build Coastguard Workertemplate <class T, size_t N> struct abi_for_size { using type = see below; };
51*58b9f456SAndroid Build Coastguard Workertemplate <class T, size_t N> using abi_for_size_t = typename abi_for_size<T, N>::type;
52*58b9f456SAndroid Build Coastguard Worker
53*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi = simd_abi::compatible<T>> struct simd_size;
54*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi = simd_abi::compatible<T>>
55*58b9f456SAndroid Build Coastguard Workerinline constexpr size_t simd_size_v = simd_size<T, Abi>::value;
56*58b9f456SAndroid Build Coastguard Worker
57*58b9f456SAndroid Build Coastguard Workertemplate <class T, class U = typename T::value_type> struct memory_alignment;
58*58b9f456SAndroid Build Coastguard Workertemplate <class T, class U = typename T::value_type>
59*58b9f456SAndroid Build Coastguard Workerinline constexpr size_t memory_alignment_v = memory_alignment<T, U>::value;
60*58b9f456SAndroid Build Coastguard Worker
61*58b9f456SAndroid Build Coastguard Worker// class template simd [simd.class]
62*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi = simd_abi::compatible<T>> class simd;
63*58b9f456SAndroid Build Coastguard Workertemplate <class T> using native_simd = simd<T, simd_abi::native<T>>;
64*58b9f456SAndroid Build Coastguard Workertemplate <class T, int N> using fixed_size_simd = simd<T, simd_abi::fixed_size<N>>;
65*58b9f456SAndroid Build Coastguard Worker
66*58b9f456SAndroid Build Coastguard Worker// class template simd_mask [simd.mask.class]
67*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi = simd_abi::compatible<T>> class simd_mask;
68*58b9f456SAndroid Build Coastguard Workertemplate <class T> using native_simd_mask = simd_mask<T, simd_abi::native<T>>;
69*58b9f456SAndroid Build Coastguard Workertemplate <class T, int N> using fixed_size_simd_mask = simd_mask<T, simd_abi::fixed_size<N>>;
70*58b9f456SAndroid Build Coastguard Worker
71*58b9f456SAndroid Build Coastguard Worker// casts [simd.casts]
72*58b9f456SAndroid Build Coastguard Workertemplate <class T, class U, class Abi> see below simd_cast(const simd<U, Abi>&);
73*58b9f456SAndroid Build Coastguard Workertemplate <class T, class U, class Abi> see below static_simd_cast(const simd<U, Abi>&);
74*58b9f456SAndroid Build Coastguard Worker
75*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi>
76*58b9f456SAndroid Build Coastguard Workerfixed_size_simd<T, simd_size_v<T, Abi>> to_fixed_size(const simd<T, Abi>&) noexcept;
77*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi>
78*58b9f456SAndroid Build Coastguard Workerfixed_size_simd_mask<T, simd_size_v<T, Abi>> to_fixed_size(const simd_mask<T, Abi>&) noexcept;
79*58b9f456SAndroid Build Coastguard Workertemplate <class T, size_t N> native_simd<T> to_native(const fixed_size_simd<T, N>&) noexcept;
80*58b9f456SAndroid Build Coastguard Workertemplate <class T, size_t N>
81*58b9f456SAndroid Build Coastguard Workernative_simd_mask<T> to_native(const fixed_size_simd_mask<T, N>> &) noexcept;
82*58b9f456SAndroid Build Coastguard Workertemplate <class T, size_t N> simd<T> to_compatible(const fixed_size_simd<T, N>&) noexcept;
83*58b9f456SAndroid Build Coastguard Workertemplate <class T, size_t N> simd_mask<T> to_compatible(const fixed_size_simd_mask<T, N>&) noexcept;
84*58b9f456SAndroid Build Coastguard Worker
85*58b9f456SAndroid Build Coastguard Workertemplate <size_t... Sizes, class T, class Abi>
86*58b9f456SAndroid Build Coastguard Workertuple<simd<T, abi_for_size_t<Sizes>>...> split(const simd<T, Abi>&);
87*58b9f456SAndroid Build Coastguard Workertemplate <size_t... Sizes, class T, class Abi>
88*58b9f456SAndroid Build Coastguard Workertuple<simd_mask<T, abi_for_size_t<Sizes>>...> split(const simd_mask<T, Abi>&);
89*58b9f456SAndroid Build Coastguard Workertemplate <class V, class Abi>
90*58b9f456SAndroid Build Coastguard Workerarray<V, simd_size_v<typename V::value_type, Abi> / V::size()> split(
91*58b9f456SAndroid Build Coastguard Workerconst simd<typename V::value_type, Abi>&);
92*58b9f456SAndroid Build Coastguard Workertemplate <class V, class Abi>
93*58b9f456SAndroid Build Coastguard Workerarray<V, simd_size_v<typename V::value_type, Abi> / V::size()> split(
94*58b9f456SAndroid Build Coastguard Workerconst simd_mask<typename V::value_type, Abi>&);
95*58b9f456SAndroid Build Coastguard Worker
96*58b9f456SAndroid Build Coastguard Workertemplate <class T, class... Abis>
97*58b9f456SAndroid Build Coastguard Workersimd<T, abi_for_size_t<T, (simd_size_v<T, Abis> + ...)>> concat(const simd<T, Abis>&...);
98*58b9f456SAndroid Build Coastguard Workertemplate <class T, class... Abis>
99*58b9f456SAndroid Build Coastguard Workersimd_mask<T, abi_for_size_t<T, (simd_size_v<T, Abis> + ...)>> concat(const simd_mask<T, Abis>&...);
100*58b9f456SAndroid Build Coastguard Worker
101*58b9f456SAndroid Build Coastguard Worker// reductions [simd.mask.reductions]
102*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi> bool all_of(const simd_mask<T, Abi>&) noexcept;
103*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi> bool any_of(const simd_mask<T, Abi>&) noexcept;
104*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi> bool none_of(const simd_mask<T, Abi>&) noexcept;
105*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi> bool some_of(const simd_mask<T, Abi>&) noexcept;
106*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi> int popcount(const simd_mask<T, Abi>&) noexcept;
107*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi> int find_first_set(const simd_mask<T, Abi>&);
108*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi> int find_last_set(const simd_mask<T, Abi>&);
109*58b9f456SAndroid Build Coastguard Worker
110*58b9f456SAndroid Build Coastguard Workerbool all_of(see below) noexcept;
111*58b9f456SAndroid Build Coastguard Workerbool any_of(see below) noexcept;
112*58b9f456SAndroid Build Coastguard Workerbool none_of(see below) noexcept;
113*58b9f456SAndroid Build Coastguard Workerbool some_of(see below) noexcept;
114*58b9f456SAndroid Build Coastguard Workerint popcount(see below) noexcept;
115*58b9f456SAndroid Build Coastguard Workerint find_first_set(see below) noexcept;
116*58b9f456SAndroid Build Coastguard Workerint find_last_set(see below) noexcept;
117*58b9f456SAndroid Build Coastguard Worker
118*58b9f456SAndroid Build Coastguard Worker// masked assignment [simd.whereexpr]
119*58b9f456SAndroid Build Coastguard Workertemplate <class M, class T> class const_where_expression;
120*58b9f456SAndroid Build Coastguard Workertemplate <class M, class T> class where_expression;
121*58b9f456SAndroid Build Coastguard Worker
122*58b9f456SAndroid Build Coastguard Worker// masked assignment [simd.mask.where]
123*58b9f456SAndroid Build Coastguard Workertemplate <class T> struct nodeduce { using type = T; }; // exposition only
124*58b9f456SAndroid Build Coastguard Worker
125*58b9f456SAndroid Build Coastguard Workertemplate <class T> using nodeduce_t = typename nodeduce<T>::type; // exposition only
126*58b9f456SAndroid Build Coastguard Worker
127*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi>
128*58b9f456SAndroid Build Coastguard Workerwhere_expression<simd_mask<T, Abi>, simd<T, Abi>>
129*58b9f456SAndroid Build Coastguard Workerwhere(const typename simd<T, Abi>::mask_type&, simd<T, Abi>&) noexcept;
130*58b9f456SAndroid Build Coastguard Worker
131*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi>
132*58b9f456SAndroid Build Coastguard Workerconst_where_expression<simd_mask<T, Abi>, const simd<T, Abi>>
133*58b9f456SAndroid Build Coastguard Workerwhere(const typename simd<T, Abi>::mask_type&, const simd<T, Abi>&) noexcept;
134*58b9f456SAndroid Build Coastguard Worker
135*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi>
136*58b9f456SAndroid Build Coastguard Workerwhere_expression<simd_mask<T, Abi>, simd_mask<T, Abi>>
137*58b9f456SAndroid Build Coastguard Workerwhere(const nodeduce_t<simd_mask<T, Abi>>&, simd_mask<T, Abi>&) noexcept;
138*58b9f456SAndroid Build Coastguard Worker
139*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi>
140*58b9f456SAndroid Build Coastguard Workerconst_where_expression<simd_mask<T, Abi>, const simd_mask<T, Abi>>
141*58b9f456SAndroid Build Coastguard Workerwhere(const nodeduce_t<simd_mask<T, Abi>>&, const simd_mask<T, Abi>&) noexcept;
142*58b9f456SAndroid Build Coastguard Worker
143*58b9f456SAndroid Build Coastguard Workertemplate <class T> where_expression<bool, T> where(see below k, T& d) noexcept;
144*58b9f456SAndroid Build Coastguard Worker
145*58b9f456SAndroid Build Coastguard Workertemplate <class T>
146*58b9f456SAndroid Build Coastguard Workerconst_where_expression<bool, const T> where(see below k, const T& d) noexcept;
147*58b9f456SAndroid Build Coastguard Worker
148*58b9f456SAndroid Build Coastguard Worker// reductions [simd.reductions]
149*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi, class BinaryOperation = std::plus<>>
150*58b9f456SAndroid Build Coastguard WorkerT reduce(const simd<T, Abi>&, BinaryOperation = BinaryOperation());
151*58b9f456SAndroid Build Coastguard Worker
152*58b9f456SAndroid Build Coastguard Workertemplate <class M, class V, class BinaryOperation>
153*58b9f456SAndroid Build Coastguard Workertypename V::value_type reduce(const const_where_expression<M, V>& x,
154*58b9f456SAndroid Build Coastguard Workertypename V::value_type neutral_element, BinaryOperation binary_op);
155*58b9f456SAndroid Build Coastguard Worker
156*58b9f456SAndroid Build Coastguard Workertemplate <class M, class V>
157*58b9f456SAndroid Build Coastguard Workertypename V::value_type reduce(const const_where_expression<M, V>& x, plus<> binary_op = plus<>());
158*58b9f456SAndroid Build Coastguard Worker
159*58b9f456SAndroid Build Coastguard Workertemplate <class M, class V>
160*58b9f456SAndroid Build Coastguard Workertypename V::value_type reduce(const const_where_expression<M, V>& x, multiplies<> binary_op);
161*58b9f456SAndroid Build Coastguard Worker
162*58b9f456SAndroid Build Coastguard Workertemplate <class M, class V>
163*58b9f456SAndroid Build Coastguard Workertypename V::value_type reduce(const const_where_expression<M, V>& x, bit_and<> binary_op);
164*58b9f456SAndroid Build Coastguard Worker
165*58b9f456SAndroid Build Coastguard Workertemplate <class M, class V>
166*58b9f456SAndroid Build Coastguard Workertypename V::value_type reduce(const const_where_expression<M, V>& x, bit_or<> binary_op);
167*58b9f456SAndroid Build Coastguard Worker
168*58b9f456SAndroid Build Coastguard Workertemplate <class M, class V>
169*58b9f456SAndroid Build Coastguard Workertypename V::value_type reduce(const const_where_expression<M, V>& x, bit_xor<> binary_op);
170*58b9f456SAndroid Build Coastguard Worker
171*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi> T hmin(const simd<T, Abi>&);
172*58b9f456SAndroid Build Coastguard Workertemplate <class M, class V> T hmin(const const_where_expression<M, V>&);
173*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi> T hmax(const simd<T, Abi>&);
174*58b9f456SAndroid Build Coastguard Workertemplate <class M, class V> T hmax(const const_where_expression<M, V>&);
175*58b9f456SAndroid Build Coastguard Worker
176*58b9f456SAndroid Build Coastguard Worker// algorithms [simd.alg]
177*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi> simd<T, Abi> min(const simd<T, Abi>&, const simd<T, Abi>&) noexcept;
178*58b9f456SAndroid Build Coastguard Worker
179*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi> simd<T, Abi> max(const simd<T, Abi>&, const simd<T, Abi>&) noexcept;
180*58b9f456SAndroid Build Coastguard Worker
181*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi>
182*58b9f456SAndroid Build Coastguard Workerstd::pair<simd<T, Abi>, simd<T, Abi>> minmax(const simd<T, Abi>&, const simd<T, Abi>&) noexcept;
183*58b9f456SAndroid Build Coastguard Worker
184*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi>
185*58b9f456SAndroid Build Coastguard Workersimd<T, Abi> clamp(const simd<T, Abi>& v, const simd<T, Abi>& lo, const simd<T, Abi>& hi);
186*58b9f456SAndroid Build Coastguard Worker
187*58b9f456SAndroid Build Coastguard Worker// [simd.whereexpr]
188*58b9f456SAndroid Build Coastguard Workertemplate <class M, class T>
189*58b9f456SAndroid Build Coastguard Workerclass const_where_expression {
190*58b9f456SAndroid Build Coastguard Worker  const M& mask; // exposition only
191*58b9f456SAndroid Build Coastguard Worker  T& data; // exposition only
192*58b9f456SAndroid Build Coastguard Workerpublic:
193*58b9f456SAndroid Build Coastguard Worker  const_where_expression(const const_where_expression&) = delete;
194*58b9f456SAndroid Build Coastguard Worker  const_where_expression& operator=(const const_where_expression&) = delete;
195*58b9f456SAndroid Build Coastguard Worker  remove_const_t<T> operator-() const &&;
196*58b9f456SAndroid Build Coastguard Worker  template <class U, class Flags> void copy_to(U* mem, Flags f) const &&;
197*58b9f456SAndroid Build Coastguard Worker};
198*58b9f456SAndroid Build Coastguard Worker
199*58b9f456SAndroid Build Coastguard Workertemplate <class M, class T>
200*58b9f456SAndroid Build Coastguard Workerclass where_expression : public const_where_expression<M, T> {
201*58b9f456SAndroid Build Coastguard Workerpublic:
202*58b9f456SAndroid Build Coastguard Worker  where_expression(const where_expression&) = delete;
203*58b9f456SAndroid Build Coastguard Worker  where_expression& operator=(const where_expression&) = delete;
204*58b9f456SAndroid Build Coastguard Worker  template <class U> void operator=(U&& x);
205*58b9f456SAndroid Build Coastguard Worker  template <class U> void operator+=(U&& x);
206*58b9f456SAndroid Build Coastguard Worker  template <class U> void operator-=(U&& x);
207*58b9f456SAndroid Build Coastguard Worker  template <class U> void operator*=(U&& x);
208*58b9f456SAndroid Build Coastguard Worker  template <class U> void operator/=(U&& x);
209*58b9f456SAndroid Build Coastguard Worker  template <class U> void operator%=(U&& x);
210*58b9f456SAndroid Build Coastguard Worker  template <class U> void operator&=(U&& x);
211*58b9f456SAndroid Build Coastguard Worker  template <class U> void operator|=(U&& x);
212*58b9f456SAndroid Build Coastguard Worker  template <class U> void operator^=(U&& x);
213*58b9f456SAndroid Build Coastguard Worker  template <class U> void operator<<=(U&& x);
214*58b9f456SAndroid Build Coastguard Worker  template <class U> void operator>>=(U&& x);
215*58b9f456SAndroid Build Coastguard Worker  void operator++();
216*58b9f456SAndroid Build Coastguard Worker  void operator++(int);
217*58b9f456SAndroid Build Coastguard Worker  void operator--();
218*58b9f456SAndroid Build Coastguard Worker  void operator--(int);
219*58b9f456SAndroid Build Coastguard Worker  template <class U, class Flags> void copy_from(const U* mem, Flags);
220*58b9f456SAndroid Build Coastguard Worker};
221*58b9f456SAndroid Build Coastguard Worker
222*58b9f456SAndroid Build Coastguard Worker// [simd.class]
223*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi> class simd {
224*58b9f456SAndroid Build Coastguard Workerpublic:
225*58b9f456SAndroid Build Coastguard Worker  using value_type = T;
226*58b9f456SAndroid Build Coastguard Worker  using reference = see below;
227*58b9f456SAndroid Build Coastguard Worker  using mask_type = simd_mask<T, Abi>;
228*58b9f456SAndroid Build Coastguard Worker
229*58b9f456SAndroid Build Coastguard Worker  using abi_type = Abi;
230*58b9f456SAndroid Build Coastguard Worker  static constexpr size_t size() noexcept;
231*58b9f456SAndroid Build Coastguard Worker  simd() = default;
232*58b9f456SAndroid Build Coastguard Worker
233*58b9f456SAndroid Build Coastguard Worker  // implicit type conversion constructor
234*58b9f456SAndroid Build Coastguard Worker  template <class U> simd(const simd<U, simd_abi::fixed_size<size()>>&);
235*58b9f456SAndroid Build Coastguard Worker
236*58b9f456SAndroid Build Coastguard Worker  // implicit broadcast constructor (see below for constraints)
237*58b9f456SAndroid Build Coastguard Worker  template <class U> simd(U&& value);
238*58b9f456SAndroid Build Coastguard Worker
239*58b9f456SAndroid Build Coastguard Worker  // generator constructor (see below for constraints)
240*58b9f456SAndroid Build Coastguard Worker  template <class G> explicit simd(G&& gen);
241*58b9f456SAndroid Build Coastguard Worker
242*58b9f456SAndroid Build Coastguard Worker  // load constructor
243*58b9f456SAndroid Build Coastguard Worker  template <class U, class Flags> simd(const U* mem, Flags f);
244*58b9f456SAndroid Build Coastguard Worker
245*58b9f456SAndroid Build Coastguard Worker  // loads [simd.load]
246*58b9f456SAndroid Build Coastguard Worker  template <class U, class Flags> void copy_from(const U* mem, Flags f);
247*58b9f456SAndroid Build Coastguard Worker
248*58b9f456SAndroid Build Coastguard Worker  // stores [simd.store]
249*58b9f456SAndroid Build Coastguard Worker  template <class U, class Flags> void copy_to(U* mem, Flags f) const;
250*58b9f456SAndroid Build Coastguard Worker
251*58b9f456SAndroid Build Coastguard Worker  // scalar access [simd.subscr]
252*58b9f456SAndroid Build Coastguard Worker  reference operator[](size_t);
253*58b9f456SAndroid Build Coastguard Worker  value_type operator[](size_t) const;
254*58b9f456SAndroid Build Coastguard Worker
255*58b9f456SAndroid Build Coastguard Worker  // unary operators [simd.unary]
256*58b9f456SAndroid Build Coastguard Worker  simd& operator++();
257*58b9f456SAndroid Build Coastguard Worker  simd operator++(int);
258*58b9f456SAndroid Build Coastguard Worker  simd& operator--();
259*58b9f456SAndroid Build Coastguard Worker  simd operator--(int);
260*58b9f456SAndroid Build Coastguard Worker  mask_type operator!() const;
261*58b9f456SAndroid Build Coastguard Worker  simd operator~() const; // see below
262*58b9f456SAndroid Build Coastguard Worker  simd operator+() const;
263*58b9f456SAndroid Build Coastguard Worker  simd operator-() const;
264*58b9f456SAndroid Build Coastguard Worker
265*58b9f456SAndroid Build Coastguard Worker  // binary operators [simd.binary]
266*58b9f456SAndroid Build Coastguard Worker  friend simd operator+ (const simd&, const simd&);
267*58b9f456SAndroid Build Coastguard Worker  friend simd operator- (const simd&, const simd&);
268*58b9f456SAndroid Build Coastguard Worker  friend simd operator* (const simd&, const simd&);
269*58b9f456SAndroid Build Coastguard Worker  friend simd operator/ (const simd&, const simd&);
270*58b9f456SAndroid Build Coastguard Worker  friend simd operator% (const simd&, const simd&);
271*58b9f456SAndroid Build Coastguard Worker  friend simd operator& (const simd&, const simd&);
272*58b9f456SAndroid Build Coastguard Worker  friend simd operator| (const simd&, const simd&);
273*58b9f456SAndroid Build Coastguard Worker  friend simd operator^ (const simd&, const simd&);
274*58b9f456SAndroid Build Coastguard Worker  friend simd operator<<(const simd&, const simd&);
275*58b9f456SAndroid Build Coastguard Worker  friend simd operator>>(const simd&, const simd&);
276*58b9f456SAndroid Build Coastguard Worker  friend simd operator<<(const simd&, int);
277*58b9f456SAndroid Build Coastguard Worker  friend simd operator>>(const simd&, int);
278*58b9f456SAndroid Build Coastguard Worker
279*58b9f456SAndroid Build Coastguard Worker  // compound assignment [simd.cassign]
280*58b9f456SAndroid Build Coastguard Worker  friend simd& operator+= (simd&, const simd&);
281*58b9f456SAndroid Build Coastguard Worker  friend simd& operator-= (simd&, const simd&);
282*58b9f456SAndroid Build Coastguard Worker  friend simd& operator*= (simd&, const simd&);
283*58b9f456SAndroid Build Coastguard Worker  friend simd& operator/= (simd&, const simd&);
284*58b9f456SAndroid Build Coastguard Worker  friend simd& operator%= (simd&, const simd&);
285*58b9f456SAndroid Build Coastguard Worker
286*58b9f456SAndroid Build Coastguard Worker  friend simd& operator&= (simd&, const simd&);
287*58b9f456SAndroid Build Coastguard Worker  friend simd& operator|= (simd&, const simd&);
288*58b9f456SAndroid Build Coastguard Worker  friend simd& operator^= (simd&, const simd&);
289*58b9f456SAndroid Build Coastguard Worker  friend simd& operator<<=(simd&, const simd&);
290*58b9f456SAndroid Build Coastguard Worker  friend simd& operator>>=(simd&, const simd&);
291*58b9f456SAndroid Build Coastguard Worker  friend simd& operator<<=(simd&, int);
292*58b9f456SAndroid Build Coastguard Worker  friend simd& operator>>=(simd&, int);
293*58b9f456SAndroid Build Coastguard Worker
294*58b9f456SAndroid Build Coastguard Worker  // compares [simd.comparison]
295*58b9f456SAndroid Build Coastguard Worker  friend mask_type operator==(const simd&, const simd&);
296*58b9f456SAndroid Build Coastguard Worker  friend mask_type operator!=(const simd&, const simd&);
297*58b9f456SAndroid Build Coastguard Worker  friend mask_type operator>=(const simd&, const simd&);
298*58b9f456SAndroid Build Coastguard Worker  friend mask_type operator<=(const simd&, const simd&);
299*58b9f456SAndroid Build Coastguard Worker  friend mask_type operator> (const simd&, const simd&);
300*58b9f456SAndroid Build Coastguard Worker  friend mask_type operator< (const simd&, const simd&);
301*58b9f456SAndroid Build Coastguard Worker};
302*58b9f456SAndroid Build Coastguard Worker
303*58b9f456SAndroid Build Coastguard Worker// [simd.math]
304*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> using scharv = simd<signed char, Abi>; // exposition only
305*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> using shortv = simd<short, Abi>; // exposition only
306*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> using intv = simd<int, Abi>; // exposition only
307*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> using longv = simd<long int, Abi>; // exposition only
308*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> using llongv = simd<long long int, Abi>; // exposition only
309*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> using floatv = simd<float, Abi>; // exposition only
310*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> using doublev = simd<double, Abi>; // exposition only
311*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> using ldoublev = simd<long double, Abi>; // exposition only
312*58b9f456SAndroid Build Coastguard Workertemplate <class T, class V> using samesize = fixed_size_simd<T, V::size()>; // exposition only
313*58b9f456SAndroid Build Coastguard Worker
314*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> acos(floatv<Abi> x);
315*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> acos(doublev<Abi> x);
316*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> acos(ldoublev<Abi> x);
317*58b9f456SAndroid Build Coastguard Worker
318*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> asin(floatv<Abi> x);
319*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> asin(doublev<Abi> x);
320*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> asin(ldoublev<Abi> x);
321*58b9f456SAndroid Build Coastguard Worker
322*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> atan(floatv<Abi> x);
323*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> atan(doublev<Abi> x);
324*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> atan(ldoublev<Abi> x);
325*58b9f456SAndroid Build Coastguard Worker
326*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> atan2(floatv<Abi> y, floatv<Abi> x);
327*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> atan2(doublev<Abi> y, doublev<Abi> x);
328*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> atan2(ldoublev<Abi> y, ldoublev<Abi> x);
329*58b9f456SAndroid Build Coastguard Worker
330*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> cos(floatv<Abi> x);
331*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> cos(doublev<Abi> x);
332*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> cos(ldoublev<Abi> x);
333*58b9f456SAndroid Build Coastguard Worker
334*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> sin(floatv<Abi> x);
335*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> sin(doublev<Abi> x);
336*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> sin(ldoublev<Abi> x);
337*58b9f456SAndroid Build Coastguard Worker
338*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> tan(floatv<Abi> x);
339*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> tan(doublev<Abi> x);
340*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> tan(ldoublev<Abi> x);
341*58b9f456SAndroid Build Coastguard Worker
342*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> acosh(floatv<Abi> x);
343*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> acosh(doublev<Abi> x);
344*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> acosh(ldoublev<Abi> x);
345*58b9f456SAndroid Build Coastguard Worker
346*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> asinh(floatv<Abi> x);
347*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> asinh(doublev<Abi> x);
348*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> asinh(ldoublev<Abi> x);
349*58b9f456SAndroid Build Coastguard Worker
350*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> atanh(floatv<Abi> x);
351*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> atanh(doublev<Abi> x);
352*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> atanh(ldoublev<Abi> x);
353*58b9f456SAndroid Build Coastguard Worker
354*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> cosh(floatv<Abi> x);
355*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> cosh(doublev<Abi> x);
356*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> cosh(ldoublev<Abi> x);
357*58b9f456SAndroid Build Coastguard Worker
358*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> sinh(floatv<Abi> x);
359*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> sinh(doublev<Abi> x);
360*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> sinh(ldoublev<Abi> x);
361*58b9f456SAndroid Build Coastguard Worker
362*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> tanh(floatv<Abi> x);
363*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> tanh(doublev<Abi> x);
364*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> tanh(ldoublev<Abi> x);
365*58b9f456SAndroid Build Coastguard Worker
366*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> exp(floatv<Abi> x);
367*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> exp(doublev<Abi> x);
368*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> exp(ldoublev<Abi> x);
369*58b9f456SAndroid Build Coastguard Worker
370*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> exp2(floatv<Abi> x);
371*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> exp2(doublev<Abi> x);
372*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> exp2(ldoublev<Abi> x);
373*58b9f456SAndroid Build Coastguard Worker
374*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> expm1(floatv<Abi> x);
375*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> expm1(doublev<Abi> x);
376*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> expm1(ldoublev<Abi> x);
377*58b9f456SAndroid Build Coastguard Worker
378*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> frexp(floatv<Abi> value, samesize<int, floatv<Abi>>* exp);
379*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> frexp(doublev<Abi> value, samesize<int, doublev<Abi>>* exp);
380*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> frexp(ldoublev<Abi> value, samesize<int, ldoublev<Abi>>* exp);
381*58b9f456SAndroid Build Coastguard Worker
382*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> samesize<int, floatv<Abi>> ilogb(floatv<Abi> x);
383*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> samesize<int, doublev<Abi>> ilogb(doublev<Abi> x);
384*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> samesize<int, ldoublev<Abi>> ilogb(ldoublev<Abi> x);
385*58b9f456SAndroid Build Coastguard Worker
386*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> ldexp(floatv<Abi> x, samesize<int, floatv<Abi>> exp);
387*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> ldexp(doublev<Abi> x, samesize<int, doublev<Abi>> exp);
388*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> ldexp(ldoublev<Abi> x, samesize<int, ldoublev<Abi>> exp);
389*58b9f456SAndroid Build Coastguard Worker
390*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> log(floatv<Abi> x);
391*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> log(doublev<Abi> x);
392*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> log(ldoublev<Abi> x);
393*58b9f456SAndroid Build Coastguard Worker
394*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> log10(floatv<Abi> x);
395*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> log10(doublev<Abi> x);
396*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> log10(ldoublev<Abi> x);
397*58b9f456SAndroid Build Coastguard Worker
398*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> log1p(floatv<Abi> x);
399*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> log1p(doublev<Abi> x);
400*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> log1p(ldoublev<Abi> x);
401*58b9f456SAndroid Build Coastguard Worker
402*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> log2(floatv<Abi> x);
403*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> log2(doublev<Abi> x);
404*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> log2(ldoublev<Abi> x);
405*58b9f456SAndroid Build Coastguard Worker
406*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> logb(floatv<Abi> x);
407*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> logb(doublev<Abi> x);
408*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> logb(ldoublev<Abi> x);
409*58b9f456SAndroid Build Coastguard Worker
410*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> modf(floatv<Abi> value, floatv<Abi>* iptr);
411*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> modf(doublev<Abi> value, doublev<Abi>* iptr);
412*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> modf(ldoublev<Abi> value, ldoublev<Abi>* iptr);
413*58b9f456SAndroid Build Coastguard Worker
414*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> scalbn(floatv<Abi> x, samesize<int, floatv<Abi>> n);
415*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> scalbn(doublev<Abi> x, samesize<int, doublev<Abi>> n);
416*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> scalbn(ldoublev<Abi> x, samesize<int, ldoublev<Abi>> n);
417*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> scalbln(floatv<Abi> x, samesize<long int, floatv<Abi>> n);
418*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> scalbln(doublev<Abi> x, samesize<long int, doublev<Abi>> n);
419*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> scalbln(ldoublev<Abi> x, samesize<long int, ldoublev<Abi>> n);
420*58b9f456SAndroid Build Coastguard Worker
421*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> cbrt(floatv<Abi> x);
422*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> cbrt(doublev<Abi> x);
423*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> cbrt(ldoublev<Abi> x);
424*58b9f456SAndroid Build Coastguard Worker
425*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> scharv<Abi> abs(scharv<Abi> j);
426*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> shortv<Abi> abs(shortv<Abi> j);
427*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> intv<Abi> abs(intv<Abi> j);
428*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> longv<Abi> abs(longv<Abi> j);
429*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> llongv<Abi> abs(llongv<Abi> j);
430*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> abs(floatv<Abi> j);
431*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> abs(doublev<Abi> j);
432*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> abs(ldoublev<Abi> j);
433*58b9f456SAndroid Build Coastguard Worker
434*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> hypot(floatv<Abi> x, floatv<Abi> y);
435*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> hypot(doublev<Abi> x, doublev<Abi> y);
436*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> hypot(doublev<Abi> x, doublev<Abi> y);
437*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> hypot(floatv<Abi> x, floatv<Abi> y, floatv<Abi> z);
438*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> hypot(doublev<Abi> x, doublev<Abi> y, doublev<Abi> z);
439*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> hypot(ldoublev<Abi> x, ldoublev<Abi> y, ldoublev<Abi> z);
440*58b9f456SAndroid Build Coastguard Worker
441*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> pow(floatv<Abi> x, floatv<Abi> y);
442*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> pow(doublev<Abi> x, doublev<Abi> y);
443*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> pow(ldoublev<Abi> x, ldoublev<Abi> y);
444*58b9f456SAndroid Build Coastguard Worker
445*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> sqrt(floatv<Abi> x);
446*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> sqrt(doublev<Abi> x);
447*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> sqrt(ldoublev<Abi> x);
448*58b9f456SAndroid Build Coastguard Worker
449*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> erf(floatv<Abi> x);
450*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> erf(doublev<Abi> x);
451*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> erf(ldoublev<Abi> x);
452*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> erfc(floatv<Abi> x);
453*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> erfc(doublev<Abi> x);
454*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> erfc(ldoublev<Abi> x);
455*58b9f456SAndroid Build Coastguard Worker
456*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> lgamma(floatv<Abi> x);
457*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> lgamma(doublev<Abi> x);
458*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> lgamma(ldoublev<Abi> x);
459*58b9f456SAndroid Build Coastguard Worker
460*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> tgamma(floatv<Abi> x);
461*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> tgamma(doublev<Abi> x);
462*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> tgamma(ldoublev<Abi> x);
463*58b9f456SAndroid Build Coastguard Worker
464*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> ceil(floatv<Abi> x);
465*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> ceil(doublev<Abi> x);
466*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> ceil(ldoublev<Abi> x);
467*58b9f456SAndroid Build Coastguard Worker
468*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> floor(floatv<Abi> x);
469*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> floor(doublev<Abi> x);
470*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> floor(ldoublev<Abi> x);
471*58b9f456SAndroid Build Coastguard Worker
472*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> nearbyint(floatv<Abi> x);
473*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> nearbyint(doublev<Abi> x);
474*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> nearbyint(ldoublev<Abi> x);
475*58b9f456SAndroid Build Coastguard Worker
476*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> rint(floatv<Abi> x);
477*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> rint(doublev<Abi> x);
478*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> rint(ldoublev<Abi> x);
479*58b9f456SAndroid Build Coastguard Worker
480*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> samesize<long int, floatv<Abi>> lrint(floatv<Abi> x);
481*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> samesize<long int, doublev<Abi>> lrint(doublev<Abi> x);
482*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> samesize<long int, ldoublev<Abi>> lrint(ldoublev<Abi> x);
483*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> samesize<long long int, floatv<Abi>> llrint(floatv<Abi> x);
484*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> samesize<long long int, doublev<Abi>> llrint(doublev<Abi> x);
485*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> samesize<long long int, ldoublev<Abi>> llrint(ldoublev<Abi> x);
486*58b9f456SAndroid Build Coastguard Worker
487*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> round(floatv<Abi> x);
488*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> round(doublev<Abi> x);
489*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> round(ldoublev<Abi> x);
490*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> samesize<long int, floatv<Abi>> lround(floatv<Abi> x);
491*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> samesize<long int, doublev<Abi>> lround(doublev<Abi> x);
492*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> samesize<long int, ldoublev<Abi>> lround(ldoublev<Abi> x);
493*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> samesize<long long int, floatv<Abi>> llround(floatv<Abi> x);
494*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> samesize<long long int, doublev<Abi>> llround(doublev<Abi> x);
495*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> samesize<long long int, ldoublev<Abi>> llround(ldoublev<Abi> x);
496*58b9f456SAndroid Build Coastguard Worker
497*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> trunc(floatv<Abi> x);
498*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> trunc(doublev<Abi> x);
499*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> trunc(ldoublev<Abi> x);
500*58b9f456SAndroid Build Coastguard Worker
501*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> fmod(floatv<Abi> x, floatv<Abi> y);
502*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> fmod(doublev<Abi> x, doublev<Abi> y);
503*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> fmod(ldoublev<Abi> x, ldoublev<Abi> y);
504*58b9f456SAndroid Build Coastguard Worker
505*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> remainder(floatv<Abi> x, floatv<Abi> y);
506*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> remainder(doublev<Abi> x, doublev<Abi> y);
507*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> remainder(ldoublev<Abi> x, ldoublev<Abi> y);
508*58b9f456SAndroid Build Coastguard Worker
509*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> remquo(floatv<Abi> x, floatv<Abi> y, samesize<int, floatv<Abi>>* quo);
510*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> remquo(doublev<Abi> x, doublev<Abi> y, samesize<int, doublev<Abi>>* quo);
511*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> remquo(ldoublev<Abi> x, ldoublev<Abi> y, samesize<int, ldoublev<Abi>>* quo);
512*58b9f456SAndroid Build Coastguard Worker
513*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> copysign(floatv<Abi> x, floatv<Abi> y);
514*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> copysign(doublev<Abi> x, doublev<Abi> y);
515*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> copysign(ldoublev<Abi> x, ldoublev<Abi> y);
516*58b9f456SAndroid Build Coastguard Worker
517*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> nan(const char* tagp);
518*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> nanf(const char* tagp);
519*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> nanl(const char* tagp);
520*58b9f456SAndroid Build Coastguard Worker
521*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> nextafter(floatv<Abi> x, floatv<Abi> y);
522*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> nextafter(doublev<Abi> x, doublev<Abi> y);
523*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> nextafter(ldoublev<Abi> x, ldoublev<Abi> y);
524*58b9f456SAndroid Build Coastguard Worker
525*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> nexttoward(floatv<Abi> x, ldoublev<Abi> y);
526*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> nexttoward(doublev<Abi> x, ldoublev<Abi> y);
527*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> nexttoward(ldoublev<Abi> x, ldoublev<Abi> y);
528*58b9f456SAndroid Build Coastguard Worker
529*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> fdim(floatv<Abi> x, floatv<Abi> y);
530*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> fdim(doublev<Abi> x, doublev<Abi> y);
531*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> fdim(ldoublev<Abi> x, ldoublev<Abi> y);
532*58b9f456SAndroid Build Coastguard Worker
533*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> fmax(floatv<Abi> x, floatv<Abi> y);
534*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> fmax(doublev<Abi> x, doublev<Abi> y);
535*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> fmax(ldoublev<Abi> x, ldoublev<Abi> y);
536*58b9f456SAndroid Build Coastguard Worker
537*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> fmin(floatv<Abi> x, floatv<Abi> y);
538*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> fmin(doublev<Abi> x, doublev<Abi> y);
539*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> fmin(ldoublev<Abi> x, ldoublev<Abi> y);
540*58b9f456SAndroid Build Coastguard Worker
541*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> floatv<Abi> fma(floatv<Abi> x, floatv<Abi> y, floatv<Abi> z);
542*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> doublev<Abi> fma(doublev<Abi> x, doublev<Abi> y, doublev<Abi> z);
543*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> ldoublev<Abi> fma(ldoublev<Abi> x, ldoublev<Abi> y, ldoublev<Abi> z);
544*58b9f456SAndroid Build Coastguard Worker
545*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> samesize<int, floatv<Abi>> fpclassify(floatv<Abi> x);
546*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> samesize<int, doublev<Abi>> fpclassify(doublev<Abi> x);
547*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> samesize<int, ldoublev<Abi>> fpclassify(ldoublev<Abi> x);
548*58b9f456SAndroid Build Coastguard Worker
549*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<float, Abi> isfinite(floatv<Abi> x);
550*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<double, Abi> isfinite(doublev<Abi> x);
551*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<long double, Abi> isfinite(ldoublev<Abi> x);
552*58b9f456SAndroid Build Coastguard Worker
553*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<float, Abi> isinf(floatv<Abi> x);
554*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<double, Abi> isinf(doublev<Abi> x);
555*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<long double, Abi> isinf(ldoublev<Abi> x);
556*58b9f456SAndroid Build Coastguard Worker
557*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<float, Abi> isnan(floatv<Abi> x);
558*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<double, Abi> isnan(doublev<Abi> x);
559*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<long double, Abi> isnan(ldoublev<Abi> x);
560*58b9f456SAndroid Build Coastguard Worker
561*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<float, Abi> isnormal(floatv<Abi> x);
562*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<double, Abi> isnormal(doublev<Abi> x);
563*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<long double, Abi> isnormal(ldoublev<Abi> x);
564*58b9f456SAndroid Build Coastguard Worker
565*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<float, Abi> signbit(floatv<Abi> x);
566*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<double, Abi> signbit(doublev<Abi> x);
567*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<long double, Abi> signbit(ldoublev<Abi> x);
568*58b9f456SAndroid Build Coastguard Worker
569*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<float, Abi> isgreater(floatv<Abi> x, floatv<Abi> y);
570*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<double, Abi> isgreater(doublev<Abi> x, doublev<Abi> y);
571*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<long double, Abi> isgreater(ldoublev<Abi> x, ldoublev<Abi> y);
572*58b9f456SAndroid Build Coastguard Worker
573*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<float, Abi> isgreaterequal(floatv<Abi> x, floatv<Abi> y);
574*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<double, Abi> isgreaterequal(doublev<Abi> x, doublev<Abi> y);
575*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<long double, Abi> isgreaterequal(ldoublev<Abi> x, ldoublev<Abi> y);
576*58b9f456SAndroid Build Coastguard Worker
577*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<float, Abi> isless(floatv<Abi> x, floatv<Abi> y);
578*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<double, Abi> isless(doublev<Abi> x, doublev<Abi> y);
579*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<long double, Abi> isless(ldoublev<Abi> x, ldoublev<Abi> y);
580*58b9f456SAndroid Build Coastguard Worker
581*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<float, Abi> islessequal(floatv<Abi> x, floatv<Abi> y);
582*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<double, Abi> islessequal(doublev<Abi> x, doublev<Abi> y);
583*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<long double, Abi> islessequal(ldoublev<Abi> x, ldoublev<Abi> y);
584*58b9f456SAndroid Build Coastguard Worker
585*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<float, Abi> islessgreater(floatv<Abi> x, floatv<Abi> y);
586*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<double, Abi> islessgreater(doublev<Abi> x, doublev<Abi> y);
587*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<long double, Abi> islessgreater(ldoublev<Abi> x, ldoublev<Abi> y);
588*58b9f456SAndroid Build Coastguard Worker
589*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<float, Abi> isunordered(floatv<Abi> x, floatv<Abi> y);
590*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<double, Abi> isunordered(doublev<Abi> x, doublev<Abi> y);
591*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_mask<long double, Abi> isunordered(ldoublev<Abi> x, ldoublev<Abi> y);
592*58b9f456SAndroid Build Coastguard Worker
593*58b9f456SAndroid Build Coastguard Workertemplate <class V> struct simd_div_t { V quot, rem; };
594*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_div_t<scharv<Abi>> div(scharv<Abi> numer, scharv<Abi> denom);
595*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_div_t<shortv<Abi>> div(shortv<Abi> numer, shortv<Abi> denom);
596*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_div_t<intv<Abi>> div(intv<Abi> numer, intv<Abi> denom);
597*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_div_t<longv<Abi>> div(longv<Abi> numer, longv<Abi> denom);
598*58b9f456SAndroid Build Coastguard Workertemplate <class Abi> simd_div_t<llongv<Abi>> div(llongv<Abi> numer, llongv<Abi> denom);
599*58b9f456SAndroid Build Coastguard Worker
600*58b9f456SAndroid Build Coastguard Worker// [simd.mask.class]
601*58b9f456SAndroid Build Coastguard Workertemplate <class T, class Abi>
602*58b9f456SAndroid Build Coastguard Workerclass simd_mask {
603*58b9f456SAndroid Build Coastguard Workerpublic:
604*58b9f456SAndroid Build Coastguard Worker  using value_type = bool;
605*58b9f456SAndroid Build Coastguard Worker  using reference = see below;
606*58b9f456SAndroid Build Coastguard Worker  using simd_type = simd<T, Abi>;
607*58b9f456SAndroid Build Coastguard Worker  using abi_type = Abi;
608*58b9f456SAndroid Build Coastguard Worker  static constexpr size_t size() noexcept;
609*58b9f456SAndroid Build Coastguard Worker  simd_mask() = default;
610*58b9f456SAndroid Build Coastguard Worker
611*58b9f456SAndroid Build Coastguard Worker  // broadcast constructor
612*58b9f456SAndroid Build Coastguard Worker  explicit simd_mask(value_type) noexcept;
613*58b9f456SAndroid Build Coastguard Worker
614*58b9f456SAndroid Build Coastguard Worker  // implicit type conversion constructor
615*58b9f456SAndroid Build Coastguard Worker  template <class U> simd_mask(const simd_mask<U, simd_abi::fixed_size<size()>>&) noexcept;
616*58b9f456SAndroid Build Coastguard Worker
617*58b9f456SAndroid Build Coastguard Worker  // load constructor
618*58b9f456SAndroid Build Coastguard Worker  template <class Flags> simd_mask(const value_type* mem, Flags);
619*58b9f456SAndroid Build Coastguard Worker
620*58b9f456SAndroid Build Coastguard Worker  // loads [simd.mask.copy]
621*58b9f456SAndroid Build Coastguard Worker  template <class Flags> void copy_from(const value_type* mem, Flags);
622*58b9f456SAndroid Build Coastguard Worker  template <class Flags> void copy_to(value_type* mem, Flags) const;
623*58b9f456SAndroid Build Coastguard Worker
624*58b9f456SAndroid Build Coastguard Worker  // scalar access [simd.mask.subscr]
625*58b9f456SAndroid Build Coastguard Worker  reference operator[](size_t);
626*58b9f456SAndroid Build Coastguard Worker  value_type operator[](size_t) const;
627*58b9f456SAndroid Build Coastguard Worker
628*58b9f456SAndroid Build Coastguard Worker  // unary operators [simd.mask.unary]
629*58b9f456SAndroid Build Coastguard Worker  simd_mask operator!() const noexcept;
630*58b9f456SAndroid Build Coastguard Worker
631*58b9f456SAndroid Build Coastguard Worker  // simd_mask binary operators [simd.mask.binary]
632*58b9f456SAndroid Build Coastguard Worker  friend simd_mask operator&&(const simd_mask&, const simd_mask&) noexcept;
633*58b9f456SAndroid Build Coastguard Worker  friend simd_mask operator||(const simd_mask&, const simd_mask&) noexcept;
634*58b9f456SAndroid Build Coastguard Worker  friend simd_mask operator& (const simd_mask&, const simd_mask&) noexcept;
635*58b9f456SAndroid Build Coastguard Worker  friend simd_mask operator| (const simd_mask&, const simd_mask&) noexcept;
636*58b9f456SAndroid Build Coastguard Worker  friend simd_mask operator^ (const simd_mask&, const simd_mask&) noexcept;
637*58b9f456SAndroid Build Coastguard Worker
638*58b9f456SAndroid Build Coastguard Worker  // simd_mask compound assignment [simd.mask.cassign]
639*58b9f456SAndroid Build Coastguard Worker  friend simd_mask& operator&=(simd_mask&, const simd_mask&) noexcept;
640*58b9f456SAndroid Build Coastguard Worker  friend simd_mask& operator|=(simd_mask&, const simd_mask&) noexcept;
641*58b9f456SAndroid Build Coastguard Worker  friend simd_mask& operator^=(simd_mask&, const simd_mask&) noexcept;
642*58b9f456SAndroid Build Coastguard Worker
643*58b9f456SAndroid Build Coastguard Worker  // simd_mask compares [simd.mask.comparison]
644*58b9f456SAndroid Build Coastguard Worker  friend simd_mask operator==(const simd_mask&, const simd_mask&) noexcept;
645*58b9f456SAndroid Build Coastguard Worker  friend simd_mask operator!=(const simd_mask&, const simd_mask&) noexcept;
646*58b9f456SAndroid Build Coastguard Worker};
647*58b9f456SAndroid Build Coastguard Worker
648*58b9f456SAndroid Build Coastguard Worker} // parallelism_v2
649*58b9f456SAndroid Build Coastguard Worker} // std::experimental
650*58b9f456SAndroid Build Coastguard Worker
651*58b9f456SAndroid Build Coastguard Worker*/
652*58b9f456SAndroid Build Coastguard Worker
653*58b9f456SAndroid Build Coastguard Worker#include <experimental/__config>
654*58b9f456SAndroid Build Coastguard Worker#include <algorithm>
655*58b9f456SAndroid Build Coastguard Worker#include <array>
656*58b9f456SAndroid Build Coastguard Worker#include <cstddef>
657*58b9f456SAndroid Build Coastguard Worker#include <functional>
658*58b9f456SAndroid Build Coastguard Worker
659*58b9f456SAndroid Build Coastguard Worker#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
660*58b9f456SAndroid Build Coastguard Worker#pragma GCC system_header
661*58b9f456SAndroid Build Coastguard Worker#endif
662*58b9f456SAndroid Build Coastguard Worker
663*58b9f456SAndroid Build Coastguard Worker_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD
664*58b9f456SAndroid Build Coastguard Worker
665*58b9f456SAndroid Build Coastguard Worker#if _LIBCPP_STD_VER >= 17
666*58b9f456SAndroid Build Coastguard Worker
667*58b9f456SAndroid Build Coastguard Workerenum class _StorageKind {
668*58b9f456SAndroid Build Coastguard Worker  _Scalar,
669*58b9f456SAndroid Build Coastguard Worker  _Array,
670*58b9f456SAndroid Build Coastguard Worker  _VecExt,
671*58b9f456SAndroid Build Coastguard Worker};
672*58b9f456SAndroid Build Coastguard Worker
673*58b9f456SAndroid Build Coastguard Workertemplate <_StorageKind __kind, int _Np>
674*58b9f456SAndroid Build Coastguard Workerstruct __simd_abi {};
675*58b9f456SAndroid Build Coastguard Worker
676*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
677*58b9f456SAndroid Build Coastguard Workerclass __simd_storage {};
678*58b9f456SAndroid Build Coastguard Worker
679*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, int __num_element>
680*58b9f456SAndroid Build Coastguard Workerclass __simd_storage<_Tp, __simd_abi<_StorageKind::_Array, __num_element>> {
681*58b9f456SAndroid Build Coastguard Worker  std::array<_Tp, __num_element> __storage_;
682*58b9f456SAndroid Build Coastguard Worker
683*58b9f456SAndroid Build Coastguard Worker  template <class, class>
684*58b9f456SAndroid Build Coastguard Worker  friend struct simd;
685*58b9f456SAndroid Build Coastguard Worker
686*58b9f456SAndroid Build Coastguard Worker  template <class, class>
687*58b9f456SAndroid Build Coastguard Worker  friend struct simd_mask;
688*58b9f456SAndroid Build Coastguard Worker
689*58b9f456SAndroid Build Coastguard Workerpublic:
690*58b9f456SAndroid Build Coastguard Worker  _Tp __get(size_t __index) const noexcept { return __storage_[__index]; };
691*58b9f456SAndroid Build Coastguard Worker  void __set(size_t __index, _Tp __val) noexcept {
692*58b9f456SAndroid Build Coastguard Worker    __storage_[__index] = __val;
693*58b9f456SAndroid Build Coastguard Worker  }
694*58b9f456SAndroid Build Coastguard Worker};
695*58b9f456SAndroid Build Coastguard Worker
696*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
697*58b9f456SAndroid Build Coastguard Workerclass __simd_storage<_Tp, __simd_abi<_StorageKind::_Scalar, 1>> {
698*58b9f456SAndroid Build Coastguard Worker  _Tp __storage_;
699*58b9f456SAndroid Build Coastguard Worker
700*58b9f456SAndroid Build Coastguard Worker  template <class, class>
701*58b9f456SAndroid Build Coastguard Worker  friend struct simd;
702*58b9f456SAndroid Build Coastguard Worker
703*58b9f456SAndroid Build Coastguard Worker  template <class, class>
704*58b9f456SAndroid Build Coastguard Worker  friend struct simd_mask;
705*58b9f456SAndroid Build Coastguard Worker
706*58b9f456SAndroid Build Coastguard Workerpublic:
707*58b9f456SAndroid Build Coastguard Worker  _Tp __get(size_t __index) const noexcept { return (&__storage_)[__index]; };
708*58b9f456SAndroid Build Coastguard Worker  void __set(size_t __index, _Tp __val) noexcept {
709*58b9f456SAndroid Build Coastguard Worker    (&__storage_)[__index] = __val;
710*58b9f456SAndroid Build Coastguard Worker  }
711*58b9f456SAndroid Build Coastguard Worker};
712*58b9f456SAndroid Build Coastguard Worker
713*58b9f456SAndroid Build Coastguard Worker#ifndef _LIBCPP_HAS_NO_VECTOR_EXTENSION
714*58b9f456SAndroid Build Coastguard Worker
715*58b9f456SAndroid Build Coastguard Workerconstexpr size_t __floor_pow_of_2(size_t __val) {
716*58b9f456SAndroid Build Coastguard Worker  return ((__val - 1) & __val) == 0 ? __val
717*58b9f456SAndroid Build Coastguard Worker                                    : __floor_pow_of_2((__val - 1) & __val);
718*58b9f456SAndroid Build Coastguard Worker}
719*58b9f456SAndroid Build Coastguard Worker
720*58b9f456SAndroid Build Coastguard Workerconstexpr size_t __ceil_pow_of_2(size_t __val) {
721*58b9f456SAndroid Build Coastguard Worker  return __val == 1 ? 1 : __floor_pow_of_2(__val - 1) << 1;
722*58b9f456SAndroid Build Coastguard Worker}
723*58b9f456SAndroid Build Coastguard Worker
724*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, size_t __bytes>
725*58b9f456SAndroid Build Coastguard Workerstruct __vec_ext_traits {
726*58b9f456SAndroid Build Coastguard Worker#if !defined(_LIBCPP_COMPILER_CLANG)
727*58b9f456SAndroid Build Coastguard Worker  typedef _Tp type __attribute__((vector_size(__ceil_pow_of_2(__bytes))));
728*58b9f456SAndroid Build Coastguard Worker#endif
729*58b9f456SAndroid Build Coastguard Worker};
730*58b9f456SAndroid Build Coastguard Worker
731*58b9f456SAndroid Build Coastguard Worker#if defined(_LIBCPP_COMPILER_CLANG)
732*58b9f456SAndroid Build Coastguard Worker#define _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, _NUM_ELEMENT)                        \
733*58b9f456SAndroid Build Coastguard Worker  template <>                                                                  \
734*58b9f456SAndroid Build Coastguard Worker  struct __vec_ext_traits<_TYPE, sizeof(_TYPE) * _NUM_ELEMENT> {               \
735*58b9f456SAndroid Build Coastguard Worker    using type =                                                               \
736*58b9f456SAndroid Build Coastguard Worker        _TYPE __attribute__((vector_size(sizeof(_TYPE) * _NUM_ELEMENT)));      \
737*58b9f456SAndroid Build Coastguard Worker  }
738*58b9f456SAndroid Build Coastguard Worker
739*58b9f456SAndroid Build Coastguard Worker#define _LIBCPP_SPECIALIZE_VEC_EXT_32(_TYPE)                                   \
740*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 1);                                        \
741*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 2);                                        \
742*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 3);                                        \
743*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 4);                                        \
744*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 5);                                        \
745*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 6);                                        \
746*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 7);                                        \
747*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 8);                                        \
748*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 9);                                        \
749*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 10);                                       \
750*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 11);                                       \
751*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 12);                                       \
752*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 13);                                       \
753*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 14);                                       \
754*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 15);                                       \
755*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 16);                                       \
756*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 17);                                       \
757*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 18);                                       \
758*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 19);                                       \
759*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 20);                                       \
760*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 21);                                       \
761*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 22);                                       \
762*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 23);                                       \
763*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 24);                                       \
764*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 25);                                       \
765*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 26);                                       \
766*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 27);                                       \
767*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 28);                                       \
768*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 29);                                       \
769*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 30);                                       \
770*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 31);                                       \
771*58b9f456SAndroid Build Coastguard Worker  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 32);
772*58b9f456SAndroid Build Coastguard Worker
773*58b9f456SAndroid Build Coastguard Worker_LIBCPP_SPECIALIZE_VEC_EXT_32(char);
774*58b9f456SAndroid Build Coastguard Worker_LIBCPP_SPECIALIZE_VEC_EXT_32(char16_t);
775*58b9f456SAndroid Build Coastguard Worker_LIBCPP_SPECIALIZE_VEC_EXT_32(char32_t);
776*58b9f456SAndroid Build Coastguard Worker_LIBCPP_SPECIALIZE_VEC_EXT_32(wchar_t);
777*58b9f456SAndroid Build Coastguard Worker_LIBCPP_SPECIALIZE_VEC_EXT_32(signed char);
778*58b9f456SAndroid Build Coastguard Worker_LIBCPP_SPECIALIZE_VEC_EXT_32(signed short);
779*58b9f456SAndroid Build Coastguard Worker_LIBCPP_SPECIALIZE_VEC_EXT_32(signed int);
780*58b9f456SAndroid Build Coastguard Worker_LIBCPP_SPECIALIZE_VEC_EXT_32(signed long);
781*58b9f456SAndroid Build Coastguard Worker_LIBCPP_SPECIALIZE_VEC_EXT_32(signed long long);
782*58b9f456SAndroid Build Coastguard Worker_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned char);
783*58b9f456SAndroid Build Coastguard Worker_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned short);
784*58b9f456SAndroid Build Coastguard Worker_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned int);
785*58b9f456SAndroid Build Coastguard Worker_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned long);
786*58b9f456SAndroid Build Coastguard Worker_LIBCPP_SPECIALIZE_VEC_EXT_32(unsigned long long);
787*58b9f456SAndroid Build Coastguard Worker_LIBCPP_SPECIALIZE_VEC_EXT_32(float);
788*58b9f456SAndroid Build Coastguard Worker_LIBCPP_SPECIALIZE_VEC_EXT_32(double);
789*58b9f456SAndroid Build Coastguard Worker_LIBCPP_SPECIALIZE_VEC_EXT_32(long double);
790*58b9f456SAndroid Build Coastguard Worker
791*58b9f456SAndroid Build Coastguard Worker#undef _LIBCPP_SPECIALIZE_VEC_EXT_32
792*58b9f456SAndroid Build Coastguard Worker#undef _LIBCPP_SPECIALIZE_VEC_EXT
793*58b9f456SAndroid Build Coastguard Worker#endif
794*58b9f456SAndroid Build Coastguard Worker
795*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, int __num_element>
796*58b9f456SAndroid Build Coastguard Workerclass __simd_storage<_Tp, __simd_abi<_StorageKind::_VecExt, __num_element>> {
797*58b9f456SAndroid Build Coastguard Worker  using _StorageType =
798*58b9f456SAndroid Build Coastguard Worker      typename __vec_ext_traits<_Tp, sizeof(_Tp) * __num_element>::type;
799*58b9f456SAndroid Build Coastguard Worker
800*58b9f456SAndroid Build Coastguard Worker  _StorageType __storage_;
801*58b9f456SAndroid Build Coastguard Worker
802*58b9f456SAndroid Build Coastguard Worker  template <class, class>
803*58b9f456SAndroid Build Coastguard Worker  friend struct simd;
804*58b9f456SAndroid Build Coastguard Worker
805*58b9f456SAndroid Build Coastguard Worker  template <class, class>
806*58b9f456SAndroid Build Coastguard Worker  friend struct simd_mask;
807*58b9f456SAndroid Build Coastguard Worker
808*58b9f456SAndroid Build Coastguard Workerpublic:
809*58b9f456SAndroid Build Coastguard Worker  _Tp __get(size_t __index) const noexcept { return __storage_[__index]; };
810*58b9f456SAndroid Build Coastguard Worker  void __set(size_t __index, _Tp __val) noexcept {
811*58b9f456SAndroid Build Coastguard Worker    __storage_[__index] = __val;
812*58b9f456SAndroid Build Coastguard Worker  }
813*58b9f456SAndroid Build Coastguard Worker};
814*58b9f456SAndroid Build Coastguard Worker
815*58b9f456SAndroid Build Coastguard Worker#endif // _LIBCPP_HAS_NO_VECTOR_EXTENSION
816*58b9f456SAndroid Build Coastguard Worker
817*58b9f456SAndroid Build Coastguard Workertemplate <class _Vp, class _Tp, class _Abi>
818*58b9f456SAndroid Build Coastguard Workerclass __simd_reference {
819*58b9f456SAndroid Build Coastguard Worker  static_assert(std::is_same<_Vp, _Tp>::value, "");
820*58b9f456SAndroid Build Coastguard Worker
821*58b9f456SAndroid Build Coastguard Worker  template <class, class>
822*58b9f456SAndroid Build Coastguard Worker  friend struct simd;
823*58b9f456SAndroid Build Coastguard Worker
824*58b9f456SAndroid Build Coastguard Worker  template <class, class>
825*58b9f456SAndroid Build Coastguard Worker  friend struct simd_mask;
826*58b9f456SAndroid Build Coastguard Worker
827*58b9f456SAndroid Build Coastguard Worker  __simd_storage<_Tp, _Abi>* __ptr_;
828*58b9f456SAndroid Build Coastguard Worker  size_t __index_;
829*58b9f456SAndroid Build Coastguard Worker
830*58b9f456SAndroid Build Coastguard Worker  __simd_reference(__simd_storage<_Tp, _Abi>* __ptr, size_t __index)
831*58b9f456SAndroid Build Coastguard Worker      : __ptr_(__ptr), __index_(__index) {}
832*58b9f456SAndroid Build Coastguard Worker
833*58b9f456SAndroid Build Coastguard Worker  __simd_reference(const __simd_reference&) = default;
834*58b9f456SAndroid Build Coastguard Worker
835*58b9f456SAndroid Build Coastguard Workerpublic:
836*58b9f456SAndroid Build Coastguard Worker  __simd_reference() = delete;
837*58b9f456SAndroid Build Coastguard Worker  __simd_reference& operator=(const __simd_reference&) = delete;
838*58b9f456SAndroid Build Coastguard Worker
839*58b9f456SAndroid Build Coastguard Worker  operator _Vp() const { return __ptr_->__get(__index_); }
840*58b9f456SAndroid Build Coastguard Worker
841*58b9f456SAndroid Build Coastguard Worker  __simd_reference operator=(_Vp __value) && {
842*58b9f456SAndroid Build Coastguard Worker    __ptr_->__set(__index_, __value);
843*58b9f456SAndroid Build Coastguard Worker    return *this;
844*58b9f456SAndroid Build Coastguard Worker  }
845*58b9f456SAndroid Build Coastguard Worker
846*58b9f456SAndroid Build Coastguard Worker  __simd_reference operator++() && {
847*58b9f456SAndroid Build Coastguard Worker    return std::move(*this) = __ptr_->__get(__index_) + 1;
848*58b9f456SAndroid Build Coastguard Worker  }
849*58b9f456SAndroid Build Coastguard Worker
850*58b9f456SAndroid Build Coastguard Worker  _Vp operator++(int) && {
851*58b9f456SAndroid Build Coastguard Worker    auto __val = __ptr_->__get(__index_);
852*58b9f456SAndroid Build Coastguard Worker    __ptr_->__set(__index_, __val + 1);
853*58b9f456SAndroid Build Coastguard Worker    return __val;
854*58b9f456SAndroid Build Coastguard Worker  }
855*58b9f456SAndroid Build Coastguard Worker
856*58b9f456SAndroid Build Coastguard Worker  __simd_reference operator--() && {
857*58b9f456SAndroid Build Coastguard Worker    return std::move(*this) = __ptr_->__get(__index_) - 1;
858*58b9f456SAndroid Build Coastguard Worker  }
859*58b9f456SAndroid Build Coastguard Worker
860*58b9f456SAndroid Build Coastguard Worker  _Vp operator--(int) && {
861*58b9f456SAndroid Build Coastguard Worker    auto __val = __ptr_->__get(__index_);
862*58b9f456SAndroid Build Coastguard Worker    __ptr_->__set(__index_, __val - 1);
863*58b9f456SAndroid Build Coastguard Worker    return __val;
864*58b9f456SAndroid Build Coastguard Worker  }
865*58b9f456SAndroid Build Coastguard Worker
866*58b9f456SAndroid Build Coastguard Worker  __simd_reference operator+=(_Vp __value) && {
867*58b9f456SAndroid Build Coastguard Worker    return std::move(*this) = __ptr_->__get(__index_) + __value;
868*58b9f456SAndroid Build Coastguard Worker  }
869*58b9f456SAndroid Build Coastguard Worker
870*58b9f456SAndroid Build Coastguard Worker  __simd_reference operator-=(_Vp __value) && {
871*58b9f456SAndroid Build Coastguard Worker    return std::move(*this) = __ptr_->__get(__index_) - __value;
872*58b9f456SAndroid Build Coastguard Worker  }
873*58b9f456SAndroid Build Coastguard Worker
874*58b9f456SAndroid Build Coastguard Worker  __simd_reference operator*=(_Vp __value) && {
875*58b9f456SAndroid Build Coastguard Worker    return std::move(*this) = __ptr_->__get(__index_) * __value;
876*58b9f456SAndroid Build Coastguard Worker  }
877*58b9f456SAndroid Build Coastguard Worker
878*58b9f456SAndroid Build Coastguard Worker  __simd_reference operator/=(_Vp __value) && {
879*58b9f456SAndroid Build Coastguard Worker    return std::move(*this) = __ptr_->__get(__index_) / __value;
880*58b9f456SAndroid Build Coastguard Worker  }
881*58b9f456SAndroid Build Coastguard Worker
882*58b9f456SAndroid Build Coastguard Worker  __simd_reference operator%=(_Vp __value) && {
883*58b9f456SAndroid Build Coastguard Worker    return std::move(*this) = __ptr_->__get(__index_) % __value;
884*58b9f456SAndroid Build Coastguard Worker  }
885*58b9f456SAndroid Build Coastguard Worker
886*58b9f456SAndroid Build Coastguard Worker  __simd_reference operator>>=(_Vp __value) && {
887*58b9f456SAndroid Build Coastguard Worker    return std::move(*this) = __ptr_->__get(__index_) >> __value;
888*58b9f456SAndroid Build Coastguard Worker  }
889*58b9f456SAndroid Build Coastguard Worker
890*58b9f456SAndroid Build Coastguard Worker  __simd_reference operator<<=(_Vp __value) && {
891*58b9f456SAndroid Build Coastguard Worker    return std::move(*this) = __ptr_->__get(__index_) << __value;
892*58b9f456SAndroid Build Coastguard Worker  }
893*58b9f456SAndroid Build Coastguard Worker
894*58b9f456SAndroid Build Coastguard Worker  __simd_reference operator&=(_Vp __value) && {
895*58b9f456SAndroid Build Coastguard Worker    return std::move(*this) = __ptr_->__get(__index_) & __value;
896*58b9f456SAndroid Build Coastguard Worker  }
897*58b9f456SAndroid Build Coastguard Worker
898*58b9f456SAndroid Build Coastguard Worker  __simd_reference operator|=(_Vp __value) && {
899*58b9f456SAndroid Build Coastguard Worker    return std::move(*this) = __ptr_->__get(__index_) | __value;
900*58b9f456SAndroid Build Coastguard Worker  }
901*58b9f456SAndroid Build Coastguard Worker
902*58b9f456SAndroid Build Coastguard Worker  __simd_reference operator^=(_Vp __value) && {
903*58b9f456SAndroid Build Coastguard Worker    return std::move(*this) = __ptr_->__get(__index_) ^ __value;
904*58b9f456SAndroid Build Coastguard Worker  }
905*58b9f456SAndroid Build Coastguard Worker};
906*58b9f456SAndroid Build Coastguard Worker
907*58b9f456SAndroid Build Coastguard Workertemplate <class _To, class _From>
908*58b9f456SAndroid Build Coastguard Workerconstexpr decltype(_To{std::declval<_From>()}, true)
909*58b9f456SAndroid Build Coastguard Worker__is_non_narrowing_convertible_impl(_From) {
910*58b9f456SAndroid Build Coastguard Worker  return true;
911*58b9f456SAndroid Build Coastguard Worker}
912*58b9f456SAndroid Build Coastguard Worker
913*58b9f456SAndroid Build Coastguard Workertemplate <class _To>
914*58b9f456SAndroid Build Coastguard Workerconstexpr bool __is_non_narrowing_convertible_impl(...) {
915*58b9f456SAndroid Build Coastguard Worker  return false;
916*58b9f456SAndroid Build Coastguard Worker}
917*58b9f456SAndroid Build Coastguard Worker
918*58b9f456SAndroid Build Coastguard Workertemplate <class _From, class _To>
919*58b9f456SAndroid Build Coastguard Workerconstexpr typename std::enable_if<std::is_arithmetic<_To>::value &&
920*58b9f456SAndroid Build Coastguard Worker                                      std::is_arithmetic<_From>::value,
921*58b9f456SAndroid Build Coastguard Worker                                  bool>::type
922*58b9f456SAndroid Build Coastguard Worker__is_non_narrowing_arithmetic_convertible() {
923*58b9f456SAndroid Build Coastguard Worker  return __is_non_narrowing_convertible_impl<_To>(_From{});
924*58b9f456SAndroid Build Coastguard Worker}
925*58b9f456SAndroid Build Coastguard Worker
926*58b9f456SAndroid Build Coastguard Workertemplate <class _From, class _To>
927*58b9f456SAndroid Build Coastguard Workerconstexpr typename std::enable_if<!(std::is_arithmetic<_To>::value &&
928*58b9f456SAndroid Build Coastguard Worker                                    std::is_arithmetic<_From>::value),
929*58b9f456SAndroid Build Coastguard Worker                                  bool>::type
930*58b9f456SAndroid Build Coastguard Worker__is_non_narrowing_arithmetic_convertible() {
931*58b9f456SAndroid Build Coastguard Worker  return false;
932*58b9f456SAndroid Build Coastguard Worker}
933*58b9f456SAndroid Build Coastguard Worker
934*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
935*58b9f456SAndroid Build Coastguard Workerconstexpr _Tp __variadic_sum() {
936*58b9f456SAndroid Build Coastguard Worker  return _Tp{};
937*58b9f456SAndroid Build Coastguard Worker}
938*58b9f456SAndroid Build Coastguard Worker
939*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Up, class... _Args>
940*58b9f456SAndroid Build Coastguard Workerconstexpr _Tp __variadic_sum(_Up __first, _Args... __rest) {
941*58b9f456SAndroid Build Coastguard Worker  return static_cast<_Tp>(__first) + __variadic_sum<_Tp>(__rest...);
942*58b9f456SAndroid Build Coastguard Worker}
943*58b9f456SAndroid Build Coastguard Worker
944*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
945*58b9f456SAndroid Build Coastguard Workerstruct __nodeduce {
946*58b9f456SAndroid Build Coastguard Worker  using type = _Tp;
947*58b9f456SAndroid Build Coastguard Worker};
948*58b9f456SAndroid Build Coastguard Worker
949*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
950*58b9f456SAndroid Build Coastguard Workerconstexpr bool __vectorizable() {
951*58b9f456SAndroid Build Coastguard Worker  return std::is_arithmetic<_Tp>::value && !std::is_const<_Tp>::value &&
952*58b9f456SAndroid Build Coastguard Worker         !std::is_volatile<_Tp>::value && !std::is_same<_Tp, bool>::value;
953*58b9f456SAndroid Build Coastguard Worker}
954*58b9f456SAndroid Build Coastguard Worker
955*58b9f456SAndroid Build Coastguard Worker_LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD
956*58b9f456SAndroid Build Coastguard Worker_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD_ABI
957*58b9f456SAndroid Build Coastguard Worker
958*58b9f456SAndroid Build Coastguard Workerusing scalar = __simd_abi<_StorageKind::_Scalar, 1>;
959*58b9f456SAndroid Build Coastguard Worker
960*58b9f456SAndroid Build Coastguard Workertemplate <int _Np>
961*58b9f456SAndroid Build Coastguard Workerusing fixed_size = __simd_abi<_StorageKind::_Array, _Np>;
962*58b9f456SAndroid Build Coastguard Worker
963*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
964*58b9f456SAndroid Build Coastguard Worker_LIBCPP_INLINE_VAR constexpr size_t max_fixed_size = 32;
965*58b9f456SAndroid Build Coastguard Worker
966*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
967*58b9f456SAndroid Build Coastguard Workerusing compatible = fixed_size<16 / sizeof(_Tp)>;
968*58b9f456SAndroid Build Coastguard Worker
969*58b9f456SAndroid Build Coastguard Worker#ifndef _LIBCPP_HAS_NO_VECTOR_EXTENSION
970*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
971*58b9f456SAndroid Build Coastguard Workerusing native = __simd_abi<_StorageKind::_VecExt,
972*58b9f456SAndroid Build Coastguard Worker                          _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(_Tp)>;
973*58b9f456SAndroid Build Coastguard Worker#else
974*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
975*58b9f456SAndroid Build Coastguard Workerusing native =
976*58b9f456SAndroid Build Coastguard Worker    fixed_size<_Tp, _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(_Tp)>;
977*58b9f456SAndroid Build Coastguard Worker#endif // _LIBCPP_HAS_NO_VECTOR_EXTENSION
978*58b9f456SAndroid Build Coastguard Worker
979*58b9f456SAndroid Build Coastguard Worker_LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD_ABI
980*58b9f456SAndroid Build Coastguard Worker_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD
981*58b9f456SAndroid Build Coastguard Worker
982*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi = simd_abi::compatible<_Tp>>
983*58b9f456SAndroid Build Coastguard Workerclass simd;
984*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi = simd_abi::compatible<_Tp>>
985*58b9f456SAndroid Build Coastguard Workerclass simd_mask;
986*58b9f456SAndroid Build Coastguard Worker
987*58b9f456SAndroid Build Coastguard Workerstruct element_aligned_tag {};
988*58b9f456SAndroid Build Coastguard Workerstruct vector_aligned_tag {};
989*58b9f456SAndroid Build Coastguard Workertemplate <size_t>
990*58b9f456SAndroid Build Coastguard Workerstruct overaligned_tag {};
991*58b9f456SAndroid Build Coastguard Worker_LIBCPP_INLINE_VAR constexpr element_aligned_tag element_aligned{};
992*58b9f456SAndroid Build Coastguard Worker_LIBCPP_INLINE_VAR constexpr vector_aligned_tag vector_aligned{};
993*58b9f456SAndroid Build Coastguard Workertemplate <size_t _Np>
994*58b9f456SAndroid Build Coastguard Worker_LIBCPP_INLINE_VAR constexpr overaligned_tag<_Np> overaligned{};
995*58b9f456SAndroid Build Coastguard Worker
996*58b9f456SAndroid Build Coastguard Worker// traits [simd.traits]
997*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
998*58b9f456SAndroid Build Coastguard Workerstruct is_abi_tag : std::integral_constant<bool, false> {};
999*58b9f456SAndroid Build Coastguard Worker
1000*58b9f456SAndroid Build Coastguard Workertemplate <_StorageKind __kind, int _Np>
1001*58b9f456SAndroid Build Coastguard Workerstruct is_abi_tag<__simd_abi<__kind, _Np>>
1002*58b9f456SAndroid Build Coastguard Worker    : std::integral_constant<bool, true> {};
1003*58b9f456SAndroid Build Coastguard Worker
1004*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
1005*58b9f456SAndroid Build Coastguard Workerstruct is_simd : std::integral_constant<bool, false> {};
1006*58b9f456SAndroid Build Coastguard Worker
1007*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1008*58b9f456SAndroid Build Coastguard Workerstruct is_simd<simd<_Tp, _Abi>> : std::integral_constant<bool, true> {};
1009*58b9f456SAndroid Build Coastguard Worker
1010*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
1011*58b9f456SAndroid Build Coastguard Workerstruct is_simd_mask : std::integral_constant<bool, false> {};
1012*58b9f456SAndroid Build Coastguard Worker
1013*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1014*58b9f456SAndroid Build Coastguard Workerstruct is_simd_mask<simd_mask<_Tp, _Abi>> : std::integral_constant<bool, true> {
1015*58b9f456SAndroid Build Coastguard Worker};
1016*58b9f456SAndroid Build Coastguard Worker
1017*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
1018*58b9f456SAndroid Build Coastguard Workerstruct is_simd_flag_type : std::integral_constant<bool, false> {};
1019*58b9f456SAndroid Build Coastguard Worker
1020*58b9f456SAndroid Build Coastguard Workertemplate <>
1021*58b9f456SAndroid Build Coastguard Workerstruct is_simd_flag_type<element_aligned_tag>
1022*58b9f456SAndroid Build Coastguard Worker    : std::integral_constant<bool, true> {};
1023*58b9f456SAndroid Build Coastguard Worker
1024*58b9f456SAndroid Build Coastguard Workertemplate <>
1025*58b9f456SAndroid Build Coastguard Workerstruct is_simd_flag_type<vector_aligned_tag>
1026*58b9f456SAndroid Build Coastguard Worker    : std::integral_constant<bool, true> {};
1027*58b9f456SAndroid Build Coastguard Worker
1028*58b9f456SAndroid Build Coastguard Workertemplate <size_t _Align>
1029*58b9f456SAndroid Build Coastguard Workerstruct is_simd_flag_type<overaligned_tag<_Align>>
1030*58b9f456SAndroid Build Coastguard Worker    : std::integral_constant<bool, true> {};
1031*58b9f456SAndroid Build Coastguard Worker
1032*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
1033*58b9f456SAndroid Build Coastguard Worker_LIBCPP_INLINE_VAR constexpr bool is_abi_tag_v = is_abi_tag<_Tp>::value;
1034*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
1035*58b9f456SAndroid Build Coastguard Worker_LIBCPP_INLINE_VAR constexpr bool is_simd_v = is_simd<_Tp>::value;
1036*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
1037*58b9f456SAndroid Build Coastguard Worker_LIBCPP_INLINE_VAR constexpr bool is_simd_mask_v = is_simd_mask<_Tp>::value;
1038*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
1039*58b9f456SAndroid Build Coastguard Worker_LIBCPP_INLINE_VAR constexpr bool is_simd_flag_type_v =
1040*58b9f456SAndroid Build Coastguard Worker    is_simd_flag_type<_Tp>::value;
1041*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, size_t _Np>
1042*58b9f456SAndroid Build Coastguard Workerstruct abi_for_size {
1043*58b9f456SAndroid Build Coastguard Worker  using type = simd_abi::fixed_size<_Np>;
1044*58b9f456SAndroid Build Coastguard Worker};
1045*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, size_t _Np>
1046*58b9f456SAndroid Build Coastguard Workerusing abi_for_size_t = typename abi_for_size<_Tp, _Np>::type;
1047*58b9f456SAndroid Build Coastguard Worker
1048*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi = simd_abi::compatible<_Tp>>
1049*58b9f456SAndroid Build Coastguard Workerstruct simd_size;
1050*58b9f456SAndroid Build Coastguard Worker
1051*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, _StorageKind __kind, int _Np>
1052*58b9f456SAndroid Build Coastguard Workerstruct simd_size<_Tp, __simd_abi<__kind, _Np>>
1053*58b9f456SAndroid Build Coastguard Worker    : std::integral_constant<size_t, _Np> {
1054*58b9f456SAndroid Build Coastguard Worker  static_assert(
1055*58b9f456SAndroid Build Coastguard Worker      std::is_arithmetic<_Tp>::value &&
1056*58b9f456SAndroid Build Coastguard Worker          !std::is_same<typename std::remove_const<_Tp>::type, bool>::value,
1057*58b9f456SAndroid Build Coastguard Worker      "Element type should be vectorizable");
1058*58b9f456SAndroid Build Coastguard Worker};
1059*58b9f456SAndroid Build Coastguard Worker
1060*58b9f456SAndroid Build Coastguard Worker// TODO: implement it.
1061*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Up = typename _Tp::value_type>
1062*58b9f456SAndroid Build Coastguard Workerstruct memory_alignment;
1063*58b9f456SAndroid Build Coastguard Worker
1064*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi = simd_abi::compatible<_Tp>>
1065*58b9f456SAndroid Build Coastguard Worker_LIBCPP_INLINE_VAR constexpr size_t simd_size_v = simd_size<_Tp, _Abi>::value;
1066*58b9f456SAndroid Build Coastguard Worker
1067*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Up = typename _Tp::value_type>
1068*58b9f456SAndroid Build Coastguard Worker_LIBCPP_INLINE_VAR constexpr size_t memory_alignment_v =
1069*58b9f456SAndroid Build Coastguard Worker    memory_alignment<_Tp, _Up>::value;
1070*58b9f456SAndroid Build Coastguard Worker
1071*58b9f456SAndroid Build Coastguard Worker// class template simd [simd.class]
1072*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
1073*58b9f456SAndroid Build Coastguard Workerusing native_simd = simd<_Tp, simd_abi::native<_Tp>>;
1074*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, int _Np>
1075*58b9f456SAndroid Build Coastguard Workerusing fixed_size_simd = simd<_Tp, simd_abi::fixed_size<_Np>>;
1076*58b9f456SAndroid Build Coastguard Worker
1077*58b9f456SAndroid Build Coastguard Worker// class template simd_mask [simd.mask.class]
1078*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
1079*58b9f456SAndroid Build Coastguard Workerusing native_simd_mask = simd_mask<_Tp, simd_abi::native<_Tp>>;
1080*58b9f456SAndroid Build Coastguard Worker
1081*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, int _Np>
1082*58b9f456SAndroid Build Coastguard Workerusing fixed_size_simd_mask = simd_mask<_Tp, simd_abi::fixed_size<_Np>>;
1083*58b9f456SAndroid Build Coastguard Worker
1084*58b9f456SAndroid Build Coastguard Worker// casts [simd.casts]
1085*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
1086*58b9f456SAndroid Build Coastguard Workerstruct __static_simd_cast_traits {
1087*58b9f456SAndroid Build Coastguard Worker  template <class _Up, class _Abi>
1088*58b9f456SAndroid Build Coastguard Worker  static simd<_Tp, _Abi> __apply(const simd<_Up, _Abi>& __v);
1089*58b9f456SAndroid Build Coastguard Worker};
1090*58b9f456SAndroid Build Coastguard Worker
1091*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _NewAbi>
1092*58b9f456SAndroid Build Coastguard Workerstruct __static_simd_cast_traits<simd<_Tp, _NewAbi>> {
1093*58b9f456SAndroid Build Coastguard Worker  template <class _Up, class _Abi>
1094*58b9f456SAndroid Build Coastguard Worker  static typename std::enable_if<simd<_Up, _Abi>::size() ==
1095*58b9f456SAndroid Build Coastguard Worker                                     simd<_Tp, _NewAbi>::size(),
1096*58b9f456SAndroid Build Coastguard Worker                                 simd<_Tp, _NewAbi>>::type
1097*58b9f456SAndroid Build Coastguard Worker  __apply(const simd<_Up, _Abi>& __v);
1098*58b9f456SAndroid Build Coastguard Worker};
1099*58b9f456SAndroid Build Coastguard Worker
1100*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
1101*58b9f456SAndroid Build Coastguard Workerstruct __simd_cast_traits {
1102*58b9f456SAndroid Build Coastguard Worker  template <class _Up, class _Abi>
1103*58b9f456SAndroid Build Coastguard Worker  static typename std::enable_if<
1104*58b9f456SAndroid Build Coastguard Worker      __is_non_narrowing_arithmetic_convertible<_Up, _Tp>(),
1105*58b9f456SAndroid Build Coastguard Worker      simd<_Tp, _Abi>>::type
1106*58b9f456SAndroid Build Coastguard Worker  __apply(const simd<_Up, _Abi>& __v);
1107*58b9f456SAndroid Build Coastguard Worker};
1108*58b9f456SAndroid Build Coastguard Worker
1109*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _NewAbi>
1110*58b9f456SAndroid Build Coastguard Workerstruct __simd_cast_traits<simd<_Tp, _NewAbi>> {
1111*58b9f456SAndroid Build Coastguard Worker  template <class _Up, class _Abi>
1112*58b9f456SAndroid Build Coastguard Worker  static typename std::enable_if<
1113*58b9f456SAndroid Build Coastguard Worker      __is_non_narrowing_arithmetic_convertible<_Up, _Tp>() &&
1114*58b9f456SAndroid Build Coastguard Worker          simd<_Up, _Abi>::size() == simd<_Tp, _NewAbi>::size(),
1115*58b9f456SAndroid Build Coastguard Worker      simd<_Tp, _NewAbi>>::type
1116*58b9f456SAndroid Build Coastguard Worker  __apply(const simd<_Up, _Abi>& __v);
1117*58b9f456SAndroid Build Coastguard Worker};
1118*58b9f456SAndroid Build Coastguard Worker
1119*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Up, class _Abi>
1120*58b9f456SAndroid Build Coastguard Workerauto simd_cast(const simd<_Up, _Abi>& __v)
1121*58b9f456SAndroid Build Coastguard Worker    -> decltype(__simd_cast_traits<_Tp>::__apply(__v)) {
1122*58b9f456SAndroid Build Coastguard Worker  return __simd_cast_traits<_Tp>::__apply(__v);
1123*58b9f456SAndroid Build Coastguard Worker}
1124*58b9f456SAndroid Build Coastguard Worker
1125*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Up, class _Abi>
1126*58b9f456SAndroid Build Coastguard Workerauto static_simd_cast(const simd<_Up, _Abi>& __v)
1127*58b9f456SAndroid Build Coastguard Worker    -> decltype(__static_simd_cast_traits<_Tp>::__apply(__v)) {
1128*58b9f456SAndroid Build Coastguard Worker  return __static_simd_cast_traits<_Tp>::__apply(__v);
1129*58b9f456SAndroid Build Coastguard Worker}
1130*58b9f456SAndroid Build Coastguard Worker
1131*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1132*58b9f456SAndroid Build Coastguard Workerfixed_size_simd<_Tp, simd_size<_Tp, _Abi>::value>
1133*58b9f456SAndroid Build Coastguard Workerto_fixed_size(const simd<_Tp, _Abi>&) noexcept;
1134*58b9f456SAndroid Build Coastguard Worker
1135*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1136*58b9f456SAndroid Build Coastguard Workerfixed_size_simd_mask<_Tp, simd_size<_Tp, _Abi>::value>
1137*58b9f456SAndroid Build Coastguard Workerto_fixed_size(const simd_mask<_Tp, _Abi>&) noexcept;
1138*58b9f456SAndroid Build Coastguard Worker
1139*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, size_t _Np>
1140*58b9f456SAndroid Build Coastguard Workernative_simd<_Tp> to_native(const fixed_size_simd<_Tp, _Np>&) noexcept;
1141*58b9f456SAndroid Build Coastguard Worker
1142*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, size_t _Np>
1143*58b9f456SAndroid Build Coastguard Workernative_simd_mask<_Tp> to_native(const fixed_size_simd_mask<_Tp, _Np>&) noexcept;
1144*58b9f456SAndroid Build Coastguard Worker
1145*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, size_t _Np>
1146*58b9f456SAndroid Build Coastguard Workersimd<_Tp> to_compatible(const fixed_size_simd<_Tp, _Np>&) noexcept;
1147*58b9f456SAndroid Build Coastguard Worker
1148*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, size_t _Np>
1149*58b9f456SAndroid Build Coastguard Workersimd_mask<_Tp> to_compatible(const fixed_size_simd_mask<_Tp, _Np>&) noexcept;
1150*58b9f456SAndroid Build Coastguard Worker
1151*58b9f456SAndroid Build Coastguard Workertemplate <size_t... __sizes, class _Tp, class _Abi>
1152*58b9f456SAndroid Build Coastguard Workertuple<simd<_Tp, abi_for_size_t<_Tp, __sizes>>...> split(const simd<_Tp, _Abi>&);
1153*58b9f456SAndroid Build Coastguard Worker
1154*58b9f456SAndroid Build Coastguard Workertemplate <size_t... __sizes, class _Tp, class _Abi>
1155*58b9f456SAndroid Build Coastguard Workertuple<simd_mask<_Tp, abi_for_size_t<_Tp, __sizes>>...>
1156*58b9f456SAndroid Build Coastguard Workersplit(const simd_mask<_Tp, _Abi>&);
1157*58b9f456SAndroid Build Coastguard Worker
1158*58b9f456SAndroid Build Coastguard Workertemplate <class _SimdType, class _Abi>
1159*58b9f456SAndroid Build Coastguard Workerarray<_SimdType, simd_size<typename _SimdType::value_type, _Abi>::value /
1160*58b9f456SAndroid Build Coastguard Worker                     _SimdType::size()>
1161*58b9f456SAndroid Build Coastguard Workersplit(const simd<typename _SimdType::value_type, _Abi>&);
1162*58b9f456SAndroid Build Coastguard Worker
1163*58b9f456SAndroid Build Coastguard Workertemplate <class _SimdType, class _Abi>
1164*58b9f456SAndroid Build Coastguard Workerarray<_SimdType, simd_size<typename _SimdType::value_type, _Abi>::value /
1165*58b9f456SAndroid Build Coastguard Worker                     _SimdType::size()>
1166*58b9f456SAndroid Build Coastguard Workersplit(const simd_mask<typename _SimdType::value_type, _Abi>&);
1167*58b9f456SAndroid Build Coastguard Worker
1168*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class... _Abis>
1169*58b9f456SAndroid Build Coastguard Workersimd<_Tp, abi_for_size_t<_Tp, __variadic_sum(simd_size<_Tp, _Abis>::value...)>>
1170*58b9f456SAndroid Build Coastguard Workerconcat(const simd<_Tp, _Abis>&...);
1171*58b9f456SAndroid Build Coastguard Worker
1172*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class... _Abis>
1173*58b9f456SAndroid Build Coastguard Workersimd_mask<_Tp,
1174*58b9f456SAndroid Build Coastguard Worker          abi_for_size_t<_Tp, __variadic_sum(simd_size<_Tp, _Abis>::value...)>>
1175*58b9f456SAndroid Build Coastguard Workerconcat(const simd_mask<_Tp, _Abis>&...);
1176*58b9f456SAndroid Build Coastguard Worker
1177*58b9f456SAndroid Build Coastguard Worker// reductions [simd.mask.reductions]
1178*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1179*58b9f456SAndroid Build Coastguard Workerbool all_of(const simd_mask<_Tp, _Abi>&) noexcept;
1180*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1181*58b9f456SAndroid Build Coastguard Workerbool any_of(const simd_mask<_Tp, _Abi>&) noexcept;
1182*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1183*58b9f456SAndroid Build Coastguard Workerbool none_of(const simd_mask<_Tp, _Abi>&) noexcept;
1184*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1185*58b9f456SAndroid Build Coastguard Workerbool some_of(const simd_mask<_Tp, _Abi>&) noexcept;
1186*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1187*58b9f456SAndroid Build Coastguard Workerint popcount(const simd_mask<_Tp, _Abi>&) noexcept;
1188*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1189*58b9f456SAndroid Build Coastguard Workerint find_first_set(const simd_mask<_Tp, _Abi>&);
1190*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1191*58b9f456SAndroid Build Coastguard Workerint find_last_set(const simd_mask<_Tp, _Abi>&);
1192*58b9f456SAndroid Build Coastguard Workerbool all_of(bool) noexcept;
1193*58b9f456SAndroid Build Coastguard Workerbool any_of(bool) noexcept;
1194*58b9f456SAndroid Build Coastguard Workerbool none_of(bool) noexcept;
1195*58b9f456SAndroid Build Coastguard Workerbool some_of(bool) noexcept;
1196*58b9f456SAndroid Build Coastguard Workerint popcount(bool) noexcept;
1197*58b9f456SAndroid Build Coastguard Workerint find_first_set(bool) noexcept;
1198*58b9f456SAndroid Build Coastguard Workerint find_last_set(bool) noexcept;
1199*58b9f456SAndroid Build Coastguard Worker
1200*58b9f456SAndroid Build Coastguard Worker// masked assignment [simd.whereexpr]
1201*58b9f456SAndroid Build Coastguard Workertemplate <class _MaskType, class _Tp>
1202*58b9f456SAndroid Build Coastguard Workerclass const_where_expression;
1203*58b9f456SAndroid Build Coastguard Workertemplate <class _MaskType, class _Tp>
1204*58b9f456SAndroid Build Coastguard Workerclass where_expression;
1205*58b9f456SAndroid Build Coastguard Worker
1206*58b9f456SAndroid Build Coastguard Worker// masked assignment [simd.mask.where]
1207*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1208*58b9f456SAndroid Build Coastguard Workerwhere_expression<simd_mask<_Tp, _Abi>, simd<_Tp, _Abi>>
1209*58b9f456SAndroid Build Coastguard Workerwhere(const typename simd<_Tp, _Abi>::mask_type&, simd<_Tp, _Abi>&) noexcept;
1210*58b9f456SAndroid Build Coastguard Worker
1211*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1212*58b9f456SAndroid Build Coastguard Workerconst_where_expression<simd_mask<_Tp, _Abi>, const simd<_Tp, _Abi>>
1213*58b9f456SAndroid Build Coastguard Workerwhere(const typename simd<_Tp, _Abi>::mask_type&,
1214*58b9f456SAndroid Build Coastguard Worker      const simd<_Tp, _Abi>&) noexcept;
1215*58b9f456SAndroid Build Coastguard Worker
1216*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1217*58b9f456SAndroid Build Coastguard Workerwhere_expression<simd_mask<_Tp, _Abi>, simd_mask<_Tp, _Abi>>
1218*58b9f456SAndroid Build Coastguard Workerwhere(const typename __nodeduce<simd_mask<_Tp, _Abi>>::type&,
1219*58b9f456SAndroid Build Coastguard Worker      simd_mask<_Tp, _Abi>&) noexcept;
1220*58b9f456SAndroid Build Coastguard Worker
1221*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1222*58b9f456SAndroid Build Coastguard Workerconst_where_expression<simd_mask<_Tp, _Abi>, const simd_mask<_Tp, _Abi>>
1223*58b9f456SAndroid Build Coastguard Workerwhere(const typename __nodeduce<simd_mask<_Tp, _Abi>>::type&,
1224*58b9f456SAndroid Build Coastguard Worker      const simd_mask<_Tp, _Abi>&) noexcept;
1225*58b9f456SAndroid Build Coastguard Worker
1226*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
1227*58b9f456SAndroid Build Coastguard Workerwhere_expression<bool, _Tp> where(bool, _Tp&) noexcept;
1228*58b9f456SAndroid Build Coastguard Worker
1229*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp>
1230*58b9f456SAndroid Build Coastguard Workerconst_where_expression<bool, const _Tp> where(bool, const _Tp&) noexcept;
1231*58b9f456SAndroid Build Coastguard Worker
1232*58b9f456SAndroid Build Coastguard Worker// reductions [simd.reductions]
1233*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi, class _BinaryOp = std::plus<_Tp>>
1234*58b9f456SAndroid Build Coastguard Worker_Tp reduce(const simd<_Tp, _Abi>&, _BinaryOp = _BinaryOp());
1235*58b9f456SAndroid Build Coastguard Worker
1236*58b9f456SAndroid Build Coastguard Workertemplate <class _MaskType, class _SimdType, class _BinaryOp>
1237*58b9f456SAndroid Build Coastguard Workertypename _SimdType::value_type
1238*58b9f456SAndroid Build Coastguard Workerreduce(const const_where_expression<_MaskType, _SimdType>&,
1239*58b9f456SAndroid Build Coastguard Worker       typename _SimdType::value_type neutral_element, _BinaryOp binary_op);
1240*58b9f456SAndroid Build Coastguard Worker
1241*58b9f456SAndroid Build Coastguard Workertemplate <class _MaskType, class _SimdType>
1242*58b9f456SAndroid Build Coastguard Workertypename _SimdType::value_type
1243*58b9f456SAndroid Build Coastguard Workerreduce(const const_where_expression<_MaskType, _SimdType>&,
1244*58b9f456SAndroid Build Coastguard Worker       plus<typename _SimdType::value_type> binary_op = {});
1245*58b9f456SAndroid Build Coastguard Worker
1246*58b9f456SAndroid Build Coastguard Workertemplate <class _MaskType, class _SimdType>
1247*58b9f456SAndroid Build Coastguard Workertypename _SimdType::value_type
1248*58b9f456SAndroid Build Coastguard Workerreduce(const const_where_expression<_MaskType, _SimdType>&,
1249*58b9f456SAndroid Build Coastguard Worker       multiplies<typename _SimdType::value_type> binary_op);
1250*58b9f456SAndroid Build Coastguard Worker
1251*58b9f456SAndroid Build Coastguard Workertemplate <class _MaskType, class _SimdType>
1252*58b9f456SAndroid Build Coastguard Workertypename _SimdType::value_type
1253*58b9f456SAndroid Build Coastguard Workerreduce(const const_where_expression<_MaskType, _SimdType>&,
1254*58b9f456SAndroid Build Coastguard Worker       bit_and<typename _SimdType::value_type> binary_op);
1255*58b9f456SAndroid Build Coastguard Worker
1256*58b9f456SAndroid Build Coastguard Workertemplate <class _MaskType, class _SimdType>
1257*58b9f456SAndroid Build Coastguard Workertypename _SimdType::value_type
1258*58b9f456SAndroid Build Coastguard Workerreduce(const const_where_expression<_MaskType, _SimdType>&,
1259*58b9f456SAndroid Build Coastguard Worker       bit_or<typename _SimdType::value_type> binary_op);
1260*58b9f456SAndroid Build Coastguard Worker
1261*58b9f456SAndroid Build Coastguard Workertemplate <class _MaskType, class _SimdType>
1262*58b9f456SAndroid Build Coastguard Workertypename _SimdType::value_type
1263*58b9f456SAndroid Build Coastguard Workerreduce(const const_where_expression<_MaskType, _SimdType>&,
1264*58b9f456SAndroid Build Coastguard Worker       bit_xor<typename _SimdType::value_type> binary_op);
1265*58b9f456SAndroid Build Coastguard Worker
1266*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1267*58b9f456SAndroid Build Coastguard Worker_Tp hmin(const simd<_Tp, _Abi>&);
1268*58b9f456SAndroid Build Coastguard Workertemplate <class _MaskType, class _SimdType>
1269*58b9f456SAndroid Build Coastguard Workertypename _SimdType::value_type
1270*58b9f456SAndroid Build Coastguard Workerhmin(const const_where_expression<_MaskType, _SimdType>&);
1271*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1272*58b9f456SAndroid Build Coastguard Worker_Tp hmax(const simd<_Tp, _Abi>&);
1273*58b9f456SAndroid Build Coastguard Workertemplate <class _MaskType, class _SimdType>
1274*58b9f456SAndroid Build Coastguard Workertypename _SimdType::value_type
1275*58b9f456SAndroid Build Coastguard Workerhmax(const const_where_expression<_MaskType, _SimdType>&);
1276*58b9f456SAndroid Build Coastguard Worker
1277*58b9f456SAndroid Build Coastguard Worker// algorithms [simd.alg]
1278*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1279*58b9f456SAndroid Build Coastguard Workersimd<_Tp, _Abi> min(const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&) noexcept;
1280*58b9f456SAndroid Build Coastguard Worker
1281*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1282*58b9f456SAndroid Build Coastguard Workersimd<_Tp, _Abi> max(const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&) noexcept;
1283*58b9f456SAndroid Build Coastguard Worker
1284*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1285*58b9f456SAndroid Build Coastguard Workerstd::pair<simd<_Tp, _Abi>, simd<_Tp, _Abi>>
1286*58b9f456SAndroid Build Coastguard Workerminmax(const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&) noexcept;
1287*58b9f456SAndroid Build Coastguard Worker
1288*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1289*58b9f456SAndroid Build Coastguard Workersimd<_Tp, _Abi> clamp(const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&,
1290*58b9f456SAndroid Build Coastguard Worker                      const simd<_Tp, _Abi>&);
1291*58b9f456SAndroid Build Coastguard Worker
1292*58b9f456SAndroid Build Coastguard Worker// [simd.whereexpr]
1293*58b9f456SAndroid Build Coastguard Worker// TODO implement where expressions.
1294*58b9f456SAndroid Build Coastguard Workertemplate <class _MaskType, class _Tp>
1295*58b9f456SAndroid Build Coastguard Workerclass const_where_expression {
1296*58b9f456SAndroid Build Coastguard Workerpublic:
1297*58b9f456SAndroid Build Coastguard Worker  const_where_expression(const const_where_expression&) = delete;
1298*58b9f456SAndroid Build Coastguard Worker  const_where_expression& operator=(const const_where_expression&) = delete;
1299*58b9f456SAndroid Build Coastguard Worker  typename remove_const<_Tp>::type operator-() const&&;
1300*58b9f456SAndroid Build Coastguard Worker  template <class _Up, class _Flags>
1301*58b9f456SAndroid Build Coastguard Worker  void copy_to(_Up*, _Flags) const&&;
1302*58b9f456SAndroid Build Coastguard Worker};
1303*58b9f456SAndroid Build Coastguard Worker
1304*58b9f456SAndroid Build Coastguard Workertemplate <class _MaskType, class _Tp>
1305*58b9f456SAndroid Build Coastguard Workerclass where_expression : public const_where_expression<_MaskType, _Tp> {
1306*58b9f456SAndroid Build Coastguard Workerpublic:
1307*58b9f456SAndroid Build Coastguard Worker  where_expression(const where_expression&) = delete;
1308*58b9f456SAndroid Build Coastguard Worker  where_expression& operator=(const where_expression&) = delete;
1309*58b9f456SAndroid Build Coastguard Worker  template <class _Up>
1310*58b9f456SAndroid Build Coastguard Worker  void operator=(_Up&&);
1311*58b9f456SAndroid Build Coastguard Worker  template <class _Up>
1312*58b9f456SAndroid Build Coastguard Worker  void operator+=(_Up&&);
1313*58b9f456SAndroid Build Coastguard Worker  template <class _Up>
1314*58b9f456SAndroid Build Coastguard Worker  void operator-=(_Up&&);
1315*58b9f456SAndroid Build Coastguard Worker  template <class _Up>
1316*58b9f456SAndroid Build Coastguard Worker  void operator*=(_Up&&);
1317*58b9f456SAndroid Build Coastguard Worker  template <class _Up>
1318*58b9f456SAndroid Build Coastguard Worker  void operator/=(_Up&&);
1319*58b9f456SAndroid Build Coastguard Worker  template <class _Up>
1320*58b9f456SAndroid Build Coastguard Worker  void operator%=(_Up&&);
1321*58b9f456SAndroid Build Coastguard Worker  template <class _Up>
1322*58b9f456SAndroid Build Coastguard Worker  void operator&=(_Up&&);
1323*58b9f456SAndroid Build Coastguard Worker  template <class _Up>
1324*58b9f456SAndroid Build Coastguard Worker  void operator|=(_Up&&);
1325*58b9f456SAndroid Build Coastguard Worker  template <class _Up>
1326*58b9f456SAndroid Build Coastguard Worker  void operator^=(_Up&&);
1327*58b9f456SAndroid Build Coastguard Worker  template <class _Up>
1328*58b9f456SAndroid Build Coastguard Worker  void operator<<=(_Up&&);
1329*58b9f456SAndroid Build Coastguard Worker  template <class _Up>
1330*58b9f456SAndroid Build Coastguard Worker  void operator>>=(_Up&&);
1331*58b9f456SAndroid Build Coastguard Worker  void operator++();
1332*58b9f456SAndroid Build Coastguard Worker  void operator++(int);
1333*58b9f456SAndroid Build Coastguard Worker  void operator--();
1334*58b9f456SAndroid Build Coastguard Worker  void operator--(int);
1335*58b9f456SAndroid Build Coastguard Worker  template <class _Up, class _Flags>
1336*58b9f456SAndroid Build Coastguard Worker  void copy_from(const _Up*, _Flags);
1337*58b9f456SAndroid Build Coastguard Worker};
1338*58b9f456SAndroid Build Coastguard Worker
1339*58b9f456SAndroid Build Coastguard Worker// [simd.class]
1340*58b9f456SAndroid Build Coastguard Worker// TODO: implement simd
1341*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1342*58b9f456SAndroid Build Coastguard Workerclass simd {
1343*58b9f456SAndroid Build Coastguard Workerpublic:
1344*58b9f456SAndroid Build Coastguard Worker  using value_type = _Tp;
1345*58b9f456SAndroid Build Coastguard Worker  using reference = __simd_reference<_Tp, _Tp, _Abi>;
1346*58b9f456SAndroid Build Coastguard Worker  using mask_type = simd_mask<_Tp, _Abi>;
1347*58b9f456SAndroid Build Coastguard Worker  using abi_type = _Abi;
1348*58b9f456SAndroid Build Coastguard Worker
1349*58b9f456SAndroid Build Coastguard Worker  simd() = default;
1350*58b9f456SAndroid Build Coastguard Worker  simd(const simd&) = default;
1351*58b9f456SAndroid Build Coastguard Worker  simd& operator=(const simd&) = default;
1352*58b9f456SAndroid Build Coastguard Worker
1353*58b9f456SAndroid Build Coastguard Worker  static constexpr size_t size() noexcept {
1354*58b9f456SAndroid Build Coastguard Worker    return simd_size<_Tp, _Abi>::value;
1355*58b9f456SAndroid Build Coastguard Worker  }
1356*58b9f456SAndroid Build Coastguard Worker
1357*58b9f456SAndroid Build Coastguard Workerprivate:
1358*58b9f456SAndroid Build Coastguard Worker  __simd_storage<_Tp, _Abi> __s_;
1359*58b9f456SAndroid Build Coastguard Worker
1360*58b9f456SAndroid Build Coastguard Worker  template <class _Up>
1361*58b9f456SAndroid Build Coastguard Worker  static constexpr bool __can_broadcast() {
1362*58b9f456SAndroid Build Coastguard Worker    return (std::is_arithmetic<_Up>::value &&
1363*58b9f456SAndroid Build Coastguard Worker            __is_non_narrowing_arithmetic_convertible<_Up, _Tp>()) ||
1364*58b9f456SAndroid Build Coastguard Worker           (!std::is_arithmetic<_Up>::value &&
1365*58b9f456SAndroid Build Coastguard Worker            std::is_convertible<_Up, _Tp>::value) ||
1366*58b9f456SAndroid Build Coastguard Worker           std::is_same<typename std::remove_const<_Up>::type, int>::value ||
1367*58b9f456SAndroid Build Coastguard Worker           (std::is_same<typename std::remove_const<_Up>::type,
1368*58b9f456SAndroid Build Coastguard Worker                         unsigned int>::value &&
1369*58b9f456SAndroid Build Coastguard Worker            std::is_unsigned<_Tp>::value);
1370*58b9f456SAndroid Build Coastguard Worker  }
1371*58b9f456SAndroid Build Coastguard Worker
1372*58b9f456SAndroid Build Coastguard Worker  template <class _Generator, size_t... __indicies>
1373*58b9f456SAndroid Build Coastguard Worker  static constexpr decltype(
1374*58b9f456SAndroid Build Coastguard Worker      std::forward_as_tuple(std::declval<_Generator>()(
1375*58b9f456SAndroid Build Coastguard Worker          std::integral_constant<size_t, __indicies>())...),
1376*58b9f456SAndroid Build Coastguard Worker      bool())
1377*58b9f456SAndroid Build Coastguard Worker  __can_generate(std::index_sequence<__indicies...>) {
1378*58b9f456SAndroid Build Coastguard Worker    return !__variadic_sum<bool>(
1379*58b9f456SAndroid Build Coastguard Worker        !__can_broadcast<decltype(std::declval<_Generator>()(
1380*58b9f456SAndroid Build Coastguard Worker            std::integral_constant<size_t, __indicies>()))>()...);
1381*58b9f456SAndroid Build Coastguard Worker  }
1382*58b9f456SAndroid Build Coastguard Worker
1383*58b9f456SAndroid Build Coastguard Worker  template <class _Generator>
1384*58b9f456SAndroid Build Coastguard Worker  static bool __can_generate(...) {
1385*58b9f456SAndroid Build Coastguard Worker    return false;
1386*58b9f456SAndroid Build Coastguard Worker  }
1387*58b9f456SAndroid Build Coastguard Worker
1388*58b9f456SAndroid Build Coastguard Worker  template <class _Generator, size_t... __indicies>
1389*58b9f456SAndroid Build Coastguard Worker  void __generator_init(_Generator&& __g, std::index_sequence<__indicies...>) {
1390*58b9f456SAndroid Build Coastguard Worker    int __not_used[]{((*this)[__indicies] =
1391*58b9f456SAndroid Build Coastguard Worker                          __g(std::integral_constant<size_t, __indicies>()),
1392*58b9f456SAndroid Build Coastguard Worker                      0)...};
1393*58b9f456SAndroid Build Coastguard Worker    (void)__not_used;
1394*58b9f456SAndroid Build Coastguard Worker  }
1395*58b9f456SAndroid Build Coastguard Worker
1396*58b9f456SAndroid Build Coastguard Workerpublic:
1397*58b9f456SAndroid Build Coastguard Worker  // implicit type conversion constructor
1398*58b9f456SAndroid Build Coastguard Worker  template <class _Up,
1399*58b9f456SAndroid Build Coastguard Worker            class = typename std::enable_if<
1400*58b9f456SAndroid Build Coastguard Worker                std::is_same<_Abi, simd_abi::fixed_size<size()>>::value &&
1401*58b9f456SAndroid Build Coastguard Worker                __is_non_narrowing_arithmetic_convertible<_Up, _Tp>()>::type>
1402*58b9f456SAndroid Build Coastguard Worker  simd(const simd<_Up, simd_abi::fixed_size<size()>>& __v) {
1403*58b9f456SAndroid Build Coastguard Worker    for (size_t __i = 0; __i < size(); __i++) {
1404*58b9f456SAndroid Build Coastguard Worker      (*this)[__i] = static_cast<_Tp>(__v[__i]);
1405*58b9f456SAndroid Build Coastguard Worker    }
1406*58b9f456SAndroid Build Coastguard Worker  }
1407*58b9f456SAndroid Build Coastguard Worker
1408*58b9f456SAndroid Build Coastguard Worker  // implicit broadcast constructor
1409*58b9f456SAndroid Build Coastguard Worker  template <class _Up,
1410*58b9f456SAndroid Build Coastguard Worker            class = typename std::enable_if<__can_broadcast<_Up>()>::type>
1411*58b9f456SAndroid Build Coastguard Worker  simd(_Up&& __rv) {
1412*58b9f456SAndroid Build Coastguard Worker    auto __v = static_cast<_Tp>(__rv);
1413*58b9f456SAndroid Build Coastguard Worker    for (size_t __i = 0; __i < size(); __i++) {
1414*58b9f456SAndroid Build Coastguard Worker      (*this)[__i] = __v;
1415*58b9f456SAndroid Build Coastguard Worker    }
1416*58b9f456SAndroid Build Coastguard Worker  }
1417*58b9f456SAndroid Build Coastguard Worker
1418*58b9f456SAndroid Build Coastguard Worker  // generator constructor
1419*58b9f456SAndroid Build Coastguard Worker  template <class _Generator,
1420*58b9f456SAndroid Build Coastguard Worker            int = typename std::enable_if<
1421*58b9f456SAndroid Build Coastguard Worker                __can_generate<_Generator>(std::make_index_sequence<size()>()),
1422*58b9f456SAndroid Build Coastguard Worker                int>::type()>
1423*58b9f456SAndroid Build Coastguard Worker  explicit simd(_Generator&& __g) {
1424*58b9f456SAndroid Build Coastguard Worker    __generator_init(std::forward<_Generator>(__g),
1425*58b9f456SAndroid Build Coastguard Worker                     std::make_index_sequence<size()>());
1426*58b9f456SAndroid Build Coastguard Worker  }
1427*58b9f456SAndroid Build Coastguard Worker
1428*58b9f456SAndroid Build Coastguard Worker  // load constructor
1429*58b9f456SAndroid Build Coastguard Worker  template <
1430*58b9f456SAndroid Build Coastguard Worker      class _Up, class _Flags,
1431*58b9f456SAndroid Build Coastguard Worker      class = typename std::enable_if<__vectorizable<_Up>()>::type,
1432*58b9f456SAndroid Build Coastguard Worker      class = typename std::enable_if<is_simd_flag_type<_Flags>::value>::type>
1433*58b9f456SAndroid Build Coastguard Worker  simd(const _Up* __buffer, _Flags) {
1434*58b9f456SAndroid Build Coastguard Worker    // TODO: optimize for overaligned flags
1435*58b9f456SAndroid Build Coastguard Worker    for (size_t __i = 0; __i < size(); __i++) {
1436*58b9f456SAndroid Build Coastguard Worker      (*this)[__i] = static_cast<_Tp>(__buffer[__i]);
1437*58b9f456SAndroid Build Coastguard Worker    }
1438*58b9f456SAndroid Build Coastguard Worker  }
1439*58b9f456SAndroid Build Coastguard Worker
1440*58b9f456SAndroid Build Coastguard Worker  // loads [simd.load]
1441*58b9f456SAndroid Build Coastguard Worker  template <class _Up, class _Flags>
1442*58b9f456SAndroid Build Coastguard Worker  typename std::enable_if<__vectorizable<_Up>() &&
1443*58b9f456SAndroid Build Coastguard Worker                          is_simd_flag_type<_Flags>::value>::type
1444*58b9f456SAndroid Build Coastguard Worker  copy_from(const _Up* __buffer, _Flags) {
1445*58b9f456SAndroid Build Coastguard Worker    *this = simd(__buffer, _Flags());
1446*58b9f456SAndroid Build Coastguard Worker  }
1447*58b9f456SAndroid Build Coastguard Worker
1448*58b9f456SAndroid Build Coastguard Worker  // stores [simd.store]
1449*58b9f456SAndroid Build Coastguard Worker  template <class _Up, class _Flags>
1450*58b9f456SAndroid Build Coastguard Worker  typename std::enable_if<__vectorizable<_Up>() &&
1451*58b9f456SAndroid Build Coastguard Worker                          is_simd_flag_type<_Flags>::value>::type
1452*58b9f456SAndroid Build Coastguard Worker  copy_to(_Up* __buffer, _Flags) const {
1453*58b9f456SAndroid Build Coastguard Worker    // TODO: optimize for overaligned flags
1454*58b9f456SAndroid Build Coastguard Worker    for (size_t __i = 0; __i < size(); __i++) {
1455*58b9f456SAndroid Build Coastguard Worker      __buffer[__i] = static_cast<_Up>((*this)[__i]);
1456*58b9f456SAndroid Build Coastguard Worker    }
1457*58b9f456SAndroid Build Coastguard Worker  }
1458*58b9f456SAndroid Build Coastguard Worker
1459*58b9f456SAndroid Build Coastguard Worker  // scalar access [simd.subscr]
1460*58b9f456SAndroid Build Coastguard Worker  reference operator[](size_t __i) { return reference(&__s_, __i); }
1461*58b9f456SAndroid Build Coastguard Worker
1462*58b9f456SAndroid Build Coastguard Worker  value_type operator[](size_t __i) const { return __s_.__get(__i); }
1463*58b9f456SAndroid Build Coastguard Worker
1464*58b9f456SAndroid Build Coastguard Worker  // unary operators [simd.unary]
1465*58b9f456SAndroid Build Coastguard Worker  simd& operator++();
1466*58b9f456SAndroid Build Coastguard Worker  simd operator++(int);
1467*58b9f456SAndroid Build Coastguard Worker  simd& operator--();
1468*58b9f456SAndroid Build Coastguard Worker  simd operator--(int);
1469*58b9f456SAndroid Build Coastguard Worker  mask_type operator!() const;
1470*58b9f456SAndroid Build Coastguard Worker  simd operator~() const;
1471*58b9f456SAndroid Build Coastguard Worker  simd operator+() const;
1472*58b9f456SAndroid Build Coastguard Worker  simd operator-() const;
1473*58b9f456SAndroid Build Coastguard Worker
1474*58b9f456SAndroid Build Coastguard Worker  // binary operators [simd.binary]
1475*58b9f456SAndroid Build Coastguard Worker  friend simd operator+(const simd&, const simd&);
1476*58b9f456SAndroid Build Coastguard Worker  friend simd operator-(const simd&, const simd&);
1477*58b9f456SAndroid Build Coastguard Worker  friend simd operator*(const simd&, const simd&);
1478*58b9f456SAndroid Build Coastguard Worker  friend simd operator/(const simd&, const simd&);
1479*58b9f456SAndroid Build Coastguard Worker  friend simd operator%(const simd&, const simd&);
1480*58b9f456SAndroid Build Coastguard Worker  friend simd operator&(const simd&, const simd&);
1481*58b9f456SAndroid Build Coastguard Worker  friend simd operator|(const simd&, const simd&);
1482*58b9f456SAndroid Build Coastguard Worker  friend simd operator^(const simd&, const simd&);
1483*58b9f456SAndroid Build Coastguard Worker  friend simd operator<<(const simd&, const simd&);
1484*58b9f456SAndroid Build Coastguard Worker  friend simd operator>>(const simd&, const simd&);
1485*58b9f456SAndroid Build Coastguard Worker  friend simd operator<<(const simd&, int);
1486*58b9f456SAndroid Build Coastguard Worker  friend simd operator>>(const simd&, int);
1487*58b9f456SAndroid Build Coastguard Worker
1488*58b9f456SAndroid Build Coastguard Worker  // compound assignment [simd.cassign]
1489*58b9f456SAndroid Build Coastguard Worker  friend simd& operator+=(simd&, const simd&);
1490*58b9f456SAndroid Build Coastguard Worker  friend simd& operator-=(simd&, const simd&);
1491*58b9f456SAndroid Build Coastguard Worker  friend simd& operator*=(simd&, const simd&);
1492*58b9f456SAndroid Build Coastguard Worker  friend simd& operator/=(simd&, const simd&);
1493*58b9f456SAndroid Build Coastguard Worker  friend simd& operator%=(simd&, const simd&);
1494*58b9f456SAndroid Build Coastguard Worker
1495*58b9f456SAndroid Build Coastguard Worker  friend simd& operator&=(simd&, const simd&);
1496*58b9f456SAndroid Build Coastguard Worker  friend simd& operator|=(simd&, const simd&);
1497*58b9f456SAndroid Build Coastguard Worker  friend simd& operator^=(simd&, const simd&);
1498*58b9f456SAndroid Build Coastguard Worker  friend simd& operator<<=(simd&, const simd&);
1499*58b9f456SAndroid Build Coastguard Worker  friend simd& operator>>=(simd&, const simd&);
1500*58b9f456SAndroid Build Coastguard Worker  friend simd& operator<<=(simd&, int);
1501*58b9f456SAndroid Build Coastguard Worker  friend simd& operator>>=(simd&, int);
1502*58b9f456SAndroid Build Coastguard Worker
1503*58b9f456SAndroid Build Coastguard Worker  // compares [simd.comparison]
1504*58b9f456SAndroid Build Coastguard Worker  friend mask_type operator==(const simd&, const simd&);
1505*58b9f456SAndroid Build Coastguard Worker  friend mask_type operator!=(const simd&, const simd&);
1506*58b9f456SAndroid Build Coastguard Worker  friend mask_type operator>=(const simd&, const simd&);
1507*58b9f456SAndroid Build Coastguard Worker  friend mask_type operator<=(const simd&, const simd&);
1508*58b9f456SAndroid Build Coastguard Worker  friend mask_type operator>(const simd&, const simd&);
1509*58b9f456SAndroid Build Coastguard Worker  friend mask_type operator<(const simd&, const simd&);
1510*58b9f456SAndroid Build Coastguard Worker};
1511*58b9f456SAndroid Build Coastguard Worker
1512*58b9f456SAndroid Build Coastguard Worker// [simd.mask.class]
1513*58b9f456SAndroid Build Coastguard Workertemplate <class _Tp, class _Abi>
1514*58b9f456SAndroid Build Coastguard Worker// TODO: implement simd_mask
1515*58b9f456SAndroid Build Coastguard Workerclass simd_mask {
1516*58b9f456SAndroid Build Coastguard Workerpublic:
1517*58b9f456SAndroid Build Coastguard Worker  using value_type = bool;
1518*58b9f456SAndroid Build Coastguard Worker  // TODO: this is strawman implementation. Turn it into a proxy type.
1519*58b9f456SAndroid Build Coastguard Worker  using reference = bool&;
1520*58b9f456SAndroid Build Coastguard Worker  using simd_type = simd<_Tp, _Abi>;
1521*58b9f456SAndroid Build Coastguard Worker  using abi_type = _Abi;
1522*58b9f456SAndroid Build Coastguard Worker  static constexpr size_t size() noexcept;
1523*58b9f456SAndroid Build Coastguard Worker  simd_mask() = default;
1524*58b9f456SAndroid Build Coastguard Worker
1525*58b9f456SAndroid Build Coastguard Worker  // broadcast constructor
1526*58b9f456SAndroid Build Coastguard Worker  explicit simd_mask(value_type) noexcept;
1527*58b9f456SAndroid Build Coastguard Worker
1528*58b9f456SAndroid Build Coastguard Worker  // implicit type conversion constructor
1529*58b9f456SAndroid Build Coastguard Worker  template <class _Up>
1530*58b9f456SAndroid Build Coastguard Worker  simd_mask(const simd_mask<_Up, simd_abi::fixed_size<size()>>&) noexcept;
1531*58b9f456SAndroid Build Coastguard Worker
1532*58b9f456SAndroid Build Coastguard Worker  // load constructor
1533*58b9f456SAndroid Build Coastguard Worker  template <class _Flags>
1534*58b9f456SAndroid Build Coastguard Worker  simd_mask(const value_type*, _Flags);
1535*58b9f456SAndroid Build Coastguard Worker
1536*58b9f456SAndroid Build Coastguard Worker  // loads [simd.mask.copy]
1537*58b9f456SAndroid Build Coastguard Worker  template <class _Flags>
1538*58b9f456SAndroid Build Coastguard Worker  void copy_from(const value_type*, _Flags);
1539*58b9f456SAndroid Build Coastguard Worker  template <class _Flags>
1540*58b9f456SAndroid Build Coastguard Worker  void copy_to(value_type*, _Flags) const;
1541*58b9f456SAndroid Build Coastguard Worker
1542*58b9f456SAndroid Build Coastguard Worker  // scalar access [simd.mask.subscr]
1543*58b9f456SAndroid Build Coastguard Worker  reference operator[](size_t);
1544*58b9f456SAndroid Build Coastguard Worker  value_type operator[](size_t) const;
1545*58b9f456SAndroid Build Coastguard Worker
1546*58b9f456SAndroid Build Coastguard Worker  // unary operators [simd.mask.unary]
1547*58b9f456SAndroid Build Coastguard Worker  simd_mask operator!() const noexcept;
1548*58b9f456SAndroid Build Coastguard Worker
1549*58b9f456SAndroid Build Coastguard Worker  // simd_mask binary operators [simd.mask.binary]
1550*58b9f456SAndroid Build Coastguard Worker  friend simd_mask operator&&(const simd_mask&, const simd_mask&) noexcept;
1551*58b9f456SAndroid Build Coastguard Worker  friend simd_mask operator||(const simd_mask&, const simd_mask&) noexcept;
1552*58b9f456SAndroid Build Coastguard Worker  friend simd_mask operator&(const simd_mask&, const simd_mask&)noexcept;
1553*58b9f456SAndroid Build Coastguard Worker  friend simd_mask operator|(const simd_mask&, const simd_mask&) noexcept;
1554*58b9f456SAndroid Build Coastguard Worker  friend simd_mask operator^(const simd_mask&, const simd_mask&) noexcept;
1555*58b9f456SAndroid Build Coastguard Worker
1556*58b9f456SAndroid Build Coastguard Worker  // simd_mask compound assignment [simd.mask.cassign]
1557*58b9f456SAndroid Build Coastguard Worker  friend simd_mask& operator&=(simd_mask&, const simd_mask&) noexcept;
1558*58b9f456SAndroid Build Coastguard Worker  friend simd_mask& operator|=(simd_mask&, const simd_mask&) noexcept;
1559*58b9f456SAndroid Build Coastguard Worker  friend simd_mask& operator^=(simd_mask&, const simd_mask&) noexcept;
1560*58b9f456SAndroid Build Coastguard Worker
1561*58b9f456SAndroid Build Coastguard Worker  // simd_mask compares [simd.mask.comparison]
1562*58b9f456SAndroid Build Coastguard Worker  friend simd_mask operator==(const simd_mask&, const simd_mask&) noexcept;
1563*58b9f456SAndroid Build Coastguard Worker  friend simd_mask operator!=(const simd_mask&, const simd_mask&) noexcept;
1564*58b9f456SAndroid Build Coastguard Worker};
1565*58b9f456SAndroid Build Coastguard Worker
1566*58b9f456SAndroid Build Coastguard Worker#endif // _LIBCPP_STD_VER >= 17
1567*58b9f456SAndroid Build Coastguard Worker
1568*58b9f456SAndroid Build Coastguard Worker_LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD
1569*58b9f456SAndroid Build Coastguard Worker
1570*58b9f456SAndroid Build Coastguard Worker#endif /* _LIBCPP_EXPERIMENTAL_SIMD */
1571