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