agg_array.h

来自「这是VCF框架的代码」· C头文件 代码 · 共 1,058 行 · 第 1/3 页

H
1,058
字号
        }        template<class DataAccessor> void add_data(DataAccessor& data)        {            while(data.size())            {                add(*data);                ++data;            }        }        void cut_at(unsigned size)        {            if(size < m_size) m_size = size;        }        unsigned size() const { return m_size; }        const T& operator [] (unsigned i) const        {            return m_blocks[i >> block_shift][i & block_mask];        }        T& operator [] (unsigned i)        {            return m_blocks[i >> block_shift][i & block_mask];        }        const T& at(unsigned i) const        {             return m_blocks[i >> block_shift][i & block_mask];        }        T& at(unsigned i)         {             return m_blocks[i >> block_shift][i & block_mask];        }        T value_at(unsigned i) const        {             return m_blocks[i >> block_shift][i & block_mask];        }        const T& curr(unsigned idx) const        {            return (*this)[idx];        }        T& curr(unsigned idx)        {            return (*this)[idx];        }        const T& prev(unsigned idx) const        {            return (*this)[(idx + m_size - 1) % m_size];        }        T& prev(unsigned idx)        {            return (*this)[(idx + m_size - 1) % m_size];        }        const T& next(unsigned idx) const        {            return (*this)[(idx + 1) % m_size];        }        T& next(unsigned idx)        {            return (*this)[(idx + 1) % m_size];        }        const T& last() const        {            return (*this)[m_size - 1];        }        T& last()        {            return (*this)[m_size - 1];        }        unsigned byte_size() const;        void serialize(int8u* ptr) const;        void deserialize(const int8u* data, unsigned byte_size);        void deserialize(unsigned start, const T& empty_val,                          const int8u* data, unsigned byte_size);        template<class ByteAccessor>         void deserialize(ByteAccessor data)        {            remove_all();            unsigned elem_size = data.size() / sizeof(T);            for(unsigned i = 0; i < elem_size; ++i)            {                int8u* ptr = (int8u*)data_ptr();                for(unsigned j = 0; j < sizeof(T); ++j)                {                    *ptr++ = *data;                    ++data;                }                ++m_size;            }        }        template<class ByteAccessor>        void deserialize(unsigned start, const T& empty_val, ByteAccessor data)        {            while(m_size < start)            {                add(empty_val);            }            unsigned elem_size = data.size() / sizeof(T);            for(unsigned i = 0; i < elem_size; ++i)            {                int8u* ptr;                if(start + i < m_size)                {                    ptr = (int8u*)(&((*this)[start + i]));                }                else                {                    ptr = (int8u*)data_ptr();                    ++m_size;                }                for(unsigned j = 0; j < sizeof(T); ++j)                {                    *ptr++ = *data;                    ++data;                }            }        }        const T* block(unsigned nb) const { return m_blocks[nb]; }    private:        void allocate_block(unsigned nb);        T*   data_ptr();        unsigned        m_size;        unsigned        m_num_blocks;        unsigned        m_max_blocks;        T**             m_blocks;        unsigned        m_block_ptr_inc;    };    //------------------------------------------------------------------------    template<class T, unsigned S> pod_bvector<T, S>::~pod_bvector()    {        if(m_num_blocks)        {            T** blk = m_blocks + m_num_blocks - 1;            while(m_num_blocks--)            {                delete [] *blk;                --blk;            }            delete [] m_blocks;        }    }    //------------------------------------------------------------------------    template<class T, unsigned S>     void pod_bvector<T, S>::free_tail(unsigned size)    {        if(size < m_size)        {            unsigned nb = (size + block_mask) >> block_shift;            while(m_num_blocks > nb)            {                delete [] m_blocks[--m_num_blocks];            }            m_size = size;        }    }    //------------------------------------------------------------------------    template<class T, unsigned S> pod_bvector<T, S>::pod_bvector() :        m_size(0),        m_num_blocks(0),        m_max_blocks(0),        m_blocks(0),        m_block_ptr_inc(block_size)    {    }    //------------------------------------------------------------------------    template<class T, unsigned S>     pod_bvector<T, S>::pod_bvector(unsigned block_ptr_inc) :        m_size(0),        m_num_blocks(0),        m_max_blocks(0),        m_blocks(0),        m_block_ptr_inc(block_ptr_inc)    {    }    //------------------------------------------------------------------------    template<class T, unsigned S>     pod_bvector<T, S>::pod_bvector(const pod_bvector<T, S>& v) :        m_size(v.m_size),        m_num_blocks(v.m_num_blocks),        m_max_blocks(v.m_max_blocks),        m_blocks(v.m_max_blocks ? new T* [v.m_max_blocks] : 0),        m_block_ptr_inc(v.m_block_ptr_inc)    {        unsigned i;        for(i = 0; i < v.m_num_blocks; ++i)        {            m_blocks[i] = new T [block_size];            memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T));        }    }    //------------------------------------------------------------------------    template<class T, unsigned S>     const pod_bvector<T, S>&     pod_bvector<T, S>::operator = (const pod_bvector<T, S>& v)    {        unsigned i;        for(i = m_num_blocks; i < v.m_num_blocks; ++i)        {            allocate_block(i);        }        for(i = 0; i < v.m_num_blocks; ++i)        {            memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T));        }        m_size = v.m_size;        return *this;    }    //------------------------------------------------------------------------    template<class T, unsigned S>    void pod_bvector<T, S>::allocate_block(unsigned nb)    {        if(nb >= m_max_blocks)         {            T** new_blocks = new T* [m_max_blocks + m_block_ptr_inc];            if(m_blocks)            {                memcpy(new_blocks,                        m_blocks,                        m_num_blocks * sizeof(T*));                delete [] m_blocks;            }            m_blocks = new_blocks;            m_max_blocks += m_block_ptr_inc;        }        m_blocks[nb] = new T [block_size];        m_num_blocks++;    }    //------------------------------------------------------------------------    template<class T, unsigned S>    inline T* pod_bvector<T, S>::data_ptr()    {        unsigned nb = m_size >> block_shift;        if(nb >= m_num_blocks)        {            allocate_block(nb);        }        return m_blocks[nb] + (m_size & block_mask);    }    //------------------------------------------------------------------------    template<class T, unsigned S>     inline void pod_bvector<T, S>::add(const T& val)    {        *data_ptr() = val;        ++m_size;    }    //------------------------------------------------------------------------    template<class T, unsigned S>     inline void pod_bvector<T, S>::remove_last()    {        if(m_size) --m_size;    }    //------------------------------------------------------------------------    template<class T, unsigned S>     void pod_bvector<T, S>::modify_last(const T& val)    {        remove_last();        add(val);    }    //------------------------------------------------------------------------    template<class T, unsigned S>     int pod_bvector<T, S>::allocate_continuous_block(unsigned num_elements)    {        if(num_elements < block_size)        {            data_ptr(); // Allocate initial block if necessary            unsigned rest = block_size - (m_size & block_mask);            unsigned index;            if(num_elements <= rest)            {                // The rest of the block is good, we can use it                //-----------------                index = m_size;                m_size += num_elements;                return index;            }            // New block            //---------------            m_size += rest;            data_ptr();            index = m_size;            m_size += num_elements;            return index;        }        return -1; // Impossible to allocate    }    //------------------------------------------------------------------------    template<class T, unsigned S>     unsigned pod_bvector<T, S>::byte_size() const    {        return m_size * sizeof(T);    }    //------------------------------------------------------------------------    template<class T, unsigned S>     void pod_bvector<T, S>::serialize(int8u* ptr) const    {        unsigned i;        for(i = 0; i < m_size; i++)        {            memcpy(ptr, &(*this)[i], sizeof(T));

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?