IVGCVSW-863 Move clamp, for_each, foldl to misc/utility.h

Also, improve for_each, foldl, and related changes.

Change-Id: I0cf0c7dbf88f26bb70cc734ba9fb5725d405585f
Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/114014
Reviewed-by: Anthony Barbier <anthony.barbier@arm.com>
Reviewed-by: Georgios Pinitas <georgios.pinitas@arm.com>
Tested-by: Jenkins <bsgcomp@arm.com>
diff --git a/arm_compute/core/Helpers.h b/arm_compute/core/Helpers.h
index c02f14a..3575fcf 100644
--- a/arm_compute/core/Helpers.h
+++ b/arm_compute/core/Helpers.h
@@ -253,72 +253,6 @@
  */
 inline uint8_t pixel_area_c1u8_clamp(const uint8_t *first_pixel_ptr, size_t stride, size_t width, size_t height, float wr, float hr, int x, int y);
 
-/** Performs clamping among a lower and upper value.
- *
- * @param[in] n     Value to clamp.
- * @param[in] lower Lower threshold.
- * @param[in] upper Upper threshold.
- *
- *  @return Clamped value.
- */
-template <typename T>
-inline T clamp(const T &n, const T &lower, const T &upper)
-{
-    return std::max(lower, std::min(n, upper));
-}
-
-/** Base case of for_each. Does nothing. */
-template <typename F>
-inline void for_each(F &&)
-{
-}
-
-/** Call the function for each of the arguments
- *
- * @param[in] func Function to be called
- * @param[in] arg  Argument passed to the function
- * @param[in] args Remaining arguments
- */
-template <typename F, typename T, typename... Ts>
-inline void for_each(F &&func, T &&arg, Ts &&... args)
-{
-    func(arg);
-    for_each(func, args...);
-}
-
-/** Base case of foldl.
- *
- * @return value.
- */
-template <typename F, typename T>
-inline T foldl(F &&, const T &value)
-{
-    return value;
-}
-
-/** Base case of foldl.
- *
- * @return Function evaluation for value1 and value2
- */
-template <typename F, typename T, typename U>
-inline auto foldl(F &&func, T &&value1, U &&value2) -> decltype(func(value1, value2))
-{
-    return func(value1, value2);
-}
-
-/** Fold left.
- *
- * @param[in] func    Function to be called
- * @param[in] initial Initial value
- * @param[in] value   Argument passed to the function
- * @param[in] values  Remaining arguments
- */
-template <typename F, typename I, typename T, typename... Vs>
-inline I foldl(F &&func, I &&initial, T &&value, Vs &&... values)
-{
-    return foldl(std::forward<F>(func), func(std::forward<I>(initial), std::forward<T>(value)), std::forward<Vs>(values)...);
-}
-
 /** Iterator updated by @ref execute_window_loop for each window element */
 class Iterator
 {
@@ -408,7 +342,7 @@
 {
     bool window_changed = false;
 
-    for_each([&](const IAccessWindow & w)
+    utility::for_each([&](const IAccessWindow & w)
     {
         window_changed |= w.update_window_if_needed(win);
     },
@@ -416,7 +350,7 @@
 
     bool padding_changed = false;
 
-    for_each([&](const IAccessWindow & w)
+    utility::for_each([&](const IAccessWindow & w)
     {
         padding_changed |= w.update_padding_if_needed(win);
     },
@@ -464,7 +398,7 @@
  * @return Intersection of all regions.
  */
 template <typename... Ts>
-ValidRegion intersect_valid_regions(Ts &&... regions)
+ValidRegion intersect_valid_regions(const Ts &... regions)
 {
     auto intersect = [](const ValidRegion & r1, const ValidRegion & r2) -> ValidRegion
     {
@@ -483,7 +417,7 @@
         return region;
     };
 
-    return foldl(intersect, std::forward<Ts>(regions)...);
+    return utility::foldl(intersect, regions...);
 }
 
 /** Create a strides object based on the provided strides and the tensor dimensions.
diff --git a/arm_compute/core/Helpers.inl b/arm_compute/core/Helpers.inl
index 3672692..4121fb1 100644
--- a/arm_compute/core/Helpers.inl
+++ b/arm_compute/core/Helpers.inl
@@ -80,17 +80,12 @@
     template <typename T, typename... Ts>
     static void unroll(T &&it, Ts &&... iterators)
     {
-        it.increment(dimension);
-        IncrementIterators<dimension>::unroll<Ts...>(std::forward<Ts>(iterators)...);
+        auto increment = [](T && it)
+        {
+            it.increment(dimension);
+        };
+        utility::for_each(increment, std::forward<T>(it), std::forward<Ts>(iterators)...);
     }
-
-    template <typename T>
-    static void unroll(T &&it)
-    {
-        it.increment(dimension);
-        // End of recursion
-    }
-
     static void unroll()
     {
         // End of recursion
diff --git a/arm_compute/core/utils/misc/utility.h b/arm_compute/core/utils/misc/utility.h
index 898d0cd..45b3b52 100644
--- a/arm_compute/core/utils/misc/utility.h
+++ b/arm_compute/core/utils/misc/utility.h
@@ -67,6 +67,62 @@
 {
     return detail::make_array(first, index_sequence_t<N> {});
 }
-} // namespace misc
+
+/** Performs clamping among a lower and upper value.
+ *
+ * @param[in] n     Value to clamp.
+ * @param[in] lower Lower threshold.
+ * @param[in] upper Upper threshold.
+ *
+ *  @return Clamped value.
+ */
+template <typename T>
+inline T clamp(const T &n, const T &lower, const T &upper)
+{
+    return std::max(lower, std::min(n, upper));
+}
+
+/** Base case of for_each. Does nothing. */
+template <typename F>
+inline void for_each(F &&)
+{
+}
+
+/** Call the function for each of the arguments
+ *
+ * @param[in] func Function to be called
+ * @param[in] arg  Argument passed to the function
+ * @param[in] args Remaining arguments
+ */
+template <typename F, typename T, typename... Ts>
+inline void for_each(F &&func, T &&arg, Ts &&... args)
+{
+    func(std::forward<T>(arg));
+    for_each(std::forward<F>(func), std::forward<Ts>(args)...);
+}
+
+/** Base case of foldl.
+ *
+ * @return value.
+ */
+template <typename F, typename T>
+inline T &&foldl(F &&, T &&value)
+{
+    return std::forward<T>(value);
+}
+
+/** Fold left.
+ *
+ * @param[in] func    Function to be called
+ * @param[in] initial Initial value
+ * @param[in] value   Argument passed to the function
+ * @param[in] values  Remaining arguments
+ */
+template <typename F, typename T, typename U, typename... Us>
+inline auto foldl(F &&func, T &&initial, U &&value, Us &&... values) -> decltype(func(std::forward<T>(initial), std::forward<U>(value)))
+{
+    return foldl(std::forward<F>(func), func(std::forward<T>(initial), std::forward<U>(value)), std::forward<Us>(values)...);
+}
+} // namespace utility
 } // namespace arm_compute
 #endif /* __ARM_COMPUTE_MISC_UTILITY_H__ */
diff --git a/arm_compute/graph/nodes/BranchLayer.h b/arm_compute/graph/nodes/BranchLayer.h
index dd05315..5e4a8d9 100644
--- a/arm_compute/graph/nodes/BranchLayer.h
+++ b/arm_compute/graph/nodes/BranchLayer.h
@@ -31,7 +31,7 @@
 #include "arm_compute/graph/SubTensor.h"
 #include "arm_compute/graph/Types.h"
 
-#include "arm_compute/core/Helpers.h"
+#include "arm_compute/core/utils/misc/utility.h"
 
 #include <vector>
 
@@ -58,7 +58,7 @@
         _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph1)));
         _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph2)));
 
-        for_each([&](SubGraph & sub_graph)
+        utility::for_each([&](SubGraph && sub_graph)
         {
             _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph)));
         },