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