@@ -139,6 +139,18 @@ let make (n:int) : 'a t =
139139 already does it *)
140140 Array. make (n+ 1 ) (null:elt )
141141
142+ let make_some (n :int ) (v :'a ) : 'a t =
143+ if n < 0 then invalid_arg " Nullable_array.make_some" ;
144+ let a = Array. make (n+ 1 ) (Obj. magic (Sys. opaque_identity v) : elt) in
145+ Array. unsafe_set a 0 null;
146+ a
147+
148+ let init_some (n :int ) (f :int -> 'a ) : 'a t =
149+ if n < 0 then invalid_arg " Nullable_array.init_some" ;
150+ Array. init (n+ 1 ) (function
151+ | 0 -> (null:elt )
152+ | i -> (Obj. magic (f (i-1 )) : elt))
153+
142154let empty_array : 'a t = [| null |]
143155
144156let get_null (a :'a t ) : elt =
@@ -171,6 +183,10 @@ let set_some (a:'a t) (n:int) (v:'a) : unit =
171183 if n < 0 then invalid_arg " Nullable_array.set_some" ;
172184 set_elt (a:'a t ) (n+ 1 ) (Obj. magic v : elt )
173185
186+ let fill_some (a :'a t ) (pos :int ) (len :int ) (v :'a ) : unit =
187+ let v = (Sys. opaque_identity (Obj. magic v : elt )) in
188+ Array. fill a (pos+ 1 ) len v
189+
174190let clear (a :'a t ) (n :int ) : unit =
175191 if n < 0 then invalid_arg " Nullable_array.clear" ;
176192 let null = get_null a in
@@ -196,6 +212,49 @@ let iteri ~(some:int -> 'a -> unit) ~(none:int -> unit) (a:'a t) : unit =
196212 done
197213[@@ ocaml.inline]
198214
215+ let map_some (f :'a -> 'b ) (from :'a t ) : 'b t =
216+ let null = get_null from in
217+ let len = Array. length from in
218+ let to_ = Array. make len null in
219+ for i = 1 to len - 1 do
220+ let elt = Array. unsafe_get from i in
221+ if elt != null then
222+ let elt' : elt = Obj. magic (f (Obj. magic elt:'a )) in
223+ unsafe_set_elt to_ i elt'
224+ done ;
225+ to_
226+
227+ let mapi_some (f :int -> 'a -> 'b ) (from :'a t ) : 'b t =
228+ let null = get_null from in
229+ let len = Array. length from in
230+ let to_ = Array. make len null in
231+ for i = 1 to len - 1 do
232+ let elt = Array. unsafe_get from i in
233+ if elt != null then
234+ let elt' : elt = Obj. magic (f (i-1 ) (Obj. magic elt:'a )) in
235+ unsafe_set_elt to_ i elt'
236+ done ;
237+ to_
238+
239+ let unsafe_sub (a :'a t ) (pos :int ) (len :int ) : 'a t =
240+ if pos = 0 then
241+ (* Let the runtime copy the null element *)
242+ Array. sub a pos (len+ 1 )
243+ else
244+ (* Include an extra element at the start of the new array,
245+ then set it to [null]. *)
246+ let res = Array. sub a (pos-1 ) (len+ 1 ) in
247+ unsafe_set_elt res 0 (get_null a);
248+ res
249+
250+ let sub (a :'a t ) (pos :int ) (len :int ) : 'a t =
251+ if pos < 0 || len < 0 || pos > length a - len
252+ then invalid_arg " Nullable_array.sub"
253+ else unsafe_sub a pos len
254+
255+ let copy (a :'a t ) : 'a t =
256+ unsafe_sub a 0 (length a)
257+
199258let unsafe_manual_blit (from :'a t ) (from_start :int ) (to_ :'a t ) (to_start :int ) (len :int ) =
200259 let null_from = get_null from in
201260 let null_to = get_null to_ in
@@ -224,6 +283,17 @@ let blit (from:'a t) (from_start:int) (to_:'a t) (to_start:int) (len:int) =
224283 (unsafe_manual_blit [@ inlined never]) from from_start to_ to_start len
225284 end
226285
286+ let of_array (a :'a array ) : 'a t =
287+ init_some (Array. length a) (fun i -> Array. unsafe_get a i)
288+
289+ let of_list (l :'a list ) : 'a t =
290+ let a = make (List. length l) in
291+ let rec fill i = function
292+ | [] -> a
293+ | x :: xs -> unsafe_set_elt a i (Obj. magic x : elt ); fill (i+ 1 ) xs
294+ in
295+ fill 1 l
296+
227297let equal (a1 :'a t ) (a2 :'a t ) ~(equal :'a -> 'a -> bool ) =
228298 length a1 = length a2 &&
229299 let null1 = get_null a1 in
@@ -247,6 +317,8 @@ let equal (a1:'a t) (a2:'a t) ~(equal:'a -> 'a -> bool) =
247317 in
248318 loop (length a1)
249319
320+ let max_length = Sys. max_array_length - 1
321+
250322(* Unsafe functions *)
251323
252324let unsafe_get_some (a :'a t ) (n :int ) : 'a =
0 commit comments