Skip to content

Conversation

denis-sh
Copy link
Contributor

@denis-sh denis-sh commented Nov 4, 2012

Documentation here: unstd.traits docs.

Additions:

  • staticArrayDims
  • MultiDimStaticArrayElementType
  • multiDimStaticArrayElementCount

@JakobOvrum
Copy link
Contributor

std.traits is very lackluster, I wish it covered more, especially more of __traits, so these changes are very welcome.

According to the language specification and discussions of the past, __traits is not meant to be used in user code at all, and the available traits and their behaviour is supposed to be implementation-defined. In this light, it's a real shame that std.traits hasn't gotten an overhaul, especially considering new traits are added all the time.

Ranting aside; shouldn't MultidimensionalStaticArrayElementsCount start with a lower case 'm' because it returns a value, not a type?

@denis-sh
Copy link
Contributor Author

denis-sh commented Nov 4, 2012

Ranting aside; shouldn't MultidimensionalStaticArrayElementsCount start with a lower case 'm' because it returns a value, not a type?

What a shame... Sorry. Fixed. Probably I'm a bit tired...

@@ -4351,6 +4351,118 @@ unittest
//static assert( isAssociativeArray!EAA);
}


/**
Get static array dimensions.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gets the rank (number of dimensions) of a static array type.

This is an important distinction from the dimensions themselves.

@alexrp
Copy link
Contributor

alexrp commented Nov 4, 2012

Looks like this is failing the auto tester?

@ghost
Copy link

ghost commented Nov 5, 2012

Why not just call it rank and add a template constraint to verify it's a static array? (I'm pretty sure I saw something like this in the D Templates book called rank) Besides, such a long name is basically unusable unless you copy-paste or use an IDE.

static if(isStaticArray!T)
enum staticArrayDimensions = 1 + staticArrayDimensions!(ArrayElementType!T);
else
enum staticArrayDimensions = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a certain amount of precedent in std.traits for raising an error instead of returning arbitrary sentinel values for invalid input. In particular, the traits that reflect on functions will generally error if the input isn't a function. I think that behaviour would be more useful here than this 0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO it will just force generic code writers to add more branches in their (already complicated and full of templates) code for essentially same cases: int[1] and int.

Consider e.g. this function and its examples: unstd.multidimensionalarray.asFlatStaticArray.

And its implementation is this:

return *(cast(MultidimensionalStaticArrayElementType!(T, n)
    [multidimensionalStaticArrayElementsCount!(T, n)]*) &t);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thought more about this and a rank function that yields the dimensionality of an array (be it static or dynamic) may be useful. Since the first line in the documentation is "Gets the rank..." let's just call it rank. As such these should pass:

static assert(rank!int == 0);
static assert(rank!(int[]) == 1);
static assert(rank!(int[42]) == 1);
static assert(rank!(int[7][8]) == 2);
static assert(rank!(int[42][]) == 2);
static assert(rank!(int[][42]) == 2);
static assert(rank!(int[][]) == 2);

A corresponding staticRank could be defined but I don't think it has much generic utility to it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can think as much as you want but I have never ever any idea why such rank may be needed. And as the opposite, staticRank is needed for practical use in my other functions.

@denis-sh
Copy link
Contributor Author

denis-sh commented Nov 5, 2012

To @alexrp:
Comments changed as you suggested. Also unittests & examples are a bit uniformed.

Looks like this is failing the auto tester?

Yes, didn't noticed that this requires pull #776.

@monarchdodra
Copy link
Collaborator

The behavior of MultidimensionalStaticArrayElementType is inconsistent with ElementType in regards to character arrays:

void main()
{
    immutable(char)[9] s = "日本語";
    alias typeof(s) S;
    "MultidimensionalStaticArrayElementType!S: ".writeln(MultidimensionalStaticArrayElementType!S.stringof);
    "ElementType!S: ".writeln(ElementType!S.stringof);
    "ElementEncodingType!S: ".writeln(ElementEncodingType!S.stringof);
}

produces

MultidimensionalStaticArrayElementType!S: immutable(char)
ElementType!S: dchar
ElementEncodingType!S: immutable(char)

Suggest chaning introducing MultidimensionalStaticArrayElementEncodingType, implemented as:

template MultidimensionalStaticArrayElementType(T, size_t n = staticArrayDimensions!T)
{
    static assert(staticArrayDimensions!T >= n, "Not enough static array dimensions");
    static if (n > 1)
        alias MultidimensionalStaticArrayElementType!(ElementEncodingType!T, n-1) MultidimensionalStaticArrayElementType;
    else static if (n == 1)
        alias ElementType!T MultidimensionalStaticArrayElementType;
    else
        alias T MultidimensionalStaticArrayElementType;
}

template MultidimensionalStaticArrayElementEncodingType(T, size_t n = staticArrayDimensions!T)
{
    static assert(staticArrayDimensions!T >= n, "Not enough static array dimensions");
    static if (n > 1)
        alias MultidimensionalStaticArrayElementEncodingType!(ElementEncodingType!T, n-1) MultidimensionalStaticArrayElementEncodingType;
    else static if (n == 1)
        alias ElementEncodingType!T MultidimensionalStaticArrayElementEncodingType;
    else
        alias T MultidimensionalStaticArrayElementEncodingType;
}

Hence the usecase:

void main()
{
    immutable(char)[9] s = "日本語";
    alias typeof(s) S;
    "MultidimensionalStaticArrayElementType!S: ".writeln(MultidimensionalStaticArrayElementType!S.stringof);
    "MultidimensionalStaticArrayElementEncodingType!S: ".writeln(MultidimensionalStaticArrayElementEncodingType!S.stringof);
    "ElementType!S: ".writeln(ElementType!S.stringof);
    "ElementEncodingType!S: ".writeln(ElementEncodingType!S.stringof);
}

And corresponding output:

MultidimensionalStaticArrayElementType!S: dchar
MultidimensionalStaticArrayElementEncodingType!S: immutable(char)
ElementType!S: dchar
ElementEncodingType!S: immutable(char)

@denis-sh
Copy link
Contributor Author

denis-sh commented Nov 5, 2012

To @monarchdodra:

These functions are for template programming and behave like ArrayElementType from pull #776.

[EDITED]
While ElementType and ElementEncodingType are for range processing which is a different task.

@denis-sh denis-sh closed this Nov 6, 2012
@denis-sh denis-sh reopened this Nov 6, 2012
@denis-sh
Copy link
Contributor Author

denis-sh commented Nov 6, 2012

Added asFlatStaticArray for pull #928. Not sure about its name and module.

@denis-sh denis-sh mentioned this pull request Nov 6, 2012
static assert(multidimensionalStaticArrayElementsCount!(int[][0]) == 0);
---
*/
template multidimensionalStaticArrayElementsCount(T, size_t n = staticArrayDimensions!T)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/Elements/Element/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@alexrp
Copy link
Contributor

alexrp commented Nov 15, 2012

Can you send asFlatStaticArray as a separate pull request please?

@ghost
Copy link

ghost commented Nov 15, 2012

Are we really ok with these insanely long names? We'll be the laughing stock of Java programmers..

@alexrp
Copy link
Contributor

alexrp commented Nov 15, 2012

@AndrejMitrovic well, suggestions welcome...

@ghost
Copy link

ghost commented Nov 15, 2012

import std.traits;
import std.range;

template ElemCount(T, size_t dim = DimCount!T)
{
    static if (dim == 0)
        enum ElemCount = 0;
    else
    static if (is(T W : W[V], int V))
        enum ElemCount = V + ElemCount!(W, dim - 1);
    else
        enum ElemCount = 0;
}

template DimCount(T)
{
    static if (is(T W : W[V], int V))
        enum DimCount = 1 + DimCount!W;
    else
        enum DimCount = 0;
}

template BaseElementType(T)
{
    static if (isStaticArray!T)
        alias BaseElementType!(ElementType!T) BaseElementType;
    else
        alias T BaseElementType;
}

template Flatten(T)
    if (isStaticArray!T)
{
    alias BaseElementType!T[ElemCount!T] Flatten;
}

void test()
{
    static assert(ElemCount!(int[3][2][1], 1) == 1);
    static assert(ElemCount!(int[3][2][1], 2) == 3);
    static assert(ElemCount!(int[3][2][1], 3) == 6);

    static assert(is(Flatten!(int[1][2][3]) == int[6u]));
    static assert(is(Flatten!(int[][2][3]) == int[][5u]));
    static assert(is(Flatten!(int[][][2][3]) == int[][][5u]));

    int[1][2][3] mdimSArr;
    alias Flatten!(typeof(mdimSArr)) FlatArr;
    cast(FlatArr)mdimSArr = [1, 2, 3, 4, 5, 6];
    assert(mdimSArr == [[[1], [2]], [[3], [4]], [[5], [6]]]);
}

As for the asFlatStaticArray overload which takes a dimension index, I really have no idea what the use-cases for this are.


static assert(is(typeof(asFlatStaticArray!2(mdimSArr)) == int[1][6]));
assert(asFlatStaticArray!2(mdimSArr) == [[1], [2], [3], [4], [5], [6]]);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can merge this to a part of std.conv.to feature.

ref toImpl(S)(ref S source) if (isStaticArray!S) {
  alias Elem = getStaticArrayTerminalElemType!S;
  enum dim = getStaticArrayFlattenDIm!S;
  return *cast(Elem[dim]*)&source;
}
unittest {
  int[1][2][3] mdimSArr;
  mdimSArr.to!(int[6]) = [1,2,3,4,5,6];
  assert(mdimSArr == [[[1], [2]], [[3], [4]], [[5], [6]]]);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To @9rnsr:

It's in pull #952 now.

mdimSArr.to!(int[6]) may be useful, but it isn't the point of asFlatStaticArray. asFlatStaticArray isn't a to* function as it doesn't create a copy. And it is important that it doesn't require to provide any types explicitly.

@denis-sh denis-sh mentioned this pull request Nov 16, 2012
@denis-sh
Copy link
Contributor Author

To @alexrp:

Can you send asFlatStaticArray as a separate pull request please?

#952.

@denis-sh
Copy link
Contributor Author

To @AndrejMitrovic:

First, all you names are too short and can be treated differently. It's unacceptable for template code as it should be as verbose as possible to eliminate any possibility to do a mistake.


import std.range;

I'll never convince to use std.range in template code without need as it is error-prone and inconsistent.


template ElemCount(T, size_t dim = DimCount!T)
{
    static if (dim == 0)
        enum ElemCount = 0;
    else
    static if (is(T W : W[V], int V))
        enum ElemCount = V + ElemCount!(W, dim - 1);
    else
        enum ElemCount = 0;
}

It's much more complicated than mine:

template multidimensionalStaticArrayElementCount(T, size_t n = staticArrayDimensions!T)
{
    static assert(staticArrayDimensions!T >= n, "Not enough static array dimensions");
    enum multidimensionalStaticArrayElementCount = T.sizeof / MultidimensionalStaticArrayElementType!(T, n).sizeof;
}

Needles over-complication is error-prone. But maybe I'm the only one stupid person here who calls every error-prone concept dangerous and every other coder is so professional that such error-prone things doesn't affect him. Let's see:

  1. ElemCount returns 0 for dim = 0 instead of 1.
  2. It doesn't show any errors (at lest unusable template errors, I'm not even telling about readable error message like mine) for dim > DimCount!T.
  3. And the final one: it just works absolutely incorrect.

template DimCount(T)
{
    static if (is(T W : W[V], int V))
        enum DimCount = 1 + DimCount!W;
    else
        enum DimCount = 0;
}

Correct but less readable that mine:

template staticArrayDimensions(T)
{
    static if(isStaticArray!T)
        enum staticArrayDimensions = 1 + staticArrayDimensions!(ArrayElementType!T);
    else
        enum staticArrayDimensions = 0;
}

as IsExpression is proved to be obviousness and hard to remember so you create needles complications for code reader. Also IsExpression is too dangerous to use ( error-prone doesn't express even a small part of how IsExpression dangerous) even if you understand it because a single typo leads to IsExpression returning false instead of showing any errors.


template BaseElementType(T)
{
    static if (isStaticArray!T)
        alias BaseElementType!(ElementType!T) BaseElementType;
    else
        alias T BaseElementType;
}

Mine one:

template MultidimensionalStaticArrayElementType(T, size_t n = staticArrayDimensions!T)
{
    static assert(staticArrayDimensions!T >= n, "Not enough static array dimensions");
    static if(n)
        alias MultidimensionalStaticArrayElementType!(ArrayElementType!T, n-1) MultidimensionalStaticArrayElementType;
    else
        alias T MultidimensionalStaticArrayElementType;
}

First, you decided that there is no need for n parameter. Sometimes we want to analyze something that has a static array as its element, why are you so sure there will be no need to do it?
By the way, it's not just a theory. All my pulls are because of practical needs and n is really needed here.

Second, you decided to use std.range where it must not be used. And, obviously, you used it incorrectly:

  • BaseElementType!char returns char;
  • BaseElementType!(char[1]) returns dchar.

template Flatten(T)
    if (isStaticArray!T)
{
    alias BaseElementType!T[ElemCount!T] Flatten;
}
void test()
{
    ...
    int[1][2][3] mdimSArr;
    alias Flatten!(typeof(mdimSArr)) FlatArr;
    cast(FlatArr)mdimSArr = [1, 2, 3, 4, 5, 6];
    assert(mdimSArr == [[[1], [2]], [[3], [4]], [[5], [6]]]);
}

Mine is in #952 now.

First, it doesn't work with non-arrays and it kills the only purpose of asFlatStaticArray - to be generic.
Second, why do you require a user to create an alias and then cast instead of providing a callable function?
Third, you again incorrectly decided that that we will never work with elements which are static arrays itself and don't need n argument.

P.S.

You just forced me to spend an hour listing you obvious mistakes and trying to proof you the fact that we must not use error-prone solutions which itself looks too obvious to even talk about. But even Walter did "Patterns of humans error" presentation once, so people really don't want to understand this fact for some reasons.

@denis-sh
Copy link
Contributor Author

@andralex, as you rejected my pull #776, are you happy you forced people to do mistakes again and again because of you desired to use range concept where is shouldn't be used?

@jmdavis
Copy link
Member

jmdavis commented Nov 16, 2012

I have to concur that these names are ridiculously long. They're completely unreasonable. At least abbreviate them (e.g. staticArrayDims) - maybe even use sa and SA or sArr and SArr instead of staticArray or StaticArray. The names should be clear, but these names are so long that they're completely unusable.

@denis-sh
Copy link
Contributor Author

Looks like you just hate arrays. )

I can also say: "I see no reason to include ... to Phobos" about any trait in std.traits. The only reason to have all that traits it to help dealing with language elements. Arrays are also language elements so they have equal rights with functions, enums, etc.

@andralex
Copy link
Member

andralex commented Dec 8, 2012

To summarize this - I think retrieving the rank and extracting the innermost element type may be of some utility. The parts that do so only for static arrays are of too narrow utility. @denis-sh could you please change this accordingly?

(One possibility would be to generalize these beyond arrays, e.g. look at the type of x[0] and transitively chase its type until indexing is no longer possible.)

@denis-sh
Copy link
Contributor Author

denis-sh commented Dec 8, 2012

To summarize, I completely disagree and will not do it.
This pull has no theory in it. Only practical utils do do concrete things.

@denis-sh
Copy link
Contributor Author

denis-sh commented Dec 8, 2012

If you so hate all my additions I can mark it all package but will not change as it is needed for other templates to finally fix emplace.

@denis-sh
Copy link
Contributor Author

denis-sh commented Dec 8, 2012

But please note, that I will be forced then to duplicate its functionality for my phobos-additions library because it also uses these templates.

@andralex
Copy link
Member

andralex commented Dec 8, 2012

OK, let's wait for others to chime in. One issue was that the supported functions (as I recall from another pull request) were also quite specialized.

@denis-sh also please let's avoid allowing any debate transgress into the personal and subjective. Keep in mind that nobody hates you or your work and that progress is achieved by making good arguments, handling criticism properly, and respecting one another. You're doing great work and there's no need to penalize us all for it by making any discussion with you an exercise in cringing. Thanks.

@denis-sh
Copy link
Contributor Author

denis-sh commented Dec 8, 2012

But you are definitely a Static Array Hater (nothing negative here). All things in std.traits are not generally needed. Most of it isn't used even in phobos itself. I see the only rule for std.traits content: if there is a language feature X, there should be traits for its properties. And if such trait is even used by somebody, we must be very happy an hurry to include it in phobos.

Example:
---
static assert(is(MultidimStaticArrayElementType!int == int));
static assert(is(MultidimStaticArrayElementType!(int[]) == int[]));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should emulate what ElementType is doing and result in void if T isn't a multidimensional, static array. It makes no sense to get a valid result for invalid input as this is doing now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I already wrote, no changes in this code. Is is practically needed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this code exactly? In one of your other pull requests, I assume? This behavior seems fundamentally broken, and at the moment, I would be inclined to argue that the code using this needs to be changed. I'd have to see the other code to make a fully educated judgement, but what what you're doing here seems like when a boolean function chooses to return false rather than throwing an exception when it hits an error condition that prevents it from actually determining the correct answer, and that's very broken behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andralex, as you see people again mixing ElementType with template programming. It was a major mistake to reject my pull #776.
And, as always, I don't see any mistakes in my opinion and it is opposite to all other phobos devs opinions...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this code exactly? In one of your other pull requests, I assume?

Yes. Search for referenced this pull request. And in phobos-additions project.

This behavior seems fundamentally broken, ...

No, it is intentional. The idea is that we have zero-dimentional static array. As a result every value is a static array and we don't need any special static array conditions in templated code any more. And I'm not just like this idea, I use it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And as I said, it makes about as much sense to say that a multimensional static array isn't a static array as it does to say that a yellow car isn't a car.

I can see an argument for staticArrayDimensions!int giving 0, since that's obviously an error condition rather than a valid number of dimensions for an array. But MultidimensionalStaticArrayElementType has no such error condition. It tries to treat scalars as if they were static arrays, which I contend makes no sense and is inconsistent with ElementType. It should either give void or not use a template constraint to prevent scalars working with it outright.

Clearly, we're not going to agree here, and this discussion is going nowhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And as I said, it makes about as much sense to say that a multimensional static array isn't a static array as it does to say that a yellow car isn't a car.

And in my opinion you are telling: a car parking without cars isn't a car parking.

Clearly, we're not going to agree here, and this discussion is going nowhere.

Of course! But thanks for your time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jmdavis: this is a matter of dimensionality, not size, so bringing T[1] into the discussion is a red herring. Consider a non-array type T (int, double, class etc). On top of it we build array types of different dimensions: T[24], T[24][42] etc. These have 1, 2, and so on dimensions. On occasion the dimensionality of T itself comes into question, and the correct answer is it's 0.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0-dimensionality is something special imo:

alias byte[0] T1;
alias byte T2;
static assert(T1.sizeof == 0);
static assert(T2.sizeof == 1);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AndrejMitrovic uhm I didn't know that ever worked. But byte[0] is not a zero-dimensional array, it's a 1-dimensional array with length 0.

@jmdavis
Copy link
Member

jmdavis commented Dec 8, 2012

I don't know whether these are quite the right traits that we want, but I see no reason not to have traits for static arrays. If it's truly something that only a select few are likely to be using, then it's of questionable value, but while I don't use much in the way of static arrays, I know that quite a few other people in the newsgroup do, and it makes sense that at least some traits relating to them would be necessary as part of that. My largest complaint with this pull request is the overly verbose names. Abbreviation can be used to mitigate that however.

I am against the idea of rank though unless it applies to both dynamic and static arrays, as it would be highly confusing for it to apply only to static arrays, especially when most everything defaults to dealing with dynamic arrays.

@denis-sh
Copy link
Contributor Author

denis-sh commented Dec 8, 2012

I am against the idea of rank though unless it applies to both dynamic and static arrays, as it would be highly confusing for it to apply only to static arrays, especially when most everything defaults to dealing with dynamic arrays.

Can not even answer... Misunderstanding is terrible. I suppose you don't want to understand my opinion (and it's OK because I don't want to understand yours too).

I will only repeat: let it be package and leave it alone. I need it. I like it. I use it.

@denis-sh
Copy link
Contributor Author

denis-sh commented Dec 8, 2012

No, I will continue this time-wasting discussion. Sorry.

when most everything defaults to dealing with dynamic arrays

This is the point. These traits are for static arrays because there is absolutely no support for it in the library now.

@jmdavis
Copy link
Member

jmdavis commented Dec 8, 2012

I am against the idea of rank though unless it applies to both dynamic and static arrays, as it would be highly confusing for it to apply only to static arrays, especially when most everything defaults to dealing with dynamic arrays.

Can not even answer... Misunderstanding is terrible. I suppose you don't want to understand my opinion (and it's OK because I don't want to understand yours too).

I meant the name rank, not the concept. I'm not against adding traits for static arrays as long as they're well thought out and well-named. Some of what you have here definitely needs some implementation tweaks, and it all needs name changes.

@jmdavis
Copy link
Member

jmdavis commented Dec 8, 2012

My problem with the name rank is that it doesn't indicate that it's dealing with a static array, and as array stuff defaults to be dynamic, a trait named rank would have to either work worth both dynamic and static arrays or just dynamic arrays - but not just static arrays. However, given that you can have dynamic arrays of static arrays and static arrays of dynamic arrays, it's probably best not to have a trait such as rank which operated on both, as that could get highly confusing with such arrays.

@DmitryOlshansky
Copy link
Member

A small note: a rank of a matrix in linear algebra (which multidimensional static arrays often represent) is something different then the number of dimensions. While it's a trait applied to a type so the math notion can't be attributed to it I stil suspect that say just dimensions would be far less confusing.

Again maybe making this discussion even worse but is there any disadvantage of having dimensions (or arrayDimensions) to work for arrays of both types. Basically why the exclusivness? If need exclusivness could be replaced by something along the lines of :
...
isStaticArray!T && arrayDimensions!T > k
...
and we have isDynamicArray so I think merging common to all kinds of arrays traits together is a better move and makes for less prefix happy names.

@jmdavis
Copy link
Member

jmdavis commented Dec 8, 2012

Again maybe making this discussion even worse but is there any disadvantage of having dimensions (or arrayDimensions) to work for arrays of both types. Basically why the exclusivness? If need exclusivness could be replaced by something along the lines of :
...
isStaticArray!T && arrayDimensions!T > k
...
and we have isDynamicArray so I think merging common to all kinds of arrays traits together is a better move and makes for less prefix happy names.

The problem is something like

int[][4] a;

or

int[4][][] b;

What would arrayDimensions!a and arrayDimensions!b be? If we're okay with it just being the outer ones (which is probably the right choice), then that can definitely work and would probably be the best way to go, but I could see someone arguing for it being supposed to give all of them. Still, I don't think that that's really valid, so it probably wouldn't be a problem.

@DmitryOlshansky
Copy link
Member

The problem is something like

int[][4] a;

or

int[4][][] b;

I agree with your notion of dimensions being that of the outer one multi-dimensional array.

The way I describe 'a' is static array of dynamic arrays of int.
And 'b' is dynamic array of dynamic array of static array of int.

Then 'dynamic array of dynamic array' is 2-dimensional dynamic array and same would go for 'static array of static array' as 2-dimensional static array.
"Mixed arrays" are not easily described as N-dimensional array of 'something' as that doesn't represent the structure accurately and thus static array of dynamic array is 1-dim static of 1-dim dynamic array.

But clarification in docs should be present regradless of logic as it's tempting to just count pairs of brackets and call it a dimension.

@denis-sh
Copy link
Contributor Author

What is the state of this?

@denis-sh
Copy link
Contributor Author

denis-sh commented Oct 9, 2013

Rebased on master. Any progress with it?

@denis-sh
Copy link
Contributor Author

@andralex, @9rnsr ping on this.

/**
Gets the rank (number of dimensions) of a static array type.
*/
template staticArrayDims(T)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not intuitive or obvious that this returns 0 when given a non-static-array type, so it either needs to be disallowed with a template constraint or included in the documentation. I think disallowing it is probably the right choice.

edit:

I see that multiDimStaticArrayElementCount depends on this, but that doesn't justify compromising a user-facing interface, there are plenty of ways to work around that.

@JakobOvrum
Copy link
Contributor

My latest line comments are based on the pull request as-is; that is, these templates are documented and public.

In that vein, I have to say I really dislike the names. I think there are shorter and more memorable names available without resorting to abbreviations, like rank and InnermostType. Can't think of one for multiDimStaticArrayElementCount though.

Existing names in std.traits are poor counter-arguments for the naming issue. ParameterStorageClassTuple is hard to remember too, but did it have any good alternative names?

So, mostly repetition of what has been said, but ultimately that's because the issues have not been resolved.

If you're going to make these internal, then you should do so and present the PR as such.

@denis-sh
Copy link
Contributor Author

The whole idea is the ability to forget about static arrays as a special case and introduce zero-dimensional static array. In contrast to asFlatStaticArray (#952) which was rejected as "non generally used" as "code that needs to do the same exact thing with each element" is seldom traits are used often for inntrospection so this is not rare case here.

I'm for better names but looks like they are already as short as possible. Proposals are welcome.

@denis-sh
Copy link
Contributor Author

Regarding to documentation I suppose unittests clearly show e.g. int is a zero-dimensional static array with one element.

@denis-sh
Copy link
Contributor Author

OK. Clarified documentation to make things obvious.

* adds `staticArrayDims`
* adds `MultidimStaticArrayElementType`
* adds `multidimStaticArrayElementCount`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants