www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - vtbl jamming

reply BCS <ao pathlink.com> writes:
can we get some way to do this?

http://www.artima.com/cppsource/backyard2.html
Sep 09 2007
next sibling parent reply "Vladimir Panteleev" <thecybershadow gmail.com> writes:
On Mon, 10 Sep 2007 09:40:59 +0300, BCS <ao pathlink.com> wrote:

 can we get some way to do this?

 http://www.artima.com/cppsource/backyard2.html

Modifying VTBLs is effectively the same as using method pointers (as a static field). The advantage is when we don't have access to the base class. Of course, D doesn't have method pointers (like C++), so... -- Best regards, Vladimir mailto:thecybershadow gmail.com
Sep 10 2007
next sibling parent reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
Vladimir Panteleev wrote:
 On Mon, 10 Sep 2007 09:40:59 +0300, BCS <ao pathlink.com> wrote:
 
 
 can we get some way to do this?
 
 http://www.artima.com/cppsource/backyard2.html

Modifying VTBLs is effectively the same as using method pointers (as a static field). The advantage is when we don't have access to the base class. Of course, D doesn't have method pointers (like C++), so...

It sort of does. You can fake them with delegates: class Foo { void bar() { writefln("Foo.bar"); } } void ptr_call(void function() fn, Object o) { void delegate() dg; dg.ptr = o; dg.funcptr = fn; dg(); } void main() { auto f = new Foo; void function() fn = &Foo.bar; ptr_call(fn, f); } I write this without testing it, and may have left out a cast or two. But the idea is sound. (Indeed, Pyd relies on it.) -- Kirk McDonald http://kirkmcdonald.blogspot.com Pyd: Connecting D and Python http://pyd.dsource.org
Sep 10 2007
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Kirk McDonald" <kirklin.mcdonald gmail.com> wrote in message 
news:fc35na$30pq$1 digitalmars.com...
 It sort of does. You can fake them with delegates:

 class Foo {
     void bar() { writefln("Foo.bar"); }
 }

 void ptr_call(void function() fn, Object o) {
     void delegate() dg;
     dg.ptr = o;
     dg.funcptr = fn;
     dg();
 }

 void main() {
     auto f = new Foo;
     void function() fn = &Foo.bar;
     ptr_call(fn, f);
 }

 I write this without testing it, and may have left out a cast or two. But 
 the idea is sound. (Indeed, Pyd relies on it.)

Here's another way, which does it all at compile time. It also has the advantage of doing a polymorphic call. struct PTM(Type, char[] name) { const fullName = Type.stringof ~ "." ~ name; alias ReturnTypeOf!(mixin(fullName)) Ret; alias ParameterTupleOf!(mixin(fullName)) Params; Ret opCall(Type obj, Params params) { mixin("return obj." ~ name ~ "(params);"); } } class A { void foo() { Stdout.formatln("Foo!"); } int bar(int x) { Stdout.formatln("Bar: {}", x); return x * 2; } } void main() { scope a = new A(); PTM!(A, "foo") f; PTM!(A, "bar") b; f(a); Stdout.formatln("Got: {}", b(a, 6)); } It also has fairly similar semantics to C++'s pointers-to-methods: each PTM is associated with a single class and with a single method. I'm sure you could make it a little more flexible though, at the cost of having to manually specify the parameter types when creating the PTM. (Also note that the PTM struct is 1 byte.)
Sep 10 2007
prev sibling parent BCS <ao pathlink.com> writes:
Reply to Vladimir,

 On Mon, 10 Sep 2007 09:40:59 +0300, BCS <ao pathlink.com> wrote:
 
 can we get some way to do this?
 
 http://www.artima.com/cppsource/backyard2.html
 

static field). The advantage is when we don't have access to the base class. Of course, D doesn't have method pointers (like C++), so...

The first use case that came to mind for me was a caching system. The first constructed object is a proxy with no data in it. The first time you ask for data, the data gets loaded and then the type gets switched so only a simple get is done next time. No ifs needed.
Sep 10 2007
prev sibling parent Lutger <lutger.blijdestijn gmail.com> writes:
BCS wrote:
 can we get some way to do this?
 
 http://www.artima.com/cppsource/backyard2.html
 
 

We can do it the same way in D, perhaps it can be done better. Or is that what you're asking? If so, ignore this then: At least the caveats mentioned in the article either do not exist (standard ABI) or can be checked at compile time. This seems to work in D as well: class Collection { void toSingle() { *(cast(void**)this) = *(cast(void**)SingleThreadedCollection.tmp); } }
Sep 10 2007