Skip to content
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
Cannot retrieve contributors at this time
(* SML has optional structures in the basis called PackRealLittle and
* PackRealBig (implementing the PACK_REAL signature) for marshalling and
* unmarshalling real data. While mlton provides these, SML/NJ does not.
* This is an implementation of PACK_REAL for SML/NJ built on top of
* unsafe casting and subscripting. *)
functor PackRealFn(val isBigEndian : bool) : PACK_REAL =
type real = real
val bytesPerElem = 8
val isBigEndian = isBigEndian
structure UR = Unsafe.Real64Array
structure UB = Unsafe.Word8Array
structure A = Word8Array
structure AS = Word8ArraySlice
structure V = Word8Vector
structure VS = Word8VectorSlice
fun rawToBytes x =
let val a : UR.array = Unsafe.cast (RealArray.array (1, x))
in V.tabulate (bytesPerElem, fn i => UB.sub (a, i)) end
fun rawFromBytes (v : V.vector) = UR.sub (Unsafe.cast v, 0)
fun rawToBytes x =
let val a = Real64Array.array (8, x) (* LOOOOOL. *)
in V.tabulate (bytesPerElem, fn i => A.sub (a, i)) end
fun rawFromBytes (v : V.vector) =
let val a = A.tabulate (V.length v, fn i => V.sub (v, i))
in Real64Array.sub (a, 0) end
(* Compare against a known result to determine the system's endianness
* and swap around byte orders if it differs from our intended endianness. *)
val isSystemBigEndian = V.sub (rawToBytes 3.14159265358979323, 0) <> 0wx18
val swizzle = if isBigEndian = isSystemBigEndian then (fn v => v) else
(fn v => V.tabulate (bytesPerElem, fn i => V.sub (v, bytesPerElem-i-1)))
val toBytes = swizzle o rawToBytes
val fromBytes = rawFromBytes o swizzle
fun subVec (v, i) =
fromBytes (VS.vector (VS.slice (v, bytesPerElem*i, SOME bytesPerElem)))
fun subArr (v, i) =
fromBytes (AS.vector (AS.slice (v, bytesPerElem*i, SOME bytesPerElem)))
fun update (v, i, x) = A.copyVec { src = toBytes x, dst = v, di = i*bytesPerElem }
structure PackRealLittle = PackRealFn(val isBigEndian = false)
structure PackReal64Little = PackRealLittle
structure PackRealBig = PackRealFn(val isBigEndian = true)
structure PackReal64Big = PackRealBig