digitalmars.D.learn - What is the proper way to outline static-if-conditions ?
- Elmar (54/54) Oct 10 2021 Hey D people.
 - Elmar (3/3) Oct 10 2021 PS: the title is a misnomer. `is(T : P*, P) && isStaticArray!P`
 - drug (24/24) Oct 10 2021 You just need to check if T is a pointer:
 - Elmar (2/27) Oct 10 2021 Wow, this is a fine solution. I gonna use it, thank you :-) .
 
Hey D people.
Currently in my project I have worked on a unified type interface 
for all arrays which requires fixed-size arrays to be stored as 
pointer (in correspondence to dynamic and associative arrays) and 
allow them being allocated with any selected allocator.
There can be code like this:
```d
enum isPointedStaticArray(T) = (is(T : P*, P) && 
.isStaticArray!P);
//...
static if (.isPointedStaticArray!T)
{
     // ...
}
```
It won't compile when the argument of `isPointedStaticArray()` is 
NO pointer.
The compiler complains, about **`P` being undefined**.
What is the best workaround for this?
It's crazy. I can reverse the problem that it only fails if the 
argument IS a pointer:
```d
	enum isPointedStaticArray(T) =
	(){
		enum condition = `is(`~T.stringof~` : P*, P) && 
.isStaticArray!P`;
		static if (__traits(compiles, mixin(condition)) )
			return mixin(condition);  // "P already defined" error
		else
			return false;
	}();
```
Types defined in `__traits(compiles, ...)` are emitted to the 
outside?!
Okay, this is my current workaround:
```d
enum isPointedStaticArray(T) =
(){
	static if (is(T : P*, P))
		return .isStaticArray!(P);
	else
		return false;
}();
// ...
static if (isPointedStaticArray!T)
{
}
```
for outlining an expression `is(...) && ...`
Is there a simpler way in D to do this? If there only would be a 
`&&&` short circuit operator which doesn't compile the right side 
if the left side wouldn't compile to true.
Did someone already had the idea of a `static-try-catch` which 
catches compilation errors?
 Oct 10 2021
PS: the title is a misnomer. `is(T : P*, P) && isStaticArray!P` doesn't either compile when inlined because `P` is not defined when not matched.
 Oct 10 2021
You just need to check if T is a pointer:
```D
import std;
alias DA = int[];
alias SA = int[3];
alias PSA = SA*;
alias PDA = DA*;
version(all)
	enum isPointedStaticArray(T) = isPointer!T && 
isStaticArray!(PointerTarget!T);
else
	enum isPointedStaticArray(T) = isPointer!T && is(PointerTarget!T : 
P[N], P, size_t N);  // this way you can get array length
static assert(!isPointedStaticArray!DA);
static assert(!isPointedStaticArray!SA);
static assert(!isPointedStaticArray!PDA);
static assert( isPointedStaticArray!PSA);
void main()
{
}
```
https://run.dlang.io/is/qKdx1D
Also you can use another way to detect static array - it can be useful 
if you need to get its length
 Oct 10 2021
On Sunday, 10 October 2021 at 14:08:13 UTC, drug wrote:
 You just need to check if T is a pointer:
 ```D
 import std;
 alias DA = int[];
 alias SA = int[3];
 alias PSA = SA*;
 alias PDA = DA*;
 version(all)
 	enum isPointedStaticArray(T) = isPointer!T && 
 isStaticArray!(PointerTarget!T);
 else
 	enum isPointedStaticArray(T) = isPointer!T && 
 is(PointerTarget!T : P[N], P, size_t N);  // this way you can 
 get array length
 static assert(!isPointedStaticArray!DA);
 static assert(!isPointedStaticArray!SA);
 static assert(!isPointedStaticArray!PDA);
 static assert( isPointedStaticArray!PSA);
 void main()
 {
 }
 ```
 https://run.dlang.io/is/qKdx1D
 Also you can use another way to detect static array - it can be 
 useful if you need to get its length
Wow, this is a fine solution. I gonna use it, thank you :-) .
 Oct 10 2021
On Sunday, 10 October 2021 at 14:36:50 UTC, Elmar wrote:On Sunday, 10 October 2021 at 14:08:13 UTC, drug wrote:Well, I just wondered why your code would compile and mine wouldn't. The `version(all)` variant will not compile on my computer with `rdmd` because `PointerTarget` only allows pointers. But the 2nd one will compile. The `is()` expression catches the compilation error which is nice. This is sufficient: ```d enum isPointedStaticArray(T) = is(PointerTarget!T : P[N], P, size_t N); ``` It would be nice if one could use pattern-matching for it in D. Is this possible? ```d enum isPointedStaticArray(X : P*, P) = .isStaticArray!(PointerTarget!X); enum isPointedStaticArray(X : else) = false; ```You just need to check if T is a pointer: ```D import std; alias DA = int[]; alias SA = int[3]; alias PSA = SA*; alias PDA = DA*; version(all) enum isPointedStaticArray(T) = isPointer!T && isStaticArray!(PointerTarget!T); else enum isPointedStaticArray(T) = isPointer!T && is(PointerTarget!T : P[N], P, size_t N); // this way you can get array length static assert(!isPointedStaticArray!DA); static assert(!isPointedStaticArray!SA); static assert(!isPointedStaticArray!PDA); static assert( isPointedStaticArray!PSA); void main() { } ``` https://run.dlang.io/is/qKdx1D Also you can use another way to detect static array - it can be useful if you need to get its lengthWow, this is a fine solution. I gonna use it, thank you :-) .
 Oct 10 2021
On Sunday, 10 October 2021 at 15:01:17 UTC, Elmar wrote:```d enum isPointedStaticArray(T) = is(PointerTarget!T : P[N], P, size_t N); ``` ```d enum isPointedStaticArray(X : P*, P) = .isStaticArray!(PointerTarget!X); ````isStaticArray` is a good example that makes me ask how to outline an `is()` expression without losing the error catching semantics of the inlined `is()` expression.
 Oct 10 2021
On 10.10.2021 18:01, Elmar wrote:Well, I just wondered why your code would compile and mine wouldn't. The `version(all)` variant will not compile on my computer with `rdmd` because `PointerTarget` only allows pointers.It depends on compiler version. This variant is compiled on version 2.092.1 and aboveBut the 2nd one will compile. The `is()` expression catches the compilation error which is nice. This is sufficient: ```d enum isPointedStaticArray(T) = is(PointerTarget!T : P[N], P, size_t N); ``` It would be nice if one could use pattern-matching for it in D. Is this possible? ```d enum isPointedStaticArray(X : P*, P) = .isStaticArray!(PointerTarget!X); enum isPointedStaticArray(X : else) = false; ```As I know it's impossible, but you can use a regular template: ```d template isPointedStaticArray(T) { static if (isPointer!T) enum isPointedStaticArray = isStaticArray!(PointerTarget!T); else enum isPointedStaticArray = false; } ``` https://run.dlang.io/is/lR7feP this compiles from 2.086.1 and above
 Oct 10 2021
On Sunday, 10 October 2021 at 15:15:51 UTC, drug wrote:
 As I know it's impossible, but you can use a regular template:
 ```d
 template isPointedStaticArray(T)
 {
     static if (isPointer!T)
         enum isPointedStaticArray = 
 isStaticArray!(PointerTarget!T);
     else
         enum isPointedStaticArray = false;
 }
 ```
 https://run.dlang.io/is/lR7feP
 this compiles from 2.086.1 and above
That's indeed close to pattern matching and is probably the best 
answer :-) .
 Oct 10 2021
On Sunday, 10 October 2021 at 15:15:51 UTC, drug wrote:If anyone is interested in pattern matching, someone provides a package "dpmatch" which uses PEG (some parsing grammer which is implemented in D) to achieve Haskel-style pattern matching, yet for sum-type definitions only. And they use GC + interfaces. Hence it cannot be used with BetterC. Sumtypes can also be created with the `sumtype` package which uses D's delegate literals for pattern matching.It would be nice if one could use pattern-matching for it in D. Is this possible?As I know it's impossible, but you can use a regular template: ...
 Oct 10 2021








 
 
 
 Elmar <chrehme gmx.de> 