2023-08-28 12:31:18 +02:00
|
|
|
/* A sliding/moving window.
|
2019-02-18 01:12:08 +01:00
|
|
|
*
|
2023-08-31 11:17:07 +02:00
|
|
|
* Author: Steffen Vogel <post@steffenvogel.de>
|
|
|
|
* SPDX-FileCopyrightText: 2014-2023 Institute for Automation of Complex Power Systems, RWTH Aachen University
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
2023-08-28 12:31:18 +02:00
|
|
|
*/
|
2019-02-18 01:12:08 +01:00
|
|
|
|
2019-04-12 09:48:18 +02:00
|
|
|
#pragma once
|
2019-02-18 01:12:08 +01:00
|
|
|
|
2022-05-02 14:57:53 +02:00
|
|
|
#include <deque>
|
2019-02-18 01:12:08 +01:00
|
|
|
|
2019-04-12 09:48:18 +02:00
|
|
|
namespace villas {
|
|
|
|
namespace dsp {
|
2019-02-18 01:12:08 +01:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
template <typename T, typename Container = std::deque<T>>
|
2022-05-02 14:57:53 +02:00
|
|
|
class Window : protected Container {
|
2019-02-18 01:12:08 +01:00
|
|
|
|
2019-04-12 09:48:18 +02:00
|
|
|
public:
|
2023-09-07 13:19:19 +02:00
|
|
|
using iterator = typename Container::iterator;
|
|
|
|
using size_type = typename Container::size_type;
|
2019-02-18 01:12:08 +01:00
|
|
|
|
2019-04-12 09:48:18 +02:00
|
|
|
protected:
|
2023-09-07 13:19:19 +02:00
|
|
|
virtual T filter(T in, size_type i) const { return in; }
|
2019-02-18 01:12:08 +01:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
class transform_iterator : public Container::const_iterator {
|
|
|
|
protected:
|
|
|
|
const Window *window;
|
2019-02-18 01:12:08 +01:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
using base_iterator = typename Container::const_iterator;
|
2019-02-18 01:12:08 +01:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
public:
|
|
|
|
transform_iterator(const Window<T> *w)
|
|
|
|
: base_iterator(w->Container::begin()), window(w) {}
|
2019-02-18 01:12:08 +01:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
T operator*() {
|
|
|
|
auto i = (*this) - window->begin();
|
|
|
|
const auto &v = base_iterator::operator*();
|
2019-02-18 01:12:08 +01:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
return window->filter(v, i);
|
|
|
|
}
|
|
|
|
};
|
2022-05-02 14:57:53 +02:00
|
|
|
|
|
|
|
public:
|
2023-09-07 13:19:19 +02:00
|
|
|
Window(size_type l = 0, T i = 0) : Container(l, i) {}
|
2019-04-12 09:48:18 +02:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
T val(size_type pos) { return this->Container::operator[](pos); }
|
2022-05-31 18:04:36 +02:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
T update(T in) {
|
|
|
|
Container::push_back(in);
|
2019-04-12 09:48:18 +02:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
auto out = (*this)[0];
|
2022-05-02 14:57:53 +02:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
Container::pop_front();
|
2019-04-12 09:48:18 +02:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
return out;
|
|
|
|
}
|
2019-04-12 09:48:18 +02:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
// Expose a limited number of functions from deque
|
2022-05-02 14:57:53 +02:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
using Container::end;
|
|
|
|
using Container::size;
|
2022-05-02 14:57:53 +02:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
transform_iterator begin() const noexcept { return transform_iterator(this); }
|
2022-05-02 14:57:53 +02:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
T operator[](size_type i) const noexcept {
|
|
|
|
auto v = Container::operator[](i);
|
2022-05-02 14:57:53 +02:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
return filter(v, i);
|
|
|
|
}
|
2019-04-12 09:48:18 +02:00
|
|
|
};
|
|
|
|
|
2022-12-02 17:16:44 +01:00
|
|
|
} // namespace dsp
|
|
|
|
} // namespace villas
|