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.
6 * MLton is released under a BSD-style license.
7 * See the file MLton-LICENSE for details.
10 (* empty tuple is also a record *)
12 functor Record (S: RECORD_STRUCTS): RECORD =
19 | Record of (Field.t * 'a) vector
25 Tuple v => Vector.mapi (v, fn (i, x) => (Field.Int i, x))
28 fun detupleOpt (r: 'a t): 'a vector option =
34 QuickSort.sortVector (v, fn ((s, _), (s', _)) => Field.<= (s, s'))
38 fun isTuple v : bool =
42 Field.Int i' => Int.equals (i, i')
44 val v = if isSorted then sort v else v
46 if isTuple v andalso Vector.length v <> 1
47 then Tuple (Vector.map (v, #2))
51 fun unzip r = Vector.unzip (toVector r)
52 fun zip z = fromVector (Vector.zip z)
54 val peek: 'a t * Field.t -> 'a option =
58 (case Vector.peek (r, fn (f', _) => Field.equals (f, f')) of
60 | SOME (_, x) => SOME x)
66 if 0 <= i andalso i < Vector.length t
67 then SOME (Vector.sub (t, i))
69 | Field.Symbol _ => NONE)
73 Tuple v => Vector.mapi (v, fn (i, _) => Field.Int i)
74 | Record r => Vector.map (r, #1)
79 | Record r => Vector.map (r, #2)
83 Tuple xs => Vector.exists (xs, p)
84 | Record r => Vector.exists (r, fn (_, x) => p x)
86 fun forall (r, p) = not (exists (r, not o p))
88 fun fold (r: 'a t, b: 'b, f: 'a * 'b -> 'b): 'b =
90 Tuple xs => Vector.fold (xs, b, f)
91 | Record r => Vector.fold (r, b, fn ((_, x), b) => f (x, b))
93 fun map (r: 'a t, f: 'a -> 'b): 'b t =
95 Tuple xs => Tuple (Vector.map (xs, f))
96 | Record r => Record (Vector.map (r, fn (field, a) => (field, f a)))
98 fun foreach (r: 'a t, f: 'a -> unit): unit =
100 Tuple xs => Vector.foreach (xs, f)
101 | Record r => Vector.foreach (r, f o #2)
103 fun change (r: 'a t, f: 'a vector -> 'b vector * 'c): 'b t * 'c =
105 Tuple xs => let val (ys, c) = f xs
108 | Record r => let val (fs, xs) = Vector.unzip r
110 in (Record (Vector.zip (fs, ys)), c)
113 fun layout {record, layoutTuple, separator, extra, layoutElt} =
114 case (record, extra) of
115 (Tuple xs, "") => layoutTuple xs
118 val r = toVector record
121 mayAlign (separateRight (Vector.toListMap