digitalmars.D.learn - Generic comparison
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (8/8) Nov 10 2020 I want to implement a generic function for "a < f(x) < b" that
- Paul Backus (11/19) Nov 10 2020 bool between(Value, Bound)(auto ref Value value, auto ref Bound
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (7/16) Nov 10 2020 Interesting, so "auto ref T" is the go-to type specifier for
- Paul Backus (13/19) Nov 10 2020 The compiler infers pure, @nogc, nothrow etc. for template
- Paul Backus (2/4) Nov 10 2020 My bad, should be `enum`, not `alias`.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (2/5) Nov 10 2020 Ok, thanks :-).
I want to implement a generic function for "a < f(x) < b" that will give the same result as "(a < f(x)) && (f(x) < b)" for any conceivable mix of types. Except if that "f(x)" should only be evaluated once. Is it sufficient to use "scope ref" in parameters? I don't want to assume _anything_ about the definition of the types and the implementation of the comparison operator (can be overloaded).
Nov 10 2020
On Tuesday, 10 November 2020 at 16:55:11 UTC, Ola Fosheim Grøstad wrote:I want to implement a generic function for "a < f(x) < b" that will give the same result as "(a < f(x)) && (f(x) < b)" for any conceivable mix of types. Except if that "f(x)" should only be evaluated once. Is it sufficient to use "scope ref" in parameters? I don't want to assume _anything_ about the definition of the types and the implementation of the comparison operator (can be overloaded).bool between(Value, Bound)(auto ref Value value, auto ref Bound low, auto ref Bound high) { return (low < value) && (value < high); } You need `auto ref` because either Bound or Value may have copying disabled. Because the function is a template, attributes like `scope` will be inferred when applicable (modulo compiler bugs).
Nov 10 2020
On Tuesday, 10 November 2020 at 17:09:00 UTC, Paul Backus wrote:bool between(Value, Bound)(auto ref Value value, auto ref Bound low, auto ref Bound high) { return (low < value) && (value < high); } You need `auto ref` because either Bound or Value may have copying disabled. Because the function is a template, attributes like `scope` will be inferred when applicable (modulo compiler bugs).Interesting, so "auto ref T" is the go-to type specifier for generic code then? I guess I also should conditionally add things like pure, nogc, nothrow... I assume I would have to test the comparison operator. I actually want to implement (low <= value) && (value < high) So I guess I need to test both. But how...? compiles-trait?
Nov 10 2020
On Tuesday, 10 November 2020 at 17:19:09 UTC, Ola Fosheim Grøstad wrote:Interesting, so "auto ref T" is the go-to type specifier for generic code then? I guess I also should conditionally add things like pure, nogc, nothrow... I assume I would have to test the comparison operator. I actually want to implementThe compiler infers pure, nogc, nothrow etc. for template functions automatically. It's actually better if you don't add them by hand.(low <= value) && (value < high) So I guess I need to test both. But how...? compiles-trait?You could add a template constraint, if you wanted. Something like: alias isOrderingComparableWith(T, U) = __traits(compiles, (T t, U u) => t < u); bool between(Value, Bound)(...) if (isOrderingComparaibleWith!(Value, Bound)) For a function this short, though, I don't think it's really necessary.
Nov 10 2020
On Tuesday, 10 November 2020 at 20:32:40 UTC, Paul Backus wrote:alias isOrderingComparableWith(T, U) = __traits(compiles, (T t, U u) => t < u);My bad, should be `enum`, not `alias`.
Nov 10 2020
On Tuesday, 10 November 2020 at 20:32:40 UTC, Paul Backus wrote:The compiler infers pure, nogc, nothrow etc. for template functions automatically. It's actually better if you don't add them by hand.Ok, thanks :-).
Nov 10 2020