source: libcfa/src/containers/array.hfa @ f5a51db

ADTast-experimentalenumpthread-emulationqualifiedEnum
Last change on this file since f5a51db was 6448f7d, checked in by Michael Brooks <mlbrooks@…>, 3 years ago

Fixing compiler warnings with new arrays due to placeholder empty function bodies.

Have not been able to reproduce the warning, but the bodies provided here are valid.
No change to programs using new arrays.

  • Property mode set to 100644
File size: 5.5 KB
Line 
1
2
3forall( __CFA_tysys_id_only_X & ) struct tag {};
4#define ttag(T) ((tag(T)){})
5#define ztag(n) ttag(n)
6
7
8//
9// Single-dim array sruct (with explicit packing and atom)
10//
11
12forall( [N], S & | sized(S), Timmed &, Tbase & ) {
13    struct arpk {
14        S strides[N];
15    };
16
17    // About the choice of integral types offered as subscript overloads:
18    // Intent is to cover these use cases:
19    //    float foo( ptrdiff_t i ) { return a[i]; }           // i : ptrdiff_t
20    //    forall( [N] ) ... for( i; N ) { total += a[i]; }    // i : typeof( sizeof(42) )
21    //    for( i; 5 ) { total += a[i]; }                      // i : int
22    // It gets complicated by:
23    // -  CFA does overloading on concrete types, like int and unsigned int, not on typedefed
24    //    types like size_t.  So trying to overload on ptrdiff_t vs int works in 64-bit mode
25    //    but not in 32-bit mode.
26    // -  Given bug of Trac #247, CFA gives sizeof expressions type unsigned long int, when it
27    //    should give them type size_t.
28    //   
29    //                          gcc -m32         cfa -m32 given bug         gcc -m64
30    // ptrdiff_t                int              int                        long int
31    // size_t                   unsigned int     unsigned int               unsigned long int
32    // typeof( sizeof(42) )     unsigned int     unsigned long int          unsigned long int
33    // int                      int              int                        int
34
35    static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, int i ) {
36        return (Timmed &) a.strides[i];
37    }
38
39    static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, unsigned int i ) {
40        return (Timmed &) a.strides[i];
41    }
42
43    static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, long int i ) {
44        return (Timmed &) a.strides[i];
45    }
46
47    static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, unsigned long int i ) {
48        return (Timmed &) a.strides[i];
49    }
50
51    static inline size_t ?`len( arpk(N, S, Timmed, Tbase) & a ) {
52        return N;
53    }
54
55    // workaround #226 (and array relevance thereof demonstrated in mike102/otype-slow-ndims.cfa)
56    static inline void ?{}( arpk(N, S, Timmed, Tbase) & this ) {
57        void ?{}( S (&inner)[N] ) {}
58        ?{}(this.strides);
59    }
60    static inline void ^?{}( arpk(N, S, Timmed, Tbase) & this ) {
61        void ^?{}( S (&inner)[N] ) {}
62        ^?{}(this.strides);
63    }
64}
65
66//
67// Sugar for declaring array structure instances
68//
69
70forall( Te )
71static inline Te mkar_( tag(Te) ) {}
72
73forall( [N], ZTags ... , Trslt &, Tatom & | { Trslt mkar_( tag(Tatom), ZTags ); } )
74static inline arpk(N, Trslt, Trslt, Tatom) mkar_( tag(Tatom), tag(N), ZTags ) {}
75
76// based on https://stackoverflow.com/questions/1872220/is-it-possible-to-iterate-over-arguments-in-variadic-macros
77
78    // Make a FOREACH macro
79    #define FE_0(WHAT)
80    #define FE_1(WHAT, X) WHAT(X)
81    #define FE_2(WHAT, X, ...) WHAT(X)FE_1(WHAT, __VA_ARGS__)
82    #define FE_3(WHAT, X, ...) WHAT(X)FE_2(WHAT, __VA_ARGS__)
83    #define FE_4(WHAT, X, ...) WHAT(X)FE_3(WHAT, __VA_ARGS__)
84    #define FE_5(WHAT, X, ...) WHAT(X)FE_4(WHAT, __VA_ARGS__)
85    //... repeat as needed
86
87    #define GET_MACRO(_0,_1,_2,_3,_4,_5,NAME,...) NAME
88    #define FOR_EACH(action,...) \
89    GET_MACRO(_0,__VA_ARGS__,FE_5,FE_4,FE_3,FE_2,FE_1,FE_0)(action,__VA_ARGS__)
90
91#define COMMA_ttag(X) , ttag(X)
92#define array( TE, ...) typeof( mkar_( ttag(TE)  FOR_EACH( COMMA_ttag, __VA_ARGS__ ) ) )
93
94#define COMMA_ztag(X) , ztag(X)
95#define zarray( TE, ...) typeof( mkar_( ttag(TE)  FOR_EACH( COMMA_ztag, __VA_ARGS__ ) ) )
96
97//
98// Sugar for multidimensional indexing
99//
100
101// Core -[[-,-,-]] operator
102
103#ifdef TRY_BROKEN_DESIRED_MD_SUBSCRIPT
104
105// Desired form.  One definition with recursion on IxBC (worked until Jan 2021, see trac #__TODO__)
106
107forall( TA &, TB &, TC &, IxAB, IxBC ... | { TB & ?[?]( TA &, IxAB ); TC & ?[?]( TB &, IxBC ); } )
108static inline TC & ?[?]( TA & this, IxAB ab, IxBC bc ) {
109    return this[ab][bc];
110}
111
112#else
113
114// Workaround form.  Listing all possibilities up to 4 dims.
115
116forall( TA &, TB &, TC &, IxAB_0, IxBC | { TB & ?[?]( TA &, IxAB_0 ); TC & ?[?]( TB &, IxBC ); } )
117static inline TC & ?[?]( TA & this, IxAB_0 ab, IxBC bc ) {
118    return this[ab][bc];
119}
120
121forall( TA &, TB &, TC &, IxAB_0, IxAB_1, IxBC | { TB & ?[?]( TA &, IxAB_0, IxAB_1 ); TC & ?[?]( TB &, IxBC ); } )
122static inline TC & ?[?]( TA & this, IxAB_0 ab0, IxAB_1 ab1, IxBC bc ) {
123    return this[[ab0,ab1]][bc];
124}
125
126forall( TA &, TB &, TC &, IxAB_0, IxAB_1, IxAB_2, IxBC | { TB & ?[?]( TA &, IxAB_0, IxAB_1, IxAB_2 ); TC & ?[?]( TB &, IxBC ); } )
127static inline TC & ?[?]( TA & this, IxAB_0 ab0, IxAB_1 ab1, IxAB_2 ab2, IxBC bc ) {
128    return this[[ab0,ab1,ab2]][bc];
129}
130
131#endif
132
133//
134// Rotation
135//
136
137// Base
138forall( [Nq], Sq & | sized(Sq), Tbase & )
139static inline tag(arpk(Nq, Sq, Tbase, Tbase)) enq_( tag(Tbase), tag(Nq), tag(Sq), tag(Tbase) ) {
140    tag(arpk(Nq, Sq, Tbase, Tbase)) ret;
141    return ret;
142}
143
144// Rec
145forall( [Nq], Sq & | sized(Sq), [N], S & | sized(S), recq &, recr &, Tbase & | { tag(recr) enq_( tag(Tbase), tag(Nq), tag(Sq), tag(recq) ); } )
146static inline tag(arpk(N, S, recr, Tbase)) enq_( tag(Tbase), tag(Nq), tag(Sq), tag(arpk(N, S, recq, Tbase)) ) {
147    tag(arpk(N, S, recr, Tbase)) ret;
148    return ret;
149}
150
151// Wrapper
152struct all_t {} all;
153forall( [N], S & | sized(S), Te &, result &, Tbase & | { tag(result) enq_( tag(Tbase), tag(N), tag(S), tag(Te) ); } )
154static inline result & ?[?]( arpk(N, S, Te, Tbase) & this, all_t ) {
155    return (result&) this;
156}
157
158//
159// Trait of array or slice
160//
161
162trait ar(A &, Tv &) {
163    Tv& ?[?]( A&, ptrdiff_t );
164    size_t ?`len( A& );
165};
Note: See TracBrowser for help on using the repository browser.