source: libcfa/src/bits/collections.hfa @ 3267041

Last change on this file since 3267041 was acafba4, checked in by Michael Brooks <mlbrooks@…>, 14 months ago

Rename internal macro away from TYPE, which is a cs343 name collision.

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