xview_utils.hpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /***************************************************************************
  2. * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
  3. * Copyright (c) QuantStack *
  4. * *
  5. * Distributed under the terms of the BSD 3-Clause License. *
  6. * *
  7. * The full license is in the file LICENSE, distributed with this software. *
  8. ****************************************************************************/
  9. #ifndef XTENSOR_VIEW_UTILS_HPP
  10. #define XTENSOR_VIEW_UTILS_HPP
  11. #include <array>
  12. #include "xlayout.hpp"
  13. #include "xslice.hpp"
  14. #include "xtensor_forward.hpp"
  15. namespace xt
  16. {
  17. /********************************
  18. * helper functions declaration *
  19. ********************************/
  20. // number of integral types in the specified sequence of types
  21. template <class... S>
  22. constexpr std::size_t integral_count();
  23. // number of integral types in the specified sequence of types before specified index
  24. template <class... S>
  25. constexpr std::size_t integral_count_before(std::size_t i);
  26. // index in the specified sequence of types of the ith non-integral type
  27. template <class... S>
  28. constexpr std::size_t integral_skip(std::size_t i);
  29. // number of newaxis types in the specified sequence of types
  30. template <class... S>
  31. constexpr std::size_t newaxis_count();
  32. // number of newaxis types in the specified sequence of types before specified index
  33. template <class... S>
  34. constexpr std::size_t newaxis_count_before(std::size_t i);
  35. // index in the specified sequence of types of the ith non-newaxis type
  36. template <class... S>
  37. constexpr std::size_t newaxis_skip(std::size_t i);
  38. template <class S, class It>
  39. inline disable_xslice<S, std::size_t> get_slice_value(const S& s, It&) noexcept
  40. {
  41. return static_cast<std::size_t>(s);
  42. }
  43. template <class S, class It>
  44. inline auto get_slice_value(const xslice<S>& slice, It& it) noexcept
  45. {
  46. return slice.derived_cast()(typename S::size_type(*it));
  47. }
  48. /***********************
  49. * view_temporary_type *
  50. ***********************/
  51. namespace detail
  52. {
  53. template <class T, class S, layout_type L, class... SL>
  54. struct view_temporary_type_impl
  55. {
  56. using type = xt::xarray<T, L>;
  57. };
  58. template <class T, class I, std::size_t N, layout_type L, class... SL>
  59. struct view_temporary_type_impl<T, std::array<I, N>, L, SL...>
  60. {
  61. using type = xt::xtensor<T, N + newaxis_count<SL...>() - integral_count<SL...>(), L>;
  62. };
  63. }
  64. template <class E, class... SL>
  65. struct view_temporary_type
  66. {
  67. using type = typename detail::view_temporary_type_impl<
  68. std::decay_t<typename E::value_type>,
  69. typename E::shape_type,
  70. E::static_layout,
  71. SL...>::type;
  72. };
  73. template <class E, class... SL>
  74. using view_temporary_type_t = typename view_temporary_type<E, SL...>::type;
  75. /************************
  76. * count integral types *
  77. ************************/
  78. namespace detail
  79. {
  80. template <class T, class... S>
  81. struct integral_count_impl
  82. {
  83. static constexpr std::size_t count(std::size_t i) noexcept
  84. {
  85. return i
  86. ? (integral_count_impl<S...>::count(i - 1)
  87. + (xtl::is_integral<std::remove_reference_t<T>>::value ? 1 : 0))
  88. : 0;
  89. }
  90. };
  91. template <>
  92. struct integral_count_impl<void>
  93. {
  94. static constexpr std::size_t count(std::size_t /*i*/) noexcept
  95. {
  96. return 0;
  97. }
  98. };
  99. }
  100. template <class... S>
  101. constexpr std::size_t integral_count()
  102. {
  103. return detail::integral_count_impl<S..., void>::count(sizeof...(S));
  104. }
  105. template <class... S>
  106. constexpr std::size_t integral_count_before(std::size_t i)
  107. {
  108. return detail::integral_count_impl<S..., void>::count(i);
  109. }
  110. /***********************
  111. * count newaxis types *
  112. ***********************/
  113. namespace detail
  114. {
  115. template <class T>
  116. struct is_newaxis : std::false_type
  117. {
  118. };
  119. template <class T>
  120. struct is_newaxis<xnewaxis<T>> : public std::true_type
  121. {
  122. };
  123. template <class T, class... S>
  124. struct newaxis_count_impl
  125. {
  126. static constexpr std::size_t count(std::size_t i) noexcept
  127. {
  128. return i
  129. ? (newaxis_count_impl<S...>::count(i - 1)
  130. + (is_newaxis<std::remove_reference_t<T>>::value ? 1 : 0))
  131. : 0;
  132. }
  133. };
  134. template <>
  135. struct newaxis_count_impl<void>
  136. {
  137. static constexpr std::size_t count(std::size_t /*i*/) noexcept
  138. {
  139. return 0;
  140. }
  141. };
  142. }
  143. template <class... S>
  144. constexpr std::size_t newaxis_count()
  145. {
  146. return detail::newaxis_count_impl<S..., void>::count(sizeof...(S));
  147. }
  148. template <class... S>
  149. constexpr std::size_t newaxis_count_before(std::size_t i)
  150. {
  151. return detail::newaxis_count_impl<S..., void>::count(i);
  152. }
  153. /**********************************
  154. * index of ith non-integral type *
  155. **********************************/
  156. namespace detail
  157. {
  158. template <class T, class... S>
  159. struct integral_skip_impl
  160. {
  161. static constexpr std::size_t count(std::size_t i) noexcept
  162. {
  163. return i == 0 ? count_impl() : count_impl(i);
  164. }
  165. private:
  166. static constexpr std::size_t count_impl(std::size_t i) noexcept
  167. {
  168. return 1
  169. + (xtl::is_integral<std::remove_reference_t<T>>::value
  170. ? integral_skip_impl<S...>::count(i)
  171. : integral_skip_impl<S...>::count(i - 1));
  172. }
  173. static constexpr std::size_t count_impl() noexcept
  174. {
  175. return xtl::is_integral<std::remove_reference_t<T>>::value
  176. ? 1 + integral_skip_impl<S...>::count(0)
  177. : 0;
  178. }
  179. };
  180. template <>
  181. struct integral_skip_impl<void>
  182. {
  183. static constexpr std::size_t count(std::size_t i) noexcept
  184. {
  185. return i;
  186. }
  187. };
  188. }
  189. template <class... S>
  190. constexpr std::size_t integral_skip(std::size_t i)
  191. {
  192. return detail::integral_skip_impl<S..., void>::count(i);
  193. }
  194. /*********************************
  195. * index of ith non-newaxis type *
  196. *********************************/
  197. namespace detail
  198. {
  199. template <class T, class... S>
  200. struct newaxis_skip_impl
  201. {
  202. static constexpr std::size_t count(std::size_t i) noexcept
  203. {
  204. return i == 0 ? count_impl() : count_impl(i);
  205. }
  206. private:
  207. static constexpr std::size_t count_impl(std::size_t i) noexcept
  208. {
  209. return 1
  210. + (is_newaxis<std::remove_reference_t<T>>::value
  211. ? newaxis_skip_impl<S...>::count(i)
  212. : newaxis_skip_impl<S...>::count(i - 1));
  213. }
  214. static constexpr std::size_t count_impl() noexcept
  215. {
  216. return is_newaxis<std::remove_reference_t<T>>::value ? 1 + newaxis_skip_impl<S...>::count(0)
  217. : 0;
  218. }
  219. };
  220. template <>
  221. struct newaxis_skip_impl<void>
  222. {
  223. static constexpr std::size_t count(std::size_t i) noexcept
  224. {
  225. return i;
  226. }
  227. };
  228. }
  229. template <class... S>
  230. constexpr std::size_t newaxis_skip(std::size_t i)
  231. {
  232. return detail::newaxis_skip_impl<S..., void>::count(i);
  233. }
  234. }
  235. #endif