xoffset_view.hpp 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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_OFFSET_VIEW_HPP
  10. #define XTENSOR_OFFSET_VIEW_HPP
  11. #include <xtl/xcomplex.hpp>
  12. #include "xtensor/xfunctor_view.hpp"
  13. namespace xt
  14. {
  15. namespace detail
  16. {
  17. template <class M, std::size_t I>
  18. struct offset_forwarder
  19. {
  20. using value_type = M;
  21. using reference = M&;
  22. using const_reference = const M&;
  23. using pointer = M*;
  24. using const_pointer = const M*;
  25. using proxy = xtl::xproxy_wrapper<M>;
  26. template <class value_type, class requested_type>
  27. using simd_return_type = xt_simd::simd_return_type<value_type, requested_type>;
  28. template <class T>
  29. decltype(auto) operator()(T&& t) const
  30. {
  31. return xtl::forward_offset<M, I>(std::forward<T>(t));
  32. }
  33. template <
  34. class align,
  35. class requested_type,
  36. std::size_t N,
  37. class E,
  38. class MF = M,
  39. class = std::enable_if_t<
  40. (std::is_same<MF, double>::value || std::is_same<MF, float>::value) && I <= sizeof(MF),
  41. int>>
  42. auto proxy_simd_load(const E& expr, std::size_t n) const
  43. {
  44. // TODO refactor using shuffle only
  45. auto batch = expr.template load_simd<align, requested_type, N>(n);
  46. if (I == 0)
  47. {
  48. return batch.real();
  49. }
  50. else
  51. {
  52. return batch.imag();
  53. }
  54. }
  55. template <
  56. class align,
  57. class simd,
  58. class E,
  59. class MF = M,
  60. class = std::enable_if_t<
  61. (std::is_same<MF, double>::value || std::is_same<MF, float>::value) && I <= sizeof(MF),
  62. int>>
  63. auto proxy_simd_store(E& expr, std::size_t n, const simd& batch) const
  64. {
  65. auto x = expr.template load_simd<align, double, simd::size>(n);
  66. if (I == 0)
  67. {
  68. x.real() = batch;
  69. }
  70. else
  71. {
  72. x.imag() = batch;
  73. }
  74. expr.template store_simd<align>(n, x);
  75. }
  76. };
  77. }
  78. template <class CT, class M, std::size_t I>
  79. using xoffset_view = xfunctor_view<detail::offset_forwarder<M, I>, CT>;
  80. template <class CT, class M, std::size_t I>
  81. using xoffset_adaptor = xfunctor_adaptor<detail::offset_forwarder<M, I>, CT>;
  82. }
  83. #endif