123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173(** Standard type for [blit] functions, and reusable code for validating [blit]
arguments. *)open!Import(** If [blit : (src, dst) blit], then [blit ~src ~src_pos ~len ~dst ~dst_pos] blits [len]
values from [src] starting at position [src_pos] to [dst] at position [dst_pos].
Furthermore, [blit] raises if [src_pos], [len], and [dst_pos] don't specify valid
slices of [src] and [dst]. *)type('src,'dst)blit=src:'src->src_pos:int->dst:'dst->dst_pos:int->len:int->unit(** [blito] is like [blit], except that the [src_pos], [src_len], and [dst_pos] are
optional (hence the "o" in "blito"). Also, we use [src_len] rather than [len] as a
reminder that if [src_len] isn't supplied, then the default is to take the slice
running from [src_pos] to the end of [src]. *)type('src,'dst)blito=src:'src->?src_pos:int(** default is [0] *)->?src_len:int(** default is [length src - src_pos] *)->dst:'dst->?dst_pos:int(** default is [0] *)->unit->unit(** If [sub : (src, dst) sub], then [sub ~src ~pos ~len] returns a sequence of type [dst]
containing [len] characters of [src] starting at [pos].
[subo] is like [sub], except [pos] and [len] are optional. *)type('src,'dst)sub='src->pos:int->len:int->'dsttype('src,'dst)subo=?pos:int(** default is [0] *)->?len:int(** default is [length src - pos] *)->'src->'dst(*_ These are not implemented less-general-in-terms-of-more-general because odoc produces
unreadable documentation in that case, with or without [inline] on [include]. *)moduletypeS=sigtypetvalblit:(t,t)blitvalblito:(t,t)blitovalunsafe_blit:(t,t)blitvalsub:(t,t)subvalsubo:(t,t)suboendmoduletypeS1=sigtype'atvalblit:('at,'at)blitvalblito:('at,'at)blitovalunsafe_blit:('at,'at)blitvalsub:('at,'at)subvalsubo:('at,'at)suboendmoduletypeS_distinct=sigtypesrctypedstvalblit:(src,dst)blitvalblito:(src,dst)blitovalunsafe_blit:(src,dst)blitvalsub:(src,dst)subvalsubo:(src,dst)suboendmoduletypeS1_distinct=sigtype'asrctype'adstvalblit:(_src,_dst)blitvalblito:(_src,_dst)blitovalunsafe_blit:(_src,_dst)blitvalsub:(_src,_dst)subvalsubo:(_src,_dst)suboendmoduletypeS_to_string=sigtypetvalsub:(t,string)subvalsubo:(t,string)suboend(** Users of modules matching the blit signatures [S], [S1], and [S1_distinct] only need
to understand the code above. The code below is only for those that need to implement
modules that match those signatures. *)moduletypeSequence=sigtypetvallength:t->intendtype'apoly='amoduletypeSequence1=sigtype'at(** [Make1*] guarantees to only call [create_like ~len t] with [len > 0] if [length t >
0]. *)valcreate_like:len:int->'at->'atvallength:_t->intvalunsafe_blit:('at,'at)blitendmoduletypeBlit=sigtypenonrec('src,'dst)blit=('src,'dst)blittypenonrec('src,'dst)blito=('src,'dst)blitotypenonrec('src,'dst)sub=('src,'dst)subtypenonrec('src,'dst)subo=('src,'dst)subomoduletypeS=SmoduletypeS1=S1moduletypeS_distinct=S_distinctmoduletypeS1_distinct=S1_distinctmoduletypeS_to_string=S_to_stringmoduletypeSequence=SequencemoduletypeSequence1=Sequence1(** There are various [Make*] functors that turn an [unsafe_blit] function into a [blit]
function. The functors differ in whether the sequence type is monomorphic or
polymorphic, and whether the src and dst types are distinct or are the same.
The blit functions make sure the slices are valid and then call [unsafe_blit]. They
guarantee at a call [unsafe_blit ~src ~src_pos ~dst ~dst_pos ~len] that:
{[
len > 0
&& src_pos >= 0
&& src_pos + len <= get_src_len src
&& dst_pos >= 0
&& dst_pos + len <= get_dst_len dst
]}
The [Make*] functors also automatically create unit tests. *)(** [Make] is for blitting between two values of the same monomorphic type. *)moduleMake(Sequence:sigincludeSequencevalcreate:len:int->tvalunsafe_blit:(t,t)blitend):Swithtypet:=Sequence.t(** [Make_distinct] is for blitting between values of distinct monomorphic types. *)moduleMake_distinct(Src:Sequence)(Dst:sigincludeSequencevalcreate:len:int->tvalunsafe_blit:(Src.t,t)blitend):S_distinctwithtypesrc:=Src.twithtypedst:=Dst.tmoduleMake_to_string(T:sigtypetend)(To_bytes:S_distinctwithtypesrc:=T.twithtypedst:=bytes):S_to_stringwithtypet:=T.t(** [Make1] is for blitting between two values of the same polymorphic type. *)moduleMake1(Sequence:Sequence1):S1withtype'at:='aSequence.t(** [Make1_generic] is for blitting between two values of the same container type that's
not fully polymorphic (in the sense of Container.Generic). *)moduleMake1_generic(Sequence:Sequence1):S1withtype'at:='aSequence.tend