lua userdata

Lua中实现位数组

#include <stdio.h>
#include <string.h>
#include <limits.h>
extern "C"
{
    #include "lua.h"
    #include "lauxlib.h"
    #include "lualib.h"
}

#define BITS_PER_WORD (CHAR_BIT*sizeof(int))
#define I_WORD(i) ((unsigned int)(i))/BITS_PER_WORD
#define I_BIT(i) (1<<((unsigned int)(i)%BITS_PER_WORD))

typedef struct NumArray
{
    int size;
    unsigned int values[1];
}NumArray;

extern "C" int newarray(lua_State * L)
{
    int n = luaL_checkinteger(L,1);
    luaL_argcheck(L,n>=1,1,"invalid size.");
    size_t nbytes = sizeof(NumArray)+I_WORD(n-1)*sizeof(int);

    NumArray* a = (NumArray*)lua_newuserdata(L,nbytes);
    a->size=n;

    luaL_getmetatable(L,"myarray");
    lua_setmetatable(L,-2);
    return 1;
}

extern "C" int setArray(lua_State * L)
{
    NumArray* a = (NumArray*)luaL_checkudata(L,1,"myarray");
    int index = luaL_checkinteger(L,2)-1;
    luaL_checkany(L,3);
    luaL_argcheck(L,a!=NULL,1,"array expected.");
    luaL_argcheck(L,0<=index&&index<a->size,2,"index out of range");
    if (lua_toboolean(L, 3))
        a->values[I_WORD(index)]|=I_BIT(index);
    else
        a->values[I_WORD(index)]&=~I_BIT(index);
    return 0;
}

extern "C" int getArray(lua_State * L)
{
    NumArray* a = (NumArray*) luaL_checkudata(L,1,"myarray");
    int index = luaL_checkinteger(L,2)-1;
    luaL_argcheck(L, a != NULL, 1, "array expected.");
    luaL_argcheck(L, 0 <= index && index < a->size, 2, "index out of range");
    lua_pushboolean(L,a->values[I_WORD(index)]&I_BIT(index));
    return 1;
}

extern "C" int getSize(lua_State * L)
{
    NumArray* a = (NumArray*)luaL_checkudata(L,1,"myarray");
    luaL_argcheck(L,a!=NULL,1,"array expected");
    lua_pushinteger(L,a->size);
    return 1;
}

extern "C" int array2string(lua_State * L)
{
    NumArray* a = (NumArray*)luaL_checkudata(L,1,"myarray");
    lua_pushfstring(L,"array(%d)",a->size);
    return 1;
}
static luaL_Reg arraylib[] = {
    {"new",newarray},
    {"set",setArray},
    {"get",getArray},
    {"size",getSize},
    {"__tostring",array2string},
    {NULL,NULL}
};

extern "C" __declspec(dllexport)
int luaopen_Array(lua_State * L)
{
    luaL_newmetatable(L,"myarray");
    lua_pushstring(L, "__index");
    lua_newtable(L);
    lua_pushstring(L,"set");
    lua_pushcclosure(L,setArray,0);
    lua_rawset(L,-3);

    lua_pushstring(L, "get");
    lua_pushcclosure(L, getArray, 0);
    lua_rawset(L, -3);

    lua_pushstring(L, "size");
    lua_pushcclosure(L, getSize, 0);
    lua_rawset(L, -3);

    lua_rawset(L,-3);
    luaL_newlib(L, arraylib);
    return 1;
}

lua调用代码

local array = require "Array"

a = array.new(1000)

a:set(3,true)

print(a:get(3))

print(a:size())

 

static luaL_Reg arraylib_f[] =
{
    {"new", newarray},
    {NULL, NULL}
};

static luaL_Reg arraylib_m[] =
{
    {"__tostring", array2string},
    {"__newindex", setArray},
    {"__index", getArray},
    {"__len", getSize},
    {NULL, NULL}
};

extern "C" __declspec(dllexport) int luaopen_Array(lua_State * L)
{
    luaL_newmetatable(L, "myarray");
    luaL_setfuncs(L, arraylib_m, 0);
    luaL_newlib(L, arraylib_f);

    return 1;
}

a = array.new(1000)

a[3]=true

print(a[3])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值