1 // 2 // Copyright © 2021 Arm Ltd and Contributors. All rights reserved. 3 // SPDX-License-Identifier: MIT 4 // 5 6 #pragma once 7 8 template<class T> 9 class SlidingWindow 10 { 11 protected: 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; 17 public: 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 */ SlidingWindow(T * data,size_t dataSize,size_t windowSize,size_t stride)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 */ Next()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 */ HasNext()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 */ Reset()69 virtual void Reset() 70 { 71 m_count = 0; 72 } 73 74 /** 75 * Resest the slider to the initial position. 76 */ GetWindowSize()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 */ Reset(T * newStart)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 */ Index()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 */ NextWindowStartIndex()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 */ FastForward(size_t index)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 */ TotalStrides()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 */ FractionalTotalStrides()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 */ RemainingData()157 int RemainingData() 158 { 159 return this->m_dataSize - this->NextWindowStartIndex(); 160 } 161 };