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
23inline namespace parallelism_v2 {
24template <class _Tp, class _Storage, class _Vp>
25class __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
45public:
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