brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.9 KiB · b9fe962 Raw
193 lines · c
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-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP_EXPERIMENTAL___SIMD_REFERENCE_H11#define _LIBCPP_EXPERIMENTAL___SIMD_REFERENCE_H12 13#include <__config>14#include <__cstddef/size_t.h>15#include <__type_traits/enable_if.h>16#include <__type_traits/is_assignable.h>17#include <__type_traits/is_same.h>18#include <__utility/declval.h>19#include <__utility/forward.h>20#include <__utility/move.h>21#include <experimental/__simd/utility.h>22 23_LIBCPP_PUSH_MACROS24#include <__undef_macros>25 26#if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)27 28_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL29inline namespace parallelism_v2 {30template <class _Tp, class _Storage, class _Vp>31class __simd_reference {32  template <class, class>33  friend class simd;34  template <class, class>35  friend class simd_mask;36 37  _Storage& __s_;38  size_t __idx_;39 40  _LIBCPP_HIDE_FROM_ABI __simd_reference(_Storage& __s, size_t __idx) : __s_(__s), __idx_(__idx) {}41 42  _LIBCPP_HIDE_FROM_ABI _Vp __get() const noexcept { return __s_.__get(__idx_); }43 44  _LIBCPP_HIDE_FROM_ABI void __set(_Vp __v) {45    if constexpr (is_same_v<_Vp, bool>)46      __s_.__set(__idx_, experimental::__set_all_bits<_Tp>(__v));47    else48      __s_.__set(__idx_, __v);49  }50 51public:52  using value_type = _Vp;53 54  __simd_reference()                        = delete;55  __simd_reference(const __simd_reference&) = delete;56 57  _LIBCPP_HIDE_FROM_ABI operator value_type() const noexcept { return __get(); }58 59  template <class _Up, enable_if_t<is_assignable_v<value_type&, _Up&&>, int> = 0>60  _LIBCPP_HIDE_FROM_ABI __simd_reference operator=(_Up&& __v) && noexcept {61    __set(static_cast<value_type>(std::forward<_Up>(__v)));62    return {__s_, __idx_};63  }64 65  // Note: This approach might not fully align with the specification,66  // which might be a wording defect. (https://wg21.link/N4808 section 9.6.3)67  template <class _Tp1, class _Storage1, class _Vp1>68  friend void69  swap(__simd_reference<_Tp1, _Storage1, _Vp1>&& __a, __simd_reference<_Tp1, _Storage1, _Vp1>&& __b) noexcept;70 71  template <class _Tp1, class _Storage1, class _Vp1>72  friend void swap(_Vp1& __a, __simd_reference<_Tp1, _Storage1, _Vp1>&& __b) noexcept;73 74  template <class _Tp1, class _Storage1, class _Vp1>75  friend void swap(__simd_reference<_Tp1, _Storage1, _Vp1>&& __a, _Vp1& __b) noexcept;76 77  template <class _Up, class = decltype(std::declval<value_type&>() += std::declval<_Up>())>78  _LIBCPP_HIDE_FROM_ABI __simd_reference operator+=(_Up&& __v) && noexcept {79    __set(__get() + static_cast<value_type>(std::forward<_Up>(__v)));80    return {__s_, __idx_};81  }82 83  template <class _Up, class = decltype(std::declval<value_type&>() -= std::declval<_Up>())>84  _LIBCPP_HIDE_FROM_ABI __simd_reference operator-=(_Up&& __v) && noexcept {85    __set(__get() - static_cast<value_type>(std::forward<_Up>(__v)));86    return {__s_, __idx_};87  }88 89  template <class _Up, class = decltype(std::declval<value_type&>() *= std::declval<_Up>())>90  _LIBCPP_HIDE_FROM_ABI __simd_reference operator*=(_Up&& __v) && noexcept {91    __set(__get() * static_cast<value_type>(std::forward<_Up>(__v)));92    return {__s_, __idx_};93  }94 95  template <class _Up, class = decltype(std::declval<value_type&>() /= std::declval<_Up>())>96  _LIBCPP_HIDE_FROM_ABI __simd_reference operator/=(_Up&& __v) && noexcept {97    __set(__get() / static_cast<value_type>(std::forward<_Up>(__v)));98    return {__s_, __idx_};99  }100 101  template <class _Up, class = decltype(std::declval<value_type&>() %= std::declval<_Up>())>102  _LIBCPP_HIDE_FROM_ABI __simd_reference operator%=(_Up&& __v) && noexcept {103    __set(__get() % static_cast<value_type>(std::forward<_Up>(__v)));104    return {__s_, __idx_};105  }106 107  template <class _Up, class = decltype(std::declval<value_type&>() &= std::declval<_Up>())>108  _LIBCPP_HIDE_FROM_ABI __simd_reference operator&=(_Up&& __v) && noexcept {109    __set(__get() & static_cast<value_type>(std::forward<_Up>(__v)));110    return {__s_, __idx_};111  }112 113  template <class _Up, class = decltype(std::declval<value_type&>() |= std::declval<_Up>())>114  _LIBCPP_HIDE_FROM_ABI __simd_reference operator|=(_Up&& __v) && noexcept {115    __set(__get() | static_cast<value_type>(std::forward<_Up>(__v)));116    return {__s_, __idx_};117  }118 119  template <class _Up, class = decltype(std::declval<value_type&>() ^= std::declval<_Up>())>120  _LIBCPP_HIDE_FROM_ABI __simd_reference operator^=(_Up&& __v) && noexcept {121    __set(__get() ^ static_cast<value_type>(std::forward<_Up>(__v)));122    return {__s_, __idx_};123  }124 125  template <class _Up, class = decltype(std::declval<value_type&>() <<= std::declval<_Up>())>126  _LIBCPP_HIDE_FROM_ABI __simd_reference operator<<=(_Up&& __v) && noexcept {127    __set(__get() << static_cast<value_type>(std::forward<_Up>(__v)));128    return {__s_, __idx_};129  }130 131  template <class _Up, class = decltype(std::declval<value_type&>() >>= std::declval<_Up>())>132  _LIBCPP_HIDE_FROM_ABI __simd_reference operator>>=(_Up&& __v) && noexcept {133    __set(__get() >> static_cast<value_type>(std::forward<_Up>(__v)));134    return {__s_, __idx_};135  }136 137  // Note: All legal vectorizable types support operator++/--.138  // There doesn't seem to be a way to trigger the constraint.139  // Therefore, no SFINAE check is added here.140  __simd_reference _LIBCPP_HIDE_FROM_ABI operator++() && noexcept {141    __set(__get() + 1);142    return {__s_, __idx_};143  }144 145  value_type _LIBCPP_HIDE_FROM_ABI operator++(int) && noexcept {146    auto __r = __get();147    __set(__get() + 1);148    return __r;149  }150 151  __simd_reference _LIBCPP_HIDE_FROM_ABI operator--() && noexcept {152    __set(__get() - 1);153    return {__s_, __idx_};154  }155 156  value_type _LIBCPP_HIDE_FROM_ABI operator--(int) && noexcept {157    auto __r = __get();158    __set(__get() - 1);159    return __r;160  }161};162 163template <class _Tp, class _Storage, class _Vp>164_LIBCPP_HIDE_FROM_ABI void165swap(__simd_reference<_Tp, _Storage, _Vp>&& __a, __simd_reference<_Tp, _Storage, _Vp>&& __b) noexcept {166  _Vp __tmp(std::move(__a));167  std::move(__a) = std::move(__b);168  std::move(__b) = std::move(__tmp);169}170 171template <class _Tp, class _Storage, class _Vp>172_LIBCPP_HIDE_FROM_ABI void swap(_Vp& __a, __simd_reference<_Tp, _Storage, _Vp>&& __b) noexcept {173  _Vp __tmp(std::move(__a));174  __a            = std::move(__b);175  std::move(__b) = std::move(__tmp);176}177 178template <class _Tp, class _Storage, class _Vp>179_LIBCPP_HIDE_FROM_ABI void swap(__simd_reference<_Tp, _Storage, _Vp>&& __a, _Vp& __b) noexcept {180  _Vp __tmp(std::move(__a));181  std::move(__a) = std::move(__b);182  __b            = std::move(__tmp);183}184 185} // namespace parallelism_v2186_LIBCPP_END_NAMESPACE_EXPERIMENTAL187 188#endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)189 190_LIBCPP_POP_MACROS191 192#endif // _LIBCPP_EXPERIMENTAL___SIMD_REFERENCE_H193