From 509dacb96fcc511ebbf7991dd7dfcd9feac9ebf5 Mon Sep 17 00:00:00 2001 From: Fardale Date: Fri, 25 Oct 2019 11:56:41 +0200 Subject: [PATCH] add CCDeque.{remove_*;update_*} functions added: CCDeque.remove_back CCDeque.remove_front CCDeque.update_back CCDeque.update_front --- src/data/CCDeque.ml | 89 ++++++++++++++++++++++++++++++++++++++++++++ src/data/CCDeque.mli | 16 ++++++++ 2 files changed, 105 insertions(+) diff --git a/src/data/CCDeque.ml b/src/data/CCDeque.ml index abc47aca..45b8901a 100644 --- a/src/data/CCDeque.ml +++ b/src/data/CCDeque.ml @@ -233,6 +233,95 @@ let take_front d = match take_front_opt d with | None -> raise Empty | Some x -> x +let remove_back d = ignore (take_back_opt d) + +(*$T remove_back + let q = of_list [1;2;3;4;5;6;7] in remove_back q; to_list q = [1;2;3;4;5;6] +*) + +let remove_front d = ignore (take_front_opt d) + +(*$T remove_front + let q = of_list [1;2;3;4;5;6;7] in remove_front q; to_list q = [2;3;4;5;6;7] +*) + +let update_front d f = + match d.cur.cell with + | Zero -> () + | One x -> + begin match f x with + | None -> if Stdlib.(!=) d.cur.prev d.cur then ( + d.cur.prev.next <- d.cur.next; + d.cur.next.prev <- d.cur.prev; + d.cur <- d.cur.next; + ) + else d.cur.cell <- Zero + | Some x -> d.cur.cell <- One x + end + | Two (x, y) -> + begin match f x with + | None -> d.cur.cell <- One (y) + | Some x -> d.cur.cell <- Two (x,y) + end + | Three (x,y,z) -> + match f x with + | None -> d.cur.cell <- Two (y,z) + | Some x -> d.cur.cell <- Three (x,y,z) + +(*$T update_front + let q = of_list [1;2;3;4;5;6;7] in update_front q (fun _ -> None); to_list q = [2;3;4;5;6;7] + let q = of_list [1;2;3;4;5;6;7] in update_front q (fun _ -> Some 9); to_list q = [9;2;3;4;5;6;7] +*) +(*$Q update_front + Q.(list int) (fun l -> \ + let q = of_list l in \ + update_front q (fun _ -> None); \ + let output_list = if l = [] then [] else List.tl l in \ + to_list q = output_list) + Q.(list int) (fun l -> \ + let q = of_list l in \ + update_front q (fun x -> Some (x + 42)); \ + let output_list = if l = [] then [] else List.((hd l + 42)::(tl l)) in \ + to_list q = output_list) +*) + +let update_back d f = + let n = d.cur.prev in + match n.cell with + | Zero -> () + | One x -> + begin match f x with + | None -> if Stdlib.(!=) d.cur.prev d.cur then remove_node_ n + else n.cell <- Zero + | Some x -> n.cell <- One x + end + | Two (x, y) -> + begin match f y with + | None -> n.cell <- One (x) + | Some y -> n.cell <- Two (x,y) + end + | Three (x,y,z) -> + match f z with + | None -> n.cell <- Two (x,y) + | Some z -> n.cell <- Three (x,y,z) + +(*$T update_back + let q = of_list [1;2;3;4;5;6;7] in update_back q (fun _ -> None); to_list q = [1;2;3;4;5;6] + let q = of_list [1;2;3;4;5;6;7] in update_back q (fun _ -> Some 9); to_list q = [1;2;3;4;5;6;9] +*) +(*$Q update_back + Q.(list int) (fun l -> \ + let q = of_list l in \ + update_back q (fun _ -> None); \ + let output_list = if l = [] then [] else List.(rev l |> tl) in \ + (to_list q |> List.rev) = output_list) + Q.(list int) (fun l -> \ + let q = of_list l in \ + update_back q (fun x -> Some (x + 42)); \ + let output_list = if l = [] then [] else List.(rev l |> fun l -> (hd l + 42)::(tl l)) in \ + (to_list q |> List.rev) = output_list) +*) + let iter f d = let rec iter f ~first n = begin match n.cell with diff --git a/src/data/CCDeque.mli b/src/data/CCDeque.mli index 4769a60b..beb34b47 100644 --- a/src/data/CCDeque.mli +++ b/src/data/CCDeque.mli @@ -57,6 +57,14 @@ val peek_back_opt : 'a t -> 'a option (** Last value. @since NEXT_RELEASE *) +val remove_back : 'a t -> unit +(** Remove last value. If the deque is empty do nothing + @since NEXT_RELEASE *) + +val remove_front : 'a t -> unit +(** Remove first value. If the deque is empty do nothing + @since NEXT_RELEASE *) + val take_back : 'a t -> 'a (** Take last value. @raise Empty if empty. *) @@ -73,6 +81,14 @@ val take_front_opt : 'a t -> 'a option (** Take first value. @since NEXT_RELEASE *) +val update_back : 'a t -> ('a -> 'a option) -> unit +(** Update last value. If the deque is empty do nothing. + @since NEXT_RELEASE *) + +val update_front : 'a t -> ('a -> 'a option) -> unit +(** Update first value. If the deque is empty do nothing. + @since NEXT_RELEASE *) + val append_front : into:'a t -> 'a t -> unit (** [append_front ~into q] adds all elements of [q] at the front of [into].