1*5f757f3fSDimitry Andric // -*- C++ -*- 2*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 3*5f757f3fSDimitry Andric // 4*5f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*5f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6*5f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*5f757f3fSDimitry Andric // 8*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 9*5f757f3fSDimitry Andric 10*5f757f3fSDimitry Andric #ifndef _LIBCPP_EXPERIMENTAL___SIMD_REFERENCE_H 11*5f757f3fSDimitry Andric #define _LIBCPP_EXPERIMENTAL___SIMD_REFERENCE_H 12*5f757f3fSDimitry Andric 13*5f757f3fSDimitry Andric #include <__type_traits/is_assignable.h> 14*5f757f3fSDimitry Andric #include <__type_traits/is_same.h> 15*5f757f3fSDimitry Andric #include <__utility/forward.h> 16*5f757f3fSDimitry Andric #include <cstddef> 17*5f757f3fSDimitry Andric #include <experimental/__config> 18*5f757f3fSDimitry Andric #include <experimental/__simd/utility.h> 19*5f757f3fSDimitry Andric 20*5f757f3fSDimitry Andric #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) 21*5f757f3fSDimitry Andric 22*5f757f3fSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL 23*5f757f3fSDimitry Andric inline namespace parallelism_v2 { 24*5f757f3fSDimitry Andric template <class _Tp, class _Storage, class _Vp> 25*5f757f3fSDimitry Andric class __simd_reference { 26*5f757f3fSDimitry Andric template <class, class> 27*5f757f3fSDimitry Andric friend class simd; 28*5f757f3fSDimitry Andric template <class, class> 29*5f757f3fSDimitry Andric friend class simd_mask; 30*5f757f3fSDimitry Andric 31*5f757f3fSDimitry Andric _Storage& __s_; 32*5f757f3fSDimitry Andric size_t __idx_; 33*5f757f3fSDimitry Andric __simd_reference(_Storage & __s,size_t __idx)34*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __simd_reference(_Storage& __s, size_t __idx) : __s_(__s), __idx_(__idx) {} 35*5f757f3fSDimitry Andric __get()36*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Vp __get() const noexcept { return __s_.__get(__idx_); } 37*5f757f3fSDimitry Andric __set(_Vp __v)38*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __set(_Vp __v) { 39*5f757f3fSDimitry Andric if constexpr (is_same_v<_Vp, bool>) 40*5f757f3fSDimitry Andric __s_.__set(__idx_, experimental::__set_all_bits<_Tp>(__v)); 41*5f757f3fSDimitry Andric else 42*5f757f3fSDimitry Andric __s_.__set(__idx_, __v); 43*5f757f3fSDimitry Andric } 44*5f757f3fSDimitry Andric 45*5f757f3fSDimitry Andric public: 46*5f757f3fSDimitry Andric using value_type = _Vp; 47*5f757f3fSDimitry Andric 48*5f757f3fSDimitry Andric __simd_reference() = delete; 49*5f757f3fSDimitry Andric __simd_reference(const __simd_reference&) = delete; 50*5f757f3fSDimitry Andric value_type()51*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI operator value_type() const noexcept { return __get(); } 52*5f757f3fSDimitry Andric 53*5f757f3fSDimitry Andric template <class _Up, enable_if_t<is_assignable_v<value_type&, _Up&&>, int> = 0> 54*5f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI __simd_reference operator=(_Up&& __v) && noexcept { 55*5f757f3fSDimitry Andric __set(static_cast<value_type>(std::forward<_Up>(__v))); 56*5f757f3fSDimitry Andric return {__s_, __idx_}; 57*5f757f3fSDimitry Andric } 58*5f757f3fSDimitry Andric }; 59*5f757f3fSDimitry Andric 60*5f757f3fSDimitry Andric } // namespace parallelism_v2 61*5f757f3fSDimitry Andric _LIBCPP_END_NAMESPACE_EXPERIMENTAL 62*5f757f3fSDimitry Andric 63*5f757f3fSDimitry Andric #endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) 64*5f757f3fSDimitry Andric #endif // _LIBCPP_EXPERIMENTAL___SIMD_REFERENCE_H 65