Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add CCVector.resize_with and CCVector.resize_with_init, tests and doc #389

Merged
merged 4 commits into from
Oct 21, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/core/CCVector.ml
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,46 @@ let push v x =
let v = of_list [1;2;3] in push v 4; to_list v = [1;2;3;4]
*)

let resize_with v f size =
if size > Sys.max_array_length then
invalid_arg "vec.resize_with: size too big"
else if size > Array.length v.vec then
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still not correct, this will not work if, say, v.size = 5 but Array.length v.vec = 10 when we want to resize to 8.

I think it's simpler to call the function to ensure capacity is >= size, and then add missing elements.

let new_vec = Array.make size (f 0) in
Array.blit v.vec 0 new_vec 0 (v.size - 1);
for i = v.size to size - 1 do
Array.unsafe_set new_vec i (f i)
done;
v.vec <- new_vec;
v.size <- size

(*$T
let v = make 1 0 in to_list (resize_with v (fun i -> i) 5) = [0;1;2;3;4]
let v = make 1 0 in length (resize_with v (fun i -> i) 5) = 5

let v = make 5 0 in to_list (resize_with v (fun i -> i) 5) = [0;0;0;0;0]
let v = make 5 0 in to_list (resize_with v (fun i -> i) 6) = [0;0;0;0;0;6]
let v = make 5 0 in to_list (resize_with v (fun i -> i) -1) = [0;0;0;0;0]
let v = make 5 0 in length (resize_with v (fun i -> i) 5) = 5
*)

let resize_with_init v ~init size =
if size > Sys.max_array_length then
invalid_arg "vec.resize_with_init: size too big"
else if size > Array.length v.vec then
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, this doesn't do anything in case v.vec is big enough but v.size < size.

let new_vec = Array.make size init in
Array.blit v.vec 0 new_vec 0 (v.size - 1);
v.vec <- new_vec;
v.size <- size

(*$T
let v = make 1 0 in to_list (resize_with_init v ~init:1 5) = [1;1;1;1;1]
let v = make 1 0 in length (resize_with_init v ~init:1 5) = 5
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need some tests to cover the case mentioned above :)


let v = make 5 0 in to_list (resize_with_init v ~init:1 5) = [1;1;1;1;1]
let v = make 5 0 in to_list (resize_with_init v ~init:1 -1) = [1;1;1;1;1]
let v = make 5 0 in length (resize_with_init v ~init:1 5) = 5
*)

(** Add all elements of b to a *)
let append a b =
if array_is_empty_ a then (
Expand Down
18 changes: 18 additions & 0 deletions src/core/CCVector.mli
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,24 @@ val is_empty : ('a, _) t -> bool
val push : ('a, rw) t -> 'a -> unit
(** Add an element at the end of the vector. *)

val resize_with : ('a, rw) t -> (int -> 'a) -> int -> unit
(** [resize_with vec f size] resizes vector [vec] up to [size], fills vector
with calls to [f] on indexes [[vec.size-1.. size - 1]].
The contents and size of vec are untouched if [size] is inferior or equal
to [length vec].
@raise Invalid_argument if the size is too big

@since NEXT_RELEASE *)

val resize_with_init : ('a, rw) t -> init:'a -> int -> unit
(** [resize_with_init vec init size] resizes vector [vec] up to [size],
fills vector with calls to [init] on indexes [[length vec -1.. size - 1]].
The contents and size of vec are untouched if [size] is inferior or equal
to [length vec].
@raise Invalid_argument if the size is too big

@since NEXT_RELEASE *)

val append : ('a, rw) t -> ('a, _) t -> unit
(** [append a b] adds all elements of b to a. *)

Expand Down