| Thread overview | |||||
|---|---|---|---|---|---|
|
June 03, 2015 Template elegance? | ||||
|---|---|---|---|---|
| ||||
Hi guys,
I was hoping some of you more experience D guys could educate me on this one.
Given the following code:
///////
// Template function
bool shouldValue(alias operation, string description, E, V)(lazy E expression, V value, string name="Value", string file = __FILE__, typeof(__LINE__) line = __LINE__) {
if (operation(expression, value)) return true;
throw new FeatureTestException(format("%s should %s %s, but was actually %s", name, description, value, expression), file, line);
}
// Utility functions that use the above template
bool shouldEqual(E, V)(lazy E expression, V value, string name="Value", string file = __FILE__, typeof(__LINE__) line = __LINE__) {
return shouldValue!((e, v) => e == v, "equal")(expression, value, name, file, line);
}
bool shouldBeGreaterThan(E, V)(lazy E expression, V value, string name="Value", string file = __FILE__, typeof(__LINE__) line = __LINE__) {
return shouldValue!((e, v) => e > v, "equal")(expression, value, name, file, line);
}
///////
The above works just fine. If I call something like:
value.shouldBeGreaterThan(5)
I get the expected results.
What I was looking for is a more elegant way of defining those secondary functions. Originally I was hoping I could do something like:
enum shouldEqual(E, V) = shouldValue((e, v) => e == v, "equal", E, V);
But that doesn't work as any call to result.shouldEqual(5) does results in the template being called with no TEMPLATE parameters. I understand this, however I was hoping there was a nice way of defining this functionality. I concede that my code above may already be as short and concise as I can get it.
Thanks in advance!
David.
| ||||
June 03, 2015 Re: Template elegance? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to David Monagle | On Wednesday, 3 June 2015 at 09:10:22 UTC, David Monagle wrote:
> What I was looking for is a more elegant way of defining those secondary functions. Originally I was hoping I could do something like:
>
> enum shouldEqual(E, V) = shouldValue((e, v) => e == v, "equal", E, V);
Here you go:
----
template shouldValue(alias operation, string description)
{
bool shouldValue(E, V)(lazy E expression, V value, string name="Value",
string file = __FILE__, typeof(__LINE__) line = __LINE__)
{
if (operation(expression, value)) return true;
throw new Exception(format("%s should %s %s, but was actually %s",
name, description, value, expression), file, line);
}
}
alias shouldEqual = shouldValue!((e, v) => e == v, "equal");
alias shouldBeGreaterThan = shouldValue!((e, v) => e > v, "be greater than");
----
The trick is to split `shouldValue` into two nested templates.
The outer template has those parameters that cannot be deduced: `operation` and `description`.
The inner template has the parameters that should be deduced: `E` and `V`.
| |||
June 03, 2015 Re: Template elegance? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to anonymous | Wow, thanks very much anonymous. I did try that as a solution but stupid me was using an enum rather than an alias for the "shortcut" functions. Been staring at the problem for so long that I couldn't see the problem right in front of me! Appreciate the help greatly. Code now looks elegant again. | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply