Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2019
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.67 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <cassert>
  4. #include <iterator>
  5. #include <array>
  6. #include <numeric>
  7. #include <vector>
  8.  
  9.  
  10. template<bool...> struct bool_pack{};
  11. template<class... Ts>
  12. using conjunction = std::is_same<bool_pack<true,Ts::value...>, bool_pack<Ts::value..., true>>;
  13.  
  14. template<typename CheckType, typename... Ts>
  15. using AllOfType = typename std::enable_if<conjunction<std::is_convertible<Ts, CheckType>...>::value>::type;
  16.  
  17. template <typename T, size_t Rank = 1>
  18. class ArrayView
  19. {
  20. using IndexType = std::ptrdiff_t;
  21.  
  22. public:
  23. ArrayView(T* d, std::initializer_list<IndexType> l) :
  24. data(d)
  25. {
  26. assert(l.size() == Rank);
  27. std::copy(l.begin(), l.end(), bounds.data());
  28. SetStride();
  29. };
  30.  
  31. template <typename...Ts, typename = AllOfType<IndexType, Ts...>>
  32. T& operator()(Ts...args)
  33. {
  34. return (*this)[{args...}];
  35. }
  36.  
  37. size_t NumberOfElements()const
  38. {
  39. return std::accumulate(bounds.begin(), bounds.end(), 1, std::multiplies<>());
  40. }
  41.  
  42. private:
  43.  
  44. T& operator[](std::initializer_list<IndexType> l)
  45. {
  46. assert(Contains(l));
  47. assert(l.size() == Rank);
  48.  
  49. return (*this)[Offset(l)];
  50. }
  51.  
  52. T& operator[](size_t index) const
  53. {
  54. return *(data + index);
  55. }
  56.  
  57. bool Contains(std::initializer_list<IndexType> l) const
  58. {
  59. bool contains = true;
  60. std::vector<IndexType> v(l);
  61. for (size_t i = 0; i < bounds.size() && contains; ++i)
  62. {
  63. contains = v[i] < bounds[i];
  64. }
  65. return contains;
  66. }
  67.  
  68. void SetStride()
  69. {
  70. stride[Rank - 1] = 1;
  71. for (int dim = static_cast<int>(Rank) - 2; dim >= 0; --dim)
  72. {
  73. stride[dim] = stride[dim + 1] * bounds[dim + 1];
  74. }
  75. }
  76.  
  77. IndexType Offset(std::initializer_list<IndexType> l) const
  78. {
  79. assert(l.size() == Rank);
  80.  
  81. IndexType offset = 0;
  82. std::vector<IndexType> v(l);
  83. for (size_t i = 0; i < l.size(); ++i)
  84. {
  85. offset += v[i] * stride[i];
  86. }
  87. return offset;
  88. }
  89.  
  90. T* data;
  91. std::array<IndexType, Rank> bounds;
  92. std::array<IndexType, Rank> stride;
  93. };
  94.  
  95. template<typename T, typename...Dimensions>
  96. auto CreateArrayView(T* t, Dimensions...ds) -> ArrayView<T, sizeof...(ds)>
  97. {
  98. return ArrayView<T, sizeof...(ds)>(t, {ds...});
  99. }
  100.  
  101. int main()
  102. {
  103. const auto r = 5;
  104. const auto c = 2;
  105. const auto l = r*c;
  106. int i[l] =
  107. {0, 1,
  108. 2, 3,
  109. 4, 5, 6, 7, 8, 9
  110. };
  111.  
  112. auto v = CreateArrayView(i, r, c);
  113.  
  114. std::cout << v(4, 1) << std::endl;
  115. v(4, 1) *= 2;
  116. std::cout << v(4, 1) << std::endl;
  117.  
  118. return 0;
  119. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement