www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - classify a user struct as an "array" or "slice"

reply james.p.leblanc <james.p.leblanc gmail.com> writes:
Greetings,

I have a user created struct, let's call this "**fakeArray**":

For all intents and purposes fakeArray behaves like an array (or 
slice, I guess).
(i.e. It has a number of operator overloadings, and *foreach* 
extensions implemented.)

I have a fairly large number of function in a module that accept 
arrays (or slices).

These are implemented as:

**auto foo(T)(T[] x) { ... }**

So, foo will accept "official" arrays and slices.

What is the easiest way to coerce all my functions to also
accept my fakeArray?

Regards,
James
Aug 20 2021
parent reply Paul Backus <snarwin gmail.com> writes:
On Friday, 20 August 2021 at 15:12:25 UTC, james.p.leblanc wrote:
 Greetings,

 I have a user created struct, let's call this "**fakeArray**":

 For all intents and purposes fakeArray behaves like an array 
 (or slice, I guess).
 (i.e. It has a number of operator overloadings, and *foreach* 
 extensions implemented.)

 I have a fairly large number of function in a module that 
 accept arrays (or slices).

 These are implemented as:

 **auto foo(T)(T[] x) { ... }**

 So, foo will accept "official" arrays and slices.

 What is the easiest way to coerce all my functions to also
 accept my fakeArray?
The most straightforward way would be to change your functions from accepting only `T[]` to accepting either `T[]` or `fakeArray`. For example: ```d import std.traits: isDynamicArray; // assuming `fakeArray` is a template struct/class enum isFakeArray(T) = is(T == fakeArray!U, U); auto foo(Array)(Array x) if (isDynamicArray!Array || isFakeArray!Array) { // ... } ``` The `if (...)` part there is a [template constraint][1]. It means that the template can only be instantiated when the condition evaluates to `true`. [1]: https://dlang.org/spec/template.html#template_constraints
Aug 20 2021
parent james.p.leblanc <james.p.leblanc gmail.com> writes:
On Friday, 20 August 2021 at 15:38:04 UTC, Paul Backus wrote:
 

 The most straightforward way would be to change your functions 
 from accepting only `T[]` to accepting either `T[]` or 
 `fakeArray`. For example:

 ```d
 import std.traits: isDynamicArray;

 // assuming `fakeArray` is a template struct/class
 enum isFakeArray(T) = is(T == fakeArray!U, U);

 auto foo(Array)(Array x)
     if (isDynamicArray!Array || isFakeArray!Array)
 {
     // ...
 }
 ```

 The `if (...)` part there is a [template constraint][1]. It 
 means that the template can only be instantiated when the 
 condition evaluates to `true`.

 [1]: https://dlang.org/spec/template.html#template_constraints
Paul, This works like a charm! I just implemented it ... I am most thankful for your help again. Next, I imagine that need to add a few "static ifs" later in the function body of foo, wherein I can dig out what the element types of my arrays are ... (I need this to initialize some summers to the correct type, etc.) These past weeks are my first attempts at using templates. It is impressive how powerful they are. I have learned quite much from this forum. But, I obviously have quite a lot to learn. Best Regards, James
Aug 20 2021