http://d.puremagic.com/issues/show_bug.cgi?id=3718
Summary: InExpression does not support two-or-more-dimensional associative array. Product: D Version: unspecified Platform: All OS/Version: All Status: NEW Severity: enhancement Priority: P2 Component: DMD AssignedTo: nob...@puremagic.com ReportedBy: michal.min...@gmail.com --- Comment #0 from Michal Minich <michal.min...@gmail.com> 2010-01-18 03:12:13 PST --- While finding if key exists in aa is very easy and 'cool' in D (it even returns pointer to value): float[char] aa1; if ('a' in aa1) ... for two dimensional array it is impossible to use this syntax: float[int][char] aa2; if (123 in *('a' in aa2)) ... = problem if "('a' in aa2)" evaluates to null, because then evaluating "123 in null" references null pointer. Similarly using: if (123 in aa2['a']) does not give desired behavior. ---------------- Simple (and bad) solution would be creating function 'doubleIn' as here for every specific case, which every user of D is doomed to do until better solution is provided in language. aa['a'][123] = 4.56; float* isIn = doubleIn(123, 'a'); float* doubleIn (int i, char ch) { float[int]* first = ch in aa; if (first is null) return null; else return i in *first; } --------------- Possible solution for standard library: Here is templated function "isIn" written by Simen kjaeraas, implemented to work with combination of AAs and normal arrays: template elementTypeOfDepth( T : V[ K ], int depth, V, K ) { static if ( depth == 0 ) { alias V elementTypeOfDepth; } else { alias elementTypeOfDepth!( V, depth -1 ) elementTypeOfDepth; } } template elementTypeOfDepth( T : V[ ], int depth, V ) { static if ( depth == 0 ) { alias V elementTypeOfDepth; } else { alias elementTypeOfDepth!( V, depth -1 ) elementTypeOfDepth; } } elementTypeOfDepth!( T, U.length )* isIn( T : V[ ], V, U... )( T arr, size_t key, U index ) { if ( key < arr.length ) { auto p = arr[ key ]; static if ( U.length > 0 ) { if ( p ) { return isIn( p, index ); } else { return null; } } else { return p; } } else { return null; } } elementTypeOfDepth!( T, U.length )* isIn( T : V[ K ], V, K, U... )( T arr, K key, U index ) { auto p = key in arr; static if ( U.length > 0 ) { if ( p ) { return isIn( *p, index ); } else { return null; } } else { return p; } } Usage: int[char][][int] foo; if ( isIn( foo, 3, 87, 'a' ) ) { writeln( "Excelsior!" ); } --------------- Possible solution for D language I did not consulted compiler implementation, but from its behavior, this simple modification should be enough: the problem with statement "123 in *('a' in aa)" is that if "('a' in aa')" returns null, then next check will fail: (123 in null) -> null reference error. if D simply check if the second part of InExpression is null, and if yes, return null, otherwise evaluate as is currently done. Additional thing would be allowing syntax "123 in ('a' in aa)" -- without the "*" pointer dereference. This could be achieved by adding another "overload" for InExpression which works with pointer to AA. Compiler should already know if the argument of InExpression is AA or pointer to AA. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------