From bc181cc0eed08adb7acc4185612abb24f471fce7 Mon Sep 17 00:00:00 2001
From: Sebanisu <peeceseven@gmail.com>
Date: Mon, 22 Mar 2021 10:15:01 -0400
Subject: [PATCH 1/5] use for, (void) and std::as_const

https://godbolt.org/z/W1oM15Evj
I just made some test code things appear to still work.

For loop can iterate and check the condition in the same line.

https://blog.codeisc.com/2018/01/09/cpp-comma-operator-nice-usages.html
https://blog.codeisc.com/2017/12/26/cpp-comma-operator-introduction.html
https://stackoverflow.com/questions/39514765/the-void-the-comma-operator-operator-and-the-impossible-overloading
https://youtu.be/AqDsso3S5fg?t=276
(void), comma operator can be overloaded. So you need to cast to void to force using the built-in comma operator.

https://stackoverflow.com/questions/5853833/casting-non-const-to-const-in-c
https://en.cppreference.com/w/cpp/utility/as_const
I was worried that a pred could mutate the values as there was nothing to prevent this. As the Iterator needs to be mutable so you can iterate. The thing it points too may or may not be const. So someone could write a pred that mutates. Same with Op for transform. You don't want to mutate the incoming just the out going value.
---
 src/aal/algorithm.hpp | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/aal/algorithm.hpp b/src/aal/algorithm.hpp
index 6ef2553..2288260 100644
--- a/src/aal/algorithm.hpp
+++ b/src/aal/algorithm.hpp
@@ -1,15 +1,16 @@
 #pragma once
 #include <tuple>
+#include <utility>
 
 namespace aal {
 namespace var {
 
 template <typename I, typename... Is, typename P>
 [[nodiscard]] constexpr auto
-find(P const pred, I f, I const l, Is... fs) {
-    while (f != l) {
-        if (pred(*f, *fs...)) break;
-        ++f, (++fs, ...);
+find(P const pred, I f, I const l, Is... fs)
+{
+    for (;f != l;(void)++f, ((void)++fs, ...)) {
+        if (pred(std::as_const(*f), std::as_const(*fs)...)) break;
     }
     return std::tuple{f, fs...};
 }
@@ -24,9 +25,8 @@ any_of(P const pred, I f, I const l, Is... fs) {
 template <typename I, typename... Is, typename O, typename Op>
 constexpr auto
 transform(Op const op, O o, I f, I const l, Is... fs) {
-    while (f != l) {
-        *o = op(*f, *fs...);
-        ++o, ++f, (++fs, ...);
+    for (;f != l;(void)++o, (void)++f, ((void)++fs, ...)) {
+        *o = op(std::as_const(*f), std::as_const(*fs)...);
     }
     return o;
 }

From 8a7b74f55aca68bc707a6760092a572093936f91 Mon Sep 17 00:00:00 2001
From: Sebanisu <peeceseven@gmail.com>
Date: Mon, 22 Mar 2021 10:49:17 -0400
Subject: [PATCH 2/5] Update algorithm.hpp

Since the comma operator takes 2 parameters you don't need to cast all of them to void but at least 1.  I'm being safe and since each one is called left to right and each call is it's own group of 2 I'm casting (void) on all but the first one.
https://stackoverflow.com/questions/38357089/why-does-stdtransform-and-similar-cast-the-for-loop-increment-to-void
---
 src/aal/algorithm.hpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/aal/algorithm.hpp b/src/aal/algorithm.hpp
index 2288260..b63ac14 100644
--- a/src/aal/algorithm.hpp
+++ b/src/aal/algorithm.hpp
@@ -9,7 +9,7 @@ template <typename I, typename... Is, typename P>
 [[nodiscard]] constexpr auto
 find(P const pred, I f, I const l, Is... fs)
 {
-    for (;f != l;(void)++f, ((void)++fs, ...)) {
+    for (;f != l;++f, ((void)++fs, ...)) {
         if (pred(std::as_const(*f), std::as_const(*fs)...)) break;
     }
     return std::tuple{f, fs...};
@@ -25,7 +25,7 @@ any_of(P const pred, I f, I const l, Is... fs) {
 template <typename I, typename... Is, typename O, typename Op>
 constexpr auto
 transform(Op const op, O o, I f, I const l, Is... fs) {
-    for (;f != l;(void)++o, (void)++f, ((void)++fs, ...)) {
+    for (;f != l;++o, (void)++f, ((void)++fs, ...)) {
         *o = op(std::as_const(*f), std::as_const(*fs)...);
     }
     return o;

From 72d3b0db8e84ac1b0a6cb53dbca2f92f27f76906 Mon Sep 17 00:00:00 2001
From: Robert Russell <peeceseven@gmail.com>
Date: Tue, 23 Mar 2021 04:31:55 -0400
Subject: [PATCH 3/5] Remove as const

---
 src/aal/algorithm.hpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/aal/algorithm.hpp b/src/aal/algorithm.hpp
index b63ac14..bc5ae06 100644
--- a/src/aal/algorithm.hpp
+++ b/src/aal/algorithm.hpp
@@ -10,7 +10,7 @@ template <typename I, typename... Is, typename P>
 find(P const pred, I f, I const l, Is... fs)
 {
     for (;f != l;++f, ((void)++fs, ...)) {
-        if (pred(std::as_const(*f), std::as_const(*fs)...)) break;
+        if (pred(*f, *fs...)) break;
     }
     return std::tuple{f, fs...};
 }
@@ -26,7 +26,7 @@ template <typename I, typename... Is, typename O, typename Op>
 constexpr auto
 transform(Op const op, O o, I f, I const l, Is... fs) {
     for (;f != l;++o, (void)++f, ((void)++fs, ...)) {
-        *o = op(std::as_const(*f), std::as_const(*fs)...);
+        *o = op(*f, *fs...);
     }
     return o;
 }

From cd8fff46f22a365fa25d6f581d9dcbe96b2a1d95 Mon Sep 17 00:00:00 2001
From: Robert Russell <peeceseven@gmail.com>
Date: Mon, 21 Jun 2021 13:24:18 -0400
Subject: [PATCH 4/5] remove const from Op and pred.

I found that mutable lambda's can't be passed to the algorithms with const.
fixes: https://github.com/codereport/An-Algorithm-Library/issues/13
---
 src/aal/algorithm.hpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/aal/algorithm.hpp b/src/aal/algorithm.hpp
index bc5ae06..9325630 100644
--- a/src/aal/algorithm.hpp
+++ b/src/aal/algorithm.hpp
@@ -7,7 +7,7 @@ namespace var {
 
 template <typename I, typename... Is, typename P>
 [[nodiscard]] constexpr auto
-find(P const pred, I f, I const l, Is... fs)
+find(P pred, I f, I const l, Is... fs)
 {
     for (;f != l;++f, ((void)++fs, ...)) {
         if (pred(*f, *fs...)) break;
@@ -17,14 +17,14 @@ find(P const pred, I f, I const l, Is... fs)
 
 template <typename I, typename... Is, typename P>
 [[nodiscard]] constexpr auto
-any_of(P const pred, I f, I const l, Is... fs) {
+any_of(P pred, I f, I const l, Is... fs) {
     auto const t = find(pred, f, l, fs...);
     return std::get<0>(t) != l;
 }
 
 template <typename I, typename... Is, typename O, typename Op>
 constexpr auto
-transform(Op const op, O o, I f, I const l, Is... fs) {
+transform(Op op, O o, I f, I const l, Is... fs) {
     for (;f != l;++o, (void)++f, ((void)++fs, ...)) {
         *o = op(*f, *fs...);
     }

From 702869d0c34a74d2138eccf2c556f4c3d7b27c99 Mon Sep 17 00:00:00 2001
From: Robert Russell <peeceseven@gmail.com>
Date: Mon, 21 Jun 2021 14:14:16 -0400
Subject: [PATCH 5/5] I think forwarding for any_of is correct here.

I only didn't forward the end iterator. As we use it again for return.

https://www.godbolt.org/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAM1QDsCBlZAQwBtMQBGAFlJvoCqAZ0wAFAB4gA5AAYppAFZdSrZrVDIApACYAQjt2kR7ZATx1KmWugDCqVgFcAtrRDbSV9ABk8tTADlnACNMYi4AdlIAB1QhQnNaO0cXZRi4szofP0CnELDOd2NMUwSGAmZiAiTnV0LMEwzaMoqCLIDg0IijcsrqlM5ulracvK5tAEojVAdiZA4pHQBmX2RHLABqTUWbCuJmAE8t7E0ZAEEllbXMTe3zIQJiTGYnI5Pz7WXaVYcNrZsCBxRdivM4ETBOIHMME3f77KJWZ7XACSpHWBDhCKcmAAdLj1kihKj0fDaIj1qIQecAKz6Gm0DB4IQsYjoTRUgAibPZ6zQtHumHEUWI62YDiI6yovnQEFE6yFmHQqKREqVPLo93WrCVQlx2IlQnGm3C%2BjO6wlJHWEC2ugl6zAYC23NY1s2egMVFRUAAbqg8OhxgZ3YT1rrxobNMa3mazXgqJb5dKAFQe9bJnW4sPrIKPZgAa2tUaNnNN60eAOItHW93QIBAAKBmAjuhTVHT2IjnMWJvO4WL51B4Mh0L%2BxMxyKJGNJWN1%2BODo6n1wpi2OZzZtN09PwTIqrI5XLVfLBguFovFan2AH1UFQZToAGz3uWPRX4%2B%2BPlPK3karWzt/aO8zq24aRiWp6oAeGoEDc3KStYEDVrWNDEAA7jufxLtgEAJpMVYEDWIBIahLJ/EiRzUDhWqFtG1E0bRZoIQRJBEay2wEmRQGhgWJZljMlYMcAmAEH8MhkQQhr2o6mpcT2fZvGCEKqMO2zzmSKJopOiIzgSE4kmSADyOljuselRJSX5HkKIpiuBDxqEISFOBAJnrKgUSonpLmqh%2BEFQT%2BBKAQaRrdmaSGWi6cYSYsTouoGeioJ6Pp%2BgGbp6Cm3q%2Bv6sXNsGobAcF0aJuBkmuRAyaommnFdoWHaFjxFYudJNVnL4UFOMwvgQHlhYMbsBxZtBQUyKiAzrO46yLDVVUlj1xB7PsPIDU2vDrFSqJ3qi4STfl5lWeKrCLTSXIQGBM5eoaAC0RxZqg9hBaWgm8ZaEBetBklUsBNgRjYIYZjFvbSWaO1gZq2gHbS7LHdZp0XVdQQ3ftTb3eWlbeq9UWjR9X0/diAZdkWAMirQl7XhAP5BNiITAB1OHk54nWosgFOYFTtCdbj%2BXnleN6sGN5OU9TqK03BOGM/zrNho1vZSJMrDSFS8iuLI8ioNIn0pTaQjTLM1xLJw8gENIchhqQuYgNwizYuEVIAJzhNbnAFNo4ScFS3AyOtstSNwCuG8r0jyEIIBDQbSuTHAsAwIgKCoBCeDsGQFAQGgsfxyAwBCKSURCAgqAEHwcdgsQgcQEEvukEEvgVPsZfJ1i9B6bQrDV0rpBYG16jsGX%2BCPCUXqYIHLcCsUYrzHI5D0PUZesHg2ZV3YWBlw8eBONIeuTPwjAsJ3PB8HQBDCGIkgt0oAyqOoKBZSoM%2BB5AkyuY0A/ndWjrALQDhZdoMjrOdelj0UJQWAgJ4PorgBieGGB0fI0RYjxDoCA1IMDGgQNyJ0AY/9GjNF6PYGoyh0GlB6K0Xw7QUFQPuC0eBaCCHINGJwSYmsZhzC4DLOWPsW4qykOIAAHHec6d5uDrGAMgZAloHgOFoLmQ0EBcCEAtLrVEdgU6hFdIsWh6w1b6D0PrX2xtTZUiGp7b2pAV7aGttiTh/5uB8M/uY7gJjLGkEVmPdhAcg6kBDkbUg4co7TAIFEMU5BKDJyiHHVBHh8BECgRvJgbAOA7w3gfCQZdkJ7CiKvaWKgWEOLLuwvSYo/FQWvOsLhPC%2BECKESI4gYiJGWgUcE%2BOyjaFaNDpMBATwsBhHpgY%2BQK9wgyGxJwcIiwqRDLtgMqkvTVqOL9lIFxwdtGTF0QBbQbtrGcPCOEbQnD7Ge0WKwpx/s3HzIyVIbQezplNKNpMPuRcEhmyAA
---
 src/aal/algorithm.hpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/aal/algorithm.hpp b/src/aal/algorithm.hpp
index 9325630..02520d8 100644
--- a/src/aal/algorithm.hpp
+++ b/src/aal/algorithm.hpp
@@ -17,8 +17,9 @@ find(P pred, I f, I const l, Is... fs)
 
 template <typename I, typename... Is, typename P>
 [[nodiscard]] constexpr auto
-any_of(P pred, I f, I const l, Is... fs) {
-    auto const t = find(pred, f, l, fs...);
+any_of(P&& pred, I&& f, I const l, Is&&... fs) {
+    auto const t = find(std::forward<P>(pred), std::forward<I>(f), l,
+                      std::forward<Is>(fs)...);
     return std::get<0>(t) != l;
 }
 
