ハッシュコンテナの使用


stlのコンテナライブラリは非常に強力ですが、様々な要素タイプを互換化するためにテンプレートを採用して汎化する利点は、非常に使いやすいことですが、コンパイラは使用した各タイプをインスタンス化し、使用するタイプが多すぎるとコンパイル速度に影響するだけでなく、生成された実行可能ファイルも冗長になります.
そこでTBOXは,コンテナアーキテクチャを設計する際にtb_を導入する.item_func_tタイプは、コンテナが使用するメンバータイプを設定することで、コンテナの汎用性を実現するとともに、冗長性が発生せず、コンテナインタフェースの操作も同様にかなり便利である.
ハッシュを簡単に使用する例を見てみましょう.
/*    hash,      8
 *  :        
 *  :long  
 */
tb_hash_ref_t hash = tb_hash_init(8, tb_item_func_str(tb_true), tb_item_func_long());
if (hash)
{
    //      :"key" => 123
    tb_hash_set(hash, "key", (tb_pointer_t)123);

    //    
    tb_long_t value = (tb_long_t)tb_hash_get(hash, "key");

    //   hash
    tb_hash_exit(hash);
}

/*    hash,      : TB_HASH_BULK_SIZE_MICRO
 *  :tb_struct_xxxx_t      ,     hash      ,                  
 *  :true  ,   tb_true,   hash   stl set<tb_struct_xxxx_t>,       value     
 */
tb_hash_ref_t hash = tb_hash_init(TB_HASH_BULK_SIZE_MICRO, tb_item_func_mem(sizeof(tb_struct_xxxx_t), tb_null, tb_null), tb_item_func_true());
if (hash)
{
    //    tb_struct_xxxx_t
    tb_struct_xxxx_t xxxx = {0};

    //      :xxxx => tb_true
    tb_hash_set(hash, &xxxx, (tb_pointer_t)tb_true);

    //        
    if (tb_hash_get(hash, &xxxx)) 
    {
        // ...
    }

    //   hash
    tb_hash_exit(hash);
}

/*    hash,            : 0
 *  :         
 *  :uint8  
 */
tb_hash_ref_t hash = tb_hash_init(0, tb_item_func_str(tb_false), tb_item_func_uint8());
if (hash)
{
    //      :"key" => 123
    tb_hash_set(hash, "key", (tb_pointer_t)123);

    //   u     
    tb_uint8_t value = (tb_uint8_t)tb_hash_get(hash, "key");

    //   hash
    tb_hash_exit(hash);
}

どうですか.簡単でしょう.様々なタイプのアイテムは、キー値で相互に使用でき、tb_に適しています.hash_getとtb_hash_setなどのコンテナインタフェースパラメータ.
コンテナを初期化するときに、カスタムメンバー解放関数、メンバー比較関数、ハッシュ計算関数などを簡単に使用できます.たとえば、次のようになります.
//         
static tb_void_t tb_hash_item_ptr_free(tb_item_func_t* func, tb_pointer_t buff)
{
    //     
    tb_assert_and_check_return(func && buff);

    //         
    tb_pointer_t priv = func->priv;

    /*       ,   tb_pointer_t  ,buff          
     *
     *    tb_item_func_str()   ,    :
     * tb_char_t* data = *((tb_char_t**)buff);
     *    
     *    tb_item_func_mem()   ,    :
     * tb_byte_t* data = (tb_byte_t*)buff;
     *
     *   tb_item_func_mem                   ,  
     * buff              
     *
     *  str、ptr           ,  item         ,    
     *    ,        
     */
    tb_pointer_t data = *((tb_pointer_t*)buff);

    //    
    if (data) tb_free(data);

    //       
    *((tb_pointer_t*)buff) = tb_null;
}

// long     ,      
static tb_long_t tb_hash_item_long_comp(tb_item_func_t* func, tb_cpointer_t ldata, tb_cpointer_t rdata)
{
    return ((tb_long_t)ldata < (tb_long_t)rdata? 1 : ((tb_long_t)ldata > (tb_long_t)rdata? -1 : 0));
}

//    long      
tb_item_func_t func = tb_item_func_long();

//       , ptr        ,        
func.comp = tb_hash_item_long_comp;

//    hash
tb_hash_ref_t hash = tb_hash_init(0, func, tb_item_func_ptr(tb_hash_item_ptr_free, "private data"));
  • TBOXプロジェクト詳細
  • TBOXプロジェクトソース
  • TBOXプロジェクトドキュメント