source: libcfa/src/bits/containers.hfa @ 2b910f9

ADTast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 2b910f9 was d0502a3, checked in by Michael Brooks <mlbrooks@…>, 4 years ago

Fixing function bodies in bits/containers and bits/sequence so they can coexist with declarations in vector Fixes #237?

libcfa/src/bits/* the fixes
libcfa/src/fstream.hfa adding the desired include, which wasn't possible under #237
tests/includes/* adding tests for these problematic combinations

  • Property mode set to 100644
File size: 6.9 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//
[73abe95]7// bits/containers.hfa -- Intrusive generic containers.hfa
[ea7d2b0]8//
9// Author           : Thierry Delisle
10// Created On       : Tue Oct 31 16:38:50 2017
[2233ad4]11// Last Modified By : Peter A. Buhr
[768bd556]12// Last Modified On : Wed Jan 15 07:42:35 2020
13// Update Count     : 28
[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
[fd54fef]71        trait is_node(T &) {
[768bd556]72                T *& get_next( T & );
[ea7d2b0]73        };
74#endif
75
76//-----------------------------------------------------------------------------
77// Stack
78//-----------------------------------------------------------------------------
[0cf5b79]79#ifdef __cforall
[fd54fef]80        forall(TYPE &)
[ea7d2b0]81        #define T TYPE
82#else
83        #define T void
84#endif
85struct __stack {
86        T * top;
87};
[0cf5b79]88#undef T
[ea7d2b0]89
[0cf5b79]90#ifdef __cforall
[ea7d2b0]91#define __stack_t(T) __stack(T)
92#else
93#define __stack_t(T) struct __stack
94#endif
95
[0cf5b79]96#ifdef __cforall
[fd54fef]97        forall(T &)
[0cf5b79]98        static inline void ?{}( __stack(T) & this ) {
[768bd556]99                (this.top){ 0p };
[ea7d2b0]100        }
101
[fd54fef]102        static inline forall( T & | is_node(T) ) {
[768bd556]103                void push( __stack(T) & this, T * val ) {
104                        verify( !get_next( *val ) );
105                        get_next( *val ) = this.top;
106                        this.top = val;
107                }
[ea7d2b0]108
[768bd556]109                T * pop( __stack(T) & this ) {
110                        T * top = this.top;
111                        if( top ) {
112                                this.top = get_next( *top );
113                                get_next( *top ) = 0p;
114                        }
115                        return top;
[ea7d2b0]116                }
[2233ad4]117
[768bd556]118                int ?!=?( const __stack(T) & this, __attribute__((unused)) zero_t zero ) {
119                        return this.top != 0;
120                }
[2233ad4]121        }
[ea7d2b0]122#endif
123
124//-----------------------------------------------------------------------------
125// Queue
126//-----------------------------------------------------------------------------
[0cf5b79]127#ifdef __cforall
[fd54fef]128        forall(TYPE &)
[ea7d2b0]129        #define T TYPE
130#else
131        #define T void
132#endif
133struct __queue {
134        T * head;
135        T ** tail;
136};
[0cf5b79]137#undef T
138
139#ifdef __cforall
140#define __queue_t(T) __queue(T)
141#else
142#define __queue_t(T) struct __queue
143#endif
[ea7d2b0]144
[0cf5b79]145#ifdef __cforall
[fd54fef]146        static inline forall( T & | is_node(T) ) {
[768bd556]147                void ?{}( __queue(T) & this ) with( this ) {
[8e655f7c]148                        (this.head){ 1p };
149                        (this.tail){ &this.head };
150                        verify(*this.tail == 1p);
[768bd556]151                }
[65deb18]152
[d0502a3]153                void append( __queue(T) & this, T * val ) with(this) {
[8e655f7c]154                        verify(this.tail != 0p);
155                        verify(*this.tail == 1p);
156                        *this.tail = val;
157                        this.tail = &get_next( *val );
158                        *this.tail = 1p;
[768bd556]159                }
[ea7d2b0]160
[ae2c27a]161                T * peek( __queue(T) & this ) {
162                        verify(*this.tail == 1p);
[d0502a3]163                        T * frontnode = this.head;
164                        if( frontnode != 1p ) {
[ae2c27a]165                                verify(*this.tail == 1p);
[d0502a3]166                                return frontnode;
[ae2c27a]167                        }
168                        verify(*this.tail == 1p);
169                        return 0p;
170                }
171
[768bd556]172                T * pop_head( __queue(T) & this ) {
[3381ed7]173                        verify(*this.tail == 1p);
[8e655f7c]174                        T * _head = this.head;
175                        if( _head != 1p ) {
176                                this.head = get_next( *_head );
177                                if( get_next( *_head ) == 1p ) {
[768bd556]178                                        this.tail = &this.head;
179                                }
[8e655f7c]180                                get_next( *_head ) = 0p;
[3381ed7]181                                verify(*this.tail == 1p);
[8e655f7c]182                                verify( get_next(*_head) == 0p );
183                                return _head;
[ea7d2b0]184                        }
[3381ed7]185                        verify(*this.tail == 1p);
186                        return 0p;
[ea7d2b0]187                }
188
[768bd556]189                T * remove( __queue(T) & this, T ** it ) with( this ) {
190                        T * val = *it;
191                        verify( val );
[ea7d2b0]192
[768bd556]193                        (*it) = get_next( *val );
[ea7d2b0]194
[8e655f7c]195                        if( this.tail == &get_next( *val ) ) {
196                                this.tail = it;
[768bd556]197                        }
[ea7d2b0]198
[768bd556]199                        get_next( *val ) = 0p;
[ea7d2b0]200
[8e655f7c]201                        verify( (this.head == 1p) == (&this.head == this.tail) );
202                        verify( *this.tail == 1p );
[768bd556]203                        return val;
204                }
[8ebbfc4]205
[768bd556]206                int ?!=?( const __queue(T) & this, __attribute__((unused)) zero_t zero ) {
[79306383]207                        return this.head != 1p;
[768bd556]208                }
[8ebbfc4]209        }
[ea7d2b0]210#endif
[65deb18]211
[14a61b5]212
213//-----------------------------------------------------------------------------
214// Doubly Linked List
215//-----------------------------------------------------------------------------
216#ifdef __cforall
[fd54fef]217        forall(TYPE &)
[14a61b5]218        #define T TYPE
[705e612]219        #define __getter_t * [T * & next, T * & prev] ( T & )
[14a61b5]220#else
[705e612]221        typedef void (*__generit_c_getter_t)();
[14a61b5]222        #define T void
[705e612]223        #define __getter_t __generit_c_getter_t
[14a61b5]224#endif
225struct __dllist {
226        T * head;
[705e612]227        __getter_t __get;
[14a61b5]228};
229#undef T
[705e612]230#undef __getter_t
[14a61b5]231
232#ifdef __cforall
233#define __dllist_t(T) __dllist(T)
234#else
235#define __dllist_t(T) struct __dllist
236#endif
237
238#ifdef __cforall
[fd54fef]239        forall(T & )
[de94a60]240        static inline [void] ?{}( __dllist(T) & this, * [T * & next, T * & prev] ( T & ) __get ) {
[8e655f7c]241                (this.head){ 0p };
[de94a60]242                this.__get = __get;
243        }
244
[639991a]245        #define next 0
246        #define prev 1
[fd54fef]247        static inline forall(T &) {
[768bd556]248                void push_front( __dllist(T) & this, T & node ) with( this ) {
249                        verify(__get);
[8e655f7c]250                        if ( this.head ) {
251                                __get( node ).next = this.head;
252                                __get( node ).prev = __get( *this.head ).prev;
[768bd556]253                                // inserted node must be consistent before it is seen
254                                // prevent code movement across barrier
255                                asm( "" : : : "memory" );
[8e655f7c]256                                __get( *this.head ).prev = &node;
[768bd556]257                                T & _prev = *__get( node ).prev;
258                                __get( _prev ).next = &node;
259                        } else {
260                                __get( node ).next = &node;
261                                __get( node ).prev = &node;
262                        }
263
[de94a60]264                        // prevent code movement across barrier
265                        asm( "" : : : "memory" );
[8e655f7c]266                        this.head = &node;
[de94a60]267                }
268
[768bd556]269                void remove( __dllist(T) & this, T & node ) with( this ) {
270                        verify(__get);
[8e655f7c]271                        if ( &node == this.head ) {
272                                if ( __get( *this.head ).next == this.head ) {
273                                        this.head = 0p;
[768bd556]274                                } else {
[8e655f7c]275                                        this.head = __get( *this.head ).next;
[768bd556]276                                }
[de94a60]277                        }
[768bd556]278                        __get( *__get( node ).next ).prev = __get( node ).prev;
279                        __get( *__get( node ).prev ).next = __get( node ).next;
280                        __get( node ).next = 0p;
281                        __get( node ).prev = 0p;
[de94a60]282                }
[0c674e8]283
[768bd556]284                int ?!=?( const __dllist(T) & this, __attribute__((unused)) zero_t zero ) {
285                        return this.head != 0;
286                }
[92e7631]287
288                void move_to_front( __dllist(T) & src, __dllist(T) & dst, T & node ) {
289                        remove    (src, node);
290                        push_front(dst, node);
291                }
[0c674e8]292        }
[639991a]293        #undef next
294        #undef prev
[14a61b5]295#endif
296
[65deb18]297//-----------------------------------------------------------------------------
298// Tools
299//-----------------------------------------------------------------------------
300#ifdef __cforall
301
[2233ad4]302#endif
[768bd556]303
304// Local Variables: //
305// tab-width: 4 //
306// End: //
Note: See TracBrowser for help on using the repository browser.