blob: 791a0b7fc013617ee15316ba3628be08f434624a [file] [log] [blame]
Éanna Ó Catháinc6ab02a2021-04-07 14:35:25 +01001//
2// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
8template<class T>
9class SlidingWindow
10{
11protected:
12 T* m_start = nullptr;
13 size_t m_dataSize = 0;
14 size_t m_size = 0;
15 size_t m_stride = 0;
16 size_t m_count = 0;
17public:
18
19 /**
20 * Creates the window slider through the given data.
21 *
22 * @param data pointer to the data to slide through.
23 * @param dataSize size in T type elements wise.
24 * @param windowSize sliding window size in T type wise elements.
25 * @param stride stride size in T type wise elements.
26 */
27 SlidingWindow(T* data, size_t dataSize,
28 size_t windowSize, size_t stride)
29 {
30 m_start = data;
31 m_dataSize = dataSize;
32 m_size = windowSize;
33 m_stride = stride;
34 }
35
36 SlidingWindow() = default;
37
38 ~SlidingWindow() = default;
39
40 /**
41 * Get the next data window.
42 * @return pointer to the next window, if next window is not available nullptr is returned.
43 */
44 virtual T* Next()
45 {
46 if (HasNext())
47 {
48 m_count++;
49 return m_start + Index() * m_stride;
50 }
51 else
52 {
53 return nullptr;
54 }
55 }
56
57 /**
58 * Checks if the next data portion is available.
59 * @return true if next data portion is available
60 */
61 bool HasNext()
62 {
63 return this->m_count < 1 + this->FractionalTotalStrides() && (this->NextWindowStartIndex() < this->m_dataSize);
64 }
65
66 /**
67 * Resest the slider to the initial position.
68 */
69 virtual void Reset()
70 {
71 m_count = 0;
72 }
73
74 /**
75 * Resest the slider to the initial position.
76 */
77 virtual size_t GetWindowSize()
78 {
79 return m_size;
80 }
81
82 /**
83 * Resets the slider to the start of the new data.
84 * New data size MUST be the same as the old one.
85 * @param newStart pointer to the new data to slide through.
86 */
87 virtual void Reset(T* newStart)
88 {
89 m_start = newStart;
90 Reset();
91 }
92
93 /**
94 * Gets current index of the sliding window.
95 * @return current position of the sliding window in number of strides
96 */
97 size_t Index()
98 {
99 return m_count == 0? 0: m_count - 1;
100 }
101
102 /**
103 * Gets the index from the start of the data where the next window will begin.
104 * While Index() returns the index of sliding window itself this function returns the index of the data
105 * element itself.
106 * @return Index from the start of the data where the next sliding window will begin.
107 */
108 virtual size_t NextWindowStartIndex()
109 {
110 return m_count == 0? 0: ((m_count) * m_stride);
111 }
112
113 /**
114 * Go to given sliding window index.
115 * @param index new position of the sliding window. if index is invalid (greater than possible range of strides)
116 * then next call to Next() will return nullptr.
117 */
118 void FastForward(size_t index)
119 {
120 m_count = index;
121 }
122
123 /**
124 * Calculates whole number of times the window can stride through the given data.
125 * @return maximum number of strides.
126 */
127 size_t TotalStrides()
128 {
129 if (m_size > m_dataSize)
130 {
131 return 0;
132 }
133 return ((m_dataSize - m_size)/m_stride);
134 }
135
136 /**
137 * Calculates number of times the window can stride through the given data. May not be a whole number.
138 * @return Number of strides to cover all data.
139 */
140 float FractionalTotalStrides()
141 {
142 if(this->m_size > this->m_dataSize)
143 {
144 return this->m_dataSize / this->m_size;
145 }
146 else
147 {
148 return ((this->m_dataSize - this->m_size)/ static_cast<float>(this->m_stride));
149 }
150
151 }
152
153 /**
154 * Calculates the remaining data left to be processed
155 * @return The remaining unprocessed data
156 */
157 int RemainingData()
158 {
159 return this->m_dataSize - this->NextWindowStartIndex();
160 }
161};