forked from gap-system/gap
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprecord.h
270 lines (226 loc) · 8.42 KB
/
precord.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
/****************************************************************************
**
*W precord.h GAP source Martin Schönert
**
**
*Y Copyright (C) 1996, Lehrstuhl D für Mathematik, RWTH Aachen, Germany
*Y (C) 1998 School Math and Comp. Sci., University of St Andrews, Scotland
*Y Copyright (C) 2002 The GAP Group
**
** This file declares the functions for plain records.
*/
#ifndef GAP_PRECORD_H
#define GAP_PRECORD_H
#include <src/records.h>
/****************************************************************************
**
*F * * * * * * * * * * standard macros for plain records * * * * * * * * * *
*/
/****************************************************************************
**
*F NEW_PREC( <len> ) . . . . . . . . . . . . . . . . make a new plain record
**
** 'NEW_PREC' returns a new plain record with room for <len> components.
** Note that you still have to set the actual length once you have populated
** the record!
*/
extern Obj NEW_PREC(UInt len);
/****************************************************************************
**
*F IS_PREC( <rec> ) . . . . . . . . . check if <rec> is in plain record rep
*/
static inline Int IS_PREC(Obj rec)
{
UInt tnum = TNUM_OBJ(rec);
return tnum == T_PREC || tnum == T_PREC+IMMUTABLE;
}
/****************************************************************************
**
*F IS_PREC_OR_COMOBJ( <list> ) . . . . . . . . . . . . . check type of <rec>
**
** Checks if this is 'PREC'-like.
** This function is used in a GAP_ASSERT checking if calling functions like
** SET_ELM_PREC is acceptable on an Obj.
**
** Unlike IS_PREC, this function also accepts precs which are being copied
** (and hence have the COPYING flag set), as well as component objects
** (which have the same memory layout as precs), as the precs APIs using it
** for assertion checks are in practice invoked on such objects, too.
*/
static inline Int IS_PREC_OR_COMOBJ(Obj rec)
{
UInt tnum = TNUM_OBJ(rec);
#if !defined(USE_THREADSAFE_COPYING)
if (tnum > COPYING)
tnum -= COPYING;
#endif
return tnum == T_PREC || tnum == T_PREC+IMMUTABLE || tnum == T_COMOBJ;
}
/****************************************************************************
**
*F CAPACITY_PREC(<list>) . . . . . . . . . . . . capacity of a plain record
**
** 'CAPACITY_PREC' returns the maximum capacity of a PREC.
**
*/
static inline Int CAPACITY_PREC(Obj rec)
{
return SIZE_OBJ(rec) / (2 * sizeof(Obj)) - 1;
}
/****************************************************************************
**
*F LEN_PREC( <rec> ) . . . . . . . . . number of components of plain record
**
** 'LEN_PREC' returns the number of components of the plain record <rec>.
*/
static inline UInt LEN_PREC(Obj rec)
{
GAP_ASSERT(IS_PREC_OR_COMOBJ(rec));
return ((const UInt *)(CONST_ADDR_OBJ(rec)))[1];
}
/****************************************************************************
**
*F SET_LEN_PREC( <rec> ) . . . . . set number of components of plain record
**
** 'SET_LEN_PREC' sets the number of components of the plain record <rec>.
*/
static inline void SET_LEN_PREC(Obj rec, UInt nr)
{
GAP_ASSERT(IS_PREC_OR_COMOBJ(rec));
((UInt *)(ADDR_OBJ(rec)))[1] = nr;
}
/****************************************************************************
**
*F SET_RNAM_PREC( <rec>, <i>, <rnam> ) . set name of <i>-th record component
**
** 'SET_RNAM_PREC' sets the name of the <i>-th record component of the
** record <rec> to the record name <rnam>.
*/
static inline void SET_RNAM_PREC(Obj rec, UInt i, UInt rnam)
{
GAP_ASSERT(IS_PREC_OR_COMOBJ(rec));
GAP_ASSERT(i <= CAPACITY_PREC(rec));
*(UInt *)(ADDR_OBJ(rec)+2*(i)) = rnam;
}
/****************************************************************************
**
*F GET_RNAM_PREC( <rec>, <i> ) . . . . . . . name of <i>-th record component
**
** 'GET_RNAM_PREC' returns the record name of the <i>-th record component of
** the record <rec>.
*/
static inline UInt GET_RNAM_PREC(Obj rec, UInt i)
{
GAP_ASSERT(IS_PREC_OR_COMOBJ(rec));
GAP_ASSERT(i <= CAPACITY_PREC(rec));
return *(const UInt *)(CONST_ADDR_OBJ(rec)+2*(i));
}
/****************************************************************************
**
*F SET_ELM_PREC( <rec>, <i>, <val> ) . set value of <i>-th record component
**
** 'SET_ELM_PREC' sets the value of the <i>-th record component of the
** record <rec> to the value <val>.
*/
static inline void SET_ELM_PREC(Obj rec, UInt i, Obj val)
{
GAP_ASSERT(IS_PREC_OR_COMOBJ(rec));
GAP_ASSERT(i <= CAPACITY_PREC(rec));
*(ADDR_OBJ(rec)+2*(i)+1) = val;
}
/****************************************************************************
**
*F GET_ELM_PREC( <rec>, <i> ) . . . . . . value of <i>-th record component
**
** 'GET_ELM_PREC' returns the value of the <i>-th record component of the
** record <rec>.
*/
static inline Obj GET_ELM_PREC(Obj rec, UInt i)
{
GAP_ASSERT(IS_PREC_OR_COMOBJ(rec));
GAP_ASSERT(i <= CAPACITY_PREC(rec));
return *(CONST_ADDR_OBJ(rec)+2*(i)+1);
}
/****************************************************************************
**
*F * * * * * * * * * standard functions for plain records * * * * * * * * * *
*/
/****************************************************************************
**
*F FindPRec( <rec>, <rnam>, <pos>, <cleanup> )
** . . . . . . . . . . . . . . . . . find a component name by binary search
**
** Searches rnam in rec, sets pos to the position where it is found (return
** value 1) or where it should be inserted if it is not found (return val 0).
** If cleanup is nonzero, a dirty record is automatically cleaned up.
** If cleanup is 0, this does not happen.
**/
extern UInt FindPRec( Obj rec, UInt rnam, UInt *pos, int cleanup );
/****************************************************************************
**
*F ElmPRec(<rec>,<rnam>) . . . . . . . select an element from a plain record
**
** 'ElmPRec' returns the element, i.e., the value of the component, with the
** record name <rnam> in the plain record <rec>. An error is signalled if
** <rec> has no component with record name <rnam>.
*/
extern Obj ElmPRec (
Obj rec,
UInt rnam );
/****************************************************************************
**
*F IsbPRec(<rec>,<rnam>) . . . . . test for an element from a plain record
**
** 'IsbPRec' returns 1 if the record <rec> has a component with the record
** name <rnam>, and 0 otherwise.
*/
extern Int IsbPRec (
Obj rec,
UInt rnam );
/****************************************************************************
**
*F AssPRec(<rec>,<rnam>,<val>) . . . . . . . . . . assign to a plain record
**
** 'AssPRec' assigns the value <val> to the record component with the record
** name <rnam> in the plain record <rec>.
*/
extern void AssPRec (
Obj rec,
UInt rnam,
Obj val );
/****************************************************************************
**
*F UnbPRec(<rec>,<rnam>) . . . unbind a record component from a plain record
**
** 'UnbPRec' removes the record component with the record name <rnam> from
** the record <rec>.
*/
extern void UnbPRec (
Obj rec,
UInt rnam );
/****************************************************************************
**
*F SortPRecRNam(<rec>, <inplace>) . . . . . . . sort the Rnams of the record
**
** This is needed after the components of a record have been assigned
** in not necessarily sorted order in the kernel. It is automatically
** called on the first read access if necessary. See the top of "precord.c"
** for a comment on lazy sorting.
** If inplace is 1 then a slightly slower algorithm is used of
** which we know that it does not produce garbage collections.
** If inplace is 0 a garbage collection may be triggered.
**
*/
extern void SortPRecRNam (
Obj rec,
int inplace );
/****************************************************************************
**
*F * * * * * * * * * * * * * initialize package * * * * * * * * * * * * * * *
*/
/****************************************************************************
**
*F InitInfoPRecord() . . . . . . . . . . . . . . . . table of init functions
*/
StructInitInfo * InitInfoPRecord ( void );
#endif // GAP_PRECORD_H