April 21, 2015
On Tuesday, 21 April 2015 at 07:46:03 UTC, Vlad Levenfeld wrote:
> template dimensionality (S) {
>   template count_dim (uint i = 0) {
>     static if (is (typeof(S.init.opSlice!i (0,0))))
>       enum count_dim = count_dim!(i+1);
>     else enum count_dim = i;
>   }
>
>   alias dimensionality = count_dim!();
> }
>
> Then you throw in some more stuff to detect 1-dimensional cases.

Great! I guess a template restriction on opSlice would be in Place aswell.

One thing: Why aren't you using opIndex instead? If there are types that have opIndex but not opSlice defined then dimensionality() could cover more types, right?
April 21, 2015
On Tuesday, 21 April 2015 at 08:09:38 UTC, Per Nordlöw wrote:
> On Tuesday, 21 April 2015 at 07:46:03 UTC, Vlad Levenfeld wrote:
>> template dimensionality (S) {
>>  template count_dim (uint i = 0) {
>>    static if (is (typeof(S.init.opSlice!i (0,0))))
>>      enum count_dim = count_dim!(i+1);
>>    else enum count_dim = i;
>>  }
>>
>>  alias dimensionality = count_dim!();
>> }
>>
>> Then you throw in some more stuff to detect 1-dimensional cases.
>
> Great! I guess a template restriction on opSlice would be in Place aswell.
>
> One thing: Why aren't you using opIndex instead? If there are types that have opIndex but not opSlice defined then dimensionality() could cover more types, right?

So, if the type is multidimensional, that means its using the new opIndex/opSlice syntax that was designed for multidimensional structures. So I know that, if dim > 1, opSlice!i must be defined, and (assuming we are only working with integral indices here) I can instantiate it with opSlice!i (0,0).

For other types, you would throw in a test for a length member, or for front, and know that you have a 1-dimensional type.

Alternatively, if we're assuming only integral indices, a recursive attempt to get the typeof(opIndex (Repeat!(i, 0))) would probably handle all the opIndex-but-not-opSlice cases (but you still need to handle non-indexed ranges and D arrays specially).
April 21, 2015
As an aside, I've put a bit of work into the generic multidimensional containers problem lately and have an interface generating library as a result.

https://github.com/evenex/autodata

It's still in the nascent stages but contains a lot of tools for working with multidimensional structures.

You can take a look at the definition in the spaces/ and topology/ folder (and the unittests in operators/) to get an idea of how it works - basically generates all the opIndex/opSlice stuff (with safety checks) under a unified system; end result being that you just write the business logic for your types, mixin the operators, and they will all interoperate with uniform semantics.

The definitions for the types themselves tend to be very short and to-the-point as a result. I've taken old containers of mine whose defs were pushing 300 lines and reimplemented them in ~50 using the autodata operators.

A full set of traits and multidim range compositions (map, zip, take, cycle, repeat) are present as well. A lot of them are full or partial reimplementations of Phobos stuff.

It's pretty poorly documented (for now) but I'm happy to answer questions (and make documentation based on that) if you decide to check it out.
April 21, 2015
On Tuesday, 21 April 2015 at 07:46:03 UTC, Vlad Levenfeld wrote:
> Then you throw in some more stuff to detect 1-dimensional cases.

Could you please elaborate a bit?
April 21, 2015
On Tuesday, 21 April 2015 at 19:46:03 UTC, Nordlöw wrote:
> On Tuesday, 21 April 2015 at 07:46:03 UTC, Vlad Levenfeld wrote:
>> Then you throw in some more stuff to detect 1-dimensional cases.
>
> Could you please elaborate a bit?

Well assuming the type is not multidimensional (does not define opSlice!i) then testing for input range primitives or opIndex(0) is probably enough to conclude that a type is 1d.
April 21, 2015
template dimensionality (S) {
  template count_dim (uint i = 0) {
    static if (is (typeof(S.init.opSlice!i (0,0))))
      enum count_dim = count_dim!(i+1);
    else static if (i == 0 && (isInputRange!S || is (typeof(S.init[0])))
      enum count_dim = 1;
    else enum count_dim = i;
  }

  alias dimensionality = count_dim!();
}

Should work for any case I can think of (assuming integral indices).
April 21, 2015
On Tuesday, 21 April 2015 at 20:30:00 UTC, Vlad Levenfeld wrote:
> Should work for any case I can think of (assuming integral indices).

Thanks.
1 2 3
Next ›   Last »