File 2372-Add-a-fold-function-to-the-queue-module.patch of Package erlang

From 025789ff2e81348ff3891cf836180e6981688c08 Mon Sep 17 00:00:00 2001
From: Maria-12648430 <maria-12648430@gmx.net>
Date: Mon, 26 Oct 2020 09:37:52 +0100
Subject: [PATCH 2/3] Add a fold function to the queue module

A fold function in the queue module removes the need for
a conversion to a list in order to achieve the same.
---
 lib/stdlib/doc/src/queue.xml    | 22 ++++++++++++++++++++++
 lib/stdlib/src/queue.erl        | 17 ++++++++++++++++-
 lib/stdlib/test/queue_SUITE.erl |  7 +++++++
 3 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/lib/stdlib/doc/src/queue.xml b/lib/stdlib/doc/src/queue.xml
index 69b66129fa..cd92547268 100644
--- a/lib/stdlib/doc/src/queue.xml
+++ b/lib/stdlib/doc/src/queue.xml
@@ -54,6 +54,7 @@
 
     <p>All operations have an amortized O(1) running time, except
       <seemfa marker="#filter/2"><c>filter/2</c></seemfa>,
+      <seemfa marker="#fold/3"><c>fold/3</c></seemfa>,
       <seemfa marker="#join/2"><c>join/2</c></seemfa>,
       <seemfa marker="#len/1"><c>len/1</c></seemfa>,
       <seemfa marker="#member/2"><c>member/2</c></seemfa>,
@@ -134,6 +135,27 @@
       </desc>
     </func>
 
+    <func>
+      <name name="fold" arity="3" since=""/>
+      <fsummary>Fold a function over a queue.</fsummary>
+      <desc>
+        <p>Calls <c><anno>Fun</anno>(<anno>Item</anno>, <anno>AccIn</anno>)</c>
+          on successive items <c>Item</c> of <c>Queue</c>, starting
+          with <c><anno>AccIn</anno> == <anno>Acc0</anno></c>. The queue is
+          traversed in queue order, that is, from front to rear.
+          <c><anno>Fun</anno>/2</c> must return a new accumulator, which is
+          passed to the next call. The function returns the final value of
+          the accumulator. <c><anno>Acc0</anno></c> is returned if the queue is
+          empty.</p>
+        <p><em>Example:</em></p>
+        <pre>
+> <input>queue:fold(fun(X, Sum) -> X + Sum end, 0, queue:from_list([1,2,3,4,5])).</input>
+15
+> <input>queue:fold(fun(X, Prod) -> X * Prod end, 1, queue:from_list([1,2,3,4,5])).</input>
+120</pre>
+      </desc>
+    </func>
+
     <func>
       <name name="from_list" arity="1" since=""/>
       <fsummary>Convert a list to a queue.</fsummary>
diff --git a/lib/stdlib/src/queue.erl b/lib/stdlib/src/queue.erl
index 69ecfed94b..9a132f0330 100644
--- a/lib/stdlib/src/queue.erl
+++ b/lib/stdlib/src/queue.erl
@@ -27,7 +27,7 @@
 -export([get/1,get_r/1,peek/1,peek_r/1,drop/1,drop_r/1]).
 
 %% Higher level API
--export([reverse/1,join/2,split/2,filter/2]).
+-export([reverse/1,join/2,split/2,filter/2,fold/3]).
 
 %% Okasaki API from klacke
 -export([cons/2,head/1,tail/1,
@@ -402,6 +402,21 @@ filter_r(Fun, [X|R0]) ->
 	    lists:reverse(L, R)
     end.
 
+%% Fold a function over a queue, in queue order.
+%%
+%% O(len(Q))
+-spec fold(Fun, Acc0, Q :: queue(Item)) -> Acc1 when
+      Fun :: fun((Item, AccIn) -> AccOut),
+      Acc0 :: term(),
+      Acc1 :: term(),
+      AccIn :: term(),
+      AccOut :: term().
+fold(Fun, Acc0, {R, F}) when is_function(Fun, 2), is_list(R), is_list(F) ->
+    Acc1 = lists:foldl(Fun, Acc0, F),
+    lists:foldr(Fun, Acc1, R);
+fold(Fun, Acc0, Q) ->
+    erlang:error(badarg, [Fun, Acc0, Q]).
+
 %%--------------------------------------------------------------------------
 %% Okasaki API inspired by an Erlang user contribution "deque.erl" 
 %% by Claes Wikstrom <klacke@kaja.klacke.net> 1999.
diff --git a/lib/stdlib/test/queue_SUITE.erl b/lib/stdlib/test/queue_SUITE.erl
index 569953dd9f..c85dd14278 100644
--- a/lib/stdlib/test/queue_SUITE.erl
+++ b/lib/stdlib/test/queue_SUITE.erl
@@ -373,6 +373,13 @@ do_op_test(F) ->
 					    (_) -> [] end, MyQ4)),
     [33,44] = queue:to_list(queue:filter(fun(X) when X < 27 -> false;
 					    (X) -> [X] end, MyQ4)),
+    FoldQ = queue:from_list(L1),
+    FoldExp1 = lists:sum(L1),
+    FoldAct1 = queue:fold(fun(X,A) -> X+A end, 0, FoldQ),
+    FoldExp1 = FoldAct1,
+    FoldExp2 = [X*X || X <- L1],
+    FoldAct2 = queue:fold(fun(X,A) -> [X*X|A] end, [], FoldQ),
+    FoldExp2 = lists:reverse(FoldAct2),
     %%
     ok.
 
-- 
2.26.2

openSUSE Build Service is sponsored by