utility.h 3.5 KB

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