[Challenge] implementing the ambiguous operator in D
Philippe Sigaud
philippe.sigaud at gmail.com
Fri Sep 3 23:58:18 PDT 2010
On Sat, Sep 4, 2010 at 01:40, Simen kjaeraas <simen.kjaras at gmail.com> wrote:
> Simen kjaeraas <simen.kjaras at gmail.com> wrote:
>
> I believe this will only work with arrays as input. Either that, or I need
>> a way to make this work:
>>
>> struct Foo( R ) if ( isForwardRange!R ) {
>> bool delegate( ElementType!R ) bar;
>> Filter!( bar, R ) range;
>> }
>>
>> Or, well, something like it. I need a static type for a Filter that
>> delegates to a struct member, in this case bar.
>>
>
Maybe with a dynamic filter?
struct DynamicFilter(R) if (isInputRange!R)
{
R range;
bool delegate(ElementType!R) predicate;
bool set;
this(R _range) { range = _range; }
this(R _range, bool delegate(ElementType!R) _predicate) { range =
_range; predicate = _predicate; set = true; popFront(); }
void setPredicate(bool delegate(ElementType!R) _predicate) { predicate =
_predicate; set = true; popFront();}
ElementType!R front() { if (set) { return range.front();} else { throw
new Exception("Calling DynamicFilter with an unset predicate.");};}
bool empty() { if (set) {return range.empty;} else { throw new
Exception("Calling DynamicFilter with an unset predicate.");};}
void popFront()
{
if (set)
{
while( !range.empty && !predicate(range.front))
{
range.popFront();
}
}
else
{
throw new Exception("Calling DynamicFilter with an unset
predicate.");
}
}
}
//DynamicFilter!(R) dynamicFilter(R)(R range)
//{
// return DynamicFilter!R(range);
//}
DynamicFilter!(R) dynamicFilter(R,E)(R range, bool delegate(E) pred = null)
if ((isInputRange!R) && is(ElementType!R == E))
{
if (pred is null)
return DynamicFilter!(R)(range);
else
return DynamicFilter!R(range, pred);
}
void main()
{
auto f = dynamicFilter([0,1,2,3], (int i) { return i%2 == 0;});
writeln(f.front); // 0
f.setPredicate((int i) { return i%2 == 1;});
writeln(f.front); // 1
}
Note that in this version, the filtered range always advances. When you
change filter, it continues to consume elements from the current point. For
backtracking, maybe you need a forward range input, a saved version of this
input, and have setPredicate rewind the inner range to the saved version.
Philippe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20100904/c789161d/attachment.html>
More information about the Digitalmars-d
mailing list