/*
序列式容器 ( Sequence containers ):
- 陣列 Array
- 向量 Vector
- 串列 List
- 雙端佇列 Deque
 
容器配接器 ( Sequence containers ):
 
- 堆疊 Stack
- 佇列 Queue
 
關聯性容器 ( Associative containers )
 
- 集合 Set
- 可重複集合 Multiset
- 映射 Map
- 可重複映射 Multimap
- 無排序關聯性容器 (Unordered associative containers)
- 無排序集合 Unordered_set
- 無排序可重複集合 Unordered_multiset
- 無排序映射 Unordered_map
- 無排序可重複映射 Unordered_multimap
*/
 
#include <array>
#include <vector>
#include <list>
#include <forward_list>
#include <deque>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>

map & multimap

Insert

For map:

 
iterator insert(const_iterator __pos, _Pp&& __p)
	{return __tree_.__insert_unique(__pos.__i_, _VSTD::forward<_Pp>(__p));}
 

For multimap

iterator insert(const_iterator __p, value_type&& __v)
	{return __tree_.__insert_multi(__p.__i_, _VSTD::move(__v));}
 

可觀察到在 map 和 multimap 當中,insert 都會回傳 iterator,而傳入的參數都是 iterator 和要 insert 的 value。對於 map 來說,常見的 insert 方式是可參考 std::map::insert。而 __tree 就是 C++ 中的 Red Black Tree。

造成 map 不能有 duplicate key 而 multimap 可以的就是 __insert_unique__insert_multi 的差別。

iterator __insert_unique(const_iterator __p, _Vp&& __v) {
	return __emplace_hint_unique(__p, _VSTD::forward<_Vp>(__v));
}
 
iterator __insert_multi(const_iterator __p, __container_value_type&& __v) {
	return __emplace_hint_multi(__p, _VSTD::move(__v));
}

hint 就是我們傳入的 iterator

__insert_unique 會回傳 __emplace_hint_unique__emplace_hint_unique 會回傳__emplace_hint_unique_extract_key__emplace_hint_unique_extract_key 會回傳 __emplace_hint_unique_impl

iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) {
        return __emplace_hint_unique_extract_key(__p, _VSTD::forward<_Pp>(__x), __can_extract_key<_Pp, key_type>());
}
 
iterator __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) {
	return __emplace_hint_unique_impl(__p, _VSTD::forward<_Pp>(__x));
}

重點在於 __find_equal

template <class _Tp, class _Compare, class _Allocator>
template <class... _Args>
typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>:: __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args)
{
    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
    __parent_pointer __parent;
    __node_base_pointer __dummy;
    __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_);
    __node_pointer __r = static_cast<__node_pointer>(__child);
    if (__child == nullptr)
    {
        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
        __r = __h.release();
    }
    return iterator(__r);
}

__emplace_hint_multi 定義如下,重點在於 __find_leaf

template <class _Tp, class _Compare, class _Allocator>
template <class... _Args>
typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p,
                                                        _Args&&... __args)
{
    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
    __parent_pointer __parent;
    __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__h->__value_));
    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
    return iterator(static_cast<__node_pointer>(__h.release()));
}