digitalmars.D - Downgrading ranges
- Lars T. Kyllingstad (32/32) Jun 09 2013 A recent pull request discussion got me thinking: The ability to
- Peter Alexander (6/10) Jun 09 2013 "Particularly for testing", or *only* for testing? Is there any
- Lars T. Kyllingstad (5/17) Jun 09 2013 I was kind of hoping someone else would come up with examples. :)
- Peter Alexander (2/7) Jun 09 2013 Ignore me. I'm not thinking.
- Jonathan M Davis (7/19) Jun 09 2013 I was working on a good solution for this which would allow you to creat...
- Andrej Mitrovic (23/31) Jun 09 2013 Well, those are range *types*, not features. So name it RangeType perhap...
- Lars T. Kyllingstad (10/16) Jun 10 2013 One solution which has come up in the aforementioned pull request
A recent pull request discussion got me thinking: The ability to "downgrade" a range to a less featureful one -- wrapping a random access range in an input range, say -- can be very useful sometimes, particularly for testing. The pull request in question was Walter's LZ77 module, where he has added an input range type solely for the purpose of ensuring that all code paths are exercised in unittests. Coincidentally, I currently find myself in need of the exact same functionality for a piece of range code I'm working on. I think this would be a generally useful thing, enough so to warrant its inclusion in std.range. It's also rather trivial to implement. The question is, what is a good API? I'm thinking a single type which can be instantiated differently based on template parameters. It is important that the range never aliases itself away to the wrapped type, as that would somewhat defeat its purpose. Example: enum RangeFeatures { input, forward, randomAccess, ... } struct RestrictedRange(Range, RangeFeatures features) { private Range m_range; static if (features == RangeFeatures.input) { auto front() property { return m_range.front() } } }
Jun 09 2013
On Sunday, 9 June 2013 at 12:19:47 UTC, Lars T. Kyllingstad wrote:A recent pull request discussion got me thinking: The ability to "downgrade" a range to a less featureful one -- wrapping a random access range in an input range, say -- can be very useful sometimes, particularly for testing."Particularly for testing", or *only* for testing? Is there any other use? (I can't think of any non-contrived use case beyond testing). If it's just for testing, would it not be better to just supply a variety of test ranges that implement all combinations of traits?
Jun 09 2013
On Sunday, 9 June 2013 at 12:25:45 UTC, Peter Alexander wrote:On Sunday, 9 June 2013 at 12:19:47 UTC, Lars T. Kyllingstad wrote:I was kind of hoping someone else would come up with examples. :) Jokes aside, maybe it's only good for testing. But testing is important enough.A recent pull request discussion got me thinking: The ability to "downgrade" a range to a less featureful one -- wrapping a random access range in an input range, say -- can be very useful sometimes, particularly for testing."Particularly for testing", or *only* for testing? Is there any other use? (I can't think of any non-contrived use case beyond testing).If it's just for testing, would it not be better to just supply a variety of test ranges that implement all combinations of traits?I'm not sure I see the difference.
Jun 09 2013
On Sunday, 9 June 2013 at 12:42:10 UTC, Lars T. Kyllingstad wrote:On Sunday, 9 June 2013 at 12:25:45 UTC, Peter Alexander wrote:Ignore me. I'm not thinking.If it's just for testing, would it not be better to just supply a variety of test ranges that implement all combinations of traits?I'm not sure I see the difference.
Jun 09 2013
On Sunday, June 09, 2013 14:25:44 Peter Alexander wrote:On Sunday, 9 June 2013 at 12:19:47 UTC, Lars T. Kyllingstad wrote:I was working on a good solution for this which would allow you to create a test range with pretty much any combination of range capabilities you wanted (as well as providing a default set of ranges to test with), but some compiler bugs were blocking me at the time, and I haven't gotten back to it yet. I really should finish that up. - Jonathan M DavisA recent pull request discussion got me thinking: The ability to "downgrade" a range to a less featureful one -- wrapping a random access range in an input range, say -- can be very useful sometimes, particularly for testing."Particularly for testing", or *only* for testing? Is there any other use? (I can't think of any non-contrived use case beyond testing). If it's just for testing, would it not be better to just supply a variety of test ranges that implement all combinations of traits?
Jun 09 2013
On 6/9/13, Lars T. Kyllingstad <public kyllingen.net> wrote:Example: enum RangeFeatures { input, forward, randomAccess, ... }Well, those are range *types*, not features. So name it RangeType perhaps. Alternatively: enum RangeFeatures { emptyEnum, // e.g. enum bool empty = true; emptyProperty, // e.g. property bool empty() { } indexable, // e.g. range[0] sliceable, // e.g. range[] hasFront, hasPopFront, hasBack, hasPopBack, hasSave, } And then autogenerate all of those somehow. Or just provide simple wrappers ala "toInputRange", "toBidirectionalRange", etc. Long story-short I do think we need these simulation ranges in std.range, exactly for unittesting purposes. There is a lot of throwaway range implementations in unittest blocks in Phobos (and many other libraries) used for the sole purpose of unittesting. It would be much simpler to be able to use "testMyFunction([1, 2, 3].toInputRange)" or something to that effect.
Jun 09 2013
On Sunday, 9 June 2013 at 12:19:47 UTC, Lars T. Kyllingstad wrote:A recent pull request discussion got me thinking: The ability to "downgrade" a range to a less featureful one -- wrapping a random access range in an input range, say -- can be very useful sometimes, particularly for testing. The pull request in question was Walter's LZ77 module, [...]One solution which has come up in the aforementioned pull request discussion (thanks to Daniel Murphy) is to downcast the result of std.range.inputRangeObject() to the desired interface. Intf!(ElementEncodingType!R) downgrade(alias Intf, R)(R rng) { return inputRangeObject(rng); } auto someInputRange = downgrade!InputRange(someRandAccRange); Maybe this is good enough for testing purposes?
Jun 10 2013