Namespaces
Variants

Standard library header <simd> (C++26)

From cppreference.com
 
 
Standard library headers
 

This header is part of the numeric library.

Classes

data-parallel vector type
(class template) [edit]
(C++26)
convenience alias template for basic_vec that can specify its width
(alias template)[edit]
data-parallel type with the element type bool
(class template) [edit]
convenience alias template for basic_mask that can specify its width
(alias template)[edit]
load and store flags for data-parallel types
(class template) [edit]
obtains an appropriate alignment for simd::flag_aligned
(class template) [edit]
changes element type of the data-parallel type
(class template) [edit]
changes the width of the data-parallel type
(class template) [edit]

Functions

loads elements from a contiguous range to basic_vec
(function template) [edit]
stores elements from basic_vec to a contiguous range
(function template) [edit]
splits single data-parallel object to multiple ones
(function template) [edit]
(C++26)
concatenates multiple data-parallel objects into a single one
(function template) [edit]
reductions of basic_mask to bool
(function template) [edit]
reduction of basic_mask to number of true values
(function template) [edit]
reductions of basic_mask to the index of first or last true value
(function template) [edit]
reduces all values in basic_vec over a specified binary operation to a single value
(function template) [edit]
element-wise min/max operations for basic_vec
(function template) [edit]
element-wise clamp operation for basic_vec
(function template) [edit]
element-wise selection using conditional operator
(function template) [edit]

Constants

default flag used on load and store operations
(constant) [edit]
flag enabling conversions that are not value-preserving on load and store operations
(constant) [edit]
flag indicating alignment of the load-store address to some specified storage to the value of simd::alignment
(constant) [edit]
flag indicating alignment of the load-store address to some specified storage to the specified alignment
(variable template)[edit]

Synopsis

namespace std::simd {
  // type Traits
  template<class T, class U = typename T::value_type> struct alignment;
  template<class T, class U = typename T::value_type>
  constexpr size_t alignment_v = alignment<T, U>::value;

  template<class T, class V> struct rebind
  {
    using type = /* see description */;
  };
  template<class T, class V> using rebind_t = rebind<T, V>::type;
  template</*simd-size-type*/ N, class V> struct resize
  {
    using type = /* see description */;
  };
  template</*simd-size-type*/ N, class V> using resize_t = resize<N, V>::type;

  // load and store flags
  template<class... Flags> struct flags;
  inline constexpr flags<> flag_default{};
  inline constexpr flags</*convert-flag*/> flag_convert{};
  inline constexpr flags</*aligned-flag*/> flag_aligned{};
  template<size_t N>
    requires(has_single_bit(N))
  constexpr flags</*overaligned-flag*/<N>> flag_overaligned{};

  // class template simd-iterator
  template<class V> class /*simd-iterator*/; // exposition-only

  // class template basic_vec
  template<class T, class Abi = /*native-abi*/<T>> class basic_vec;
  template<class T, /*simd-size-type*/ N = /*simd-size-v*/<T, /*native-abi*/<T>>>
  using vec = basic_vec<T, /*deduce-abi-t*/<T, N>>;

  // reductions
  template<class T, class Abi, class BinaryOperation = plus<>>
  constexpr T reduce(const basic_vec<T, Abi>&, BinaryOperation = {});
  template<class T, class Abi, class BinaryOperation = plus<>>
  constexpr T reduce(const basic_vec<T, Abi>& x,
                     const typename basic_vec<T, Abi>::mask_type& mask,
                     BinaryOperation binary_op = {},
                     type_identity_t<T> identity_element = /* see description */);

  template<class T, class BinaryOperation = plus<>>
  constexpr T reduce(const T&, BinaryOperation = {});
  template<class T, class BinaryOperation = plus<>>
  constexpr T reduce(const T& x,
                     same_as<bool> auto mask,
                     BinaryOperation binary_op = {},
                     type_identity_t<T> identity_element = /* see description */);

  template<class T, class Abi> constexpr T reduce_min(const basic_vec<T, Abi>&) noexcept;
  template<class T, class Abi>
  constexpr T reduce_min(const basic_vec<T, Abi>&,
                         const typename basic_vec<T, Abi>::mask_type&) noexcept;
  template<class T, class Abi> constexpr T reduce_max(const basic_vec<T, Abi>&) noexcept;
  template<class T, class Abi>
  constexpr T reduce_max(const basic_vec<T, Abi>&,
                         const typename basic_vec<T, Abi>::mask_type&) noexcept;

  template<class T> constexpr T reduce_min(const T&) noexcept;
  template<class T> constexpr T reduce_min(const T&, same_as<bool> auto) noexcept;
  template<class T> constexpr T reduce_max(const T&) noexcept;
  template<class T> constexpr T reduce_max(const T&, same_as<bool> auto) noexcept;

  // load and store functions
  template<class V = /* see description */, ranges::contiguous_range R, class... Flags>
    requires ranges::sized_range<R>
  constexpr V unchecked_load(R&& r, flags<Flags...> f = {});
  template<class V = /* see description */, ranges::contiguous_range R, class... Flags>
    requires ranges::sized_range<R>
  constexpr V unchecked_load(R&& r,
                             const typename V::mask_type& k,
                             flags<Flags...> f = {});
  template<class V = /* see description */, contiguous_iterator I, class... Flags>
  constexpr V unchecked_load(I first, iter_difference_t<I> n, flags<Flags...> f = {});
  template<class V = /* see description */, contiguous_iterator I, class... Flags>
  constexpr V unchecked_load(I first,
                             iter_difference_t<I> n,
                             const typename V::mask_type& k,
                             flags<Flags...> f = {});
  template<class V = /* see description */,
           contiguous_iterator I,
           sized_sentinel_for<I> S,
           class... Flags>
  constexpr V unchecked_load(I first, S last, flags<Flags...> f = {});
  template<class V = /* see description */,
           contiguous_iterator I,
           sized_sentinel_for<I> S,
           class... Flags>
  constexpr V unchecked_load(I first,
                             S last,
                             const typename V::mask_type& k,
                             flags<Flags...> f = {});

  template<class V = /* see description */, ranges::contiguous_range R, class... Flags>
    requires ranges::sized_range<R>
  constexpr V partial_load(R&& r, flags<Flags...> f = {});
  template<class V = /* see description */, ranges::contiguous_range R, class... Flags>
    requires ranges::sized_range<R>
  constexpr V partial_load(R&& r, const typename V::mask_type& k, flags<Flags...> f = {});
  template<class V = /* see description */, contiguous_iterator I, class... Flags>
  constexpr V partial_load(I first, iter_difference_t<I> n, flags<Flags...> f = {});
  template<class V = /* see description */, contiguous_iterator I, class... Flags>
  constexpr V partial_load(I first,
                           iter_difference_t<I> n,
                           const typename V::mask_type& k,
                           flags<Flags...> f = {});
  template<class V = /* see description */,
           contiguous_iterator I,
           sized_sentinel_for<I> S,
           class... Flags>
  constexpr V partial_load(I first, S last, flags<Flags...> f = {});
  template<class V = /* see description */,
           contiguous_iterator I,
           sized_sentinel_for<I> S,
           class... Flags>
  constexpr V partial_load(I first,
                           S last,
                           const typename V::mask_type& k,
                           flags<Flags...> f = {});

  template<class T, class Abi, ranges::contiguous_range R, class... Flags>
    requires ranges::sized_range<R>
  constexpr void unchecked_store(const basic_vec<T, Abi>& v,
                                 R&& r,
                                 flags<Flags...> f = {});
  template<class T, class Abi, ranges::contiguous_range R, class... Flags>
    requires ranges::sized_range<R>
  constexpr void unchecked_store(const basic_vec<T, Abi>& v,
                                 R&& r,
                                 const typename basic_vec<T, Abi>::mask_type& mask,
                                 flags<Flags...> f = {});
  template<class T, class Abi, contiguous_iterator I, class... Flags>
  constexpr void unchecked_store(const basic_vec<T, Abi>& v,
                                 I first,
                                 iter_difference_t<I> n,
                                 flags<Flags...> f = {});
  template<class T, class Abi, contiguous_iterator I, class... Flags>
  constexpr void unchecked_store(const basic_vec<T, Abi>& v,
                                 I first,
                                 iter_difference_t<I> n,
                                 const typename basic_vec<T, Abi>::mask_type& mask,
                                 flags<Flags...> f = {});
  template<class T,
           class Abi,
           contiguous_iterator I,
           sized_sentinel_for<I> S,
           class... Flags>
  constexpr void unchecked_store(const basic_vec<T, Abi>& v,
                                 I first,
                                 S last,
                                 flags<Flags...> f = {});
  template<class T,
           class Abi,
           contiguous_iterator I,
           sized_sentinel_for<I> S,
           class... Flags>
  constexpr void unchecked_store(const basic_vec<T, Abi>& v,
                                 I first,
                                 S last,
                                 const typename basic_vec<T, Abi>::mask_type& mask,
                                 flags<Flags...> f = {});

  template<class T, class Abi, ranges::contiguous_range R, class... Flags>
    requires ranges::sized_range<R>
  constexpr void partial_store(const basic_vec<T, Abi>& v, R&& r, flags<Flags...> f = {});
  template<class T, class Abi, ranges::contiguous_range R, class... Flags>
    requires ranges::sized_range<R>
  constexpr void partial_store(const basic_vec<T, Abi>& v,
                               R&& r,
                               const typename basic_vec<T, Abi>::mask_type& mask,
                               flags<Flags...> f = {});
  template<class T, class Abi, contiguous_iterator I, class... Flags>
  constexpr void partial_store(const basic_vec<T, Abi>& v,
                               I first,
                               iter_difference_t<I> n,
                               flags<Flags...> f = {});
  template<class T, class Abi, contiguous_iterator I, class... Flags>
  constexpr void partial_store(const basic_vec<T, Abi>& v,
                               I first,
                               iter_difference_t<I> n,
                               const typename basic_vec<T, Abi>::mask_type& mask,
                               flags<Flags...> f = {});
  template<class T,
           class Abi,
           contiguous_iterator I,
           sized_sentinel_for<I> S,
           class... Flags>
  constexpr void partial_store(const basic_vec<T, Abi>& v,
                               I first,
                               S last,
                               flags<Flags...> f = {});
  template<class T,
           class Abi,
           contiguous_iterator I,
           sized_sentinel_for<I> S,
           class... Flags>
  constexpr void partial_store(const basic_vec<T, Abi>& v,
                               I first,
                               S last,
                               const typename basic_vec<T, Abi>::mask_type& mask,
                               flags<Flags...> f = {});

  // static permute
  inline constexpr /*simd-size-type*/ zero_element = /* implementation-defined */;
  inline constexpr /*simd-size-type*/ uninit_element = /* implementation-defined */;

  template</*simd-size-type*/ N =
             /* see description */, /*simd-vec-type*/ V, class IdxMap>
  constexpr resize_t<N, V> permute(const V& v, IdxMap&& idxmap);
  template</*simd-size-type*/ N =
             /* see description */, /*simd-mask-type*/ V, class IdxMap>
  constexpr resize_t<N, V> permute(const V& v, IdxMap&& idxmap);

  // dynamic permute
  template</*simd-vec-type*/ V, /*simd-integral*/ I>
  constexpr resize_t<I::size(), V> permute(const V& v, const I& indices);
  template</*simd-mask-type*/ V, /*simd-integral*/ I>
  constexpr resize_t<I::size(), V> permute(const V& v, const I& indices);

  // mask permute
  template</*simd-vec-type*/ V>
  constexpr V compress(const V& v, const typename V::mask_type& selector);
  template</*simd-mask-type*/ V>
  constexpr V compress(const V& v, const type_identity_t<V>& selector);
  template</*simd-vec-type*/ V>
  constexpr V compress(const V& v,
                       const typename V::mask_type& selector,
                       const typename V::value_type& fill_value);
  template</*simd-mask-type*/ V>
  constexpr V compress(const V& v,
                       const type_identity_t<V>& selector,
                       const typename V::value_type& fill_value);

  template</*simd-vec-type*/ V>
  constexpr V expand(const V& v,
                     const typename V::mask_type& selector,
                     const V& original = {});
  template</*simd-mask-type*/ V>
  constexpr V expand(const V& v,
                     const type_identity_t<V>& selector,
                     const V& original = {});

  // memory permute
  template<class V = /* see description */,
           ranges::contiguous_range R,
           /*simd-integral*/ I,
           class... Flags>
    requires ranges::sized_range<R>
  constexpr V unchecked_gather_from(R&& in, const I& indices, flags<Flags...> f = {});
  template<class V = /* see description */,
           ranges::contiguous_range R,
           /*simd-integral*/ I,
           class... Flags>
    requires ranges::sized_range<R>
  constexpr V unchecked_gather_from(R&& in,
                                    const typename I::mask_type& mask,
                                    const I& indices,
                                    flags<Flags...> f = {});

  template<class V = /* see description */,
           ranges::contiguous_range R,
           /*simd-integral*/ I,
           class... Flags>
    requires ranges::sized_range<R>
  constexpr V partial_gather_from(R&& in, const I& indices, flags<Flags...> f = {});
  template<class V = /* see description */,
           ranges::contiguous_range R,
           /*simd-integral*/ I,
           class... Flags>
    requires ranges::sized_range<R>
  constexpr V partial_gather_from(R&& in,
                                  const typename I::mask_type& mask,
                                  const I& indices,
                                  flags<Flags...> f = {});

  template</*simd-vec-type*/ V,
           ranges::contiguous_range R,
           /*simd-integral*/ I,
           class... Flags>
    requires ranges::sized_range<R>
  constexpr void unchecked_scatter_to(const V& v,
                                      R&& out,
                                      const I& indices,
                                      flags<Flags...> f = {});
  template</*simd-vec-type*/ V,
           ranges::contiguous_range R,
           /*simd-integral*/ I,
           class... Flags>
    requires ranges::sized_range<R>
  constexpr void unchecked_scatter_to(const V& v,
                                      R&& out,
                                      const typename I::mask_type& mask,
                                      const I& indices,
                                      flags<Flags...> f = {});

  template</*simd-vec-type*/ V,
           ranges::contiguous_range R,
           /*simd-integral*/ I,
           class... Flags>
    requires ranges::sized_range<R>
  constexpr void partial_scatter_to(const V& v,
                                    R&& out,
                                    const I& indices,
                                    flags<Flags...> f = {});
  template</*simd-vec-type*/ V,
           ranges::contiguous_range R,
           /*simd-integral*/ I,
           class... Flags>
    requires ranges::sized_range<R>
  constexpr void partial_scatter_to(const V& v,
                                    R&& out,
                                    const typename I::mask_type& mask,
                                    const I& indices,
                                    flags<Flags...> f = {});

  // creation
  template<class T, class Abi>
  constexpr auto chunk(const basic_vec<typename T::value_type, Abi>& x) noexcept;
  template<class T, class Abi>
  constexpr auto chunk(const basic_mask</*mask-element-size*/<T>, Abi>& x) noexcept;

  template</*simd-size-type*/ N, class T, class Abi>
  constexpr auto chunk(const basic_vec<T, Abi>& x) noexcept;
  template</*simd-size-type*/ N, size_t Bytes, class Abi>
  constexpr auto chunk(const basic_mask<Bytes, Abi>& x) noexcept;

  template<class T, class... Abis>
  constexpr resize_t<(basic_vec<T, Abis>::size() + ...), basic_vec<T, Abis...[0]>> cat(
    const basic_vec<T, Abis>&...) noexcept;
  template<size_t Bytes, class... Abis>
  constexpr resize_t<(basic_mask<Bytes, Abis>::size() + ...),
                     basic_mask<Bytes, Abis...[0]>>
  cat(const basic_mask<Bytes, Abis>&...) noexcept;

  // algorithms
  template<class T, class Abi>
  constexpr basic_vec<T, Abi> min(const basic_vec<T, Abi>& a,
                                  const basic_vec<T, Abi>& b) noexcept;
  template<class T, class Abi>
  constexpr basic_vec<T, Abi> max(const basic_vec<T, Abi>& a,
                                  const basic_vec<T, Abi>& b) noexcept;
  template<class T, class Abi>
  constexpr pair<basic_vec<T, Abi>, basic_vec<T, Abi>> minmax(
    const basic_vec<T, Abi>& a, const basic_vec<T, Abi>& b) noexcept;
  template<class T, class Abi>
  constexpr basic_vec<T, Abi> clamp(const basic_vec<T, Abi>& v,
                                    const basic_vec<T, Abi>& lo,
                                    const basic_vec<T, Abi>& hi);

  template<class T, class U>
  constexpr auto select(bool c, const T& a, const U& b)
    -> remove_cvref_t<decltype(c ? a : b)>;
  template<size_t Bytes, class Abi, class T, class U>
  constexpr auto select(const basic_mask<Bytes, Abi>& c, const T& a, const U& b) noexcept
    -> decltype(/*simd-select-impl*/(c, a, b));

  // mathematical functions
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> acos(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> asin(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> atan(const V& x);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> atan2(const V& y, const V& x);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> atan2(const /*deduced-vec-t*/<V>& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> atan2(const V& x, const /*deduced-vec-t*/<V>& y);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> cos(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> sin(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> tan(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> acosh(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> asinh(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> atanh(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> cosh(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> sinh(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> tanh(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> exp(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> exp2(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> expm1(const V& x);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> frexp(const V& value,
                                       rebind_t<int, /*deduced-vec-t*/<V>>* exp);
  template</*math-floating-point*/ V>
  constexpr rebind_t<int, /*deduced-vec-t*/<V>> ilogb(const V& x);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> ldexp(const V& x,
                                       const rebind_t<int, /*deduced-vec-t*/<V>>& exp);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> log(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> log10(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> log1p(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> log2(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> logb(const V& x);
  template<class T, class Abi>
  constexpr basic_vec<T, Abi> modf(const type_identity_t<basic_vec<T, Abi>>& value,
                                   basic_vec<T, Abi>* iptr);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> scalbn(const V& x,
                                        const rebind_t<int, /*deduced-vec-t*/<V>>& n);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> scalbln(
    const V& x, const rebind_t<long int, /*deduced-vec-t*/<V>>& n);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> cbrt(const V& x);
  template<signed_integral T, class Abi>
  constexpr basic_vec<T, Abi> abs(const basic_vec<T, Abi>& j);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> abs(const V& j);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> fabs(const V& x);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> hypot(const V& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> hypot(const /*deduced-vec-t*/<V>& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> hypot(const V& x, const /*deduced-vec-t*/<V>& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> hypot(const V& x, const V& y, const V& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> hypot(const /*deduced-vec-t*/<V>& x,
                                       const V& y,
                                       const V& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> hypot(const V& x,
                                       const /*deduced-vec-t*/<V>& y,
                                       const V& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> hypot(const V& x,
                                       const V& y,
                                       const /*deduced-vec-t*/<V>& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> hypot(const /*deduced-vec-t*/<V>& x,
                                       const /*deduced-vec-t*/<V>& y,
                                       const V& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> hypot(const /*deduced-vec-t*/<V>& x,
                                       const V& y,
                                       const /*deduced-vec-t*/<V>& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> hypot(const V& x,
                                       const /*deduced-vec-t*/<V>& y,
                                       const /*deduced-vec-t*/<V>& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> pow(const V& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> pow(const /*deduced-vec-t*/<V>& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> pow(const V& x, const /*deduced-vec-t*/<V>& y);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> sqrt(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> erf(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> erfc(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> lgamma(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> tgamma(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> ceil(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> floor(const V& x);
  template</*math-floating-point*/ V> /*deduced-vec-t*/<V> nearbyint(const V& x);
  template</*math-floating-point*/ V> /*deduced-vec-t*/<V> rint(const V& x);
  template</*math-floating-point*/ V>
  rebind_t<long int, /*deduced-vec-t*/<V>> lrint(const V& x);
  template</*math-floating-point*/ V>
  rebind_t<long long int, V> llrint(const /*deduced-vec-t*/<V>& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> round(const V& x);
  template</*math-floating-point*/ V>
  constexpr rebind_t<long int, /*deduced-vec-t*/<V>> lround(const V& x);
  template</*math-floating-point*/ V>
  constexpr rebind_t<long long int, /*deduced-vec-t*/<V>> llround(const V& x);
  template</*math-floating-point*/ V> constexpr /*deduced-vec-t*/<V> trunc(const V& x);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fmod(const V& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fmod(const /*deduced-vec-t*/<V>& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fmod(const V& x, const /*deduced-vec-t*/<V>& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> remainder(const V& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> remainder(const /*deduced-vec-t*/<V>& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> remainder(const V& x, const /*deduced-vec-t*/<V>& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> remquo(const V& x,
                                        const V& y,
                                        rebind_t<int, /*deduced-vec-t*/<V>>* quo);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> remquo(const /*deduced-vec-t*/<V>& x,
                                        const V& y,
                                        rebind_t<int, /*deduced-vec-t*/<V>>* quo);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> remquo(const V& x,
                                        const /*deduced-vec-t*/<V>& y,
                                        rebind_t<int, /*deduced-vec-t*/<V>>* quo);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> copysign(const V& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> copysign(const /*deduced-vec-t*/<V>& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> copysign(const V& x, const /*deduced-vec-t*/<V>& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> nextafter(const V& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> nextafter(const /*deduced-vec-t*/<V>& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> nextafter(const V& x, const /*deduced-vec-t*/<V>& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fdim(const V& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fdim(const /*deduced-vec-t*/<V>& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fdim(const V& x, const /*deduced-vec-t*/<V>& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fmax(const V& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fmax(const /*deduced-vec-t*/<V>& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fmax(const V& x, const /*deduced-vec-t*/<V>& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fmin(const V& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fmin(const /*deduced-vec-t*/<V>& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fmin(const V& x, const /*deduced-vec-t*/<V>& y);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fma(const V& x, const V& y, const V& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fma(const /*deduced-vec-t*/<V>& x,
                                     const V& y,
                                     const V& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fma(const V& x,
                                     const /*deduced-vec-t*/<V>& y,
                                     const V& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fma(const V& x,
                                     const V& y,
                                     const /*deduced-vec-t*/<V>& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fma(const /*deduced-vec-t*/<V>& x,
                                     const /*deduced-vec-t*/<V>& y,
                                     const V& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fma(const /*deduced-vec-t*/<V>& x,
                                     const V& y,
                                     const /*deduced-vec-t*/<V>& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> fma(const V& x,
                                     const /*deduced-vec-t*/<V>& y,
                                     const /*deduced-vec-t*/<V>& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> lerp(const V& a, const V& b, const V& t) noexcept;
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> lerp(const /*deduced-vec-t*/<V>& x,
                                      const V& y,
                                      const V& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> lerp(const V& x,
                                      const /*deduced-vec-t*/<V>& y,
                                      const V& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> lerp(const V& x,
                                      const V& y,
                                      const /*deduced-vec-t*/<V>& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> lerp(const /*deduced-vec-t*/<V>& x,
                                      const /*deduced-vec-t*/<V>& y,
                                      const V& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> lerp(const /*deduced-vec-t*/<V>& x,
                                      const V& y,
                                      const /*deduced-vec-t*/<V>& z);
  template</*math-floating-point*/ V>
  constexpr /*deduced-vec-t*/<V> lerp(const V& x,
                                      const /*deduced-vec-t*/<V>& y,
                                      const /*deduced-vec-t*/<V>& z);
  template</*math-floating-point*/ V>
  constexpr rebind_t<int, /*deduced-vec-t*/<V>> fpclassify(const V& x);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type isfinite(const V& x);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type isinf(const V& x);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type isnan(const V& x);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type isnormal(const V& x);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type signbit(const V& x);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type isgreater(const V& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type isgreater(
    const /*deduced-vec-t*/<V>& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type isgreater(
    const V& x, const /*deduced-vec-t*/<V>& y);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type isgreaterequal(const V& x,
                                                                    const V& y);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type isgreaterequal(
    const /*deduced-vec-t*/<V>& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type isgreaterequal(
    const V& x, const /*deduced-vec-t*/<V>& y);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type isless(const V& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type isless(const /*deduced-vec-t*/<V>& x,
                                                            const V& y);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type isless(
    const V& x, const /*deduced-vec-t*/<V>& y);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type islessequal(const V& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type islessequal(
    const /*deduced-vec-t*/<V>& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type islessequal(
    const V& x, const /*deduced-vec-t*/<V>& y);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type islessgreater(const V& x,
                                                                   const V& y);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type islessgreater(
    const /*deduced-vec-t*/<V>& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type islessgreater(
    const V& x, const /*deduced-vec-t*/<V>& y);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type isunordered(const V& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type isunordered(
    const /*deduced-vec-t*/<V>& x, const V& y);
  template</*math-floating-point*/ V>
  constexpr typename /*deduced-vec-t*/<V>::mask_type isunordered(
    const V& x, const /*deduced-vec-t*/<V>& y);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> assoc_laguerre(const rebind_t<unsigned, /*deduced-vec-t*/<V>>& n,
                                      const rebind_t<unsigned, /*deduced-vec-t*/<V>>& m,
                                      const V& x);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> assoc_legendre(const rebind_t<unsigned, /*deduced-vec-t*/<V>>& l,
                                      const rebind_t<unsigned, /*deduced-vec-t*/<V>>& m,
                                      const V& x);
  template</*math-floating-point*/ V> /*deduced-vec-t*/<V> beta(const V& x, const V& y);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> beta(const /*deduced-vec-t*/<V>& x, const V& y);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> beta(const V& x, const /*deduced-vec-t*/<V>& y);
  template</*math-floating-point*/ V> /*deduced-vec-t*/<V> comp_ellint_1(const V& k);
  template</*math-floating-point*/ V> /*deduced-vec-t*/<V> comp_ellint_2(const V& k);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> comp_ellint_3(const V& k, const V& nu);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> comp_ellint_3(const /*deduced-vec-t*/<V>& k, const V& nu);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> comp_ellint_3(const V& k, const /*deduced-vec-t*/<V>& nu);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> cyl_bessel_i(const V& nu, const V& x);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> cyl_bessel_i(const /*deduced-vec-t*/<V>& nu, const V& x);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> cyl_bessel_i(const V& nu, const /*deduced-vec-t*/<V>& x);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> cyl_bessel_j(const V& nu, const V& x);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> cyl_bessel_j(const /*deduced-vec-t*/<V>& nu, const V& x);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> cyl_bessel_j(const V& nu, const /*deduced-vec-t*/<V>& x);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> cyl_bessel_k(const V& nu, const V& x);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> cyl_bessel_k(const /*deduced-vec-t*/<V>& nu, const V& x);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> cyl_bessel_k(const V& nu, const /*deduced-vec-t*/<V>& x);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> cyl_neumann(const V& nu, const V& x);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> cyl_neumann(const /*deduced-vec-t*/<V>& nu, const V& x);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> cyl_neumann(const V& nu, const /*deduced-vec-t*/<V>& x);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> ellint_1(const V& k, const V& phi);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> ellint_1(const /*deduced-vec-t*/<V>& k, const V& phi);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> ellint_1(const V& k, const /*deduced-vec-t*/<V>& phi);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> ellint_2(const V& k, const V& phi);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> ellint_2(const /*deduced-vec-t*/<V>& k, const V& phi);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> ellint_2(const V& k, const /*deduced-vec-t*/<V>& phi);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> ellint_3(const V& k, const V& nu, const V& phi);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> ellint_3(const /*deduced-vec-t*/<V>& k, const V& nu, const V& phi);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> ellint_3(const V& k, const /*deduced-vec-t*/<V>& nu, const V& phi);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> ellint_3(const V& k, const V& nu, const /*deduced-vec-t*/<V>& phi);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> ellint_3(const /*deduced-vec-t*/<V>& k,
                                const /*deduced-vec-t*/<V>& nu,
                                const V& phi);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> ellint_3(const /*deduced-vec-t*/<V>& k,
                                const V& nu,
                                const /*deduced-vec-t*/<V>& phi);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> ellint_3(const V& k,
                                const /*deduced-vec-t*/<V>& nu,
                                const /*deduced-vec-t*/<V>& phi);
  template</*math-floating-point*/ V> /*deduced-vec-t*/<V> expint(const V& x);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> hermite(const rebind_t<unsigned, /*deduced-vec-t*/<V>>& n,
                               const V& x);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> laguerre(const rebind_t<unsigned, /*deduced-vec-t*/<V>>& n,
                                const V& x);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> legendre(const rebind_t<unsigned, /*deduced-vec-t*/<V>>& l,
                                const V& x);
  template</*math-floating-point*/ V> /*deduced-vec-t*/<V> riemann_zeta(const V& x);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> sph_bessel(const rebind_t<unsigned, /*deduced-vec-t*/<V>>& n,
                                  const V& x);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> sph_legendre(const rebind_t<unsigned, /*deduced-vec-t*/<V>>& l,
                                    const rebind_t<unsigned, /*deduced-vec-t*/<V>>& m,
                                    const V& theta);
  template</*math-floating-point*/ V>
  /*deduced-vec-t*/<V> sph_neumann(const rebind_t<unsigned, /*deduced-vec-t*/<V>>& n,
                                   const V& x);

  // bit manipulation
  template</*simd-vec-type*/ V> constexpr V byteswap(const V& v) noexcept;
  template</*simd-vec-type*/ V> constexpr V bit_ceil(const V& v);
  template</*simd-vec-type*/ V> constexpr V bit_floor(const V& v) noexcept;

  template</*simd-vec-type*/ V>
  constexpr typename V::mask_type has_single_bit(const V& v) noexcept;

  template</*simd-vec-type*/ V0, /*simd-vec-type*/ V1>
  constexpr V0 rotl(const V0& v, const V1& s) noexcept;
  template</*simd-vec-type*/ V> constexpr V rotl(const V& v, int s) noexcept;

  template</*simd-vec-type*/ V0, /*simd-vec-type*/ V1>
  constexpr V0 rotr(const V0& v, const V1& s) noexcept;
  template</*simd-vec-type*/ V> constexpr V rotr(const V& v, int s) noexcept;

  template</*simd-vec-type*/ V>
  constexpr rebind_t<make_signed_t<typename V::value_type>, V> bit_width(
    const V& v) noexcept;
  template</*simd-vec-type*/ V>
  constexpr rebind_t<make_signed_t<typename V::value_type>, V> countl_zero(
    const V& v) noexcept;
  template</*simd-vec-type*/ V>
  constexpr rebind_t<make_signed_t<typename V::value_type>, V> countl_one(
    const V& v) noexcept;
  template</*simd-vec-type*/ V>
  constexpr rebind_t<make_signed_t<typename V::value_type>, V> countr_zero(
    const V& v) noexcept;
  template</*simd-vec-type*/ V>
  constexpr rebind_t<make_signed_t<typename V::value_type>, V> countr_one(
    const V& v) noexcept;
  template</*simd-vec-type*/ V>
  constexpr rebind_t<make_signed_t<typename V::value_type>, V> popcount(
    const V& v) noexcept;

  // complex math
  template</*simd-complex*/ V>
  constexpr rebind_t</*simd-complex-value-type*/<V>, V> real(const V&) noexcept;

  template</*simd-complex*/ V>
  constexpr rebind_t</*simd-complex-value-type*/<V>, V> imag(const V&) noexcept;

  template</*simd-complex*/ V>
  constexpr rebind_t</*simd-complex-value-type*/<V>, V> abs(const V&);

  template</*simd-complex*/ V>
  constexpr rebind_t</*simd-complex-value-type*/<V>, V> arg(const V&);

  template</*simd-complex*/ V>
  constexpr rebind_t</*simd-complex-value-type*/<V>, V> norm(const V&);

  template</*simd-complex*/ V> constexpr V conj(const V&);
  template</*simd-complex*/ V> constexpr V proj(const V&);
  template</*simd-complex*/ V> constexpr V exp(const V& v);
  template</*simd-complex*/ V> constexpr V log(const V& v);
  template</*simd-complex*/ V> constexpr V log10(const V& v);

  template</*simd-complex*/ V> constexpr V sqrt(const V& v);
  template</*simd-complex*/ V> constexpr V sin(const V& v);
  template</*simd-complex*/ V> constexpr V asin(const V& v);
  template</*simd-complex*/ V> constexpr V cos(const V& v);
  template</*simd-complex*/ V> constexpr V acos(const V& v);
  template</*simd-complex*/ V> constexpr V tan(const V& v);
  template</*simd-complex*/ V> constexpr V atan(const V& v);
  template</*simd-complex*/ V> constexpr V sinh(const V& v);
  template</*simd-complex*/ V> constexpr V asinh(const V& v);
  template</*simd-complex*/ V> constexpr V cosh(const V& v);
  template</*simd-complex*/ V> constexpr V acosh(const V& v);
  template</*simd-complex*/ V> constexpr V tanh(const V& v);
  template</*simd-complex*/ V> constexpr V atanh(const V& v);

  template</*simd-floating-point*/ V>
  rebind_t<complex<typename V::value_type>, V> polar(const V& x, const V& y = {});

  template</*simd-complex*/ V> constexpr V pow(const V& x, const V& y);

  // class template basic_mask
  template<size_t Bytes, class Abi> class basic_mask;
  template<class T, /*simd-size-type*/ N = /*simd-size-v*/<T, /*native-abi*/<T>>>
  using mask = vec<T, N>::mask_type;

  // reductions
  template<size_t Bytes, class Abi>
  constexpr bool all_of(const basic_mask<Bytes, Abi>&) noexcept;
  template<size_t Bytes, class Abi>
  constexpr bool any_of(const basic_mask<Bytes, Abi>&) noexcept;
  template<size_t Bytes, class Abi>
  constexpr bool none_of(const basic_mask<Bytes, Abi>&) noexcept;
  template<size_t Bytes, class Abi>
  constexpr /*simd-size-type*/ reduce_count(const basic_mask<Bytes, Abi>&) noexcept;
  template<size_t Bytes, class Abi>
  constexpr /*simd-size-type*/ reduce_min_index(const basic_mask<Bytes, Abi>&);
  template<size_t Bytes, class Abi>
  constexpr /*simd-size-type*/ reduce_max_index(const basic_mask<Bytes, Abi>&);

  constexpr bool all_of(same_as<bool> auto) noexcept;
  constexpr bool any_of(same_as<bool> auto) noexcept;
  constexpr bool none_of(same_as<bool> auto) noexcept;
  constexpr /*simd-size-type*/ reduce_count(same_as<bool> auto) noexcept;
  constexpr /*simd-size-type*/ reduce_min_index(same_as<bool> auto);
  constexpr /*simd-size-type*/ reduce_max_index(same_as<bool> auto);
}

namespace std {
  // algorithms
  using simd::min;
  using simd::max;
  using simd::minmax;
  using simd::clamp;

  // mathematical functions
  using simd::acos;
  using simd::asin;
  using simd::atan;
  using simd::atan2;
  using simd::cos;
  using simd::sin;
  using simd::tan;
  using simd::acosh;
  using simd::asinh;
  using simd::atanh;
  using simd::cosh;
  using simd::sinh;
  using simd::tanh;
  using simd::exp;
  using simd::exp2;
  using simd::expm1;
  using simd::frexp;
  using simd::ilogb;
  using simd::ldexp;
  using simd::log;
  using simd::log10;
  using simd::log1p;
  using simd::log2;
  using simd::logb;
  using simd::modf;
  using simd::scalbn;
  using simd::scalbln;
  using simd::cbrt;
  using simd::abs;
  using simd::fabs;
  using simd::hypot;
  using simd::pow;
  using simd::sqrt;
  using simd::erf;
  using simd::erfc;
  using simd::lgamma;
  using simd::tgamma;
  using simd::ceil;
  using simd::floor;
  using simd::nearbyint;
  using simd::rint;
  using simd::lrint;
  using simd::llrint;
  using simd::round;
  using simd::lround;
  using simd::llround;
  using simd::trunc;
  using simd::fmod;
  using simd::remainder;
  using simd::remquo;
  using simd::copysign;
  using simd::nextafter;
  using simd::fdim;
  using simd::fmax;
  using simd::fmin;
  using simd::fma;
  using simd::lerp;
  using simd::fpclassify;
  using simd::isfinite;
  using simd::isinf;
  using simd::isnan;
  using simd::isnormal;
  using simd::signbit;
  using simd::isgreater;
  using simd::isgreaterequal;
  using simd::isless;
  using simd::islessequal;
  using simd::islessgreater;
  using simd::isunordered;
  using simd::assoc_laguerre;
  using simd::assoc_legendre;
  using simd::beta;
  using simd::comp_ellint_1;
  using simd::comp_ellint_2;
  using simd::comp_ellint_3;
  using simd::cyl_bessel_i;
  using simd::cyl_bessel_j;
  using simd::cyl_bessel_k;
  using simd::cyl_neumann;
  using simd::ellint_1;
  using simd::ellint_2;
  using simd::ellint_3;
  using simd::expint;
  using simd::hermite;
  using simd::laguerre;
  using simd::legendre;
  using simd::riemann_zeta;
  using simd::sph_bessel;
  using simd::sph_legendre;
  using simd::sph_neumann;

  // bit manipulation
  using simd::byteswap;
  using simd::bit_ceil;
  using simd::bit_floor;
  using simd::has_single_bit;
  using simd::rotl;
  using simd::rotr;
  using simd::bit_width;
  using simd::countl_zero;
  using simd::countl_one;
  using simd::countr_zero;
  using simd::countr_one;
  using simd::popcount;

  // vec complex math
  using simd::real;
  using simd::imag;
  using simd::arg;
  using simd::norm;
  using simd::conj;
  using simd::proj;
  using simd::polar;
}

Class template std::simd::flags

namespace std::simd {
  template<class... Flags> struct flags
  {
    // simd.flags.oper, flags operators
    template<class... Other> friend consteval auto operator|(flags, flags<Other...>);
  };
}

Class template std::simd::simd-iterator

namespace std::simd {
  template<class V> class /*simd-iterator*/
  {                                                                     // exposition-only
    V* /*data_*/ = nullptr;                                             // exposition-only
    /*simd-size-type*/ /*offset_*/ = 0;                                 // exposition-only

    constexpr /*simd-iterator*/(V& d, /*simd-size-type*/ off) noexcept; // exposition-only

  public:
    using value_type = V::value_type;
    using iterator_category = input_iterator_tag;
    using iterator_concept = random_access_iterator_tag;
    using difference_type = /*simd-size-type*/;

    constexpr /*simd-iterator*/() = default;

    constexpr /*simd-iterator*/(const /*simd-iterator*/&) = default;
    constexpr /*simd-iterator*/& operator=(const /*simd-iterator*/&) = default;

    constexpr /*simd-iterator*/(const /*simd-iterator*/<remove_const_t<V>>&)
      requires is_const_v<V>;

    constexpr value_type operator*() const;

    constexpr /*simd-iterator*/& operator++();
    constexpr /*simd-iterator*/ operator++(int);
    constexpr /*simd-iterator*/& operator--();
    constexpr /*simd-iterator*/ operator--(int);

    constexpr /*simd-iterator*/& operator+=(difference_type n);
    constexpr /*simd-iterator*/& operator-=(difference_type n);

    constexpr value_type operator[](difference_type n) const;

    friend constexpr bool operator==(/*simd-iterator*/ a, /*simd-iterator*/ b) = default;
    friend constexpr bool operator==(/*simd-iterator*/ a, default_sentinel_t) noexcept;
    friend constexpr auto operator<=>(/*simd-iterator*/ a, /*simd-iterator*/ b);

    friend constexpr /*simd-iterator*/ operator+(/*simd-iterator*/ i, difference_type n);
    friend constexpr /*simd-iterator*/ operator+(difference_type n, /*simd-iterator*/ i);
    friend constexpr /*simd-iterator*/ operator-(/*simd-iterator*/ i, difference_type n);

    friend constexpr difference_type operator-(/*simd-iterator*/ a, /*simd-iterator*/ b);
    friend constexpr difference_type operator-(/*simd-iterator*/ i,
                                               default_sentinel_t) noexcept;
    friend constexpr difference_type operator-(default_sentinel_t,
                                               /*simd-iterator*/ i) noexcept;
  };
}

Class template std::simd::basic_vec

namespace std::simd {
  template<class T, class Abi> class basic_vec
  {
    using /*real-type*/ = /* see description */; // exposition-only
  public:
    using value_type = T;
    using mask_type = basic_mask<sizeof(T), Abi>;
    using abi_type = Abi;
    using iterator = /*simd-iterator*/<basic_vec>;
    using const_iterator = /*simd-iterator*/<const basic_vec>;

    constexpr iterator begin() noexcept { return { *this, 0 }; }
    constexpr const_iterator begin() const noexcept { return { *this, 0 }; }
    constexpr const_iterator cbegin() const noexcept { return { *this, 0 }; }
    constexpr default_sentinel_t end() const noexcept { return {}; }
    constexpr default_sentinel_t cend() const noexcept { return {}; }

    static constexpr integral_constant</*simd-size-type*/, /*simd-size-v*/<T, Abi>>
      size{};

    constexpr basic_vec() noexcept = default;

    // simd.ctor, basic_vec constructors
    template<class U> constexpr basic_vec(U&& value) noexcept;
    template<class U, class UAbi>
    constexpr explicit(/* see description */)
      basic_vec(const basic_vec<U, UAbi>&) noexcept;
    template<class G> constexpr explicit basic_vec(G&& gen);
    template<class R, class... Flags>
    constexpr basic_vec(R&& range, flags<Flags...> = {});
    template<class R, class... Flags>
    constexpr basic_vec(R&& range, const mask_type& mask, flags<Flags...> = {});
    constexpr basic_vec(const /*real-type*/& reals,
                        const /*real-type*/& imags = {}) noexcept;

    // simd.subscr, basic_vec subscript operators
    constexpr value_type operator[](/*simd-size-type*/) const;
    template</*simd-integral*/ I>
    constexpr resize_t<I::size(), basic_vec> operator[](const I& indices) const;

    // simd.complex.access, basic_vec complex accessors
    constexpr /*real-type*/ real() const noexcept;
    constexpr /*real-type*/ imag() const noexcept;
    constexpr void real(const /*real-type*/& v) noexcept;
    constexpr void imag(const /*real-type*/& v) noexcept;

    // simd.unary, basic_vec unary operators
    constexpr basic_vec& operator++() noexcept;
    constexpr basic_vec operator++(int) noexcept;
    constexpr basic_vec& operator--() noexcept;
    constexpr basic_vec operator--(int) noexcept;
    constexpr mask_type operator!() const noexcept;
    constexpr basic_vec operator~() const noexcept;
    constexpr basic_vec operator+() const noexcept;
    constexpr basic_vec operator-() const noexcept;

    // simd.binary, basic_vec binary operators
    friend constexpr basic_vec operator+(const basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec operator-(const basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec operator*(const basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec operator/(const basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec operator%(const basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec operator&(const basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec operator|(const basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec operator^(const basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec operator<<(const basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec operator>>(const basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec operator<<(const basic_vec&, /*simd-size-type*/) noexcept;
    friend constexpr basic_vec operator>>(const basic_vec&, /*simd-size-type*/) noexcept;

    // simd.cassign, basic_vec compound assignment
    friend constexpr basic_vec& operator+=(basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec& operator-=(basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec& operator*=(basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec& operator/=(basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec& operator%=(basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec& operator&=(basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec& operator|=(basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec& operator^=(basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec& operator<<=(basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec& operator>>=(basic_vec&, const basic_vec&) noexcept;
    friend constexpr basic_vec& operator<<=(basic_vec&, /*simd-size-type*/) noexcept;
    friend constexpr basic_vec& operator>>=(basic_vec&, /*simd-size-type*/) noexcept;

    // simd.comparison, basic_vec compare operators
    friend constexpr mask_type operator==(const basic_vec&, const basic_vec&) noexcept;
    friend constexpr mask_type operator!=(const basic_vec&, const basic_vec&) noexcept;
    friend constexpr mask_type operator>=(const basic_vec&, const basic_vec&) noexcept;
    friend constexpr mask_type operator<=(const basic_vec&, const basic_vec&) noexcept;
    friend constexpr mask_type operator>(const basic_vec&, const basic_vec&) noexcept;
    friend constexpr mask_type operator<(const basic_vec&, const basic_vec&) noexcept;

    // simd.cond, basic_vec exposition only conditional operators
    friend constexpr basic_vec /*simd-select-impl*/( // exposition-only
      const mask_type&,
      const basic_vec&,
      const basic_vec&) noexcept;
  };

  template<class R, class... Ts> basic_vec(R&& r, Ts...)->/* see description */;

  template<size_t Bytes, class Abi>
  basic_vec(basic_mask<Bytes, Abi>)->/* see description */;
}

Class template std::simd::basic_mask

namespace std::simd {
  template<size_t Bytes, class Abi> class basic_mask
  {
  public:
    using value_type = bool;
    using abi_type = Abi;
    using iterator = /*simd-iterator*/<basic_mask>;
    using const_iterator = /*simd-iterator*/<const basic_mask>;

    constexpr iterator begin() noexcept { return { *this, 0 }; }
    constexpr const_iterator begin() const noexcept { return { *this, 0 }; }
    constexpr const_iterator cbegin() const noexcept { return { *this, 0 }; }
    constexpr default_sentinel_t end() const noexcept { return {}; }
    constexpr default_sentinel_t cend() const noexcept { return {}; }

    static constexpr integral_constant</*simd-size-type*/, /*mask-size-v*/<Bytes, Abi>>
      size{};

    constexpr basic_mask() noexcept = default;

    // simd.mask.ctor, basic_mask constructors
    constexpr explicit basic_mask(same_as<value_type> auto) noexcept;
    template<size_t UBytes, class UAbi>
    constexpr explicit basic_mask(const basic_mask<UBytes, UAbi>&) noexcept;
    template<class G> constexpr explicit basic_mask(G&& gen);
    template<same_as<bitset<size()>> T> constexpr basic_mask(const T& b) noexcept;
    template<unsigned_integral T>
      requires(!same_as<T, value_type>)
    constexpr explicit basic_mask(T val) noexcept;

    // simd.mask.subscr, basic_mask subscript operators
    constexpr value_type operator[](/*simd-size-type*/) const;
    template</*simd-integral*/ I>
    constexpr resize_t<I::size(), basic_mask> operator[](const I& indices) const;

    // simd.mask.unary, basic_mask unary operators
    constexpr basic_mask operator!() const noexcept;
    constexpr /* see description */ operator+() const noexcept;
    constexpr /* see description */ operator-() const noexcept;
    constexpr /* see description */ operator~() const noexcept;

    // simd.mask.conv, basic_mask conversions
    template<class U, class A>
    constexpr explicit(sizeof(U) != Bytes) operator basic_vec<U, A>() const noexcept;
    constexpr bitset<size()> to_bitset() const noexcept;
    constexpr unsigned long long to_ullong() const;

    // simd.mask.binary, basic_mask binary operators
    friend constexpr basic_mask operator&&(const basic_mask&, const basic_mask&) noexcept;
    friend constexpr basic_mask operator||(const basic_mask&, const basic_mask&) noexcept;
    friend constexpr basic_mask operator&(const basic_mask&, const basic_mask&) noexcept;
    friend constexpr basic_mask operator|(const basic_mask&, const basic_mask&) noexcept;
    friend constexpr basic_mask operator^(const basic_mask&, const basic_mask&) noexcept;

    // simd.mask.cassign, basic_mask compound assignment
    friend constexpr basic_mask& operator&=(basic_mask&, const basic_mask&) noexcept;
    friend constexpr basic_mask& operator|=(basic_mask&, const basic_mask&) noexcept;
    friend constexpr basic_mask& operator^=(basic_mask&, const basic_mask&) noexcept;

    // simd.mask.comparison, basic_mask comparisons
    friend constexpr basic_mask operator==(const basic_mask&, const basic_mask&) noexcept;
    friend constexpr basic_mask operator!=(const basic_mask&, const basic_mask&) noexcept;
    friend constexpr basic_mask operator>=(const basic_mask&, const basic_mask&) noexcept;
    friend constexpr basic_mask operator<=(const basic_mask&, const basic_mask&) noexcept;
    friend constexpr basic_mask operator>(const basic_mask&, const basic_mask&) noexcept;
    friend constexpr basic_mask operator<(const basic_mask&, const basic_mask&) noexcept;

    // simd.mask.cond, basic_mask exposition only conditional operators
    friend constexpr basic_mask /*simd-select-impl*/(    // exposition-only
      const basic_mask&,
      const basic_mask&,
      const basic_mask&) noexcept;
    friend constexpr basic_mask /*simd-select-impl*/(    // exposition-only
      const basic_mask&,
      same_as<bool> auto,
      same_as<bool> auto) noexcept;
    template<class T0, class T1>
    friend constexpr vec</* see description */, size()> /*simd-select-impl*/(
      const basic_mask&, const T0&, const T1&) noexcept; // exposition-only
  };
}