utility.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. #ifndef _LIBCPP_EXPERIMENTAL___SIMD_UTILITY_H
  10. #define _LIBCPP_EXPERIMENTAL___SIMD_UTILITY_H
  11. #include <__type_traits/is_arithmetic.h>
  12. #include <__type_traits/is_const.h>
  13. #include <__type_traits/is_constant_evaluated.h>
  14. #include <__type_traits/is_convertible.h>
  15. #include <__type_traits/is_same.h>
  16. #include <__type_traits/is_unsigned.h>
  17. #include <__type_traits/is_volatile.h>
  18. #include <__type_traits/void_t.h>
  19. #include <__utility/declval.h>
  20. #include <__utility/integer_sequence.h>
  21. #include <cstddef>
  22. #include <cstdint>
  23. #include <experimental/__config>
  24. #include <limits>
  25. _LIBCPP_PUSH_MACROS
  26. #include <__undef_macros>
  27. #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
  28. _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
  29. inline namespace parallelism_v2 {
  30. template <class _Tp>
  31. inline constexpr bool __is_vectorizable_v =
  32. is_arithmetic_v<_Tp> && !is_const_v<_Tp> && !is_volatile_v<_Tp> && !is_same_v<_Tp, bool>;
  33. template <class _Tp>
  34. _LIBCPP_HIDE_FROM_ABI auto __choose_mask_type() {
  35. if constexpr (sizeof(_Tp) == 1) {
  36. return uint8_t{};
  37. } else if constexpr (sizeof(_Tp) == 2) {
  38. return uint16_t{};
  39. } else if constexpr (sizeof(_Tp) == 4) {
  40. return uint32_t{};
  41. } else if constexpr (sizeof(_Tp) == 8) {
  42. return uint64_t{};
  43. }
  44. # ifndef _LIBCPP_HAS_NO_INT128
  45. else if constexpr (sizeof(_Tp) == 16) {
  46. return __uint128_t{};
  47. }
  48. # endif
  49. else
  50. static_assert(sizeof(_Tp) == 0, "Unexpected size");
  51. }
  52. template <class _Tp>
  53. _LIBCPP_HIDE_FROM_ABI auto constexpr __set_all_bits(bool __v) {
  54. return __v ? (numeric_limits<decltype(__choose_mask_type<_Tp>())>::max()) : 0;
  55. }
  56. template <class _From, class _To, class = void>
  57. inline constexpr bool __is_non_narrowing_convertible_v = false;
  58. template <class _From, class _To>
  59. inline constexpr bool __is_non_narrowing_convertible_v<_From, _To, std::void_t<decltype(_To{std::declval<_From>()})>> =
  60. true;
  61. template <class _Tp, class _Up>
  62. inline constexpr bool __can_broadcast_v =
  63. (__is_vectorizable_v<_Up> && __is_non_narrowing_convertible_v<_Up, _Tp>) ||
  64. (!__is_vectorizable_v<_Up> && is_convertible_v<_Up, _Tp>) || is_same_v<_Up, int> ||
  65. (is_same_v<_Up, unsigned int> && is_unsigned_v<_Tp>);
  66. template <class _Tp, class _Generator, std::size_t _Idx, class = void>
  67. inline constexpr bool __is_well_formed = false;
  68. template <class _Tp, class _Generator, std::size_t _Idx>
  69. inline constexpr bool
  70. __is_well_formed<_Tp,
  71. _Generator,
  72. _Idx,
  73. std::void_t<decltype(std::declval<_Generator>()(integral_constant<size_t, _Idx>()))>> =
  74. __can_broadcast_v<_Tp, decltype(std::declval<_Generator>()(integral_constant<size_t, _Idx>()))>;
  75. template <class _Tp, class _Generator, std::size_t... _Idxes>
  76. _LIBCPP_HIDE_FROM_ABI constexpr bool __can_generate(index_sequence<_Idxes...>) {
  77. return (true && ... && __is_well_formed<_Tp, _Generator, _Idxes>);
  78. }
  79. template <class _Tp, class _Generator, std::size_t _Size>
  80. inline constexpr bool __can_generate_v = experimental::__can_generate<_Tp, _Generator>(make_index_sequence<_Size>());
  81. } // namespace parallelism_v2
  82. _LIBCPP_END_NAMESPACE_EXPERIMENTAL
  83. #endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
  84. _LIBCPP_POP_MACROS
  85. #endif // _LIBCPP_EXPERIMENTAL___SIMD_UTILITY_H