within the STL, the Map,set is implemented using the same red-black tree, the map corresponds to the template parameter key_type,mapped_type, and the set The corresponding template parameter has no mapped_type
both support insert operations
Pair<iterator, bool> Insert (const value_type& value);
??
for Map
typedef pair<key_type, mapped_type> Value_type;
for Set
Typdef Key_type Value_type;
??
so in the extension library Pb_ds ( code in ext/pb_ds)
It 's designed like this, like trie.
Trie<string, int> says key is string,mapped is int
Trie<string, null_type> says that key is a string without mapped similar to a trieset concept.
so how to do this, such as writing a trie structure, how to better avoid triemap,trieset code duplication, while providing two kinds of implementations (Trieset No mapped takes up less space ).
??
In addition to the template class commonly used techniques traits and tag forward , here to use the #define #endef skills, first look at the Folly of a
about the Fbvector 's test.
In the . h of test
Testfun (clause_23_3_6_1_1) {
VECTOR v;
Expect_true (V.empty ());
Vector::allocator_type A;
VECTOR v1 (a);
Expect_true (V1.empty ());
}
??
in the cpp of test
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 is a similar approach.
#define Pb_ds_data_true_indicator
#define PB_DS_V2F (x) (x).
#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
Here's a look at the 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:
??
In fact, two times, # include PAT_TRIE_.HPP, respectively, define
Pat_trie_map and Pat_trie_set
??
look inside the class Pb_ds_pat_trie_name.
Inline std::p air<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
}
??
look at the implementation of This insert pat_trie_/insert_join_fn_imps.hpp
Pb_ds_class_t_dec
Inline std::p air<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, that's what it means. when used in map pb_ds_v2f is x.first and set inside uses pb_ds_v2f is x itself.
??
??
Using # define to implement multiple approximate codes-application in Map,set