xref: /llvm-project/libcxx/include/__cxx03/experimental/__simd/reference.h (revision ce7771902dc50d900de639d499a60486b83f70e0)
1e78f53d1SNikolas Klauser // -*- C++ -*-
2e78f53d1SNikolas Klauser //===----------------------------------------------------------------------===//
3e78f53d1SNikolas Klauser //
4e78f53d1SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5e78f53d1SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information.
6e78f53d1SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7e78f53d1SNikolas Klauser //
8e78f53d1SNikolas Klauser //===----------------------------------------------------------------------===//
9e78f53d1SNikolas Klauser 
10*ce777190SNikolas Klauser #ifndef _LIBCPP___CXX03_EXPERIMENTAL___SIMD_REFERENCE_H
11*ce777190SNikolas Klauser #define _LIBCPP___CXX03_EXPERIMENTAL___SIMD_REFERENCE_H
12e78f53d1SNikolas Klauser 
1373fbae83SNikolas Klauser #include <__cxx03/__type_traits/is_assignable.h>
1473fbae83SNikolas Klauser #include <__cxx03/__type_traits/is_same.h>
1573fbae83SNikolas Klauser #include <__cxx03/__utility/forward.h>
1673fbae83SNikolas Klauser #include <__cxx03/__utility/move.h>
1773fbae83SNikolas Klauser #include <__cxx03/cstddef>
1873fbae83SNikolas Klauser #include <__cxx03/experimental/__config>
1973fbae83SNikolas Klauser #include <__cxx03/experimental/__simd/utility.h>
20e78f53d1SNikolas Klauser 
21e78f53d1SNikolas Klauser _LIBCPP_PUSH_MACROS
2273fbae83SNikolas Klauser #include <__cxx03/__undef_macros>
23e78f53d1SNikolas Klauser 
24e78f53d1SNikolas Klauser #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
25e78f53d1SNikolas Klauser 
26e78f53d1SNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
27e78f53d1SNikolas Klauser inline namespace parallelism_v2 {
28e78f53d1SNikolas Klauser template <class _Tp, class _Storage, class _Vp>
29e78f53d1SNikolas Klauser class __simd_reference {
30e78f53d1SNikolas Klauser   template <class, class>
31e78f53d1SNikolas Klauser   friend class simd;
32e78f53d1SNikolas Klauser   template <class, class>
33e78f53d1SNikolas Klauser   friend class simd_mask;
34e78f53d1SNikolas Klauser 
35e78f53d1SNikolas Klauser   _Storage& __s_;
36e78f53d1SNikolas Klauser   size_t __idx_;
37e78f53d1SNikolas Klauser 
38e78f53d1SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI __simd_reference(_Storage& __s, size_t __idx) : __s_(__s), __idx_(__idx) {}
39e78f53d1SNikolas Klauser 
40e78f53d1SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI _Vp __get() const noexcept { return __s_.__get(__idx_); }
41e78f53d1SNikolas Klauser 
42e78f53d1SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI void __set(_Vp __v) {
43e78f53d1SNikolas Klauser     if constexpr (is_same_v<_Vp, bool>)
44e78f53d1SNikolas Klauser       __s_.__set(__idx_, experimental::__set_all_bits<_Tp>(__v));
45e78f53d1SNikolas Klauser     else
46e78f53d1SNikolas Klauser       __s_.__set(__idx_, __v);
47e78f53d1SNikolas Klauser   }
48e78f53d1SNikolas Klauser 
49e78f53d1SNikolas Klauser public:
50e78f53d1SNikolas Klauser   using value_type = _Vp;
51e78f53d1SNikolas Klauser 
52e78f53d1SNikolas Klauser   __simd_reference()                        = delete;
53e78f53d1SNikolas Klauser   __simd_reference(const __simd_reference&) = delete;
54e78f53d1SNikolas Klauser 
55e78f53d1SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI operator value_type() const noexcept { return __get(); }
56e78f53d1SNikolas Klauser 
57e78f53d1SNikolas Klauser   template <class _Up, enable_if_t<is_assignable_v<value_type&, _Up&&>, int> = 0>
58e78f53d1SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI __simd_reference operator=(_Up&& __v) && noexcept {
59e78f53d1SNikolas Klauser     __set(static_cast<value_type>(std::forward<_Up>(__v)));
60e78f53d1SNikolas Klauser     return {__s_, __idx_};
61e78f53d1SNikolas Klauser   }
62e78f53d1SNikolas Klauser 
63e78f53d1SNikolas Klauser   // Note: This approach might not fully align with the specification,
64e78f53d1SNikolas Klauser   // which might be a wording defect. (https://wg21.link/N4808 section 9.6.3)
65e78f53d1SNikolas Klauser   template <class _Tp1, class _Storage1, class _Vp1>
66e78f53d1SNikolas Klauser   friend void
67e78f53d1SNikolas Klauser   swap(__simd_reference<_Tp1, _Storage1, _Vp1>&& __a, __simd_reference<_Tp1, _Storage1, _Vp1>&& __b) noexcept;
68e78f53d1SNikolas Klauser 
69e78f53d1SNikolas Klauser   template <class _Tp1, class _Storage1, class _Vp1>
70e78f53d1SNikolas Klauser   friend void swap(_Vp1& __a, __simd_reference<_Tp1, _Storage1, _Vp1>&& __b) noexcept;
71e78f53d1SNikolas Klauser 
72e78f53d1SNikolas Klauser   template <class _Tp1, class _Storage1, class _Vp1>
73e78f53d1SNikolas Klauser   friend void swap(__simd_reference<_Tp1, _Storage1, _Vp1>&& __a, _Vp1& __b) noexcept;
74e78f53d1SNikolas Klauser };
75e78f53d1SNikolas Klauser 
76e78f53d1SNikolas Klauser template <class _Tp, class _Storage, class _Vp>
77e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI void
78e78f53d1SNikolas Klauser swap(__simd_reference<_Tp, _Storage, _Vp>&& __a, __simd_reference<_Tp, _Storage, _Vp>&& __b) noexcept {
79e78f53d1SNikolas Klauser   _Vp __tmp(std::move(__a));
80e78f53d1SNikolas Klauser   std::move(__a) = std::move(__b);
81e78f53d1SNikolas Klauser   std::move(__b) = std::move(__tmp);
82e78f53d1SNikolas Klauser }
83e78f53d1SNikolas Klauser 
84e78f53d1SNikolas Klauser template <class _Tp, class _Storage, class _Vp>
85e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI void swap(_Vp& __a, __simd_reference<_Tp, _Storage, _Vp>&& __b) noexcept {
86e78f53d1SNikolas Klauser   _Vp __tmp(std::move(__a));
87e78f53d1SNikolas Klauser   __a            = std::move(__b);
88e78f53d1SNikolas Klauser   std::move(__b) = std::move(__tmp);
89e78f53d1SNikolas Klauser }
90e78f53d1SNikolas Klauser 
91e78f53d1SNikolas Klauser template <class _Tp, class _Storage, class _Vp>
92e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI void swap(__simd_reference<_Tp, _Storage, _Vp>&& __a, _Vp& __b) noexcept {
93e78f53d1SNikolas Klauser   _Vp __tmp(std::move(__a));
94e78f53d1SNikolas Klauser   std::move(__a) = std::move(__b);
95e78f53d1SNikolas Klauser   __b            = std::move(__tmp);
96e78f53d1SNikolas Klauser }
97e78f53d1SNikolas Klauser 
98e78f53d1SNikolas Klauser } // namespace parallelism_v2
99e78f53d1SNikolas Klauser _LIBCPP_END_NAMESPACE_EXPERIMENTAL
100e78f53d1SNikolas Klauser 
101e78f53d1SNikolas Klauser #endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
102e78f53d1SNikolas Klauser 
103e78f53d1SNikolas Klauser _LIBCPP_POP_MACROS
104e78f53d1SNikolas Klauser 
105*ce777190SNikolas Klauser #endif // _LIBCPP___CXX03_EXPERIMENTAL___SIMD_REFERENCE_H
106