1 /****************************************************************************
2 **
3 ** This file is part of GAP, a system for computational discrete algebra.
4 **
5 ** Copyright of GAP belongs to its developers, whose names are too numerous
6 ** to list here. Please refer to the COPYRIGHT file for details.
7 **
8 ** SPDX-License-Identifier: GPL-2.0-or-later
9 **
10 ** This file declares the functions that deal with ranges.
11 **
12 ** A *range* is a list without holes consisting of consecutive integers.
13 ** For the full definition of ranges see chapter "Ranges" in the GAP Manual.
14 ** Read also "More about Ranges" about the different representation of
15 ** ranges.
16 **
17 ** Ranges can be accessed through the functions 'NEW_RANGE', 'IS_RANGE',
18 ** 'SET_LEN_RANGE', 'GET_LEN_RANGE', 'SET_LOW_RANGE', 'GET_LOW_RANGE',
19 ** 'SET_INC_RANGE', 'GET_INC_RANGE', and 'GET_ELM_RANGE'.
20 **
21 ** This package also contains the list functions for ranges, which are
22 ** installed in the appropriate tables by 'InitRange'.
23 */
24
25 #ifndef GAP_RANGE_H
26 #define GAP_RANGE_H
27
28 #include "objects.h"
29
30 /****************************************************************************
31 **
32 *F NEW_RANGE() . . . . . . . . . . . . . . . . . . . . . . make a new range
33 **
34 ** 'NEW_RANGE' returns a new range. Note that you must set the length, the
35 ** low value, and the increment before you can use the range.
36 */
NEW_RANGE_NSORT(void)37 EXPORT_INLINE Obj NEW_RANGE_NSORT(void)
38 {
39 return NewBag(T_RANGE_NSORT, 3 * sizeof(Obj));
40 }
41
NEW_RANGE_SSORT(void)42 EXPORT_INLINE Obj NEW_RANGE_SSORT(void)
43 {
44 return NewBag(T_RANGE_SSORT, 3 * sizeof(Obj));
45 }
46
47 /****************************************************************************
48 **
49 *F IS_RANGE(<val>) . . . . . . . . . . . . . . . test if a value is a range
50 **
51 ** 'IS_RANGE' returns 1 if the value <val> is known to be a range, and 0
52 ** otherwise. Note that a list for which 'IS_RANGE' returns 0 may still be
53 ** a range, but the kernel does not know this yet. Use 'IsRange' to test
54 ** whether a list is a range.
55 */
IS_RANGE(Obj val)56 EXPORT_INLINE Int IS_RANGE(Obj val)
57 {
58 return TNUM_OBJ(val) >= T_RANGE_NSORT &&
59 TNUM_OBJ(val) <= T_RANGE_SSORT + IMMUTABLE;
60 }
61
62
63 /****************************************************************************
64 **
65 *F SET_LEN_RANGE(<list>,<len>) . . . . . . . . . . set the length of a range
66 **
67 ** 'SET_LEN_RANGE' sets the length of the range <list> to the value <len>,
68 ** which must be a C integer larger than 1.
69 */
SET_LEN_RANGE(Obj list,Int len)70 EXPORT_INLINE void SET_LEN_RANGE(Obj list, Int len)
71 {
72 GAP_ASSERT(IS_RANGE(list));
73 ADDR_OBJ(list)[0] = INTOBJ_INT(len);
74 }
75
76
77 /****************************************************************************
78 **
79 *F GET_LEN_RANGE(<list>) . . . . . . . . . . . . . . . . . length of a range
80 **
81 ** 'GET_LEN_RANGE' returns the logical length of the range <list>, as a C
82 ** integer.
83 */
GET_LEN_RANGE(Obj list)84 EXPORT_INLINE Int GET_LEN_RANGE(Obj list)
85 {
86 GAP_ASSERT(IS_RANGE(list));
87 return INT_INTOBJ(CONST_ADDR_OBJ(list)[0]);
88 }
89
90
91 /****************************************************************************
92 **
93 *F SET_LOW_RANGE(<list>,<low>) . . . . . . set the first element of a range
94 **
95 ** 'SET_LOW_RANGE' sets the first element of the range <list> to the value
96 ** <low>, which must be a C integer.
97 */
SET_LOW_RANGE(Obj list,Int low)98 EXPORT_INLINE void SET_LOW_RANGE(Obj list, Int low)
99 {
100 GAP_ASSERT(IS_RANGE(list));
101 ADDR_OBJ(list)[1] = INTOBJ_INT(low);
102 }
103
104
105 /****************************************************************************
106 **
107 *F GET_LOW_RANGE(<list>) . . . . . . . . . . . . . first element of a range
108 **
109 ** 'GET_LOW_RANGE' returns the first element of the range <list> as a C
110 ** integer.
111 */
GET_LOW_RANGE(Obj list)112 EXPORT_INLINE Int GET_LOW_RANGE(Obj list)
113 {
114 GAP_ASSERT(IS_RANGE(list));
115 return INT_INTOBJ(CONST_ADDR_OBJ(list)[1]);
116 }
117
118
119 /****************************************************************************
120 **
121 *F SET_INC_RANGE(<list>,<inc>) . . . . . . . . set the increment of a range
122 **
123 ** 'SET_INC_RANGE' sets the increment of the range <list> to the value
124 ** <inc>, which must be a C integer.
125 */
SET_INC_RANGE(Obj list,Int inc)126 EXPORT_INLINE void SET_INC_RANGE(Obj list, Int inc)
127 {
128 GAP_ASSERT(IS_RANGE(list));
129 ADDR_OBJ(list)[2] = INTOBJ_INT(inc);
130 }
131
132
133 /****************************************************************************
134 **
135 *F GET_INC_RANGE(<list>) . . . . . . . . . . . . . . . increment of a range
136 **
137 ** 'GET_INC_RANGE' returns the increment of the range <list> as a C integer.
138 */
GET_INC_RANGE(Obj list)139 EXPORT_INLINE Int GET_INC_RANGE(Obj list)
140 {
141 GAP_ASSERT(IS_RANGE(list));
142 return INT_INTOBJ(CONST_ADDR_OBJ(list)[2]);
143 }
144
145
146 /****************************************************************************
147 **
148 *F GET_ELM_RANGE(<list>,<pos>) . . . . . . . . . . . . . element of a range
149 **
150 ** 'GET_ELM_RANGE' return the <pos>-th element of the range <list>. <pos>
151 ** must be a positive integer less than or equal to the length of <list>.
152 */
GET_ELM_RANGE(Obj list,Int pos)153 EXPORT_INLINE Obj GET_ELM_RANGE(Obj list, Int pos)
154 {
155 Int val;
156 GAP_ASSERT(IS_RANGE(list));
157 val = GET_LOW_RANGE(list) + ((pos)-1) * GET_INC_RANGE(list);
158 GAP_ASSERT(pos >= 1 && pos <= GET_LEN_RANGE(list));
159 return INTOBJ_INT(val);
160 }
161
162 /****************************************************************************
163 **
164 *F PosRange(<list>,<val>,<start>) . . . . position of an element in a range
165 **
166 ** 'PosRange' returns the position of the value <val> in the range <list>
167 ** after the first position <start> as a GAP integer. Fail is returned if <val>
168 ** is not in the list.
169 **
170 ** 'PosRange' is the function in 'PosListFuncs' for ranges.
171 */
172 Obj PosRange(Obj list, Obj val, Obj start);
173
174
175 /****************************************************************************
176 **
177 *F Range2Check( <first>, <last> ) . . . . . . . . . . . . . construct range
178 */
179 Obj Range2Check(Obj first, Obj last);
180
181
182 /****************************************************************************
183 **
184 *F Range3Check( <first>, <second>, <last> ) . . . . . . . . construct range
185 */
186 Obj Range3Check(Obj first, Obj second, Obj last);
187
188
189 /****************************************************************************
190 **
191 *F * * * * * * * * * * * * * initialize module * * * * * * * * * * * * * * *
192 */
193
194
195 /****************************************************************************
196 **
197 *F InitInfoRange() . . . . . . . . . . . . . . . . . table of init functions
198 */
199 StructInitInfo * InitInfoRange ( void );
200
201
202 #endif // GAP_RANGE_H
203