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 1 commit
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
46 changes: 46 additions & 0 deletions src/core/CCVector.ml
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,52 @@ 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
failwith "vec.resize_with: size too big"

Choose a reason for hiding this comment

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

Invalid_argument ?

Copy link
Owner

Choose a reason for hiding this comment

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

Agreed, invalid_argument "…" is more in line with the rest 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Understood

else if size <= Array.length v.vec then
for i = 0 to v.size - 1 do
Array.unsafe_set v.vec i (f i)
done
else
let new_vec = Array.make size (f 0) in
for i = 0 to size - 1 do
Array.unsafe_set new_vec i (f i)
done;
v.vec <- new_vec;
v.size <- size;
()
Copy link
Owner

Choose a reason for hiding this comment

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

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

The semantics should be, imho, that f is only called for new arguments. In particular, resize_with v f (size v) should not do anything.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got it


(*$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;1;2;3;4]
let v = make 5 0 in to_list (resize_with v (fun i -> i) -1) = [0;1;2;3;4]
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
failwith "vec.resize_with_init: size too big"
else if size <= Array.length v.vec then
for i = 0 to v.size - 1 do
Copy link
Owner

Choose a reason for hiding this comment

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

same remark here, don't touch the existing elements

Array.unsafe_set v.vec i init
done
else
v.vec <- Array.make size init;
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
14 changes: 14 additions & 0 deletions src/core/CCVector.mli
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,20 @@ 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 [[0.. size - 1]].
The contents of [vec] are merely overwritten with calls to [f] if [size]
is inferior or equal to the current size of [vec].
Copy link
Owner

Choose a reason for hiding this comment

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

both the docs could mention @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 value [init].
The contents of [vec] are merely overwritten with [init] if [size]
is inferior or equal to the current size of [vec].
@since NEXT_RELEASE *)

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

Expand Down