xref: /llvm-project/libcxx/include/__cxx03/experimental/__simd/utility.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_UTILITY_H
11*ce777190SNikolas Klauser #define _LIBCPP___CXX03_EXPERIMENTAL___SIMD_UTILITY_H
12e78f53d1SNikolas Klauser 
1373fbae83SNikolas Klauser #include <__cxx03/__type_traits/is_arithmetic.h>
1473fbae83SNikolas Klauser #include <__cxx03/__type_traits/is_const.h>
1573fbae83SNikolas Klauser #include <__cxx03/__type_traits/is_constant_evaluated.h>
1673fbae83SNikolas Klauser #include <__cxx03/__type_traits/is_convertible.h>
1773fbae83SNikolas Klauser #include <__cxx03/__type_traits/is_same.h>
1873fbae83SNikolas Klauser #include <__cxx03/__type_traits/is_unsigned.h>
1973fbae83SNikolas Klauser #include <__cxx03/__type_traits/is_volatile.h>
2073fbae83SNikolas Klauser #include <__cxx03/__type_traits/void_t.h>
2173fbae83SNikolas Klauser #include <__cxx03/__utility/declval.h>
2273fbae83SNikolas Klauser #include <__cxx03/__utility/integer_sequence.h>
2373fbae83SNikolas Klauser #include <__cxx03/cstddef>
2473fbae83SNikolas Klauser #include <__cxx03/cstdint>
2573fbae83SNikolas Klauser #include <__cxx03/experimental/__config>
2673fbae83SNikolas Klauser #include <__cxx03/limits>
27e78f53d1SNikolas Klauser 
28e78f53d1SNikolas Klauser _LIBCPP_PUSH_MACROS
2973fbae83SNikolas Klauser #include <__cxx03/__undef_macros>
30e78f53d1SNikolas Klauser 
31e78f53d1SNikolas Klauser #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
32e78f53d1SNikolas Klauser 
33e78f53d1SNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
34e78f53d1SNikolas Klauser inline namespace parallelism_v2 {
35e78f53d1SNikolas Klauser template <class _Tp>
36e78f53d1SNikolas Klauser inline constexpr bool __is_vectorizable_v =
37e78f53d1SNikolas Klauser     is_arithmetic_v<_Tp> && !is_const_v<_Tp> && !is_volatile_v<_Tp> && !is_same_v<_Tp, bool>;
38e78f53d1SNikolas Klauser 
39e78f53d1SNikolas Klauser template <class _Tp>
40e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI auto __choose_mask_type() {
41e78f53d1SNikolas Klauser   if constexpr (sizeof(_Tp) == 1) {
42e78f53d1SNikolas Klauser     return uint8_t{};
43e78f53d1SNikolas Klauser   } else if constexpr (sizeof(_Tp) == 2) {
44e78f53d1SNikolas Klauser     return uint16_t{};
45e78f53d1SNikolas Klauser   } else if constexpr (sizeof(_Tp) == 4) {
46e78f53d1SNikolas Klauser     return uint32_t{};
47e78f53d1SNikolas Klauser   } else if constexpr (sizeof(_Tp) == 8) {
48e78f53d1SNikolas Klauser     return uint64_t{};
49e78f53d1SNikolas Klauser   }
50e78f53d1SNikolas Klauser #  ifndef _LIBCPP_HAS_NO_INT128
51e78f53d1SNikolas Klauser   else if constexpr (sizeof(_Tp) == 16) {
52e78f53d1SNikolas Klauser     return __uint128_t{};
53e78f53d1SNikolas Klauser   }
54e78f53d1SNikolas Klauser #  endif
55e78f53d1SNikolas Klauser   else
56e78f53d1SNikolas Klauser     static_assert(sizeof(_Tp) == 0, "Unexpected size");
57e78f53d1SNikolas Klauser }
58e78f53d1SNikolas Klauser 
59e78f53d1SNikolas Klauser template <class _Tp>
60e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI auto constexpr __set_all_bits(bool __v) {
61e78f53d1SNikolas Klauser   return __v ? (numeric_limits<decltype(__choose_mask_type<_Tp>())>::max()) : 0;
62e78f53d1SNikolas Klauser }
63e78f53d1SNikolas Klauser 
64e78f53d1SNikolas Klauser template <class _From, class _To, class = void>
65e78f53d1SNikolas Klauser inline constexpr bool __is_non_narrowing_convertible_v = false;
66e78f53d1SNikolas Klauser 
67e78f53d1SNikolas Klauser template <class _From, class _To>
68e78f53d1SNikolas Klauser inline constexpr bool __is_non_narrowing_convertible_v<_From, _To, std::void_t<decltype(_To{std::declval<_From>()})>> =
69e78f53d1SNikolas Klauser     true;
70e78f53d1SNikolas Klauser 
71e78f53d1SNikolas Klauser template <class _Tp, class _Up>
72e78f53d1SNikolas Klauser inline constexpr bool __can_broadcast_v =
73e78f53d1SNikolas Klauser     (__is_vectorizable_v<_Up> && __is_non_narrowing_convertible_v<_Up, _Tp>) ||
74e78f53d1SNikolas Klauser     (!__is_vectorizable_v<_Up> && is_convertible_v<_Up, _Tp>) || is_same_v<_Up, int> ||
75e78f53d1SNikolas Klauser     (is_same_v<_Up, unsigned int> && is_unsigned_v<_Tp>);
76e78f53d1SNikolas Klauser 
77e78f53d1SNikolas Klauser template <class _Tp, class _Generator, std::size_t _Idx, class = void>
78e78f53d1SNikolas Klauser inline constexpr bool __is_well_formed = false;
79e78f53d1SNikolas Klauser 
80e78f53d1SNikolas Klauser template <class _Tp, class _Generator, std::size_t _Idx>
81e78f53d1SNikolas Klauser inline constexpr bool
82e78f53d1SNikolas Klauser     __is_well_formed<_Tp,
83e78f53d1SNikolas Klauser                      _Generator,
84e78f53d1SNikolas Klauser                      _Idx,
85e78f53d1SNikolas Klauser                      std::void_t<decltype(std::declval<_Generator>()(integral_constant<size_t, _Idx>()))>> =
86e78f53d1SNikolas Klauser         __can_broadcast_v<_Tp, decltype(std::declval<_Generator>()(integral_constant<size_t, _Idx>()))>;
87e78f53d1SNikolas Klauser 
88e78f53d1SNikolas Klauser template <class _Tp, class _Generator, std::size_t... _Idxes>
89e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr bool __can_generate(index_sequence<_Idxes...>) {
90e78f53d1SNikolas Klauser   return (true && ... && __is_well_formed<_Tp, _Generator, _Idxes>);
91e78f53d1SNikolas Klauser }
92e78f53d1SNikolas Klauser 
93e78f53d1SNikolas Klauser template <class _Tp, class _Generator, std::size_t _Size>
94e78f53d1SNikolas Klauser inline constexpr bool __can_generate_v = experimental::__can_generate<_Tp, _Generator>(make_index_sequence<_Size>());
95e78f53d1SNikolas Klauser 
96e78f53d1SNikolas Klauser } // namespace parallelism_v2
97e78f53d1SNikolas Klauser _LIBCPP_END_NAMESPACE_EXPERIMENTAL
98e78f53d1SNikolas Klauser 
99e78f53d1SNikolas Klauser #endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
100e78f53d1SNikolas Klauser 
101e78f53d1SNikolas Klauser _LIBCPP_POP_MACROS
102e78f53d1SNikolas Klauser 
103*ce777190SNikolas Klauser #endif // _LIBCPP___CXX03_EXPERIMENTAL___SIMD_UTILITY_H
104