File indexing completed on 2026-05-03 08:13:45
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___CXX03_EXPERIMENTAL___SIMD_SIMD_H
0011 #define _LIBCPP___CXX03_EXPERIMENTAL___SIMD_SIMD_H
0012
0013 #include <__cxx03/__type_traits/is_same.h>
0014 #include <__cxx03/__type_traits/remove_cvref.h>
0015 #include <__cxx03/__utility/forward.h>
0016 #include <__cxx03/cstddef>
0017 #include <__cxx03/experimental/__config>
0018 #include <__cxx03/experimental/__simd/declaration.h>
0019 #include <__cxx03/experimental/__simd/reference.h>
0020 #include <__cxx03/experimental/__simd/traits.h>
0021 #include <__cxx03/experimental/__simd/utility.h>
0022
0023 #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
0024
0025 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
0026 inline namespace parallelism_v2 {
0027
0028
0029
0030 template <class _Tp, class _Abi>
0031 class simd {
0032 using _Impl = __simd_operations<_Tp, _Abi>;
0033 using _Storage = typename _Impl::_SimdStorage;
0034
0035 _Storage __s_;
0036
0037 public:
0038 using value_type = _Tp;
0039 using reference = __simd_reference<_Tp, _Storage, value_type>;
0040 using mask_type = simd_mask<_Tp, _Abi>;
0041 using abi_type = _Abi;
0042
0043 static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return simd_size_v<value_type, abi_type>; }
0044
0045 _LIBCPP_HIDE_FROM_ABI simd() noexcept = default;
0046
0047
0048 template <class _Up, enable_if_t<__can_broadcast_v<value_type, __remove_cvref_t<_Up>>, int> = 0>
0049 _LIBCPP_HIDE_FROM_ABI simd(_Up&& __v) noexcept : __s_(_Impl::__broadcast(static_cast<value_type>(__v))) {}
0050
0051
0052 template <class _Up,
0053 enable_if_t<!is_same_v<_Up, _Tp> && is_same_v<abi_type, simd_abi::fixed_size<size()>> &&
0054 __is_non_narrowing_convertible_v<_Up, value_type>,
0055 int> = 0>
0056 _LIBCPP_HIDE_FROM_ABI simd(const simd<_Up, simd_abi::fixed_size<size()>>& __v) noexcept {
0057 for (size_t __i = 0; __i < size(); __i++) {
0058 (*this)[__i] = static_cast<value_type>(__v[__i]);
0059 }
0060 }
0061
0062
0063 template <class _Generator, enable_if_t<__can_generate_v<value_type, _Generator, size()>, int> = 0>
0064 explicit _LIBCPP_HIDE_FROM_ABI simd(_Generator&& __g) noexcept
0065 : __s_(_Impl::__generate(std::forward<_Generator>(__g))) {}
0066
0067
0068 template <class _Up, class _Flags, enable_if_t<__is_vectorizable_v<_Up> && is_simd_flag_type_v<_Flags>, int> = 0>
0069 _LIBCPP_HIDE_FROM_ABI simd(const _Up* __mem, _Flags) {
0070 _Impl::__load(__s_, _Flags::template __apply<simd>(__mem));
0071 }
0072
0073
0074 template <class _Up, class _Flags, enable_if_t<__is_vectorizable_v<_Up> && is_simd_flag_type_v<_Flags>, int> = 0>
0075 _LIBCPP_HIDE_FROM_ABI void copy_from(const _Up* __mem, _Flags) {
0076 _Impl::__load(__s_, _Flags::template __apply<simd>(__mem));
0077 }
0078
0079 template <class _Up, class _Flags, enable_if_t<__is_vectorizable_v<_Up> && is_simd_flag_type_v<_Flags>, int> = 0>
0080 _LIBCPP_HIDE_FROM_ABI void copy_to(_Up* __mem, _Flags) const {
0081 _Impl::__store(__s_, _Flags::template __apply<simd>(__mem));
0082 }
0083
0084
0085 _LIBCPP_HIDE_FROM_ABI reference operator[](size_t __i) noexcept { return reference(__s_, __i); }
0086 _LIBCPP_HIDE_FROM_ABI value_type operator[](size_t __i) const noexcept { return __s_.__get(__i); }
0087 };
0088
0089 template <class _Tp, class _Abi>
0090 inline constexpr bool is_simd_v<simd<_Tp, _Abi>> = true;
0091
0092 template <class _Tp>
0093 using native_simd = simd<_Tp, simd_abi::native<_Tp>>;
0094
0095 template <class _Tp, int _Np>
0096 using fixed_size_simd = simd<_Tp, simd_abi::fixed_size<_Np>>;
0097
0098 }
0099 _LIBCPP_END_NAMESPACE_EXPERIMENTAL
0100
0101 #endif
0102 #endif