[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: A Lua implementation of boost::bind
- From: Peter Cawley <lua@...>
- Date: Mon, 6 Apr 2009 16:16:23 +0100
The following examples do not work as I'd expect them to:
bbind (print,nil) () --> nothing ; should be nil?
bbind (print,nil,_1) (1) --> nothing; should be nil 1?
bbind (print,_3,_3) (1,2,3) --> table table; should be 3 3?
On Mon, Apr 6, 2009 at 2:51 PM, steve donovan <steve.j.donovan@gmail.com> wrote:
> Hi all,
>
> This demonstrates how to implement boost::bind while still producing
> an efficient binding. The key is code generation. So e.g. bbind
> (print,_2,_1,true) will generate the following code string:
>
> return function (fn,_v1)
> return function(_1,_2) return fn(_2,_1,_v1) end
> end
>
> Which is then compiled and called twice, first to compile the wrapper
> function and next to extract the wrapped function.
>
> This is of course a relatively expensive function, but the resulting
> binding is fast.
>
> steve d.
>
>
> -- testbind.lua
> -- Lua implementation of boost::bind
> -- http://www.boost.org/doc/libs/1_38_0/libs/bind/bind.html
> local append = table.insert
> local concat = table.concat
>
> _1,_2,_3,_4,_5 = {'_1'},{'_2'},{'_3'},{'_4'},{'_5'}
> local placeholders = {[_1]=true,[_2]=true,[_3]=true,[_4]=true,[_5]=true}
>
> function bbind(fn,...)
> local args = {...}
> local holders,parms,bvalues,values = {},{},{'fn'},{}
> local np,nv = 1,1
> for i,a in ipairs(args) do
> if placeholders[a] then
> append(holders,a[1])
> append(parms,'_'..np)
> np = np + 1
> else
> local v = '_v'..nv
> append(bvalues,v)
> append(holders,v)
> append(values,a)
> nv = nv + 1
> end
> end
> bvalues = concat(bvalues,',')
> parms = concat(parms,',')
> holders = concat(holders,',')
> local fstr = ([[
> return function (%s)
> return function(%s) return fn(%s) end
> end
> ]]):format(bvalues,parms,holders)
> local res,err = loadstring(fstr)
> res = res()
> return res(fn,unpack(values))
> end
>
>
>
> bbind (print,_1,_2,true) (1,2)
> -- 1 2 true
> bbind (print,_2,_1,false) (1,2)
> -- 2 1 false
> bbind (print,_2,_1) (1,2)
> -- 2 1
> bbind (print,10,_1,20) (1)
> -- 10 1 20
>