candlewick 0.1.0
A renderer
Loading...
Searching...
No Matches
StridedView.h
Go to the documentation of this file.
1#pragma once
2
3#include <iterator>
4#include <span>
5#include <type_traits>
6#include <stdexcept>
7
8namespace candlewick {
9
14template <typename T> class strided_view {
15 using erased_type =
16 std::conditional_t<std::is_const_v<T>, const char, char> *;
17
18 [[nodiscard]] erased_type erased_ptr() const {
19 return reinterpret_cast<erased_type>(m_data);
20 }
21
22public:
23 using element_type = T;
24 using value_type = std::remove_cv_t<T>;
25 using size_type = std::size_t;
26 using difference_type = std::ptrdiff_t;
27 using pointer = T *;
28 using const_pointer = const T *;
31
32 class iterator final {
33 pointer _ptr;
34 size_type _stride;
35
36 public:
37 using iterator_concept = std::forward_iterator_tag;
40
41 iterator() : _ptr(nullptr), _stride(0) {}
42
43 iterator(pointer ptr, size_type stride) : _ptr(ptr), _stride(stride) {}
44
45 reference operator*() const { return *_ptr; }
46 pointer operator->() const { return _ptr; }
47
49 auto p = reinterpret_cast<erased_type>(_ptr) + _stride;
50 _ptr = reinterpret_cast<pointer>(p);
51 return *this;
52 }
53
55 iterator tmp = *this;
56 ++(*this);
57 return tmp;
58 }
59
60 bool operator<=>(const iterator &) const = default;
61 };
62 static_assert(std::forward_iterator<iterator>);
63
64 constexpr strided_view() noexcept : m_data(nullptr), m_size(0), m_stride(0) {}
65
67 template <std::random_access_iterator It>
68 strided_view(It first, size_type count, size_type stride_bytes) noexcept
69 : m_data(std::to_address(first)), m_size(count), m_stride(stride_bytes) {}
70
73 template <std::random_access_iterator It>
74 strided_view(It first, size_type count) noexcept
75 : strided_view(first, count, sizeof(T)) {}
76
77 template <size_t extent>
78 strided_view(std::span<element_type, extent> other,
79 size_type stride_bytes) noexcept
80 : m_data(other.data()), m_size(other.size()), m_stride(stride_bytes) {}
81
82 template <size_t extent>
83 strided_view(std::span<element_type, extent> other) noexcept
84 : strided_view(other, sizeof(element_type)) {}
85
86 template <size_t array_extent>
87 strided_view(std::type_identity_t<element_type> (&arr)[array_extent],
88 size_t stride_bytes = sizeof(element_type)) noexcept
89 : strided_view(static_cast<pointer>(arr), array_extent, stride_bytes) {}
90
91 ~strided_view() noexcept = default;
92
93 strided_view &operator=(const strided_view &) noexcept = default;
94
95 iterator begin() const { return iterator{m_data, m_stride}; }
96
97 iterator end() const {
98 return iterator{
99 reinterpret_cast<pointer>(erased_ptr() + m_stride * max_index()),
100 m_stride};
101 }
102
103 iterator cbegin() const { return this->begin(); }
104 iterator cend() const { return this->end(); }
105
107 [[nodiscard]] size_type size() const noexcept { return m_size; }
108
110 [[nodiscard]] size_type stride_bytes() const noexcept { return m_stride; }
111
112 [[nodiscard]] size_t max_index() const {
113 size_t stride_in_T = m_stride / sizeof(element_type);
114 size_t q = m_size / stride_in_T;
115 size_t m = m_size % stride_in_T;
116 return q + ((m > 0) ? 1 : 0);
117 }
118
119 [[nodiscard]] bool empty() const noexcept { return size() == 0; }
120
121 [[nodiscard]] reference front() const noexcept { return *m_data; }
122
123 [[nodiscard]] reference back() const noexcept {
124 return *reinterpret_cast<pointer>(erased_ptr() +
125 m_stride * (max_index() - 1));
126 }
127
128 [[nodiscard]] reference operator[](size_type idx) const noexcept {
129 return *reinterpret_cast<pointer>(erased_ptr() + m_stride * idx);
130 }
131
132 [[nodiscard]] reference at(size_type idx) const {
133 if (idx >= max_index())
134 throw std::out_of_range("Access out of range.");
135 return this->operator[](idx);
136 }
137
138 [[nodiscard]] pointer data() const noexcept { return m_data; }
139
140private:
141 pointer m_data; //< Pointer to the first element in the view
142 size_type m_size; //<
143 size_type m_stride; //< Stride in bytes
144};
145
146template <typename T> strided_view(T *first, size_t, size_t) -> strided_view<T>;
147
148template <typename T, size_t extent>
149strided_view(std::span<T, extent>, size_t) -> strided_view<T>;
150
151template <typename T, size_t arr_extent>
152strided_view(T (&)[arr_extent]) -> strided_view<T>;
153
154} // namespace candlewick
Definition StridedView.h:32
iterator(pointer ptr, size_type stride)
Definition StridedView.h:43
reference operator*() const
Definition StridedView.h:45
iterator operator++(int)
Definition StridedView.h:54
std::forward_iterator_tag iterator_concept
Definition StridedView.h:37
bool operator<=>(const iterator &) const =default
pointer operator->() const
Definition StridedView.h:46
strided_view::difference_type difference_type
Definition StridedView.h:39
iterator & operator++()
Definition StridedView.h:48
iterator()
Definition StridedView.h:41
strided_view::value_type value_type
Definition StridedView.h:38
A strided view to data, allowing for type-erased data.
Definition StridedView.h:14
iterator begin() const
Definition StridedView.h:95
strided_view(std::span< element_type, extent > other) noexcept
Definition StridedView.h:83
std::size_t size_type
Definition StridedView.h:25
T element_type
Definition StridedView.h:23
std::remove_cv_t< T > value_type
Definition StridedView.h:24
pointer data() const noexcept
Definition StridedView.h:138
reference operator[](size_type idx) const noexcept
Definition StridedView.h:128
const T * const_pointer
Definition StridedView.h:28
strided_view(It first, size_type count) noexcept
Build a view from an iterator and given element count. The stride is assumed to be sizeof(T),...
Definition StridedView.h:74
bool empty() const noexcept
Definition StridedView.h:119
strided_view(std::type_identity_t< element_type >(&arr)[array_extent], size_t stride_bytes=sizeof(element_type)) noexcept
Definition StridedView.h:87
reference back() const noexcept
Definition StridedView.h:123
std::ptrdiff_t difference_type
Definition StridedView.h:26
iterator cbegin() const
Definition StridedView.h:103
size_t max_index() const
Definition StridedView.h:112
strided_view(std::span< element_type, extent > other, size_type stride_bytes) noexcept
Definition StridedView.h:78
size_type stride_bytes() const noexcept
Stride in bytes between two elements of the view.
Definition StridedView.h:110
element_type & reference
Definition StridedView.h:29
iterator cend() const
Definition StridedView.h:104
size_type size() const noexcept
Size (number of elements) of the view.
Definition StridedView.h:107
reference at(size_type idx) const
Definition StridedView.h:132
iterator end() const
Definition StridedView.h:97
const element_type & const_reference
Definition StridedView.h:30
constexpr strided_view() noexcept
Definition StridedView.h:64
reference front() const noexcept
Definition StridedView.h:121
~strided_view() noexcept=default
T * pointer
Definition StridedView.h:27
strided_view(It first, size_type count, size_type stride_bytes) noexcept
Build a view from an iterator given the size and stride.
Definition StridedView.h:68
Definition Camera.h:8
strided_view(T *first, size_t, size_t) -> strided_view< T >