Trying to use a template class with ranges
Steven Schveighoffer
schveiguy at gmail.com
Thu Feb 6 15:21:46 UTC 2020
On 2/6/20 7:16 AM, mark wrote:
> I am starting on porting Python's difflib's sequence matcher to D.
>
> I want to have a class that will accept two ranges whose elements are of
> the same type and whose elements can be compared for equality.
>
> How do I make a class declaration that specifies a (forward) range type
> and an equality-supporting element type?
>
> Here's what doesn't work:
>
> class Diff(T, E) {
> T a; // T should be a forward range of E elements
> T b; // E elements must support == and !=
> // This is a hash key=E element, value=slice of size_t
> size_t[][E] b2j;
>
> this(T a, T b) {
> this.a = a;
> this.b = b;
> chainB();
> }
>
> void chainB() {
> foreach (i, element; b)
> b2j[element] ~= i;
> // TODO
> }
> }
>
> unittest {
> import std.stdio: writeln;
>
> writeln("unittest for the diffrange library.");
> auto a = ["Tulips are yellow,", "Violets are blue,",
> "Agar is sweet,", "As are you."];
> auto b = ["Roses are red,", "Violets are blue,",
> "Sugar is sweet,", "And so are you."];
> auto diff = Diff(a, b);
> }
>
1. If one template parameter depends 100% on the other, it doesn't need
to be a parameter. i.e. I would do:
class Diff(T) {
alias E = ElementType!T;
...
}
2. Class constructors do not support IFTI. You have to explicitly
instantiate. To use IFTI, you need to create a factory function. i.e. to
make the code above work, your ctor call should be Diff!(typeof(a))
(assuming you take the advice in 1).
But you can instead write a function to use IFTI:
auto makeDiff(T)(T r1, T r2) { return Diff!T(r1, r2); }
...
auto diff = makeDiff(a, b);
3. You should declare constraints signifying what types are valid. i.e.:
class Diff(T) if (
isForwardRange!T // it's a forward range
&& is(typeof(T.init.front == T.init.front)) // elements are comparable
)
Might be good to put this constraint on the factory function too.
Note: is(typeof(...)) basically checks if the thing inside the typeof
compiles.
-Steve
More information about the Digitalmars-d-learn
mailing list