Lua之实现一个bool数组

版权声明:本文来自行者(http://blog.csdn.net/liuyuan185442111),转载请注明出处。 https://blog.csdn.net/liuyuan185442111/article/details/74331784

参考《Lua程序设计》第28章 用户自定义类型

#include <stdlib.h>
#include <limits.h>
#include "lua.h"
#include "lauxlib.h"

#define BITS_PER_WORD (CHAR_BIT*sizeof(unsigned int))
#define I_WORD(n) ((n-1+BITS_PER_WORD)/BITS_PER_WORD)
#define I_MASK(n) (1<<((n-1)%BITS_PER_WORD))

typedef struct BoolArray {
    int size;
    unsigned int value[0];
} BoolArray;

static int newArray(lua_State *L)
{
    int n = luaL_checkint(L, 1);
    luaL_argcheck(L, n>0, 1, "invalid size");
    int nbytes = sizeof(int) + sizeof(unsigned int)*I_WORD(n);
    BoolArray *b = (BoolArray*)lua_newuserdata(L, nbytes);
    b->size = n;
    int i=0;
    for(; i<I_WORD(n); ++i)
        b->value[i] = 0;
    luaL_getmetatable(L, "ba.meta");
    lua_setmetatable(L, -2);//将创建的userdata的metatable设为栈顶的ba.meta
    return 1;
}

static int setArray(lua_State *L)
{
    BoolArray *b = (BoolArray*)luaL_checkudata(L, 1, "ba.meta");
    int index = luaL_checkint(L, 2);
    luaL_argcheck(L, index>0 && index<=b->size, 1, "index out of range");
    if(lua_toboolean(L, 3))
        b->value[I_WORD(index)] |= I_MASK(index);
    else
        b->value[I_WORD(index)] &= ~I_MASK(index);
    return 0;
}

static int getArray(lua_State *L)
{
    BoolArray *b = (BoolArray*)luaL_checkudata(L, 1, "ba.meta");
    int index = luaL_checkint(L, 2);
    luaL_argcheck(L, index>0 && index<=b->size, 1, "index out of range");
    lua_pushboolean(L, b->value[I_WORD(index)] & I_MASK(index));
    return 1;
}

static int getSize(lua_State *L)
{
    BoolArray *b = (BoolArray*)luaL_checkudata(L, 1, "ba.meta");
    lua_pushinteger(L, b->size);
    return 1;
}

static const luaL_Reg lib[] = {
    {"new", newArray},
    {NULL, NULL}
};
static const luaL_Reg lib_m[] = {
    {"size", getSize},
    {"set", setArray},
    {"get", getArray},
    {NULL, NULL}
};

LUA_API int luaopen_boolarray (lua_State *L) {
    luaL_newmetatable(L, "ba.meta");//创建一个metatable
    lua_pushvalue(L, -1);//复制它
    lua_setfield(L, -2, "__index");//将它的__index指向它自己
    luaL_register(L, NULL, lib_m);//为栈顶的table添加一些成员
    luaL_register(L, "boolarray", lib);//创建名为boolarray的table,并为其添加一个new成员
    return 1;
}

编译
gcc -fpic -shared boolarray.c -o boolarray.so

测试

require "boolarray"
m=boolarray.new(4)
print(m:size())
m:set(3,true)
m:set(2,false)
print(m:get(1))
print(m:get(2))
print(m:get(3))
print(m:get(4))

猜你喜欢

转载自blog.csdn.net/liuyuan185442111/article/details/74331784
今日推荐