Thread overview
How to create a template class using foreach delegate to filter objects in a member function call?
May 30, 2019
Robert M. Münch
May 31, 2019
Alex
May 31, 2019
Robert M. Münch
Jun 01, 2019
Alex
Jun 01, 2019
Robert M. Münch
Jun 01, 2019
Alex
May 30, 2019
I have myClass and I want to add a way where I can provide a delegate to iterate over myClass.objects when a member function put(...) of myClass is called. The idea is that a user of myClass can provide something like an "iterator filter" so that the function is only called on a subset of myClass.objects.


myClass(E){
	myOtherClass!E objects;

	void put(E obj) {
		.put(objects, obj);
	}

	void put(T)(E obj, T filter) {
		foreach(o ; filter!E(objects)){
			.put(o, obj);
		}
	}
}

struct myFilter {
	myOtherClass!E object;

	opApply(int delegate(E) foreach_body) const {
		if(mytestfunc(object))
			return(foreach_body(object));
	}
}

But I'm struggeling how to write all this down with tempaltes, because E is not known in myFilter. But the filter code needs to be aware of the template type if myClass. I hope the idea want to do is understandable.

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

May 31, 2019
On Thursday, 30 May 2019 at 18:34:31 UTC, Robert M. Münch wrote:
> I have myClass and I want to add a way where I can provide a delegate to iterate over myClass.objects when a member function put(...) of myClass is called. The idea is that a user of myClass can provide something like an "iterator filter" so that the function is only called on a subset of myClass.objects.
>
>
> myClass(E){
> 	myOtherClass!E objects;
>
> 	void put(E obj) {
> 		.put(objects, obj);
> 	}
>
> 	void put(T)(E obj, T filter) {
> 		foreach(o ; filter!E(objects)){
> 			.put(o, obj);
> 		}
> 	}
> }
>
> struct myFilter {
> 	myOtherClass!E object;
>
> 	opApply(int delegate(E) foreach_body) const {
> 		if(mytestfunc(object))
> 			return(foreach_body(object));
> 	}
> }
>
> But I'm struggeling how to write all this down with tempaltes, because E is not known in myFilter. But the filter code needs to be aware of the template type if myClass. I hope the idea want to do is understandable.

Not sure, if I understood your problem correctly. It is meant that the class myClass defines an array of myOtherClass objects? The code does not compile and it does not provide an example, how you would apply the pattern, even in a non-compileable way... However,

commonly, a filter is a higher order function, which expects a predicate acting on each element of a set. Even if it's higher order, it is still a function, not a delegate. Therefore, it is unexpected, that you want to store something inside the filter.

Said this, I for myself had a similar problem. I solved this by reversing the hierarchy:
I templated my objects I wanted to use the filter on with the filter function and removed the need of the template parameter inside the filter.
You could still write a general filter function in this case, if you want. For example, you could use mixins for this...
As I said... not sure if this is of any help for you...
May 31, 2019
On 2019-05-31 11:07:00 +0000, Alex said:

> Not sure, if I understood your problem correctly.

I can imagine... I try my best :-)

> It is meant that the class myClass defines an array of myOtherClass objects?

Yes. So there is one class having an array of other stuff.

> The code does not compile and it does not provide an example, how you would apply the pattern, even in a non-compileable way...

The code is just to show the problem and not meant to compile. I couldn't get anything to compile...

> However, commonly, a filter is a higher order function, which expects a predicate acting on each element of a set. Even if it's higher order, it is still a function, not a delegate. Therefore, it is unexpected, that you want to store something inside the filter.

I choose filter to give a hint what the idea is, not meant to be that I want to use a filter.

> Said this, I for myself had a similar problem. I solved this by reversing the hierarchy: I templated my objects I wanted to use the filter on with the filter function and removed the need of the template parameter inside the filter.

The thing is, myClass is not under my control. It's coming from a library I don't maintain and I don't want to mess around with the code or if, as minimalistic as possible. That's why I was thinking about providing a put(T)... function.

My first idea was to sub-class myClass, but objects is private, so no chance to get access to it.

> You could still write a general filter function in this case, if you want. For example, you could use mixins for this...

Then myClass needs to somehow get the mixin in.

So, to summurize the problem: Given a class that manages an array of things as an OutputRange how can I provide a put() function with something like a filter-predicate? I only want to put() to some of the things, not all.

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

June 01, 2019
On Friday, 31 May 2019 at 16:24:28 UTC, Robert M. Münch wrote:
> The code is just to show the problem and not meant to compile. I couldn't get anything to compile...

That's ok, but could you provide an example anyway? Is it like this?

´´´
void main(){
    auto target = new myClass!int();
    target.objects.length = 4;
    auto val = 42;
    put(target, val, testfunction); // does the test function enters here?
    put(target, val);
    auto f = myFilter!int; // where do you want to use this entity?
}
´´´

>> Said this, I for myself had a similar problem. I solved this by reversing the hierarchy: I templated my objects I wanted to use the filter on with the filter function and removed the need of the template parameter inside the filter.
>
> The thing is, myClass is not under my control. It's coming from a library I don't maintain and I don't want to mess around with the code or if, as minimalistic as possible. That's why I was thinking about providing a put(T)... function.

*

>
> My first idea was to sub-class myClass, but objects is private, so no chance to get access to it.
>
>> You could still write a general filter function in this case, if you want. For example, you could use mixins for this...
>
> Then myClass needs to somehow get the mixin in.
>
> So, to summarize the problem: Given a class that manages an array of things as an OutputRange how can I provide a put() function with something like a filter-predicate? I only want to put() to some of the things, not all.

Do you have control about the contained classes? If so, it is a hint to implement the testing inside them. Like:

/* probably inside a templated mixin */
bool testfunction(inputs){...}

class myOtherClass(/*probably templated*/){... mixin testfunction ... & provide a put function}

* So, you are not totally against the idea of modifying the foreign library, but you want to keep modifications small? With the approach now, you could, for example, handle compile time blocks inside the put function in the myClass and dynamical ones inside the myOtherClasses.

class myClass(E){/* inserted put function */ void put(...){static if put action is at all possible --> put. }}
June 01, 2019
On 2019-06-01 04:43:13 +0000, Alex said:

> That's ok, but could you provide an example anyway? Is it like this?
> 
> ´´´
> void main(){
>      auto target = new myClass!int();
>      target.objects.length = 4;
>      auto val = 42;
>      put(target, val, testfunction); // does the test function enters here?
>      put(target, val);
>      auto f = myFilter!int; // where do you want to use this entity?
> }
> ´´´

myClass shouldn't be subclassed, only just used.

The myFilter struct is the implementation which myClass.put() should use to iterate over all objects. All things being only examples. So, the idea is, that I can provide a delegate which foreach(...; myFilter(objects)) uses. Like a run-time plug-in.

> Do you have control about the contained classes? If so, it is a hint to implement the testing inside them. Like:
> 
> /* probably inside a templated mixin */
> bool testfunction(inputs){...}
> 
> class myOtherClass(/*probably templated*/){... mixin testfunction ... & provide a put function}

I thought about a mixin too. But this requires an understanding of how myClass works. Which I what I want to avoid.

> * So, you are not totally against the idea of modifying the foreign library, but you want to keep modifications small?

Yes, because myClass is some external lib, which can be changed to support this approach here. But not more.

> With the approach now, you could, for example, handle compile time blocks inside the put function in the myClass and dynamical ones inside the myOtherClasses. class myClass(E){/* inserted put function */ void put(...){static if put action is at all possible --> put. }}

As said, KISS and really just want to provide a plug-in which is used to iterate of a sequence I provide from the outside.

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

June 01, 2019
On Saturday, 1 June 2019 at 14:24:11 UTC, Robert M. Münch wrote:
>
> The myFilter struct is the implementation which myClass.put() should use to iterate over all objects.

Which ones? The E-objects, or the objects contained in myClass, which you don't want to know about?

> All things being only examples.

Sure. So, please, provide a minimal example, as I'm only guessing what use case you want to solve. Even if it is not compilable.

> So, the idea is, that I can provide a delegate which foreach(...; myFilter(objects)) uses. Like a run-time plug-in.

Maybe you can. But "put" has to remain a function, not a template.

>
>> Do you have control about the contained classes? If so, it is a hint to implement the testing inside them. Like:
>> 
>> /* probably inside a templated mixin */
>> bool testfunction(inputs){...}
>> 
>> class myOtherClass(/*probably templated*/){... mixin testfunction ... & provide a put function}
>
> I thought about a mixin too. But this requires an understanding of how myClass works. Which I what I want to avoid.

Over which objects your filter will be iterating then?

>> * So, you are not totally against the idea of modifying the foreign library, but you want to keep modifications small?
>
> Yes, because myClass is some external lib, which can be changed to support this approach here. But not more.