On Sunday, 8 December 2019 at 01:10:21 UTC, AA wrote:
I'd like to accept the return type of map. From some previous questions that I should accept a template?
So for something like:

```
void mapAccepter(Range)(Range r)
{
    import std.array : array;
    import std.stdio : writeln;

    auto collected = r.array;
    writeln(collected);
}

void main()
{
    import std.algorithm.iteration : map;

    int[] nums = [1, 2, 3];
    auto evenness = map!(n => n % 2 == 0)(nums);
    mapAccepter(evenness);
}
```

1) Is there any way I can make `mapAccepter` not a templated function?

Yes (mostly, anyway), using the interfaces in std.range.interfaces:
https://dlang.org/phobos/std_range_interfaces.html

import std.algorithm;
import std.range;

void mapAccepter(E)(InputRange!E r)
{
    import std.array: array;
    import std.stdio: writeln;

    auto collected = r.array;
    writeln(collected);
}

void main()
{
    int[] nums = [1, 2, 3];
    auto evenness = inputRangeObject(map!(n => n % 2 == 0)(nums));
    mapAccepter(evenness);
}

`mapAccepter` still needs to be templated on the element type of the range, but there are ways to avoid that as well, if desired. I wouldn't recommend it,
however, as it wouldn't be that useful in this case.

2) Is there any way if I need to make `mapAccepter` templated to constrain Range to be a range of booleans.

Yup, there are two ways that you you primarily do that. Either
constraining E in the template declaration, or adding a constraint
on the template. Generally option 2 is the more idiomatic D way.

Option 1: constrain E to be of type bool:
void mapAccepter(E: bool)(InputRange!E r);

OR

void mapAccepter(E)(InputRange!E r)
if (is(E == bool));

There's not much difference between these two, but the latter is probably preferred.

Option 2: use std.traits and a template constraint:
void mapAccepter(E)(InputRange!E r)
if (is(ElementType!r == bool));

Reply via email to