lua bitset

bitset = {}
function bitset.new(self,bitset_size)
    local function bit_make_debug_data(data,is_debug)
        local debug_data = {}
        if is_debug then
            local num_bit_conunt = 31
            for index = 1, #data do
                for loop = 0, num_bit_conunt do
                    local a = ( 1 << loop)
                    local b = data[index] & a
                    if a == b then
                        debug_data[loop + (index - 1) * num_bit_conunt] = true
                    end
                end
            end

        end
        return debug_data
    end
    local function bit_and(num_l,num_r)
        return num_l & num_r
    end
    local function bit_or(num_l,num_r)
        return num_l | num_r
    end
    local function bit_xor(num_l,num_r)
        return num_l ~ num_r
    end
    local function bit_not(obj_l)
        for loop = 1,#obj_l.data do
            obj_l.data[loop] = ~obj_l.data[loop]
        end
        obj_l.debug_data = bit_make_debug_data(obj_l.data,obj_l.is_debug)
        return obj_l
    end
    local function bit_sub(obj_l,obj_r)
        if obj_l:size() ~= obj_r:size() then
            assert(false)
        end
        local temp
        if obj_l == obj_r then
            temp = deep_copy(obj_l)
            return temp
        end
        temp = obj_l & obj_r
        temp.debug_data = bit_make_debug_data(temp.data,temp.is_debug)
        return temp
    end
    local function bit_add(obj_l,obj_r)
        if obj_l:size() ~= obj_r:size() then
            assert(false)
        end
        local temp
        if obj_l == obj_r then
            temp = deep_copy(obj_l)
            return temp
        end
        temp = obj_l | obj_r
        temp.debug_data = bit_make_debug_data(temp.data,temp.is_debug)
        return temp
    end
    local function bit_eq(obj_l,obj_r)
        if type(obj_l) == type(obj_r) then
            if type(obj_l) == "table" then
                if getn(obj_l) ~= getn(obj_r) then
                    return false
                end
                for k,v in pairs(obj_l) do
                    if(bit_eq(v,obj_r[k])) == false then
                        return false
                    end
                end
                return true
            else
                return obj_l == obj_r
            end
        end
        return false
    end
    local function bit_operator(obj_l,obj_r,op)
        if obj_l:size() ~= obj_r:size() then
            assert(false)
        end
        local temp = bitset:new(obj_l:size())
        local loop_end = #obj_l.data > #obj_r.data and #obj_l.data or #obj_r.data
        for loop_begin = 1,loop_end do
            local left_value    = 0
            if obj_l.data[loop_begin] ~= nil then
                left_value = obj_l.data[loop_begin]
            end
            local right_value   = 0
            if obj_r.data[loop_begin] ~= nil then
                right_value = obj_r.data[loop_begin]
            end
            temp.data[loop_begin] = op(left_value,right_value)
        end
        temp.is_debug = obj_l.is_debug
        temp.debug_data = bit_make_debug_data(temp.data,temp.is_debug)
        return temp
    end

    local mt =
    {
        __index=bitset,
        __band = function(Args1,Args2)
            return bit_operator(Args1,Args2,bit_and)
        end,
        __bor = function(Args1,Args2)
            return bit_operator(Args1,Args2,bit_or)
        end,
        __bxor = function(Args1,Args2)
            return bit_operator(Args1,Args2,bit_xor)
        end,
        __bnot = function(Args1)
            return bit_not(Args1)
        end,
        __sub = function(Args1,Args2)
            return bit_sub(Args1,Args2)
        end,
        __add = function(Args1,Args2)
            return bit_add(Args1,Args2)
        end,
        __eq = function(Args1,Args2)
            return bit_eq(Args1,Args2)
        end
    }

    if bitset_size == nil then
        assert(false)
    end
    local temp_size = nil
    local temp_data = nil
    if type(bitset_size) =="table" then
        temp_data = {}
        for loop = 0,(#bitset_size - 1) do
            if bitset_size[loop] == true then
                table.insert(temp_data,loop)
            end
        end
        temp_size =getn(bitset_size)
    else
        temp_size = bitset_size
    end

    local t = {data = {},inner_size = temp_size,is_debug = true,debug_data = {}}
    local temp_bitset = setmetatable(t,mt)
    if temp_data ~= nil then
        temp_bitset:set(table.unpack(temp_data))
    end
    return temp_bitset
end
function bitset.get_data_table(self)
    local get_data_table = {}
    for index = 0,(self:size() - 1) do
        if self:get(index) ~= true then
            get_data_table[index] = false
        else
            get_data_table[index] = true
        end
    end
    return get_data_table
end
function bitset.size(self)
    return self.inner_size
end
-- set 接口
function bitset.set(self,...)
    local index_list = {...}
    for loop = 1,#index_list do
        if self.is_debug then
            self.debug_data [index_list[loop]] = true
        end
        if self:size() <= index_list[loop] then
            assert(false)
        end
        local element           = index_list[loop]
        local index_inner       = math.floor(element / 32) + 1
        local position_inner    = element % 32
        local data_temp         = self.data
        local buffer            = 1 << position_inner
        -- 内存足时候添加元素
        while #data_temp < index_inner do
            data_temp[#data_temp + 1] = 0
        end
        data_temp[index_inner] = (data_temp[index_inner] or 0) | buffer
    end
    return self
end
function bitset.test(self,index)
    return self:get(index)
end
-- get 接口
function bitset.get(self,...)
    local index_list = {...}
    local rets = {}
    for loop = 1,#index_list do
        if self:size() <= index_list[loop] then
            assert(false)
        end
        local element           = index_list[loop]
        local index_inner       = math.floor(element / 32) + 1
        local position_inner    = element % 32
        local data_temp         = self.data
        local buffer            = 1 << position_inner
        rets[#rets +1] = ((data_temp[index_inner] or 0) & buffer) ~= 0
    end
    if #index_list == 1 then
        return rets[1]
    end
    return rets
end
-- reset 接口
function bitset.reset(self,...)
    local index_list = {...}
    for loop = 1, #index_list do
        if self.is_debug then
            for k,v in pairs(self.debug_data) do
                if k == index_list[loop] then
                    self.debug_data[k] = nil
                end
            end
        end
        if self:size() <= index_list[loop] then
            assert(false)
        end
        local element           = index_list[loop]
        local index_inner       = math.floor(element / 32) + 1
        local data_temp         = self.data
        if #data_temp >= index_inner then
            local position_inner    = element % 32
            local buffer            = ~(1 << position_inner)
            data_temp[index_inner]  = (data_temp[index_inner] or 0) & buffer
        end
    end
    return self
end

function bitset.is_only_type(self,...)
    local index_list = {...}
    local temp = bitset:new(self:size())
    temp:set(index_list)
    return temp == self
end
function bitset.any(self)
    for i = 1, #self.data do
        if self.data[i] ~= 0 then
            return true
        end
    end
    return false
end
function bitset.has_same_type(self,obj)
    local temp
    temp = deep_copy(self)
    temp = temp & obj
    return temp:any()
end
function bitset.get_same_type(self,obj_l,obj_r)
    if self ==  obj_l then
        self = self & obj_r
        return self
    end
    if self == obj_r then
        self = self & obj_l
    end
    self = obj_l & obj_r
end
function bitset.take_off_same(self,obj)
    self = self - obj
end
function bitset.take_off_diff(self,obj)
    self = self & obj
end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熊猫Devin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值