⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yc_chkarray.c

📁 一个类STL的多平台可移植的算法容器库,主要用于嵌入式系统编程时的内存管理等方面
💻 C
📖 第 1 页 / 共 4 页
字号:
    if( false == chkarr_insert_append(self, index, count) )
        return false;

    if( index < (old_len / 2) )  /* 移动前面的元素 */
    {
        chkarr_iterator insert_start;

        pos = chkarr_itr_add( self->m_start, index + count );
        insert_start = chkarr_itr_sub( pos, count );

        if( !src )
        {
            if( self->m_elmt_init && index < count )
                chkarr_init_range( self, &insert_start, count - index );
        }
        else
        {
            if( count <= index )
            {
                chkarr_copy_array( self, &insert_start, src, count,
                                   self->m_elmt_assign_copy );
            }
            else
            {
                ylib_byte_t* src_mid = (ylib_byte_t*)src + (count - index)
                                       * self->m_element_size;

                chkarr_copy_array( self, &insert_start, src, count - index,
                                   self->m_elmt_init_copy );

                chkarr_copy_array( self, &insert_start, src_mid, index,
                                   self->m_elmt_assign_copy );
            }
        }
    }
    else  /* 移动后面的元素 */
    {
        size_t after = old_len - index;
        pos = chkarr_itr_sub( self->m_finish, after + count );

        if( !src )
        {
            chkarr_itr_inc_n( &pos, after );
            if( self->m_elmt_init && after < count )
            {
                chkarr_init_range( self, &pos, count - after );
            }
        }
        else
        {
            if( count <= after )
            {
                chkarr_copy_array( self, &pos, src, count,
                                   self->m_elmt_assign_copy );
            }
            else
            {
                ylib_byte_t* mid = (ylib_byte_t*)src
                                   + after * self->m_element_size;

                chkarr_copy_array( self, &pos, src, after,
                                   self->m_elmt_assign_copy );

                chkarr_copy_array( self, &pos, mid, count - after,
                                   self->m_elmt_init_copy );
            }
        }
    }

    return true;
}

/******************************************************************************/

bool chkarr_replace_fill( chkarray* self,
                          size_t index,
                          size_t old_count,
                          const void* value,
                          size_t new_count )
{
    chkarr_iterator pos;
    size_t keep, len = chkarr_itr_diff( &(self->m_finish), &(self->m_start) );

    if( index > len )
        return false;

    if( old_count > len - index )
        old_count = len - index;

    if( len - old_count > chkarr_max_size() - new_count )
        return false;

    if( value )
    {
        keep = old_count < new_count ? old_count : new_count;
        pos = chkarr_itr_add( self->m_start, index );
        chkarr_fill_value( self, &pos, value, keep, self->m_elmt_assign_copy );
    }

    if( old_count < new_count )
        return chkarr_insert_value( self, index + old_count, value,
                                    new_count - old_count );
    else if( old_count > new_count )
        chkarr_erase_range( self, index + new_count, index + old_count );

    return true;
}

/******************************************************************************/

bool chkarr_replace_array( chkarray* self,
                           size_t index,
                           size_t old_count,
                           const void* src,
                           size_t new_count )
{
    chkarr_iterator pos;
    size_t keep, len = chkarr_itr_diff( &(self->m_finish), &(self->m_start) );

    if( index > len )
        return false;

    if( old_count > len - index )
        old_count = len - index;

    if( len - old_count > chkarr_max_size() - new_count )
        return false;

    if( src )
    {
        keep = old_count < new_count ? old_count : new_count;
        pos = chkarr_itr_add( self->m_start, index );
        chkarr_copy_array( self, &pos, src, keep, self->m_elmt_assign_copy );
        src = (ylib_byte_t*)src + keep * self->m_element_size;
    }

    if( old_count < new_count )
        return chkarr_insert_array( self, index + old_count, src,
                                    new_count - old_count );
    else if( old_count > new_count )
        chkarr_erase_range( self, index + new_count, index + old_count );

    return true;
}

/******************************************************************************/

void chkarr_pop_back( chkarray* self )
{
    if( self->m_start.current == self->m_finish.current )
        return;

    if( self->m_finish.current != self->m_finish.first )
    {
        self->m_finish.current = (ylib_byte_t*)(self->m_finish.current)
                                 - self->m_element_size;
    }
    else
    {
        self->m_dealloc( self->m_finish.first, self->m_chunk_size );
        *( self->m_finish.map ) = NULL;
        chkarr_itr_set_chunk( &(self->m_finish),
                              self->m_finish.map - 1 );
        self->m_finish.current = (ylib_byte_t*)(self->m_finish.last)
                                 - self->m_element_size;
    }

    if( self->m_elmt_destroy )
        self->m_elmt_destroy( self->m_finish.current );
}

/******************************************************************************/

void chkarr_pop_front( chkarray* self )
{
    if( self->m_start.current == self->m_finish.current )
        return;

    if( self->m_elmt_destroy )
        self->m_elmt_destroy( self->m_start.current );

    self->m_start.current = (ylib_byte_t*)(self->m_start.current)
                            + self->m_element_size;

    if( self->m_start.current == self->m_start.last )
    {
        self->m_dealloc( self->m_start.first, self->m_chunk_size );
        *( self->m_start.map ) = NULL;
        chkarr_itr_set_chunk( &(self->m_start), self->m_start.map + 1 );
        self->m_start.current = self->m_start.first;
    }
}

/******************************************************************************/

bool chkarr_push_back( chkarray* self, const void* value )
{
    if( self->m_chunk_array && self->m_finish.current
        != (ylib_byte_t*)(self->m_finish.last) - self->m_element_size )
    {
        if( self->m_elmt_init_copy )
            self->m_elmt_init_copy( self->m_finish.current, value );
        else
            ylib_memcopy( self->m_finish.current, value, self->m_element_size );
    }
    else  /* allocate chunk */
    {
        bool empty_array = ( self->m_chunk_array ? false : true );

        if( false == chkarr_reserve_array(self, 1, false) )
            return false;

        /* 如果 m_chunk_array 为空,则在调用 chkarr_reserve_array 函数时
         * 会自动分配一块 chunk,否则必须手动分配一块 */
        if( false == empty_array )
        {
            *(self->m_finish.map + 1) = self->m_alloc( self->m_chunk_size );

            if( !(*(self->m_finish.map + 1)) )
                return false;
        }

        if( self->m_elmt_init_copy )
            self->m_elmt_init_copy( self->m_finish.current, value );
        else
            ylib_memcopy( self->m_finish.current, value, self->m_element_size );

        if( false == empty_array )
        {
            chkarr_itr_set_chunk( &(self->m_finish),
                                  self->m_finish.map + 1 );
            self->m_finish.current = self->m_finish.first;
            return true;
        }
    }

    self->m_finish.current = (ylib_byte_t*)(self->m_finish.current)
                             + self->m_element_size;

    return true;
}

/******************************************************************************/

bool chkarr_push_front( chkarray* self, const void* value )
{
    if( self->m_start.current != self->m_start.first )
    {
        self->m_start.current = (ylib_byte_t*)(self->m_start.current)
                                - self->m_element_size;

        if( self->m_elmt_init_copy )
            self->m_elmt_init_copy( self->m_start.current, value );
        else
            ylib_memcopy( self->m_start.current, value, self->m_element_size );
    }
    else  /* allocate chunk */
    {
        bool empty_array = ( self->m_chunk_array ? false : true );

        if( false == chkarr_reserve_array(self, 1, true) )
            return false;

        /* 如果 m_chunk_array 为空,则在调用 chkarr_reserve_array 函数时
         * 会自动分配一块 chunk,否则必须手动分配一块 */
        if( true == empty_array )
            self->m_finish.current = (ylib_byte_t*)(self->m_finish.current)
                                     + self->m_element_size;
        else
        {
            *(self->m_start.map - 1) = self->m_alloc( self->m_chunk_size );

            if( !(*(self->m_start.map - 1)) )
                return false;

            chkarr_itr_set_chunk( &(self->m_start),
                                  self->m_start.map - 1 );
            self->m_start.current = (ylib_byte_t*)(self->m_start.last)
                                    - self->m_element_size;
        }

        if( self->m_elmt_init_copy )
            self->m_elmt_init_copy( self->m_start.current, value );
        else
            ylib_memcopy( self->m_start.current, value, self->m_element_size );
    }

    return true;
}

/******************************************************************************/

bool chkarr_resize( chkarray* self, size_t new_length, const void* value )
{
    size_t len = chkarr_itr_diff( &(self->m_finish), &(self->m_start) );

    if( len < new_length )
        return chkarr_insert_value( self, len, value, new_length - len );
    else if( len > new_length )
        chkarr_erase_range( self, new_length, len );

    return true;
}

/******************************************************************************/

#ifndef __MACRO_C_YOUNG_LIBRARY_COMPILER_SUPPORT_INLINE_FUNCTION__
    bool chkarr_empty( chkarray* self )
    {
        return self->m_start.current == self->m_finish.current ? true : false;
    }

/******************************************************************************/

    size_t chkarr_size( chkarray* self )
    {
        return chkarr_itr_diff( &(self->m_finish), &(self->m_start) );
    }

/******************************************************************************/

    size_t chkarr_max_size( void )
    {
        return SIZE_MAX;
    }

/******************************************************************************/

    size_t chkarr_chunk_size( chkarray* self )
    {
        return self->m_chunk_size;
    }

/******************************************************************************/

    size_t chkarr_chunk_elements( chkarray* self )
    {
        return self->m_chunk_size / self->m_element_size;
    }

/******************************************************************************/

    chkarr_iterator chkarr_begin( chkarray* self )
    {
        return self->m_start;
    }

/******************************************************************************/

    chkarr_iterator chkarr_end( chkarray* self )
    {
        return self->m_finish;
    }

/******************************************************************************/

    void* chkarr_front( chkarray* self )
    {
        return self->m_start.current;
    }

/******************************************************************************/

    void* chkarr_back( chkarray* self )
    {
        return chkarr_itr_sub( self->m_finish, 1 ).current;
    }

/******************************************************************************/

    void* chkarr_index( chkarray* self, size_t index )
    {
        return chkarr_itr_add( self->m_start, index ).current;
    }

/******************************************************************************/

    void* chkarr_at( chkarray* self, size_t index )
    {
        return index < (size_t)chkarr_itr_diff( &(self->m_finish),
                                                &(self->m_start) );
               ? chkarr_itr_add( self->m_start, index ).current : NULL;
    }
#endif

/******************************************************************************/
/******************************************************************************/
#ifdef __cplusplus
    }  }
#endif
/******************************************************************************/
/******************************************************************************/

⌨️ 快捷键说明

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