From 9bb280e35321982191c2dce26eaef0ea1b221be6 Mon Sep 17 00:00:00 2001 From: Yotam Barnoy Date: Mon, 21 Feb 2022 18:42:16 +0200 Subject: [PATCH 1/2] CCVector: add insert --- src/core/CCVector.ml | 18 ++++++++++++++++++ src/core/CCVector.mli | 6 ++++++ 2 files changed, 24 insertions(+) diff --git a/src/core/CCVector.ml b/src/core/CCVector.ml index 719ea85e..40e6198a 100644 --- a/src/core/CCVector.ml +++ b/src/core/CCVector.ml @@ -345,6 +345,24 @@ let remove_unordered v i = to_list v1 = (List.sort CCInt.compare (to_list v2))) *) +let insert v i x = + (* Note that we can insert at i=v.size *) + if i < 0 || i > v.size then invalid_arg "CCVector.insert"; + if v.size = Array.length v.vec + then grow_with_ v ~filler:x; + (* Shift the following elements, then put the element at i *) + Array.blit v.vec i v.vec (i+1) (v.size - i); + v.vec.(i) <- x; + v.size <- v.size + 1 + +(*$T + let v = (1 -- 5) in insert v 3 9; to_list v = [1;2;3;9;4;5] + let v = create () in insert v 0 2; to_list v = [2] + let v = (1 -- 3) in remove_and_shift v 1; insert v 1 5; to_list v = [1;5;3] + let v = (1 -- 3) in remove_and_shift v 0; insert v 2 5; to_list v = [2;3;5] + let v = (1 -- 3) in insert v 3 5; to_list v = [1;2;3;5] +*) + let[@inline] append_iter a i = i (fun x -> push a x) let append_seq a seq = Seq.iter (fun x -> push a x) seq diff --git a/src/core/CCVector.mli b/src/core/CCVector.mli index c631a721..08221d73 100644 --- a/src/core/CCVector.mli +++ b/src/core/CCVector.mli @@ -277,6 +277,12 @@ val remove_unordered : ('a, rw) t -> int -> unit (might swap with the last element). See {!remove_and_shift} if you want to keep the ordering. *) +val insert : ('a, rw) t -> int -> 'a -> unit +(** [insert v i x] insert the given element at index i. + Elements at location [i] and later are first shifted over in linear time before inserting [x]. + Preserve the order of elements in [v]. + @since 3.7 *) + val rev : ('a,_) t -> ('a, 'mut) t (** Reverse the vector. *) From 408c14fac7076678bad0239915b109aaa666d75b Mon Sep 17 00:00:00 2001 From: Yotam Barnoy Date: Mon, 21 Feb 2022 18:50:19 +0200 Subject: [PATCH 2/2] CCVector.insert: check if there's a need to blit Co-authored-by: Simon Cruanes --- src/core/CCVector.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/CCVector.ml b/src/core/CCVector.ml index 40e6198a..29f9a01c 100644 --- a/src/core/CCVector.ml +++ b/src/core/CCVector.ml @@ -351,7 +351,7 @@ let insert v i x = if v.size = Array.length v.vec then grow_with_ v ~filler:x; (* Shift the following elements, then put the element at i *) - Array.blit v.vec i v.vec (i+1) (v.size - i); + if i < v.size then Array.blit v.vec i v.vec (i+1) (v.size - i); v.vec.(i) <- x; v.size <- v.size + 1