Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/containers/array.hfa

    r8d76f2b ra5e2682  
     1#pragma once
     2
    13#include <assert.h>
    24
     
    1820    // About the choice of integral types offered as subscript overloads:
    1921    // Intent is to cover these use cases:
     22    //    a[0]                                                // i : zero_t
     23    //    a[1]                                                // i : one_t
     24    //    a[2]                                                // i : int
    2025    //    float foo( ptrdiff_t i ) { return a[i]; }           // i : ptrdiff_t
     26    //    float foo( size_t i ) { return a[i]; }              // i : size_t
    2127    //    forall( [N] ) ... for( i; N ) { total += a[i]; }    // i : typeof( sizeof(42) )
    2228    //    for( i; 5 ) { total += a[i]; }                      // i : int
     29    //
    2330    // It gets complicated by:
    2431    // -  CFA does overloading on concrete types, like int and unsigned int, not on typedefed
     
    2734    // -  Given bug of Trac #247, CFA gives sizeof expressions type unsigned long int, when it
    2835    //    should give them type size_t.
    29     //   
    30     //                          gcc -m32         cfa -m32 given bug         gcc -m64
     36    //
     37    //                          gcc -m32         cfa -m32 given bug         gcc -m64 (and cfa)
    3138    // ptrdiff_t                int              int                        long int
    3239    // size_t                   unsigned int     unsigned int               unsigned long int
    3340    // typeof( sizeof(42) )     unsigned int     unsigned long int          unsigned long int
    3441    // int                      int              int                        int
     42    //
     43    // So the solution must support types {zero_t, one_t, int, unsigned int, long int, unsigned long int}
     44    //
     45    // The solution cannot rely on implicit conversions (e.g. just have one overload for ptrdiff_t)
     46    // because assertion satisfaction requires types to match exacly.  Both higher-dimensional
     47    // subscripting and operations on slices use asserted subscript operators.  The test case
     48    // array-container/array-sbscr-cases covers the combinations.  Mike beleives that commenting out
     49    // any of the current overloads leads to one of those cases failing, either on 64- or 32-bit.
     50    // Mike is open to being shown a smaller set of overloads that still passes the test.
     51
     52    static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, zero_t ) {
     53        assert( 0 < N );
     54        return (Timmed &) a.strides[0];
     55    }
     56
     57    static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, one_t ) {
     58        assert( 1 < N );
     59        return (Timmed &) a.strides[1];
     60    }
    3561
    3662    static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, int i ) {
     
    3965    }
    4066
     67    static inline const Timmed & ?[?]( const arpk(N, S, Timmed, Tbase) & a, int i ) {
     68        assert( i < N );
     69        return (Timmed &) a.strides[i];
     70    }
     71
    4172    static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, unsigned int i ) {
    4273        assert( i < N );
     
    4475    }
    4576
     77    static inline const Timmed & ?[?]( const arpk(N, S, Timmed, Tbase) & a, unsigned int i ) {
     78        assert( i < N );
     79        return (Timmed &) a.strides[i];
     80    }
     81
    4682    static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, long int i ) {
    4783        assert( i < N );
     
    4985    }
    5086
     87    static inline const Timmed & ?[?]( const arpk(N, S, Timmed, Tbase) & a, long int i ) {
     88        assert( i < N );
     89        return (Timmed &) a.strides[i];
     90    }
     91
    5192    static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, unsigned long int i ) {
     93        assert( i < N );
     94        return (Timmed &) a.strides[i];
     95    }
     96
     97    static inline const Timmed & ?[?]( const arpk(N, S, Timmed, Tbase) & a, unsigned long int i ) {
    5298        assert( i < N );
    5399        return (Timmed &) a.strides[i];
     
    57103        return N;
    58104    }
     105
     106    static inline void __taglen( tag(arpk(N, S, Timmed, Tbase)), tag(N) ) {}
    59107
    60108    // workaround #226 (and array relevance thereof demonstrated in mike102/otype-slow-ndims.cfa)
     
    83131    // Make a FOREACH macro
    84132    #define FE_0(WHAT)
    85     #define FE_1(WHAT, X) WHAT(X) 
     133    #define FE_1(WHAT, X) WHAT(X)
    86134    #define FE_2(WHAT, X, ...) WHAT(X)FE_1(WHAT, __VA_ARGS__)
    87135    #define FE_3(WHAT, X, ...) WHAT(X)FE_2(WHAT, __VA_ARGS__)
     
    90138    //... repeat as needed
    91139
    92     #define GET_MACRO(_0,_1,_2,_3,_4,_5,NAME,...) NAME 
     140    #define GET_MACRO(_0,_1,_2,_3,_4,_5,NAME,...) NAME
    93141    #define FOR_EACH(action,...) \
    94142    GET_MACRO(_0,__VA_ARGS__,FE_5,FE_4,FE_3,FE_2,FE_1,FE_0)(action,__VA_ARGS__)
     
    115163}
    116164
    117 #else 
     165#else
    118166
    119167// Workaround form.  Listing all possibilities up to 4 dims.
     
    135183
    136184#endif
     185
     186// Available for users to work around Trac #265
     187// If `a[...0...]` isn't working, try `a[...ix0...]` instead.
     188
     189#define ix0 ((ptrdiff_t)0)
     190
     191
    137192
    138193//
     
    155210
    156211// Wrapper
    157 struct all_t {} all;
     212extern struct all_t {} all;
    158213forall( [N], S & | sized(S), Te &, result &, Tbase & | { tag(result) enq_( tag(Tbase), tag(N), tag(S), tag(Te) ); } )
    159214static inline result & ?[?]( arpk(N, S, Te, Tbase) & this, all_t ) {
     
    165220//
    166221
    167 trait ar(A &, Tv &) {
    168     Tv& ?[?]( A&, ptrdiff_t );
    169     size_t ?`len( A& );
    170 };
     222// desired:
     223// trait ar(A &, Tv &, [N]) {
     224//     Tv& ?[?]( A&, zero_t );
     225//     Tv& ?[?]( A&, one_t  );
     226//     Tv& ?[?]( A&, int    );
     227//                   ...
     228//     size_t ?`len( A& );
     229//     void __taglen( tag(C), tag(N) );
     230// };
     231
     232// working around N's not being accepted as arguments to traits
     233
     234#define ar(A, Tv, N) {                 \
     235    Tv& ?[?]( A&, zero_t );            \
     236    Tv& ?[?]( A&, one_t );             \
     237    Tv& ?[?]( A&, int );               \
     238    Tv& ?[?]( A&, unsigned int );      \
     239    Tv& ?[?]( A&, long int );          \
     240    Tv& ?[?]( A&, unsigned long int ); \
     241    size_t ?`len( A& );                \
     242    void __taglen( tag(A), tag(N) );   \
     243}
Note: See TracChangeset for help on using the changeset viewer.