File 3203-Add-a-filtermap-function-to-the-queue-module.patch of Package erlang

From 496e490de24cece137b9adb543c390f9e7703e45 Mon Sep 17 00:00:00 2001
From: Maria-12648430 <maria-12648430@gmx.net>
Date: Mon, 26 Oct 2020 09:53:04 +0100
Subject: [PATCH 3/3] Add a filtermap function to the queue module

---
 lib/stdlib/doc/src/queue.xml    | 16 ++++++++++++++
 lib/stdlib/src/queue.erl        | 38 ++++++++++++++++++++++++++++++++-
 lib/stdlib/test/queue_SUITE.erl |  8 +++++++
 3 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/lib/stdlib/doc/src/queue.xml b/lib/stdlib/doc/src/queue.xml
index cd92547268..98971b1f4e 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
       <seealso marker="#filter/2"><c>filter/2</c></seealso>,
+      <seealso marker="#filtermap/2"><c>filtermap/2</c></seealso>,
       <seealso marker="#fold/3"><c>fold/3</c></seealso>,
       <seealso marker="#join/2"><c>join/2</c></seealso>,
       <seealso marker="#len/1"><c>len/1</c></seealso>,
@@ -135,6 +136,21 @@
       </desc>
     </func>
 
+    <func>
+      <name name="filtermap" arity="2"/>
+      <fsummary>Filter and map a queue.</fsummary>
+      <desc>
+        <p>Returns a queue <c><anno>Q2</anno></c> that is the result of calling
+          <c><anno>Fun</anno>(<anno>Item</anno>)</c> on all items in
+          <c><anno>Q1</anno></c>, in order from front to rear.</p>
+        <p>If <c><anno>Fun</anno>(<anno>Item</anno>)</c> returns <c>true</c>,
+          <c>Item</c> is copied to the result queue. If it returns <c>false</c>,
+          <c><anno>Item</anno></c> is not copied. If it returns
+          <c>{true, NewItem}</c>, the queue element at this position is replaced
+          with <c>NewItem</c> in the result queue.</p>
+      </desc>
+    </func>
+
     <func>
       <name name="fold" arity="3"/>
       <fsummary>Fold a function over a queue.</fsummary>
diff --git a/lib/stdlib/src/queue.erl b/lib/stdlib/src/queue.erl
index 9a132f0330..06c8ae51df 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,fold/3]).
+-export([reverse/1,join/2,split/2,filter/2,filtermap/2,fold/3]).
 
 %% Okasaki API from klacke
 -export([cons/2,head/1,tail/1,
@@ -402,6 +402,42 @@ filter_r(Fun, [X|R0]) ->
 	    lists:reverse(L, R)
     end.
 
+%% Filter and map a queue, traverses in queue order.
+%%
+%% O(len(Q1))
+-spec filtermap(Fun, Q1) -> Q2 when
+      Fun :: fun((Item) -> boolean() | {'true', Value}),
+      Q1 :: queue(Item),
+      Q2 :: queue(Item | Value),
+      Item :: term(),
+      Value :: term().
+filtermap(Fun, {R0, F0}) when is_function(Fun, 1), is_list(R0), is_list(F0) ->
+    F = lists:filtermap(Fun, F0),
+    R = filtermap_r(Fun, R0),
+    if R =:= [] ->
+	    f2r(F);
+       F =:= [] ->
+	    r2f(R);
+       true ->
+	    {R,F}
+    end;
+filtermap(Fun, Q) ->
+    erlang:error(badarg, [Fun,Q]).
+
+%% Call Fun in reverse order, i.e tail to head
+filtermap_r(_, []) ->
+    [];
+filtermap_r(Fun, [X|R0]) ->
+    R = filtermap_r(Fun, R0),
+    case Fun(X) of
+	true ->
+	    [X|R];
+	{true, Y} ->
+	    [Y|R];
+	false ->
+	    R
+    end.
+
 %% Fold a function over a queue, in queue order.
 %%
 %% O(len(Q))
diff --git a/lib/stdlib/test/queue_SUITE.erl b/lib/stdlib/test/queue_SUITE.erl
index c85dd14278..f2bad3c3b8 100644
--- a/lib/stdlib/test/queue_SUITE.erl
+++ b/lib/stdlib/test/queue_SUITE.erl
@@ -373,6 +373,14 @@ do_op_test(F) ->
 					    (_) -> [] end, MyQ4)),
     [33,44] = queue:to_list(queue:filter(fun(X) when X < 27 -> false;
 					    (X) -> [X] end, MyQ4)),
+    [11,22*22,33*33] = queue:to_list(queue:filtermap(fun(X) when X < 17 -> true;
+							(X) when X > 37 -> false;
+							(X) -> {true, X*X}
+						     end, MyQ4)),
+    [22*22,33*33,44] = queue:to_list(queue:filtermap(fun(X) when X < 17 -> false;
+							(X) when X > 37 -> true;
+							(X) -> {true, X*X}
+						     end, MyQ4)),
     FoldQ = queue:from_list(L1),
     FoldExp1 = lists:sum(L1),
     FoldAct1 = queue:fold(fun(X,A) -> X+A end, 0, FoldQ),
-- 
2.26.2

openSUSE Build Service is sponsored by