digitalmars.D.learn - Template elegance?
- David Monagle (43/43) Jun 03 2015 Hi guys,
- anonymous (24/29) Jun 03 2015 Here you go:
- David Monagle (6/6) Jun 03 2015 Wow, thanks very much anonymous. I did try that as a solution but
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.
Jun 03 2015
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`.
Jun 03 2015
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.
Jun 03 2015