12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849(* The following code is taken from the library [sek] by Arthur Charguéraud
and François Pottier. *)(** [blit_circularly_dst a1 i1 a2 i2 k] copies [k] elements from the array
[a1], starting at index [i1], to the array [a2], starting at index [i2].
The destination array is regarded as circular, so it is permitted for the
destination range to wrap around. *)letblit_circularly_dsta1i1a2i2k=(* The source range must be well-formed. *)assert(0<=k&&0<=i1&&i1+k<=Array.lengtha1);(* The destination array must be large enough to hold the data. *)letn2=Array.lengtha2inassert(k<=n2);(* The destination index must be well-formed. *)assert(0<=i2&&i2<n2);(* We need either one or two blits. *)ifi2+k<=n2thenArray.blita1i1a2i2kelseletk1=n2-i2inassert(0<k1&&k1<k);Array.blita1i1a2i2k1;Array.blita1(i1+k1)a20(k-k1)(** [blit_circularly a1 i1 a2 i2 k] copies [k] elements from the array [a1],
starting at index [i1], to the array [a2], starting at index [i2]. Both
the source array and the destination array are regarded as circular, so
it is permitted for the source range or destination range to wrap around.
[i1] must be comprised between 0 included and [Array.length a1] excluded.
[i2] must be comprised between 0 included and [Array.length a2] excluded.
[k] must be comprised between 0 included and [Array.length a2] included. *)letblit_circularlya1i1a2i2k=letn1=Array.lengtha1in(* The source range must be well-formed. *)assert(0<=i1&&i1<n1);assert(0<=k);(* The destination array must be large enough to hold the data. *)letn2=Array.lengtha2inassert(k<=n2);(* The destination index must be well-formed. *)assert(0<=i2&&i2<n2);(* We need either one or two calls to [blit_circularly_dst]. *)ifi1+k<=n1thenblit_circularly_dsta1i1a2i2kelseletk1=n1-i1inassert(0<k1&&k1<k);blit_circularly_dsta1i1a2i2k1;leti2=i2+k1inleti2=ifi2<n2theni2elsei2-n2inblit_circularly_dsta10a2i2(k-k1)