File 3215-Add-delete_with-delete_with_r-to-the-queue-module.patch of Package erlang

From c54720eaa52d3c12c2a49ab0aa4950589b2b0b80 Mon Sep 17 00:00:00 2001
From: Maria-12648430 <maria-12648430@gmx.net>
Date: Wed, 25 Nov 2020 10:05:36 +0100
Subject: [PATCH 5/5] Add delete_with/delete_with_r to the queue module

---
 lib/stdlib/doc/src/queue.xml    | 28 +++++++++++-
 lib/stdlib/src/queue.erl        | 75 ++++++++++++++++++++++++++++++++-
 lib/stdlib/test/queue_SUITE.erl | 12 ++++++
 3 files changed, 112 insertions(+), 3 deletions(-)

diff --git a/lib/stdlib/doc/src/queue.xml b/lib/stdlib/doc/src/queue.xml
index 9d353fb856..08320f4ec4 100644
--- a/lib/stdlib/doc/src/queue.xml
+++ b/lib/stdlib/doc/src/queue.xml
@@ -57,6 +57,8 @@
       <seealso marker="#any/2"><c>any/2</c></seealso>,
       <seealso marker="#delete/2"><c>delete/2</c></seealso>,
       <seealso marker="#delete_r/2"><c>delete_r/2</c></seealso>,
+      <seealso marker="#delete_with/2"><c>delete_with/2</c></seealso>,
+      <seealso marker="#delete_with_r/2"><c>delete_with_r/2</c></seealso>,
       <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>,
@@ -147,7 +149,7 @@
       <desc>
         <p>Returns a copy of <c><anno>Q1</anno></c> where the first item
           matching <c><anno>Item</anno></c> is deleted, if there is such an
-          element.</p>
+          item.</p>
       </desc>
     </func>
 
@@ -157,7 +159,29 @@
       <desc>
         <p>Returns a copy of <c><anno>Q1</anno></c> where the last item
           matching <c><anno>Item</anno></c> is deleted, if there is such an
-          element.</p>
+          item.</p>
+      </desc>
+    </func>
+
+    <func>
+      <name name="delete_with" arity="2"/>
+      <fsummary>Delete an item matching a predicate from the front of a
+        queue.</fsummary>
+      <desc>
+        <p>Returns a copy of <c><anno>Q1</anno></c> where the first item
+          for which <c><anno>Pred</anno></c> returns <c>true</c> is deleted,
+          if there is such an item.</p>
+      </desc>
+    </func>
+
+    <func>
+      <name name="delete_with_r" arity="2"/>
+      <fsummary>Delete an item matching a predicate from the rear of a
+        queue.</fsummary>
+      <desc>
+        <p>Returns a copy of <c><anno>Q1</anno></c> where the last item
+          for which <c><anno>Pred</anno></c> returns <c>true</c> is deleted,
+          if there is such an item.</p>
       </desc>
     </func>
 
diff --git a/lib/stdlib/src/queue.erl b/lib/stdlib/src/queue.erl
index 2447f68946..2bbffcc753 100644
--- a/lib/stdlib/src/queue.erl
+++ b/lib/stdlib/src/queue.erl
@@ -28,7 +28,7 @@
 
 %% Higher level API
 -export([reverse/1,join/2,split/2,filter/2,filtermap/2,fold/3,any/2,all/2,
-	 delete/2,delete_r/2]).
+	 delete/2,delete_r/2,delete_with/2,delete_with_r/2]).
 
 %% Okasaki API from klacke
 -export([cons/2,head/1,tail/1,
@@ -541,6 +541,79 @@ delete_rear(Item, [X|Rest]) ->
 delete_rear(_, []) ->
     false.
 
+%% Delete the first occurence of an item in the queue
+%% matching a predicate, according to queue order.
+%%
+%% O(len(Q1)) worst case
+-spec delete_with(Pred, Q1) -> Q2 when
+      Pred :: fun((Item) -> boolean()),
+      Q1 :: queue(Item),
+      Q2 :: queue(Item),
+      Item :: term().
+delete_with(Pred, {R0, F0} = Q) when is_function(Pred, 1), is_list(R0), is_list(F0) ->
+    case delete_with_front(Pred, F0) of
+	false ->
+	    case delete_with_rear(Pred, R0) of
+		false ->
+		    Q;
+		[] ->
+		    f2r(F0);
+		R1 ->
+		    {R1, F0}
+	    end;
+	[] ->
+	    r2f(R0);
+	F1 ->
+	    {R0, F1}
+    end;
+delete_with(Pred, Q) ->
+    erlang:error(badarg, [Pred, Q]).
+
+%% Delete the last occurence of an item in the queue
+%% matching a predicate, according to queue order.
+%%
+%% O(len(Q1)) worst case
+-spec delete_with_r(Pred, Q1) -> Q2 when
+      Pred :: fun((Item) -> boolean()),
+      Q1 :: queue(Item),
+      Q2 :: queue(Item),
+      Item :: term().
+delete_with_r(Pred, {R0, F0}) when is_function(Pred, 1), is_list(R0), is_list(F0) ->
+    {F1, R1} = delete_with(Pred, {F0, R0}),
+    {R1, F1};
+delete_with_r(Pred, Q) ->
+    erlang:error(badarg, [Pred, Q]).
+
+delete_with_front(Pred, [X|Rest]) ->
+    case Pred(X) of
+	true ->
+	    Rest;
+	false ->
+	    case delete_with_front(Pred, Rest) of
+		false ->
+		    false;
+		F ->
+		    [X|F]
+	    end
+    end;
+delete_with_front(_, []) ->
+    false.
+
+delete_with_rear(Pred, [X|Rest]) ->
+    case delete_with_rear(Pred, Rest) of
+	false ->
+	    case Pred(X) of
+		true ->
+		    Rest;
+		false ->
+		    false
+	    end;
+	R ->
+	    [X|R]
+    end;
+delete_with_rear(_, []) ->
+    false.
+
 %%--------------------------------------------------------------------------
 %% 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 71af5fcf2d..9623e08f04 100644
--- a/lib/stdlib/test/queue_SUITE.erl
+++ b/lib/stdlib/test/queue_SUITE.erl
@@ -412,6 +412,18 @@ do_op_test(F) ->
     [1,3] = queue:to_list(queue:delete_r(x, queue:from_list([1,x,3]))),
     [1,2] = queue:to_list(queue:delete_r(x, queue:from_list([1,2,x]))),
     [x,1,2] = queue:to_list(queue:delete_r(x, queue:from_list([x,1,2,x]))),
+    [] = queue:to_list(queue:delete_with(fun(_) -> false end, queue:new())),
+    [1,2,3] = queue:to_list(queue:delete_with(fun(X) -> X<0 end, queue:from_list([1,2,3]))),
+    [2,3] = queue:to_list(queue:delete_with(fun(X) -> X>0 end, queue:from_list([1,2,3]))),
+    [1,3] = queue:to_list(queue:delete_with(fun(X) -> X>1 end, queue:from_list([1,2,3]))),
+    [1,2] = queue:to_list(queue:delete_with(fun(X) -> X>2 end, queue:from_list([1,2,3]))),
+    [1,2,3] = queue:to_list(queue:delete_with(fun(X) -> X>1 end, queue:from_list([1,2,2,3]))),
+    [] = queue:to_list(queue:delete_with_r(fun(_) -> false end, queue:new())),
+    [1,2,3] = queue:to_list(queue:delete_with_r(fun(X) -> X>9 end, queue:from_list([1,2,3]))),
+    [1,2] = queue:to_list(queue:delete_with_r(fun(X) -> X<9 end, queue:from_list([1,2,3]))),
+    [1,3] = queue:to_list(queue:delete_with_r(fun(X) -> X<3 end, queue:from_list([1,2,3]))),
+    [2,3] = queue:to_list(queue:delete_with_r(fun(X) -> X<2 end, queue:from_list([1,2,3]))),
+    [1,2,3] = queue:to_list(queue:delete_with_r(fun(X) -> X<3 end, queue:from_list([1,2,2,3]))),
     %%
     ok.
 
-- 
2.26.2

openSUSE Build Service is sponsored by