123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139moduletypeElt_sig=sigtypetvalsize:intvalallocate:unit->tendmoduletypeCarray_sig=sigtypet=Bigstringaf.ttypeeltvalt:tRepr.tvalallocate:int->t(** [allocate len] creates a C array of size [len] initialized with zeros. *)valerase:t->int->unit(** [erase p n] fills with zeros the first [n] elements of [p]. *)vallength:t->int(** [length c] returns the length of a C array [c] *)valget:t->int->elt(** [get c i] returns the [i]-th element of a C array [c] *)valset:t->elt->int->unitvalcopy:?offset:int->?len:int->t->t(** [copy c] copies [len] elements from a C array [c] starting from position [offset] *)valblit:t->src_off:int->t->dst_off:int->len:int->unit(** [blit src src_off dst dst_off len] copies [len] elements from [src] to
[dst] starting at the respective offsets. *)valto_array:?offset:int->?len:int->t->eltarray(** [to_array c] converts a C array [c] to an OCaml array *)valof_array:eltarray->t(** [of_array c] converts an OCaml array [c] to a C array *)end(** Note that an unsafe type casting is performed by this module.
USE WITH CARE!
The type of get and set changes with whatever Elt.t is given as input.
This works because Elt also indicates the size in bytes which would be
read/written and because Elt is assumed to be backed by a custom block
(it is accessed with [Data_custom_val]). *)moduleMake(Elt:Elt_sig):Carray_sigwithtypeelt=Elt.t=structtypet=Bigstringaf.ttypeelt=Elt.tmoduleStubs=structexternalget:elt->t->int->int->unit="caml_polynomial_carray_get_stubs"[@@noalloc](** [get elt p i size] copies the [i]-th element of a given array [p] in [elt],
assuming elements of [size] bytes.
- requires: [0 <= i < size p]
- ensures: [elt = p[i]] *)externalset:t->elt->int->int->unit="caml_polynomial_carray_set_stubs"[@@noalloc](** [set p elt i size] copies [elt] in the [i]-th element of [p],
assuming elements of [size] bytes.
- requires: [0 <= i < size p]
- ensures: [elt = p[i]] *)externalmemset_zero:t->int->unit="caml_polynomial_memset_zero_stubs"[@@noalloc](** [memset_zero p n] writes [n] bytes of zeros in [p]
- requires: [n <= size p] *)endlett:tRepr.t=Repr.(mapstring(funs->Bigstringaf.of_string~off:0~len:(String.lengths)s)Bigstringaf.to_string)letlengtha=Bigstringaf.lengtha/Elt.sizeletallocaten=ifn<1thenraise@@Invalid_argument"allocate: size should be >= 1";letsize=Elt.size*ninletres=Bigstringaf.createsizeinStubs.memset_zeroressize;resleterasepn=ifn<0||n>lengthpthenraise@@Invalid_argument"erase: invalid length";Stubs.memset_zerop(Elt.size*n)letgetpi=ifi<0||i>=lengthpthenraise@@Invalid_argument"get: index out of bounds";letres=Elt.allocate()inStubs.getrespiElt.size;resletsetpfri=ifi<0||i>=lengthpthenraise@@Invalid_argument"set: index out of bounds";Stubs.setpfriElt.sizeletto_array?(offset=0)?lenp=letlen=Option.value~default:(lengthp-offset)leniniflen<0||offset<0||lengthp-offset<lenthenraise@@Invalid_argument(Format.sprintf"to_array: invalid len %d or offset %d for size %d"lenoffset(lengthp));Array.initlen(funi->getp(offset+i))letof_arraycaml_array=letn=Array.lengthcaml_arrayinletres=allocateninArray.iteri(funig->setresgi)caml_array;resletblitsrc~src_offdst~dst_off~len=letsrc_off=src_off*Elt.sizeinletdst_off=dst_off*Elt.sizeinletlen=len*Elt.sizeinBigstringaf.blitsrc~src_offdst~dst_off~lenletcopy?(offset=0)?lenp=letlen=Option.value~default:(lengthp-offset)leniniflen<0||offset<0||lengthp-offset<lenthenraise@@Invalid_argument(Format.sprintf"copy: invalid len %d or offset %d for size %d"lenoffset(lengthp));letres=allocateleninblitp~src_off:offsetres~dst_off:0~len;resend