8000 Added forward iterator and begin() and end() functions to MultiDelegate. · dok-net/arduino-esp8266@680abe1 · GitHub
[go: up one dir, main page]

Skip to content

Commit 680abe1

Browse files
committed
Added forward iterator and begin() and end() functions to MultiDelegate.
WIP: remove() during iteration.
1 parent e3888ca commit 680abe1

File tree

1 file changed

+72
-5
lines changed

1 file changed

+72
-5
lines changed

cores/esp8266/MultiDelegate.h

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2121
#ifndef __MULTIDELEGATE_H
2222
#define __MULTIDELEGATE_H
2323

24+
#include <iterator>
2425
#if defined(ESP8266) || defined(ESP32) || !defined(ARDUINO)
2526
#include <atomic>
2627
#else
@@ -216,6 +217,10 @@ namespace delegate
216217
unused = node;
217218
}
218219

220+
void traverse(Node_t*& current) const
221+
{
222+
current = current->mNext;
223+
}
219224
void traverse(Node_t*& prev, Node_t*& current, bool remove = true)
220225
{
221226
if (remove && ISQUEUE)
@@ -248,14 +253,64 @@ namespace delegate
248253
else
249254
{
250255
prev = current;
251-
current = current->mNext;
256+
traverse(current);
252257
}
253258
}
254259

255260
#ifndef ARDUINO
256261
std::mutex mutex_unused;
257262
#endif
258263
public:
264+
class iterator : public std::iterator<std::forward_iterator_tag, Delegate>
265+
{
266+
protected:
267+
MultiDelegatePImpl& multiDel;
268+
Node_t* current = nullptr;
269+
Node_t* const stop = nullptr;
270+
public:
271+
iterator(MultiDelegatePImpl& md) : multiDel(md), current(md.first), stop(md.last) {}
272+
iterator(MultiDelegatePImpl& md, nullptr_t) : multiDel(md) {}
273+
iterator() = default;
274+
iterator(const iterator&) = default;
275+
iterator& operator=(const iterator&) = default;
276+
bool operator==(const iterator& rhs) const
277+
{
278+
return &multiDel == &rhs.multiDel && current == rhs.current;
279+
}
280+
bool operator!=(const iterator& rhs) const {
281+
return !operator==(rhs);
282+
}
283+
const Delegate& operator*() const
284+
{
285+
return current->mDelegate;
286+
}
287+
const Delegate* const operator->() const
288+
{
289+
return &current->mDelegate;
290+
}
291+
iterator& operator++() // prefix
292+
{
293+
if (current && stop != current)
294+
multiDel.traverse(current);
295+
else
296+
current = nullptr; // end
297+
return *this;
298+
}
299+
iterator& operator++(int) // postfix
300+
{
301+
iterator tmp(*this);
302+
operator++();
303+
return tmp;
304+
}
305+
};
306+
307+
iterator begin() const {
308+
return iterator(*this);
309+
}
310+
iterator end() const {
311+
return iterator(*this, nullptr);
312+
}
313+
259314
const Delegate* IRAM_ATTR add(const Delegate& del)
260315
{
261316
return add(Delegate(del));
@@ -372,7 +427,10 @@ namespace delegate
372427
{
373428
done = current == stop;
374429
result = CallP<Delegate, R, ISQUEUE, P...>::execute(current->mDelegate, args...);
375-
traverse(prev, current, result);
430+
if (ISQUEUE)
431+
traverse(prev, current, result);
432+
else
433+
traverse(current);
376434
#if defined(ESP8266) || defined(ESP32)
377435
// running callbacks might last too long for watchdog etc.
378436
optimistic_yield(10000);
@@ -426,7 +484,10 @@ namespace delegate
426484
{
427485
done = current == stop;
428486
result = Call<Delegate, R, ISQUEUE>::execute(current->mDelegate);
429-
this->traverse(prev, current, result);
487+
if (ISQUEUE)
488+
this->traverse(prev, current, result);
489+
else
490+
this->traverse(current);
430491
#if defined(ESP8266) || defined(ESP32)
431492
// running callbacks might last too long for watchdog etc.
432493
optimistic_yield(10000);
@@ -487,7 +548,10 @@ namespace delegate
487548
{
488549
done = current == stop;
489550
CallP<Delegate, void, ISQUEUE, P...>::execute(current->mDelegate, args...);
490-
this->traverse(prev, current);
551+
if (ISQUEUE)
552+
this->traverse(prev, current);
553+
else
554+
traverse(current);
491555
#if defined(ESP8266) || defined(ESP32)
492556
// running callbacks might last too long for watchdog etc.
493557
optimistic_yield(10000);
@@ -531,7 +595,10 @@ namespace delegate
531595
{
532596
done = current == stop;
533597
Call<Delegate, void, ISQUEUE>::execute(current->mDelegate);
534-
this->traverse(prev, current);
598+
if (ISQUEUE)
599+
this->traverse(prev, current);
600+
else
601+
this->traverse(current);
535602
#if defined(ESP8266) || defined(ESP32)
536603
// running callbacks might last too long for watchdog etc.
537604
optimistic_yield(10000);

0 commit comments

Comments
 (0)
0