用#define來實現多份近似代碼 - map,set中的應用

來源:互聯網
上載者:User

標籤:

在stl中map,set內部都是使用相同的紅/黑樹狀結構實現,map對應模板參數key_type,mapped_type,而set對應模板參數沒有mapped_type

兩者都支援insert操作

pair<iterator, bool> insert(const value_type& value);

??

對於map

typedef pair<key_type, mapped_type> value_type;

對於set

typdef key_type value_type;

??

那麼在擴充庫pb_ds中(代碼在ext/pb_ds)

是這樣設計的,比如trie

trie<string, int> 表示key是string,mapped 是int

trie<string, null_type> 表示key是string 沒有mapped 類似一個TrieSet的概念。

那麼是怎樣做到這些的呢,比如自己寫一個trie的結構,如何更好的避免TrieMap,TrieSet的實現代碼重複,同時能提供兩種實現(TrieSet沒有mapped佔用更少空間)。

??

除了模板類常用的技巧traits和tag forward之外,這裡用到了#define #endef的技巧,先看下folly的一個

關於FBVector的test。

在test的.h中

TESTFUN(clause_23_3_6_1_1) {

VECTOR v;

EXPECT_TRUE(v.empty());

VECTOR::allocator_type a;

VECTOR v1(a);

EXPECT_TRUE(v1.empty());

}

??

在test的cpp中

typedef vector<int> IntVector;

typedef fbvector<int> IntFBVector;

typedef vector<folly::fbstring> FBStringVector;

typedef fbvector<folly::fbstring> FBStringFBVector

??

#define VECTOR IntVector

#include <folly/test/FBVectorTestBenchmarks.cpp.h> // nolint

#undef VECTOR

#define VECTOR IntFBVector

#include <folly/test/FBVectorTestBenchmarks.cpp.h> // nolint

#undef VECTOR

#define VECTOR FBStringVector

#include <folly/test/FBVectorTestBenchmarks.cpp.h> // nolint

#undef VECTOR

#define VECTOR FBStringFBVector

#include <folly/test/FBVectorTestBenchmarks.cpp.h> // nolint

#undef VECTOR

??

pb_ds也是類似的方法

#define PB_DS_DATA_TRUE_INDICATOR

#define PB_DS_V2F(X) (X).first

#include <ext/pb_ds/detail/pat_trie_/pat_trie_.hpp>

#undef PB_DS_DATA_TRUE_INDICATOR

#undef PB_DS_V2F

??

#define PB_DS_DATA_FALSE_INDICATOR

#define PB_DS_V2F(X) (X)

#include <ext/pb_ds/detail/pat_trie_/pat_trie_.hpp>

#undef PB_DS_DATA_FALSE_INDICATOR

#undef PB_DS_V2F

這裡看下pat_trie_.hpp

#ifdef PB_DS_DATA_TRUE_INDICATOR

#define PB_DS_PAT_TRIE_NAME pat_trie_map

#endif

??

#ifdef PB_DS_DATA_FALSE_INDICATOR

#define PB_DS_PAT_TRIE_NAME pat_trie_set

#endif

??

template<typename Key, typename Mapped, typename Node_And_It_Traits,

typename _Alloc>

class PB_DS_PAT_TRIE_NAME :

??

也就是其實兩次#include pat_trie_.hpp分別定義了

pat_trie_map和pat_trie_set

??

看看class PB_DS_PAT_TRIE_NAME內部

inline std::pair<point_iterator, bool>

insert(const_reference);

??

inline mapped_reference

operator[](key_const_reference r_key)

{

#ifdef PB_DS_DATA_TRUE_INDICATOR

return insert(std::make_pair(r_key, mapped_type())).first->second;

#else

insert(r_key);

return traits_base::s_null_type;

#endif

}

??

看下這個insert的實現pat_trie_/insert_join_fn_imps.hpp

PB_DS_CLASS_T_DEC

inline std::pair<typename PB_DS_CLASS_C_DEC::iterator, bool>

PB_DS_CLASS_C_DEC::

insert(const_reference r_val)

{

node_pointer p_lf = find_imp(PB_DS_V2F(r_val));

if (p_lf != 0 && p_lf->m_type == leaf_node &&

synth_access_traits::equal_keys(PB_DS_V2F(static_cast<leaf_pointer>(p_lf)->value()), PB_DS_V2F(r_val)))

{

PB_DS_CHECK_KEY_EXISTS(PB_DS_V2F(r_val))

PB_DS_ASSERT_VALID((*this))

return std::make_pair(iterator(p_lf), false);

}

??

PB_DS_CHECK_KEY_DOES_NOT_EXIST(PB_DS_V2F(r_val))

??

leaf_pointer p_new_lf = s_leaf_allocator.allocate(1);

cond_dealtor cond(p_new_lf);

??

new (p_new_lf) leaf(r_val);

apply_update(p_new_lf, (node_update*)this);

cond.set_call_destructor();

branch_bag bag;

bag.add_branch();

m_p_head->m_p_parent = rec_join(m_p_head->m_p_parent, p_new_lf, 0, bag);

m_p_head->m_p_parent->m_p_parent = m_p_head;

cond.set_no_action_dtor();

++m_size;

update_min_max_for_inserted_leaf(p_new_lf);

_GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));)

PB_DS_ASSERT_VALID((*this))

return std::make_pair(point_iterator(p_new_lf), true);

}

??

OK,就是這麼個意思了。。 map裡面使用的時候PB_DS_V2F是 x.first 而set裡面使用PB_DS_V2F就是x本身。

??

??

用#define來實現多份近似代碼 - map,set中的應用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.