Choice ranges?

H. S. Teoh hsteoh at quickfur.ath.cx
Fri Mar 28 18:39:47 PDT 2014


On Sat, Mar 29, 2014 at 01:37:42AM +0100, Artur Skawina wrote:
[...]
> D is statically typed -- there is no way for one function to return
> different types that are selected by a runtime condition.
> The fact that the produced elements have the same type is irrelevant.
> 
> You can wrap the range in a common one. When the above approach isn't
> enough, there's always the next level:
> 
>    struct DynRange(R, F...) {
>       R r;
>       /*immutable*/ size_t n;
> 
>       static _ugh() { string r; foreach (N, _; F) r~="typeof(F["~N.stringof~"](r)) f"~N.stringof~";"; return r; }
>       union U { mixin(_ugh()); }
>       U u;

Heh, I thought of using a union as well. :P


[...]
> [Optimizing DynRange is left as an exercise for the reader. ;) In
> practice, when used with just two chains, the gain would be minimal
> anyway. Adding a level of indirection for the range primitives would
> prevent inlining.] 
[...]

Yeah. :(  One idea I had was to use function pointers for .empty,
.front, .popFront, but that also prevents inlining. But it seems
inevitable that something like this has to be done if runtime
polymorphism is needed.

Another (very ugly) approach might be to use compile-time branches in
the caller:

	auto polymorphicRange(size_t i, R...)(R ranges)
	{
		static if (i==0)
			return ranges[0];
		else static if (i==1)
			return ranges[1];
		else ... // etc
	}

	void processRange(R)(R range) { ... }

	void unfortunateConsumer(size_t i)
	{
		auto RangeA = ...;
		auto RangeB = ...;
		...

		if (i==0)
			processRange(polymorphicRange!0(RangeA, RangeB));
		else if (i==1)
			processRange(polymorphicRange!1(RangeA, RangeB));
		else
			...
	}

This way, you get the advantage of inlining in processRange, but then
you have to suffer from the very ugly boilerplate and the template
bloat. And it doesn't generalize well to multiple nested polymorphic
ranges (unfortunateConsumer will basically have to enumerate all
possible combinations and instantiate each of them separately). :-(

Some days you win, most days you lose...


T

-- 
WINDOWS = Will Install Needless Data On Whole System -- CompuMan


More information about the Digitalmars-d-learn mailing list