add CCDeque.{remove_*;update_*}

functions added:
CCDeque.remove_back
CCDeque.remove_front
CCDeque.update_back
CCDeque.update_front
This commit is contained in:
Fardale 2019-10-25 11:56:41 +02:00 committed by Simon Cruanes
parent a33963c335
commit 509dacb96f
2 changed files with 105 additions and 0 deletions

View file

@ -233,6 +233,95 @@ let take_front d = match take_front_opt d with
| None -> raise Empty | None -> raise Empty
| Some x -> x | 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 iter f d =
let rec iter f ~first n = let rec iter f ~first n =
begin match n.cell with begin match n.cell with

View file

@ -57,6 +57,14 @@ val peek_back_opt : 'a t -> 'a option
(** Last value. (** Last value.
@since NEXT_RELEASE *) @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 val take_back : 'a t -> 'a
(** Take last value. (** Take last value.
@raise Empty if empty. *) @raise Empty if empty. *)
@ -73,6 +81,14 @@ val take_front_opt : 'a t -> 'a option
(** Take first value. (** Take first value.
@since NEXT_RELEASE *) @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 val append_front : into:'a t -> 'a t -> unit
(** [append_front ~into q] adds all elements of [q] at the front (** [append_front ~into q] adds all elements of [q] at the front
of [into]. of [into].