source: libcfa/src/bits/containers.hfa@ d9b7b66

Last change on this file since d9b7b66 was 8a97248, checked in by Peter A. Buhr <pabuhr@…>, 3 years ago

switch from old trait syntax to new trait syntax using forall clause

  • Property mode set to 100644
File size: 6.9 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// bits/containers.hfa -- Intrusive generic containers.hfa
8//
9// Author : Thierry Delisle
10// Created On : Tue Oct 31 16:38:50 2017
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Thu Feb 2 11:33:08 2023
13// Update Count : 29
14
15#pragma once
16
17#include "bits/align.hfa"
18#include "bits/defs.hfa"
19#include <stdio.h>
20//-----------------------------------------------------------------------------
21// Array
22//-----------------------------------------------------------------------------
23
24#ifdef __cforall
25 forall(T &)
26#else
27 #define T void
28#endif
29struct __small_array {
30 T * data;
31 __lock_size_t size;
32};
33#undef T
34
35#ifdef __cforall
36 #define __small_array_t(T) __small_array(T)
37#else
38 #define __small_array_t(T) __small_array
39#endif
40
41#ifdef __cforall
42 // forall(T | sized(T))
43 // static inline void ?{}(__small_array(T) & this) {}
44
45 forall(T & | sized(T))
46 static inline T & ?[?]( __small_array(T) & this, __lock_size_t idx ) {
47 return ((typeof(this.data))this.data)[idx];
48 }
49
50 forall(T & | sized(T))
51 static inline T & ?[?]( const __small_array(T) & this, __lock_size_t idx ) {
52 return ((typeof(this.data))this.data)[idx];
53 }
54
55 forall(T &)
56 static inline T * begin( const __small_array(T) & this ) {
57 return ((typeof(this.data))this.data);
58 }
59
60 forall(T & | sized(T))
61 static inline T * end( const __small_array(T) & this ) {
62 return ((typeof(this.data))this.data) + this.size;
63 }
64#endif
65
66//-----------------------------------------------------------------------------
67// Node Base
68//-----------------------------------------------------------------------------
69
70#ifdef __cforall
71 forall( T & )
72 trait is_node {
73 T *& get_next( T & );
74 };
75#endif
76
77//-----------------------------------------------------------------------------
78// Stack
79//-----------------------------------------------------------------------------
80#ifdef __cforall
81 forall(TYPE &)
82 #define T TYPE
83#else
84 #define T void
85#endif
86struct __stack {
87 T * top;
88};
89#undef T
90
91#ifdef __cforall
92#define __stack_t(T) __stack(T)
93#else
94#define __stack_t(T) struct __stack
95#endif
96
97#ifdef __cforall
98 forall(T &)
99 static inline void ?{}( __stack(T) & this ) {
100 (this.top){ 0p };
101 }
102
103 static inline forall( T & | is_node(T) ) {
104 void push( __stack(T) & this, T * val ) {
105 verify( !get_next( *val ) );
106 get_next( *val ) = this.top;
107 this.top = val;
108 }
109
110 T * pop( __stack(T) & this ) {
111 T * top = this.top;
112 if( top ) {
113 this.top = get_next( *top );
114 get_next( *top ) = 0p;
115 }
116 return top;
117 }
118
119 int ?!=?( const __stack(T) & this, __attribute__((unused)) zero_t zero ) {
120 return this.top != 0;
121 }
122 }
123#endif
124
125//-----------------------------------------------------------------------------
126// Queue
127//-----------------------------------------------------------------------------
128#ifdef __cforall
129 forall(TYPE &)
130 #define T TYPE
131#else
132 #define T void
133#endif
134struct __queue {
135 T * head;
136 T ** tail;
137};
138#undef T
139
140#ifdef __cforall
141#define __queue_t(T) __queue(T)
142#else
143#define __queue_t(T) struct __queue
144#endif
145
146#ifdef __cforall
147 static inline forall( T & | is_node(T) ) {
148 void ?{}( __queue(T) & this ) with( this ) {
149 (this.head){ 1p };
150 (this.tail){ &this.head };
151 verify(*this.tail == 1p);
152 }
153
154 void append( __queue(T) & this, T * val ) with(this) {
155 verify(get_next( *val ) == 0p);
156 verify(this.tail != 0p);
157 verify(*this.tail == 1p);
158 *this.tail = val;
159 this.tail = &get_next( *val );
160 *this.tail = 1p;
161 }
162
163 T * peek( __queue(T) & this ) {
164 verify(*this.tail == 1p);
165 T * frontnode = this.head;
166 if( frontnode != 1p ) {
167 verify(*this.tail == 1p);
168 return frontnode;
169 }
170 verify(*this.tail == 1p);
171 return 0p;
172 }
173
174 T * pop_head( __queue(T) & this ) {
175 verify(*this.tail == 1p);
176 T * _head = this.head;
177 if( _head != 1p ) {
178 this.head = get_next( *_head );
179 if( get_next( *_head ) == 1p ) {
180 this.tail = &this.head;
181 }
182 get_next( *_head ) = 0p;
183 verify(*this.tail == 1p);
184 verify( get_next(*_head) == 0p );
185 return _head;
186 }
187 verify(*this.tail == 1p);
188 return 0p;
189 }
190
191 T * remove( __queue(T) & this, T ** it ) with( this ) {
192 T * val = *it;
193 verify( val );
194
195 (*it) = get_next( *val );
196
197 if( this.tail == &get_next( *val ) ) {
198 this.tail = it;
199 }
200
201 get_next( *val ) = 0p;
202
203 verify( (this.head == 1p) == (&this.head == this.tail) );
204 verify( *this.tail == 1p );
205 return val;
206 }
207
208 int ?!=?( const __queue(T) & this, __attribute__((unused)) zero_t zero ) {
209 return this.head != 1p;
210 }
211 }
212#endif
213
214
215//-----------------------------------------------------------------------------
216// Doubly Linked List
217//-----------------------------------------------------------------------------
218#ifdef __cforall
219 forall(TYPE &)
220 #define T TYPE
221 #define __getter_t * [T * & next, T * & prev] ( T & )
222#else
223 typedef void (*__generit_c_getter_t)();
224 #define T void
225 #define __getter_t __generit_c_getter_t
226#endif
227struct __dllist {
228 T * head;
229 __getter_t __get;
230};
231#undef T
232#undef __getter_t
233
234#ifdef __cforall
235#define __dllist_t(T) __dllist(T)
236#else
237#define __dllist_t(T) struct __dllist
238#endif
239
240#ifdef __cforall
241 forall(T & )
242 static inline [void] ?{}( __dllist(T) & this, * [T * & next, T * & prev] ( T & ) __get ) {
243 (this.head){ 0p };
244 this.__get = __get;
245 }
246
247 #define next 0
248 #define prev 1
249 static inline forall(T &) {
250 void push_front( __dllist(T) & this, T & node ) with( this ) {
251 verify(__get);
252 if ( this.head ) {
253 __get( node ).next = this.head;
254 __get( node ).prev = __get( *this.head ).prev;
255 // inserted node must be consistent before it is seen
256 // prevent code movement across barrier
257 asm( "" : : : "memory" );
258 __get( *this.head ).prev = &node;
259 T & _prev = *__get( node ).prev;
260 __get( _prev ).next = &node;
261 } else {
262 __get( node ).next = &node;
263 __get( node ).prev = &node;
264 }
265
266 // prevent code movement across barrier
267 asm( "" : : : "memory" );
268 this.head = &node;
269 }
270
271 void remove( __dllist(T) & this, T & node ) with( this ) {
272 verify(__get);
273 if ( &node == this.head ) {
274 if ( __get( *this.head ).next == this.head ) {
275 this.head = 0p;
276 } else {
277 this.head = __get( *this.head ).next;
278 }
279 }
280 __get( *__get( node ).next ).prev = __get( node ).prev;
281 __get( *__get( node ).prev ).next = __get( node ).next;
282 __get( node ).next = 0p;
283 __get( node ).prev = 0p;
284 }
285
286 int ?!=?( const __dllist(T) & this, __attribute__((unused)) zero_t zero ) {
287 return this.head != 0;
288 }
289
290 void move_to_front( __dllist(T) & src, __dllist(T) & dst, T & node ) {
291 remove (src, node);
292 push_front(dst, node);
293 }
294 }
295 #undef next
296 #undef prev
297#endif
298
299//-----------------------------------------------------------------------------
300// Tools
301//-----------------------------------------------------------------------------
302#ifdef __cforall
303
304#endif
305
306// Local Variables: //
307// tab-width: 4 //
308// End: //
Note: See TracBrowser for help on using the repository browser.