mirror of
https://github.com/RGBCube/serenity
synced 2025-07-28 08:07:44 +00:00
AK+Kernel+LibELF: Remove the need for IteratorDecision::Continue
By constraining two implementations, the compiler will select the best fitting one. All this will require is duplicating the implementation and simplifying for the `void` case. This constraining also informs both the caller and compiler by passing the callback parameter types as part of the constraint (e.g.: `IterationFunction<int>`). Some `for_each` functions in LibELF only take functions which return `void`. This is a minimal correctness check, as it removes one way for a function to incompletely do something. There seems to be a possible idiom where inside a lambda, a `return;` is the same as `continue;` in a for-loop.
This commit is contained in:
parent
bbaa463032
commit
aa4d41fe2c
25 changed files with 311 additions and 127 deletions
|
@ -6,6 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/IterationDecision.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
|
||||
namespace AK::Concepts {
|
||||
|
@ -27,6 +28,27 @@ concept Signed = IsSigned<T>;
|
|||
template<typename T>
|
||||
concept Unsigned = IsUnsigned<T>;
|
||||
|
||||
template<typename T, typename U>
|
||||
concept SameAs = IsSame<T, U>;
|
||||
|
||||
template<typename Func, typename... Args>
|
||||
concept VoidFunction = requires(Func func, Args... args)
|
||||
{
|
||||
{
|
||||
func(args...)
|
||||
}
|
||||
->SameAs<void>;
|
||||
};
|
||||
|
||||
template<typename Func, typename... Args>
|
||||
concept IteratorFunction = requires(Func func, Args... args)
|
||||
{
|
||||
{
|
||||
func(args...)
|
||||
}
|
||||
->SameAs<IterationDecision>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -36,7 +58,9 @@ concept Unsigned = IsUnsigned<T>;
|
|||
using AK::Concepts::Arithmetic;
|
||||
using AK::Concepts::FloatingPoint;
|
||||
using AK::Concepts::Integral;
|
||||
using AK::Concepts::IteratorFunction;
|
||||
using AK::Concepts::Signed;
|
||||
using AK::Concepts::Unsigned;
|
||||
using AK::Concepts::VoidFunction;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/Concepts.h>
|
||||
#include <AK/Types.h>
|
||||
|
||||
namespace AK {
|
||||
|
@ -112,7 +113,7 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
template<IteratorFunction<T&> F>
|
||||
IterationDecision for_each(F func) const
|
||||
{
|
||||
for (T* node = m_head; node; node = node->next()) {
|
||||
|
@ -123,6 +124,13 @@ public:
|
|||
return IterationDecision::Continue;
|
||||
}
|
||||
|
||||
template<VoidFunction<T&> F>
|
||||
void for_each(F func) const
|
||||
{
|
||||
for (T* node = m_head; node; node = node->next())
|
||||
func(*node);
|
||||
}
|
||||
|
||||
using Iterator = InlineLinkedListIterator<T>;
|
||||
friend Iterator;
|
||||
Iterator begin() { return Iterator(m_head); }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue