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));