Import Debian changes 20180207-1
[hcoop/debian/mlton.git] / basis-library / real / pack-real.sml
CommitLineData
7f918cf1
CE
1(* Copyright (C) 2017 Matthew Fluet.
2 * Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh
3 * Jagannathan, and Stephen Weeks.
4 * Copyright (C) 1997-2000 NEC Research Institute.
5 *
6 * MLton is released under a BSD-style license.
7 * See the file MLton-LICENSE for details.
8 *)
9
10functor PackRealArg (S: sig
11 type real
12 type word
13 val subArr: Word8.word array * SeqIndex.int -> word
14 val subVec: Word8.word vector * SeqIndex.int -> word
15 val update: Word8.word array * SeqIndex.int * word -> unit
16 val bswap: word -> word
17 val castFromWord: word -> real
18 val castToWord: real -> word
19 end) =
20struct
21
22open S
23
24val subArrRev = castFromWord o bswap o subArr
25val subVecRev = castFromWord o bswap o subVec
26fun updateRev (a, i, r) = update (a, i, bswap (castToWord r))
27
28val subArr = castFromWord o subArr
29val subVec = castFromWord o subVec
30val update = fn (a, i, r) => update (a, i, castToWord r)
31
32end
33
34structure PackReal32Arg =
35 PackRealArg (open Primitive.PackReal32
36 open Primitive.PackWord32
37 val bswap = Word32.bswap)
38structure PackReal64Arg =
39 PackRealArg (open Primitive.PackReal64
40 open Primitive.PackWord64
41 val bswap = Word64.bswap)
42structure PackRealArg =
43 struct
44 type real = Real.real
45 local
46 structure S =
47 Real_ChooseRealN
48 (type 'a t = int
49 val fReal32 = Real32.realSize
50 val fReal64 = Real64.realSize)
51 in
52 val realSize = S.f
53 end
54 local
55 structure S =
56 Real_ChooseRealN
57 (type 'a t = Word8.word array * SeqIndex.int -> 'a
58 val fReal32 = PackReal32Arg.subArr
59 val fReal64 = PackReal64Arg.subArr)
60 in
61 val subArr = S.f
62 end
63 local
64 structure S =
65 Real_ChooseRealN
66 (type 'a t = Word8.word vector * SeqIndex.int -> 'a
67 val fReal32 = PackReal32Arg.subVec
68 val fReal64 = PackReal64Arg.subVec)
69 in
70 val subVec = S.f
71 end
72 local
73 structure S =
74 Real_ChooseRealN
75 (type 'a t = Word8.word array * SeqIndex.int * 'a -> unit
76 val fReal32 = PackReal32Arg.update
77 val fReal64 = PackReal64Arg.update)
78 in
79 val update = S.f
80 end
81 local
82 structure S =
83 Real_ChooseRealN
84 (type 'a t = Word8.word array * SeqIndex.int -> 'a
85 val fReal32 = PackReal32Arg.subArrRev
86 val fReal64 = PackReal64Arg.subArrRev)
87 in
88 val subArrRev = S.f
89 end
90 local
91 structure S =
92 Real_ChooseRealN
93 (type 'a t = Word8.word vector * SeqIndex.int -> 'a
94 val fReal32 = PackReal32Arg.subVecRev
95 val fReal64 = PackReal64Arg.subVecRev)
96 in
97 val subVecRev = S.f
98 end
99 local
100 structure S =
101 Real_ChooseRealN
102 (type 'a t = Word8.word array * SeqIndex.int * 'a -> unit
103 val fReal32 = PackReal32Arg.updateRev
104 val fReal64 = PackReal64Arg.updateRev)
105 in
106 val updateRev = S.f
107 end
108 end
109structure PackLargeRealArg =
110 struct
111 type real = LargeReal.real
112 local
113 structure S =
114 LargeReal_ChooseRealN
115 (type 'a t = int
116 val fReal32 = Real32.realSize
117 val fReal64 = Real64.realSize)
118 in
119 val realSize = S.f
120 end
121 local
122 structure S =
123 LargeReal_ChooseRealN
124 (type 'a t = Word8.word array * SeqIndex.int -> 'a
125 val fReal32 = PackReal32Arg.subArr
126 val fReal64 = PackReal64Arg.subArr)
127 in
128 val subArr = S.f
129 end
130 local
131 structure S =
132 LargeReal_ChooseRealN
133 (type 'a t = Word8.word vector * SeqIndex.int -> 'a
134 val fReal32 = PackReal32Arg.subVec
135 val fReal64 = PackReal64Arg.subVec)
136 in
137 val subVec = S.f
138 end
139 local
140 structure S =
141 LargeReal_ChooseRealN
142 (type 'a t = Word8.word array * SeqIndex.int * 'a -> unit
143 val fReal32 = PackReal32Arg.update
144 val fReal64 = PackReal64Arg.update)
145 in
146 val update = S.f
147 end
148 local
149 structure S =
150 LargeReal_ChooseRealN
151 (type 'a t = Word8.word array * SeqIndex.int -> 'a
152 val fReal32 = PackReal32Arg.subArrRev
153 val fReal64 = PackReal64Arg.subArrRev)
154 in
155 val subArrRev = S.f
156 end
157 local
158 structure S =
159 LargeReal_ChooseRealN
160 (type 'a t = Word8.word vector * SeqIndex.int -> 'a
161 val fReal32 = PackReal32Arg.subVecRev
162 val fReal64 = PackReal64Arg.subVecRev)
163 in
164 val subVecRev = S.f
165 end
166 local
167 structure S =
168 LargeReal_ChooseRealN
169 (type 'a t = Word8.word array * SeqIndex.int * 'a -> unit
170 val fReal32 = PackReal32Arg.updateRev
171 val fReal64 = PackReal64Arg.updateRev)
172 in
173 val updateRev = S.f
174 end
175 end
176
177functor PackReal (S: sig
178 type real
179 val realSize: int
180 val isBigEndian: bool
181 val subArr: Word8.word array * SeqIndex.int -> real
182 val subVec: Word8.word vector * SeqIndex.int -> real
183 val update: Word8.word array * SeqIndex.int * real -> unit
184 val subArrRev: Word8.word array * SeqIndex.int -> real
185 val subVecRev: Word8.word vector * SeqIndex.int -> real
186 val updateRev: Word8.word array * SeqIndex.int * real -> unit
187 end): PACK_REAL_EXTRA =
188struct
189
190open S
191
192val bytesPerElem = Int.div (realSize, 8)
193
194fun offset (i, n) =
195 let
196 val i' = Int.* (bytesPerElem, i)
197 val () =
198 if Primitive.Controls.safe
199 andalso (Int.geu (Int.+ (i', Int.- (bytesPerElem, 1)), n))
200 then raise Subscript
201 else ()
202 in
203 SeqIndex.fromInt i
204 end
205 handle Overflow => raise Subscript
206
207
208val (subA, subV, updA) =
209 if isBigEndian = Primitive.MLton.Platform.Arch.hostIsBigEndian
210 then (subArr, subVec, update)
211 else (subArrRev, subVecRev, updateRev)
212
213fun update (a, i, r) =
214 let
215 val i = offset (i, Word8Array.length a)
216 val a = Word8Array.toPoly a
217 in
218 updA (a, i, r)
219 end
220
221fun unsafeUpdate (a, i, r) =
222 let
223 val i = SeqIndex.fromInt i
224 val a = Word8Array.toPoly a
225 in
226 updA (a, i, r)
227 end
228
229local
230 fun make (sub, length, toPoly) (av, i) =
231 let
232 val i = offset (i, length av)
233 in
234 sub (toPoly av, i)
235 end
236in
237 val subArr = make (subA, Word8Array.length, Word8Array.toPoly)
238 val subVec = make (subV, Word8Vector.length, Word8Vector.toPoly)
239end
240
241local
242 fun make (sub, length, toPoly) (av, i) =
243 let
244 val i = SeqIndex.fromInt i
245 in
246 sub (toPoly av, i)
247 end
248in
249 val unsafeSubArr = make (subA, Word8Array.length, Word8Array.toPoly)
250 val unsafeSubVec = make (subV, Word8Vector.length, Word8Vector.toPoly)
251end
252
253fun toBytes (r: real): Word8Vector.vector =
254 let
255 val a = Array.alloc bytesPerElem
256 in
257 (updA (a, 0, r)
258 ; Word8Vector.fromPoly (Array.vector a))
259 end
260
261fun fromBytes v = subVec (v, 0)
262
263end
264
265structure PackReal32Big: PACK_REAL_EXTRA =
266 PackReal (open Real32
267 open PackReal32Arg
268 val isBigEndian = true)
269structure PackReal32Little: PACK_REAL_EXTRA =
270 PackReal (open Real32
271 open PackReal32Arg
272 val isBigEndian = false)
273structure PackReal32Host: PACK_REAL_EXTRA =
274 PackReal (open Real32
275 open PackReal32Arg
276 val isBigEndian = Primitive.MLton.Platform.Arch.hostIsBigEndian)
277structure PackReal64Big: PACK_REAL_EXTRA =
278 PackReal (open Real64
279 open PackReal64Arg
280 val isBigEndian = true)
281structure PackReal64Little: PACK_REAL_EXTRA =
282 PackReal (open Real64
283 open PackReal64Arg
284 val isBigEndian = false)
285structure PackReal64Host: PACK_REAL_EXTRA =
286 PackReal (open Real64
287 open PackReal64Arg
288 val isBigEndian = Primitive.MLton.Platform.Arch.hostIsBigEndian)
289structure PackRealBig: PACK_REAL_EXTRA =
290 PackReal (open Real
291 open PackRealArg
292 val isBigEndian = true)
293structure PackRealLittle: PACK_REAL_EXTRA =
294 PackReal (open Real
295 open PackRealArg
296 val isBigEndian = false)
297structure PackRealHost: PACK_REAL_EXTRA =
298 PackReal (open Real
299 open PackRealArg
300 val isBigEndian = Primitive.MLton.Platform.Arch.hostIsBigEndian)
301structure PackLargeRealBig: PACK_REAL_EXTRA =
302 PackReal (open LargeReal
303 open PackLargeRealArg
304 val isBigEndian = true)
305structure PackLargeRealLittle: PACK_REAL_EXTRA =
306 PackReal (open LargeReal
307 open PackLargeRealArg
308 val isBigEndian = false)
309structure PackLargeRealHost: PACK_REAL_EXTRA =
310 PackReal (open LargeReal
311 open PackLargeRealArg
312 val isBigEndian = Primitive.MLton.Platform.Arch.hostIsBigEndian)